From b5da40af1b89019ffe7ee34f49676514c45411b3 Mon Sep 17 00:00:00 2001 From: Mateusz Kwiatkowski Date: Thu, 17 Nov 2022 10:28:59 +0100 Subject: [PATCH] drm/vc4: vec: Check for VEC output constraints MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The VEC can accept pretty much any relatively reasonable mode, but still has a bunch of constraints to meet. Let's create an atomic_check() implementation that will make sure we don't end up accepting a non-functional mode. Acked-by: Noralf Trønnes Signed-off-by: Mateusz Kwiatkowski Tested-by: Mateusz Kwiatkowski Acked-in-principle-or-something-like-that-by: Daniel Vetter Link: https://lore.kernel.org/r/20220728-rpi-analog-tv-properties-v10-16-256dad125326@cerno.tech Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_vec.c | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index 90e375a..bfa8a58 100644 --- a/drivers/gpu/drm/vc4/vc4_vec.c +++ b/drivers/gpu/drm/vc4/vc4_vec.c @@ -453,6 +453,7 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { + const struct drm_display_mode *mode = &crtc_state->adjusted_mode; const struct vc4_vec_tv_mode *vec_mode; vec_mode = &vc4_vec_tv_modes[conn_state->tv.legacy_mode]; @@ -461,6 +462,55 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder, !drm_mode_equal(vec_mode->mode, &crtc_state->adjusted_mode)) return -EINVAL; + if (mode->crtc_hdisplay % 4) + return -EINVAL; + + if (!(mode->crtc_hsync_end - mode->crtc_hsync_start)) + return -EINVAL; + + switch (mode->htotal) { + /* NTSC */ + case 858: + if (mode->crtc_vtotal > 262) + return -EINVAL; + + if (mode->crtc_vdisplay < 1 || mode->crtc_vdisplay > 253) + return -EINVAL; + + if (!(mode->crtc_vsync_start - mode->crtc_vdisplay)) + return -EINVAL; + + if ((mode->crtc_vsync_end - mode->crtc_vsync_start) != 3) + return -EINVAL; + + if ((mode->crtc_vtotal - mode->crtc_vsync_end) < 4) + return -EINVAL; + + break; + + /* PAL/SECAM */ + case 864: + if (mode->crtc_vtotal > 312) + return -EINVAL; + + if (mode->crtc_vdisplay < 1 || mode->crtc_vdisplay > 305) + return -EINVAL; + + if (!(mode->crtc_vsync_start - mode->crtc_vdisplay)) + return -EINVAL; + + if ((mode->crtc_vsync_end - mode->crtc_vsync_start) != 3) + return -EINVAL; + + if ((mode->crtc_vtotal - mode->crtc_vsync_end) < 2) + return -EINVAL; + + break; + + default: + return -EINVAL; + } + return 0; } -- 2.7.4