aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.15/950-0555-drm-vc4-Relax-VEC-modeline-requirements-and-add-prog.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.15/950-0555-drm-vc4-Relax-VEC-modeline-requirements-and-add-prog.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.15/950-0555-drm-vc4-Relax-VEC-modeline-requirements-and-add-prog.patch156
1 files changed, 156 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.15/950-0555-drm-vc4-Relax-VEC-modeline-requirements-and-add-prog.patch b/target/linux/bcm27xx/patches-5.15/950-0555-drm-vc4-Relax-VEC-modeline-requirements-and-add-prog.patch
new file mode 100644
index 0000000000..51fac0e0d4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.15/950-0555-drm-vc4-Relax-VEC-modeline-requirements-and-add-prog.patch
@@ -0,0 +1,156 @@
+From ae200c4c1d2d0c9f827e7f73d00f00074e3a7a04 Mon Sep 17 00:00:00 2001
+From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
+Date: Thu, 15 Jul 2021 01:08:08 +0200
+Subject: [PATCH] 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 <kfyatek+publicgit@gmail.com>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 1 +
+ drivers/gpu/drm/vc4/vc4_vec.c | 97 ++++++++++++++++++++++++++++------
+ 2 files changed, 83 insertions(+), 15 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -410,6 +410,7 @@ static void vc4_crtc_config_pv(struct dr
+ CRTC_WRITE(PV_V_CONTROL,
+ PV_VCONTROL_CONTINUOUS |
+ (is_dsi ? PV_VCONTROL_DSI : 0));
++ CRTC_WRITE(PV_VSYNCD_EVEN, 0);
+ }
+
+ CRTC_WRITE(PV_VERTA,
+--- a/drivers/gpu/drm/vc4/vc4_vec.c
++++ b/drivers/gpu/drm/vc4/vc4_vec.c
+@@ -423,18 +423,11 @@ static int vc4_vec_connector_atomic_chec
+ struct drm_connector_state *new_state =
+ drm_atomic_get_new_connector_state(state, conn);
+
+- const struct vc4_vec_tv_mode *vec_mode =
+- &vc4_vec_tv_modes[new_state->tv.mode];
+-
+- if (new_state->crtc) {
++ if (new_state->crtc && old_state->tv.mode != new_state->tv.mode) {
+ struct drm_crtc_state *crtc_state =
+ drm_atomic_get_new_crtc_state(state, new_state->crtc);
+
+- if (!drm_mode_equal(vec_mode->mode, &crtc_state->mode))
+- return -EINVAL;
+-
+- if (old_state->tv.mode != new_state->tv.mode)
+- crtc_state->mode_changed = true;
++ crtc_state->mode_changed = true;
+ }
+
+ return 0;
+@@ -559,7 +552,10 @@ static void vc4_vec_encoder_enable(struc
+ VEC_WRITE(VEC_CLMP0_START, 0xac);
+ VEC_WRITE(VEC_CLMP0_END, 0xec);
+ VEC_WRITE(VEC_CONFIG2,
+- VEC_CONFIG2_UV_DIG_DIS | VEC_CONFIG2_RGB_DIG_DIS);
++ VEC_CONFIG2_UV_DIG_DIS |
++ VEC_CONFIG2_RGB_DIG_DIS |
++ ((encoder->crtc->state->adjusted_mode.flags &
++ DRM_MODE_FLAG_INTERLACE) ? 0 : VEC_CONFIG2_PROG_SCAN));
+ VEC_WRITE(VEC_CONFIG3, VEC_CONFIG3_HORIZ_LEN_STD);
+ VEC_WRITE(VEC_DAC_CONFIG, vec->variant->dac_config);
+
+@@ -582,17 +578,88 @@ static void vc4_vec_encoder_enable(struc
+ }
+
+
+-static bool vc4_vec_encoder_mode_fixup(struct drm_encoder *encoder,
+- const struct drm_display_mode *mode,
+- struct drm_display_mode *adjusted_mode)
++static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
++ struct drm_crtc_state *crtc_state,
++ struct drm_connector_state *conn_state)
+ {
+- return true;
++ const struct drm_display_mode *reference_mode =
++ vc4_vec_tv_modes[conn_state->tv.mode].mode;
++
++ if (crtc_state->adjusted_mode.crtc_clock != reference_mode->clock ||
++ crtc_state->adjusted_mode.crtc_htotal != reference_mode->htotal ||
++ crtc_state->adjusted_mode.crtc_hdisplay % 4 != 0 ||
++ crtc_state->adjusted_mode.crtc_hsync_end -
++ crtc_state->adjusted_mode.crtc_hsync_start < 1)
++ return -EINVAL;
++
++ switch (reference_mode->vtotal) {
++ case 525:
++ if (crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
++ crtc_state->adjusted_mode.crtc_vdisplay > 253 ||
++ crtc_state->adjusted_mode.crtc_vsync_start -
++ crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
++ crtc_state->adjusted_mode.crtc_vsync_end -
++ crtc_state->adjusted_mode.crtc_vsync_start != 3 ||
++ crtc_state->adjusted_mode.crtc_vtotal -
++ crtc_state->adjusted_mode.crtc_vsync_end < 4 ||
++ crtc_state->adjusted_mode.crtc_vtotal > 262)
++ return -EINVAL;
++
++ if ((crtc_state->adjusted_mode.flags &
++ DRM_MODE_FLAG_INTERLACE) &&
++ (crtc_state->adjusted_mode.vdisplay % 2 != 0 ||
++ crtc_state->adjusted_mode.vsync_start % 2 != 1 ||
++ crtc_state->adjusted_mode.vsync_end % 2 != 1 ||
++ crtc_state->adjusted_mode.vtotal % 2 != 1))
++ return -EINVAL;
++
++ /* progressive mode is hard-wired to 262 total lines */
++ if (!(crtc_state->adjusted_mode.flags &
++ DRM_MODE_FLAG_INTERLACE) &&
++ crtc_state->adjusted_mode.crtc_vtotal != 262)
++ return -EINVAL;
++
++ break;
++
++ case 625:
++ if (crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
++ crtc_state->adjusted_mode.crtc_vdisplay > 305 ||
++ crtc_state->adjusted_mode.crtc_vsync_start -
++ crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
++ crtc_state->adjusted_mode.crtc_vsync_end -
++ crtc_state->adjusted_mode.crtc_vsync_start != 3 ||
++ crtc_state->adjusted_mode.crtc_vtotal -
++ crtc_state->adjusted_mode.crtc_vsync_end < 2 ||
++ crtc_state->adjusted_mode.crtc_vtotal > 312)
++ return -EINVAL;
++
++ if ((crtc_state->adjusted_mode.flags &
++ DRM_MODE_FLAG_INTERLACE) &&
++ (crtc_state->adjusted_mode.vdisplay % 2 != 0 ||
++ crtc_state->adjusted_mode.vsync_start % 2 != 0 ||
++ crtc_state->adjusted_mode.vsync_end % 2 != 0 ||
++ crtc_state->adjusted_mode.vtotal % 2 != 1))
++ return -EINVAL;
++
++ /* progressive mode is hard-wired to 312 total lines */
++ if (!(crtc_state->adjusted_mode.flags &
++ DRM_MODE_FLAG_INTERLACE) &&
++ crtc_state->adjusted_mode.crtc_vtotal != 312)
++ return -EINVAL;
++
++ break;
++
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
+ }
+
+ static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
+ .disable = vc4_vec_encoder_disable,
+ .enable = vc4_vec_encoder_enable,
+- .mode_fixup = vc4_vec_encoder_mode_fixup,
++ .atomic_check = vc4_vec_encoder_atomic_check,
+ };
+
+ static const struct vc4_vec_variant bcm2835_vec_variant = {