diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.10/950-0699-drm-vc4-Fix-timings-for-VEC-modes.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.10/950-0699-drm-vc4-Fix-timings-for-VEC-modes.patch | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.10/950-0699-drm-vc4-Fix-timings-for-VEC-modes.patch b/target/linux/bcm27xx/patches-5.10/950-0699-drm-vc4-Fix-timings-for-VEC-modes.patch new file mode 100644 index 0000000000..43dfcfc5bc --- /dev/null +++ b/target/linux/bcm27xx/patches-5.10/950-0699-drm-vc4-Fix-timings-for-VEC-modes.patch @@ -0,0 +1,148 @@ +From 023e20cf561dc49897997f55e88b7d336eb5cee9 Mon Sep 17 00:00:00 2001 +From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com> +Date: Thu, 15 Jul 2021 01:07:30 +0200 +Subject: [PATCH] drm/vc4: Fix timings for VEC modes + +This commit fixes vertical timings of the VEC (composite output) modes +to accurately represent the 525-line ("NTSC") and 625-line ("PAL") ITU-R +standards. + +Previous timings were actually defined as 502 and 601 lines, resulting +in non-standard 62.69 Hz and 52 Hz signals being generated, +respectively. + +Changes to vc4_crtc.c have also been made, to make the PixelValve +vertical timings accurately correspond to the DRM modeline in interlaced +modes. The resulting VERTA/VERTB register values have been verified +against the reference values set by the Raspberry Pi firmware. + +Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com> +--- + drivers/gpu/drm/vc4/vc4_crtc.c | 70 +++++++++++++++++++++------------- + drivers/gpu/drm/vc4/vc4_vec.c | 4 +- + 2 files changed, 45 insertions(+), 29 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_crtc.c ++++ b/drivers/gpu/drm/vc4/vc4_crtc.c +@@ -316,8 +316,14 @@ static void vc4_crtc_config_pv(struct dr + bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 || + vc4_encoder->type == VC4_ENCODER_TYPE_DSI1); + bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1; ++ bool is_vec = vc4_encoder->type == VC4_ENCODER_TYPE_VEC; + u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24; + u8 ppc = pv_data->pixels_per_clock; ++ ++ u16 vert_bp = mode->crtc_vtotal - mode->crtc_vsync_end; ++ u16 vert_sync = mode->crtc_vsync_end - mode->crtc_vsync_start; ++ u16 vert_fp = mode->crtc_vsync_start - mode->crtc_vdisplay; ++ + bool debug_dump_regs = false; + + if (debug_dump_regs) { +@@ -341,49 +347,59 @@ static void vc4_crtc_config_pv(struct dr + VC4_SET_FIELD(mode->hdisplay * pixel_rep / ppc, + PV_HORZB_HACTIVE)); + +- CRTC_WRITE(PV_VERTA, +- VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end + +- interlace, +- PV_VERTA_VBP) | +- VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start, +- PV_VERTA_VSYNC)); +- CRTC_WRITE(PV_VERTB, +- VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay, +- PV_VERTB_VFP) | +- VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE)); +- + if (interlace) { ++ bool odd_field_first = false; ++ u32 field_delay = mode->htotal * pixel_rep / (2 * ppc); ++ u16 vert_bp_even = vert_bp; ++ u16 vert_fp_even = vert_fp; ++ ++ if (is_vec) { ++ /* VEC (composite output) */ ++ ++field_delay; ++ if (mode->htotal == 858) { ++ /* 525-line mode (NTSC or PAL-M) */ ++ odd_field_first = true; ++ } ++ } ++ ++ if (odd_field_first) ++ ++vert_fp_even; ++ else ++ ++vert_bp; ++ + CRTC_WRITE(PV_VERTA_EVEN, +- VC4_SET_FIELD(mode->crtc_vtotal - +- mode->crtc_vsync_end, +- PV_VERTA_VBP) | +- VC4_SET_FIELD(mode->crtc_vsync_end - +- mode->crtc_vsync_start, +- PV_VERTA_VSYNC)); ++ VC4_SET_FIELD(vert_bp_even, PV_VERTA_VBP) | ++ VC4_SET_FIELD(vert_sync, PV_VERTA_VSYNC)); + CRTC_WRITE(PV_VERTB_EVEN, +- VC4_SET_FIELD(mode->crtc_vsync_start - +- mode->crtc_vdisplay, +- PV_VERTB_VFP) | ++ VC4_SET_FIELD(vert_fp_even, PV_VERTB_VFP) | + VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE)); + +- /* We set up first field even mode for HDMI. VEC's +- * NTSC mode would want first field odd instead, once +- * we support it (to do so, set ODD_FIRST and put the +- * delay in VSYNCD_EVEN instead). ++ /* We set up first field even mode for HDMI and VEC's PAL. ++ * For NTSC, we need first field odd. + */ + CRTC_WRITE(PV_V_CONTROL, + PV_VCONTROL_CONTINUOUS | + (is_dsi ? PV_VCONTROL_DSI : 0) | + PV_VCONTROL_INTERLACE | +- VC4_SET_FIELD(mode->htotal * pixel_rep / (2 * ppc), +- PV_VCONTROL_ODD_DELAY)); +- CRTC_WRITE(PV_VSYNCD_EVEN, 0); ++ (odd_field_first ++ ? PV_VCONTROL_ODD_FIRST ++ : VC4_SET_FIELD(field_delay, ++ PV_VCONTROL_ODD_DELAY))); ++ CRTC_WRITE(PV_VSYNCD_EVEN, ++ (odd_field_first ? field_delay : 0)); + } else { + CRTC_WRITE(PV_V_CONTROL, + PV_VCONTROL_CONTINUOUS | + (is_dsi ? PV_VCONTROL_DSI : 0)); + } + ++ CRTC_WRITE(PV_VERTA, ++ VC4_SET_FIELD(vert_bp, PV_VERTA_VBP) | ++ VC4_SET_FIELD(vert_sync, PV_VERTA_VSYNC)); ++ CRTC_WRITE(PV_VERTB, ++ VC4_SET_FIELD(vert_fp, PV_VERTB_VFP) | ++ VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE)); ++ + if (is_dsi) + CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep); + +--- a/drivers/gpu/drm/vc4/vc4_vec.c ++++ b/drivers/gpu/drm/vc4/vc4_vec.c +@@ -262,7 +262,7 @@ static void vc4_vec_ntsc_j_mode_set(stru + static const struct drm_display_mode ntsc_mode = { + DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500, + 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0, +- 480, 480 + 3, 480 + 3 + 3, 480 + 3 + 3 + 16, 0, ++ 480, 480 + 7, 480 + 7 + 6, 525, 0, + DRM_MODE_FLAG_INTERLACE) + }; + +@@ -284,7 +284,7 @@ static void vc4_vec_pal_m_mode_set(struc + static const struct drm_display_mode pal_mode = { + DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500, + 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0, +- 576, 576 + 2, 576 + 2 + 3, 576 + 2 + 3 + 20, 0, ++ 576, 576 + 4, 576 + 4 + 6, 625, 0, + DRM_MODE_FLAG_INTERLACE) + }; + |