49
49
#include "rp1_vec.h"
50
50
51
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.
52
+ * Default initial TV standard parameter; it may be overridden
53
+ * by the command-line "video/tv_mode" option where specified.
54
+ * It is used to initialize the connector's "tv_mode" property
55
+ * and affects which video mode will be preferred.
63
56
*/
64
57
65
58
static char * rp1vec_tv_norm_str ;
66
59
module_param_named (tv_norm , rp1vec_tv_norm_str , charp , 0600 );
67
60
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
- }
61
+ "\t\tSupported: NTSC, NTSC-J, NTSC-443, PAL, PAL-M, PAL-N\n"
62
+ "\t\tDefault: NTSC (but 50Hz modes will default to PAL)" );
96
63
97
64
static void rp1vec_pipe_update (struct drm_simple_display_pipe * pipe ,
98
65
struct drm_plane_state * old_state )
@@ -143,7 +110,7 @@ static void rp1vec_pipe_update(struct drm_simple_display_pipe *pipe,
143
110
144
111
static void rp1vec_pipe_enable (struct drm_simple_display_pipe * pipe ,
145
112
struct drm_crtc_state * crtc_state ,
146
- struct drm_plane_state * plane_state )
113
+ struct drm_plane_state * plane_state )
147
114
{
148
115
struct rp1_vec * vec = pipe -> crtc .dev -> dev_private ;
149
116
@@ -231,36 +198,47 @@ static const struct drm_display_mode rp1vec_modes[4] = {
231
198
}
232
199
};
233
200
201
+ /*
202
+ * Advertise standard and preferred video modes.
203
+ *
204
+ * From each interlaced mode in the table above, derive a progressive one.
205
+ *
206
+ * This driver always support all 50Hz and 60Hz video modes, regardless
207
+ * of tv_norm or connector->tv_mode; nonstandard combinations generally
208
+ * default to PAL[-BDGHIKL] or NTSC[-M] depending on the video mode
209
+ * (except that "PAL" with 525/60 will be implemented as "PAL60").
210
+ */
211
+
234
212
static int rp1vec_connector_get_modes (struct drm_connector * connector )
235
213
{
236
214
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 );
215
+ bool prefer625 =
216
+ vec -> tv_norm == DRM_MODE_TV_MODE_PAL ||
217
+ vec -> tv_norm == DRM_MODE_TV_MODE_PAL_N ||
218
+ vec -> tv_norm == DRM_MODE_TV_MODE_SECAM ;
239
219
int i , prog , n = 0 ;
240
220
241
221
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 ++ ;
222
+ for (prog = 0 ; prog < 2 ; prog ++ ) {
223
+ struct drm_display_mode * mode =
224
+ drm_mode_duplicate (connector -> dev ,
225
+ & rp1vec_modes [i ]);
226
+
227
+ if (prog ) {
228
+ mode -> flags &= ~DRM_MODE_FLAG_INTERLACE ;
229
+ mode -> vdisplay >>= 1 ;
230
+ mode -> vsync_start >>= 1 ;
231
+ mode -> vsync_end >>= 1 ;
232
+ mode -> vtotal >>= 1 ;
263
233
}
234
+
235
+ if (mode -> hdisplay == 704 &&
236
+ mode -> vtotal == (prefer625 ? 625 : 525 ))
237
+ mode -> type |= DRM_MODE_TYPE_PREFERRED ;
238
+
239
+ drm_mode_set_name (mode );
240
+ drm_mode_probed_add (connector , mode );
241
+ n ++ ;
264
242
}
265
243
}
266
244
@@ -396,7 +374,6 @@ static int rp1vec_platform_probe(struct platform_device *pdev)
396
374
struct device * dev = & pdev -> dev ;
397
375
struct drm_device * drm ;
398
376
struct rp1_vec * vec ;
399
- const char * str ;
400
377
int i , ret ;
401
378
402
379
dev_info (dev , __func__ );
@@ -419,10 +396,6 @@ static int rp1vec_platform_probe(struct platform_device *pdev)
419
396
drm -> dev_private = vec ;
420
397
platform_set_drvdata (pdev , drm );
421
398
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
-
426
399
for (i = 0 ; i < RP1VEC_NUM_HW_BLOCKS ; i ++ ) {
427
400
vec -> hw_base [i ] =
428
401
devm_ioremap_resource (dev ,
@@ -463,9 +436,7 @@ static int rp1vec_platform_probe(struct platform_device *pdev)
463
436
drm -> mode_config .funcs = & rp1vec_mode_funcs ;
464
437
drm_vblank_init (drm , 1 );
465
438
466
- ret = drm_mode_create_tv_properties_legacy (drm ,
467
- ARRAY_SIZE (rp1vec_tvstd_names ),
468
- rp1vec_tvstd_names );
439
+ ret = drm_mode_create_tv_properties (drm , RP1VEC_SUPPORTED_TV_MODES );
469
440
if (ret )
470
441
goto err_free_drm ;
471
442
@@ -477,6 +448,15 @@ static int rp1vec_platform_probe(struct platform_device *pdev)
477
448
vec -> connector .interlace_allowed = true;
478
449
drm_connector_helper_add (& vec -> connector , & rp1vec_connector_helper_funcs );
479
450
451
+ if (vec -> connector .cmdline_mode .tv_mode_specified ) {
452
+ vec -> tv_norm = vec -> connector .cmdline_mode .tv_mode ;
453
+ } else if (rp1vec_tv_norm_str ) {
454
+ vec -> tv_norm = drm_get_tv_mode_from_name (rp1vec_tv_norm_str ,
455
+ strlen (rp1vec_tv_norm_str ));
456
+ if (vec -> tv_norm < 0 )
457
+ vec -> tv_norm = DRM_MODE_TV_MODE_NTSC ;
458
+ }
459
+
480
460
drm_object_attach_property (& vec -> connector .base ,
481
461
drm -> mode_config .tv_mode_property ,
482
462
vec -> tv_norm );
0 commit comments