Skip to content

Commit e7a6e10

Browse files
Mateusz Kwiatkowskipelwell
Mateusz Kwiatkowski
authored andcommitted
drm/vc4: Make VEC progressive modes readily accessible
Add predefined modelines for the 240p (NTSC) and 288p (PAL) progressive modes, and report them through vc4_vec_connector_get_modes(). Signed-off-by: Mateusz Kwiatkowski <[email protected]>
1 parent 9c5ade1 commit e7a6e10

File tree

1 file changed

+55
-18
lines changed

1 file changed

+55
-18
lines changed

drivers/gpu/drm/vc4/vc4_vec.c

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ enum vc4_vec_tv_mode_id {
251251
};
252252

253253
struct vc4_vec_tv_mode {
254-
const struct drm_display_mode *mode;
254+
const struct drm_display_mode *interlaced_mode;
255+
const struct drm_display_mode *progressive_mode;
255256
u32 config0;
256257
u32 config1;
257258
u32 custom_freq;
@@ -285,61 +286,81 @@ static const struct debugfs_reg32 vec_regs[] = {
285286
};
286287

287288
static const struct drm_display_mode drm_mode_480i = {
288-
DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
289+
DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
289290
720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
290291
480, 480 + 7, 480 + 7 + 6, 525, 0,
291292
DRM_MODE_FLAG_INTERLACE)
292293
};
293294

295+
static const struct drm_display_mode drm_mode_240p = {
296+
DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500,
297+
720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
298+
240, 240 + 3, 240 + 3 + 3, 262, 0, 0)
299+
};
300+
294301
static const struct drm_display_mode drm_mode_576i = {
295-
DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
302+
DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
296303
720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
297304
576, 576 + 4, 576 + 4 + 6, 625, 0,
298305
DRM_MODE_FLAG_INTERLACE)
299306
};
300307

308+
static const struct drm_display_mode drm_mode_288p = {
309+
DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500,
310+
720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
311+
288, 288 + 2, 288 + 2 + 3, 312, 0, 0)
312+
};
313+
301314
static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
302315
[VC4_VEC_TV_MODE_NTSC] = {
303-
.mode = &drm_mode_480i,
316+
.interlaced_mode = &drm_mode_480i,
317+
.progressive_mode = &drm_mode_240p,
304318
.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
305319
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
306320
},
307321
[VC4_VEC_TV_MODE_NTSC_J] = {
308-
.mode = &drm_mode_480i,
322+
.interlaced_mode = &drm_mode_480i,
323+
.progressive_mode = &drm_mode_240p,
309324
.config0 = VEC_CONFIG0_NTSC_STD,
310325
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
311326
},
312327
[VC4_VEC_TV_MODE_NTSC_443] = {
313328
/* NTSC with PAL chroma frequency */
314-
.mode = &drm_mode_480i,
329+
.interlaced_mode = &drm_mode_480i,
330+
.progressive_mode = &drm_mode_240p,
315331
.config0 = VEC_CONFIG0_NTSC_STD,
316332
.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
317333
.custom_freq = 0x2a098acb,
318334
},
319335
[VC4_VEC_TV_MODE_PAL] = {
320-
.mode = &drm_mode_576i,
336+
.interlaced_mode = &drm_mode_576i,
337+
.progressive_mode = &drm_mode_288p,
321338
.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
322339
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
323340
},
324341
[VC4_VEC_TV_MODE_PAL_M] = {
325-
.mode = &drm_mode_480i,
342+
.interlaced_mode = &drm_mode_480i,
343+
.progressive_mode = &drm_mode_240p,
326344
.config0 = VEC_CONFIG0_PAL_M_STD,
327345
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
328346
},
329347
[VC4_VEC_TV_MODE_PAL_N] = {
330-
.mode = &drm_mode_576i,
348+
.interlaced_mode = &drm_mode_576i,
349+
.progressive_mode = &drm_mode_288p,
331350
.config0 = VEC_CONFIG0_PAL_N_STD,
332351
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
333352
},
334353
[VC4_VEC_TV_MODE_PAL60] = {
335354
/* PAL-M with chroma frequency of regular PAL */
336-
.mode = &drm_mode_480i,
355+
.interlaced_mode = &drm_mode_480i,
356+
.progressive_mode = &drm_mode_240p,
337357
.config0 = VEC_CONFIG0_PAL_M_STD,
338358
.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
339359
.custom_freq = 0x2a098acb,
340360
},
341361
[VC4_VEC_TV_MODE_SECAM] = {
342-
.mode = &drm_mode_576i,
362+
.interlaced_mode = &drm_mode_576i,
363+
.progressive_mode = &drm_mode_288p,
343364
.config0 = VEC_CONFIG0_SECAM_STD,
344365
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
345366
.custom_freq = 0x29c71c72,
@@ -399,16 +420,32 @@ static void vc4_vec_connector_destroy(struct drm_connector *connector)
399420
static int vc4_vec_connector_get_modes(struct drm_connector *connector)
400421
{
401422
struct drm_connector_state *state = connector->state;
402-
struct drm_display_mode *mode;
403-
404-
mode = drm_mode_duplicate(connector->dev,
405-
vc4_vec_tv_modes[state->tv.mode].mode);
406-
if (!mode) {
423+
struct drm_display_mode *interlaced_mode, *progressive_mode;
424+
425+
interlaced_mode =
426+
drm_mode_duplicate(connector->dev,
427+
vc4_vec_tv_modes[state->tv.mode].interlaced_mode);
428+
progressive_mode =
429+
drm_mode_duplicate(connector->dev,
430+
vc4_vec_tv_modes[state->tv.mode].progressive_mode);
431+
if (!interlaced_mode || !progressive_mode) {
407432
DRM_ERROR("Failed to create a new display mode\n");
433+
drm_mode_destroy(connector->dev, interlaced_mode);
434+
drm_mode_destroy(connector->dev, progressive_mode);
408435
return -ENOMEM;
409436
}
410437

411-
drm_mode_probed_add(connector, mode);
438+
if (connector->cmdline_mode.specified &&
439+
connector->cmdline_mode.refresh_specified &&
440+
!connector->cmdline_mode.interlace)
441+
/* progressive mode set at boot, let's make it preferred */
442+
progressive_mode->type |= DRM_MODE_TYPE_PREFERRED;
443+
else
444+
/* otherwise, interlaced mode is preferred */
445+
interlaced_mode->type |= DRM_MODE_TYPE_PREFERRED;
446+
447+
drm_mode_probed_add(connector, interlaced_mode);
448+
drm_mode_probed_add(connector, progressive_mode);
412449

413450
return 1;
414451
}
@@ -589,7 +626,7 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
589626
struct drm_connector_state *conn_state)
590627
{
591628
const struct drm_display_mode *reference_mode =
592-
vc4_vec_tv_modes[conn_state->tv.mode].mode;
629+
vc4_vec_tv_modes[conn_state->tv.mode].interlaced_mode;
593630

594631
if (crtc_state->adjusted_mode.crtc_clock != reference_mode->clock ||
595632
crtc_state->adjusted_mode.crtc_htotal != reference_mode->htotal ||

0 commit comments

Comments
 (0)