Skip to content

Commit 5baecda

Browse files
committed
drm/vc4: Relax VEC modeline requirements and add progressive mode support
Make vc4_vec_encoder_atomic_check() accept arbitrary modelines, as long as they result in somewhat sane output from the VEC. The bounds have been determined empirically. Additionally, add support for the progressive 262-line and 312-line modes. Signed-off-by: Mateusz Kwiatkowski <[email protected]>
1 parent b697b87 commit 5baecda

File tree

2 files changed

+76
-8
lines changed

2 files changed

+76
-8
lines changed

drivers/gpu/drm/vc4/vc4_crtc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
391391
CRTC_WRITE(PV_V_CONTROL,
392392
PV_VCONTROL_CONTINUOUS |
393393
(is_dsi ? PV_VCONTROL_DSI : 0));
394+
CRTC_WRITE(PV_VSYNCD_EVEN, 0);
394395
}
395396

396397
CRTC_WRITE(PV_VERTA,

drivers/gpu/drm/vc4/vc4_vec.c

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,10 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
539539
VEC_WRITE(VEC_CLMP0_START, 0xac);
540540
VEC_WRITE(VEC_CLMP0_END, 0xec);
541541
VEC_WRITE(VEC_CONFIG2,
542-
VEC_CONFIG2_UV_DIG_DIS | VEC_CONFIG2_RGB_DIG_DIS);
542+
VEC_CONFIG2_UV_DIG_DIS |
543+
VEC_CONFIG2_RGB_DIG_DIS |
544+
((encoder->crtc->state->adjusted_mode.flags &
545+
DRM_MODE_FLAG_INTERLACE) ? 0 : VEC_CONFIG2_PROG_SCAN));
543546
VEC_WRITE(VEC_CONFIG3, VEC_CONFIG3_HORIZ_LEN_STD);
544547
VEC_WRITE(VEC_DAC_CONFIG, vec->variant->dac_config);
545548

@@ -573,13 +576,77 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
573576
struct drm_crtc_state *crtc_state,
574577
struct drm_connector_state *conn_state)
575578
{
576-
const struct vc4_vec_tv_mode *vec_mode;
577-
578-
vec_mode = &vc4_vec_tv_modes[conn_state->tv.mode];
579-
580-
if (conn_state->crtc &&
581-
!drm_mode_equal(vec_mode->mode, &crtc_state->adjusted_mode))
582-
return -EINVAL;
579+
if (conn_state->crtc) {
580+
if (crtc_state->adjusted_mode.htotal !=
581+
vc4_vec_tv_modes[conn_state->tv.mode].mode->htotal ||
582+
crtc_state->adjusted_mode.hdisplay % 4 != 0 ||
583+
crtc_state->adjusted_mode.hsync_end -
584+
crtc_state->adjusted_mode.hsync_start < 1)
585+
return -EINVAL;
586+
587+
switch (crtc_state->adjusted_mode.htotal) {
588+
case 858:
589+
/* 525-line mode */
590+
if (crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
591+
crtc_state->adjusted_mode.crtc_vdisplay > 253 ||
592+
crtc_state->adjusted_mode.crtc_vsync_start -
593+
crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
594+
crtc_state->adjusted_mode.crtc_vsync_end -
595+
crtc_state->adjusted_mode.crtc_vsync_start != 3 ||
596+
crtc_state->adjusted_mode.crtc_vtotal -
597+
crtc_state->adjusted_mode.crtc_vsync_end < 4 ||
598+
crtc_state->adjusted_mode.crtc_vtotal > 262)
599+
return -EINVAL;
600+
601+
if ((crtc_state->adjusted_mode.flags &
602+
DRM_MODE_FLAG_INTERLACE) &&
603+
(crtc_state->adjusted_mode.vdisplay % 2 != 0 ||
604+
crtc_state->adjusted_mode.vsync_start % 2 != 1 ||
605+
crtc_state->adjusted_mode.vsync_end % 2 != 1 ||
606+
crtc_state->adjusted_mode.vtotal % 2 != 1))
607+
return -EINVAL;
608+
609+
/* progressive mode is hard-wired to 262 total lines */
610+
if (!(crtc_state->adjusted_mode.flags &
611+
DRM_MODE_FLAG_INTERLACE) &&
612+
crtc_state->adjusted_mode.vtotal != 262)
613+
return -EINVAL;
614+
615+
break;
616+
617+
case 864:
618+
/* 625-line mode */
619+
if (crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
620+
crtc_state->adjusted_mode.crtc_vdisplay > 305 ||
621+
crtc_state->adjusted_mode.crtc_vsync_start -
622+
crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
623+
crtc_state->adjusted_mode.crtc_vsync_end -
624+
crtc_state->adjusted_mode.crtc_vsync_start != 3 ||
625+
crtc_state->adjusted_mode.crtc_vtotal -
626+
crtc_state->adjusted_mode.crtc_vsync_end < 2 ||
627+
crtc_state->adjusted_mode.crtc_vtotal > 312)
628+
return -EINVAL;
629+
630+
if ((crtc_state->adjusted_mode.flags &
631+
DRM_MODE_FLAG_INTERLACE) &&
632+
(crtc_state->adjusted_mode.vdisplay % 2 != 0 ||
633+
crtc_state->adjusted_mode.vsync_start % 2 != 0 ||
634+
crtc_state->adjusted_mode.vsync_end % 2 != 0 ||
635+
crtc_state->adjusted_mode.vtotal % 2 != 1))
636+
return -EINVAL;
637+
638+
/* progressive mode is hard-wired to 312 total lines */
639+
if (!(crtc_state->adjusted_mode.flags &
640+
DRM_MODE_FLAG_INTERLACE) &&
641+
crtc_state->adjusted_mode.vtotal != 312)
642+
return -EINVAL;
643+
644+
break;
645+
646+
default:
647+
return -EINVAL;
648+
}
649+
}
583650

584651
return 0;
585652
}

0 commit comments

Comments
 (0)