4848
4949#include "rp1_vec.h"
5050
51- /*
52- * Default TV standard parameter; it may be overridden by the OF
53- * property "tv_norm" (which should be one of the strings below).
54- *
55- * The default (empty string) supports various 60Hz and 50Hz modes,
56- * and will automatically select NTSC[-M] or PAL[-BDGHIKL]; the two
57- * "fake" 60Hz standards NTSC-443 and PAL60 also support 50Hz PAL.
58- * Other values will restrict the set of video modes offered.
59- *
60- * Finally, the DRM connector property "mode" (which is an integer)
61- * can be used to override this value, but it does not prevent the
62- * selection of an inapplicable video mode.
63- */
64-
65- static char * rp1vec_tv_norm_str ;
66- module_param_named (tv_norm , rp1vec_tv_norm_str , charp , 0600 );
67- MODULE_PARM_DESC (tv_norm , "Default TV norm.\n"
68- "\t\tSupported: NTSC, NTSC-J, NTSC-443, PAL, PAL-M, PAL-N,\n"
69- "\t\t\tPAL60.\n"
70- "\t\tDefault: empty string: infer PAL for a 50 Hz mode,\n"
71- "\t\t\tNTSC otherwise" );
72-
73- const char * const rp1vec_tvstd_names [] = {
74- [RP1VEC_TVSTD_NTSC ] = "NTSC" ,
75- [RP1VEC_TVSTD_NTSC_J ] = "NTSC-J" ,
76- [RP1VEC_TVSTD_NTSC_443 ] = "NTSC-443" ,
77- [RP1VEC_TVSTD_PAL ] = "PAL" ,
78- [RP1VEC_TVSTD_PAL_M ] = "PAL-M" ,
79- [RP1VEC_TVSTD_PAL_N ] = "PAL-N" ,
80- [RP1VEC_TVSTD_PAL60 ] = "PAL60" ,
81- [RP1VEC_TVSTD_DEFAULT ] = "" ,
82- };
83-
84- static int rp1vec_parse_tv_norm (const char * str )
85- {
86- int i ;
87-
88- if (str && * str ) {
89- for (i = 0 ; i < ARRAY_SIZE (rp1vec_tvstd_names ); ++ i ) {
90- if (strcasecmp (str , rp1vec_tvstd_names [i ]) == 0 )
91- return i ;
92- }
93- }
94- return RP1VEC_TVSTD_DEFAULT ;
95- }
96-
9751static void rp1vec_pipe_update (struct drm_simple_display_pipe * pipe ,
9852 struct drm_plane_state * old_state )
9953{
@@ -143,7 +97,7 @@ static void rp1vec_pipe_update(struct drm_simple_display_pipe *pipe,
14397
14498static void rp1vec_pipe_enable (struct drm_simple_display_pipe * pipe ,
14599 struct drm_crtc_state * crtc_state ,
146- struct drm_plane_state * plane_state )
100+ struct drm_plane_state * plane_state )
147101{
148102 struct rp1_vec * vec = pipe -> crtc .dev -> dev_private ;
149103
@@ -219,48 +173,64 @@ static const struct drm_display_mode rp1vec_modes[4] = {
219173 },
220174 { /* Full size 625/50i with Rec.601 pixel rate */
221175 DRM_MODE ("720x576i" , DRM_MODE_TYPE_DRIVER , 13500 ,
222- 720 , 720 + 20 , 720 + 20 + 64 , 864 , 0 ,
176+ 720 , 720 + 12 , 720 + 12 + 64 , 864 , 0 ,
223177 576 , 576 + 5 , 576 + 5 + 5 , 625 , 0 ,
224178 DRM_MODE_FLAG_INTERLACE )
225179 },
226180 { /* Cropped and squashed, for square(ish) pixels */
227181 DRM_MODE ("704x512i" , DRM_MODE_TYPE_DRIVER , 15429 ,
228- 704 , 704 + 80 , 704 + 80 + 72 , 987 , 0 ,
182+ 704 , 704 + 72 , 704 + 72 + 72 , 987 , 0 ,
229183 512 , 512 + 37 , 512 + 37 + 5 , 625 , 0 ,
230184 DRM_MODE_FLAG_INTERLACE )
231185 }
232186};
233187
188+ /*
189+ * Advertise standard and preferred video modes.
190+ *
191+ * From each interlaced mode in the table above, derive a progressive one.
192+ *
193+ * This driver always supports all 50Hz and 60Hz video modes, regardless
194+ * of connector's tv_mode; nonstandard combinations generally default
195+ * to PAL[-BDGHIKL] or NTSC[-M] depending on resolution and field-rate
196+ * (except that "PAL" with 525/60 will be implemented as "PAL60").
197+ * However, the preferred mode will depend on the default TV mode.
198+ */
199+
234200static int rp1vec_connector_get_modes (struct drm_connector * connector )
235201{
236- struct rp1_vec * vec = container_of (connector , struct rp1_vec , connector );
237- bool ok525 = RP1VEC_TVSTD_SUPPORT_525 (vec -> tv_norm );
238- bool ok625 = RP1VEC_TVSTD_SUPPORT_625 (vec -> tv_norm );
202+ u64 val ;
239203 int i , prog , n = 0 ;
204+ bool prefer625 = false;
205+
206+ if (!drm_object_property_get_default_value (& connector -> base ,
207+ connector -> dev -> mode_config .tv_mode_property ,
208+ & val ))
209+ prefer625 = (val == DRM_MODE_TV_MODE_PAL ||
210+ val == DRM_MODE_TV_MODE_PAL_N ||
211+ val == DRM_MODE_TV_MODE_SECAM );
240212
241213 for (i = 0 ; i < ARRAY_SIZE (rp1vec_modes ); i ++ ) {
242- if ((rp1vec_modes [i ].vtotal == 625 ) ? ok625 : ok525 ) {
243- for (prog = 0 ; prog < 2 ; prog ++ ) {
244- struct drm_display_mode * mode =
245- drm_mode_duplicate (connector -> dev ,
246- & rp1vec_modes [i ]);
247-
248- if (prog ) {
249- mode -> flags &= ~DRM_MODE_FLAG_INTERLACE ;
250- mode -> vdisplay >>= 1 ;
251- mode -> vsync_start >>= 1 ;
252- mode -> vsync_end >>= 1 ;
253- mode -> vtotal >>= 1 ;
254- }
255-
256- if (mode -> hdisplay == 704 &&
257- mode -> vtotal == ((ok525 ) ? 525 : 625 ))
258- mode -> type |= DRM_MODE_TYPE_PREFERRED ;
259-
260- drm_mode_set_name (mode );
261- drm_mode_probed_add (connector , mode );
262- n ++ ;
214+ for (prog = 0 ; prog < 2 ; prog ++ ) {
215+ struct drm_display_mode * mode =
216+ drm_mode_duplicate (connector -> dev ,
217+ & rp1vec_modes [i ]);
218+
219+ if (prog ) {
220+ mode -> flags &= ~DRM_MODE_FLAG_INTERLACE ;
221+ mode -> vdisplay >>= 1 ;
222+ mode -> vsync_start >>= 1 ;
223+ mode -> vsync_end >>= 1 ;
224+ mode -> vtotal >>= 1 ;
263225 }
226+
227+ if (mode -> hdisplay == 704 &&
228+ mode -> vtotal == (prefer625 ? 625 : 525 ))
229+ mode -> type |= DRM_MODE_TYPE_PREFERRED ;
230+
231+ drm_mode_set_name (mode );
232+ drm_mode_probed_add (connector , mode );
233+ n ++ ;
264234 }
265235 }
266236
@@ -269,11 +239,8 @@ static int rp1vec_connector_get_modes(struct drm_connector *connector)
269239
270240static void rp1vec_connector_reset (struct drm_connector * connector )
271241{
272- struct rp1_vec * vec = container_of (connector , struct rp1_vec , connector );
273-
274242 drm_atomic_helper_connector_reset (connector );
275- if (connector -> state )
276- connector -> state -> tv .mode = vec -> tv_norm ;
243+ drm_atomic_helper_connector_tv_reset (connector );
277244}
278245
279246static int rp1vec_connector_atomic_check (struct drm_connector * conn ,
@@ -396,7 +363,6 @@ static int rp1vec_platform_probe(struct platform_device *pdev)
396363 struct device * dev = & pdev -> dev ;
397364 struct drm_device * drm ;
398365 struct rp1_vec * vec ;
399- const char * str ;
400366 int i , ret ;
401367
402368 dev_info (dev , __func__ );
@@ -419,10 +385,6 @@ static int rp1vec_platform_probe(struct platform_device *pdev)
419385 drm -> dev_private = vec ;
420386 platform_set_drvdata (pdev , drm );
421387
422- str = rp1vec_tv_norm_str ;
423- of_property_read_string (dev -> of_node , "tv_norm" , & str );
424- vec -> tv_norm = rp1vec_parse_tv_norm (str );
425-
426388 for (i = 0 ; i < RP1VEC_NUM_HW_BLOCKS ; i ++ ) {
427389 vec -> hw_base [i ] =
428390 devm_ioremap_resource (dev ,
@@ -463,9 +425,7 @@ static int rp1vec_platform_probe(struct platform_device *pdev)
463425 drm -> mode_config .funcs = & rp1vec_mode_funcs ;
464426 drm_vblank_init (drm , 1 );
465427
466- ret = drm_mode_create_tv_properties_legacy (drm ,
467- ARRAY_SIZE (rp1vec_tvstd_names ),
468- rp1vec_tvstd_names );
428+ ret = drm_mode_create_tv_properties (drm , RP1VEC_SUPPORTED_TV_MODES );
469429 if (ret )
470430 goto err_free_drm ;
471431
@@ -479,7 +439,9 @@ static int rp1vec_platform_probe(struct platform_device *pdev)
479439
480440 drm_object_attach_property (& vec -> connector .base ,
481441 drm -> mode_config .tv_mode_property ,
482- vec -> tv_norm );
442+ (vec -> connector .cmdline_mode .tv_mode_specified ) ?
443+ vec -> connector .cmdline_mode .tv_mode :
444+ DRM_MODE_TV_MODE_NTSC );
483445
484446 ret = drm_simple_display_pipe_init (drm ,
485447 & vec -> pipe ,
0 commit comments