<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">From 3246c9abe5f4358cc5c60b8621485faa9883d06b Mon Sep 17 00:00:00 2001
From: Mateusz Kwiatkowski &lt;kfyatek+publicgit@gmail.com&gt;
Date: Thu, 15 Jul 2021 01:08:05 +0200
Subject: [PATCH] drm/vc4: Refactor mode checking logic

Replace drm_encoder_helper_funcs::atomic_check with
drm_connector_helper_funcs::atomic_check - the former is not called
during drm_mode_obj_set_property_ioctl(). Set crtc_state-&gt;mode_changed
if TV norm changes even without explicit mode change. This makes things
like "xrandr --output Composite-1 --set mode PAL-M" work properly.

Signed-off-by: Mateusz Kwiatkowski &lt;kfyatek+publicgit@gmail.com&gt;
---
 drivers/gpu/drm/vc4/vc4_vec.c | 42 ++++++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 16 deletions(-)

--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -392,6 +392,31 @@ static void vc4_vec_connector_reset(stru
 		connector-&gt;state-&gt;tv.mode = vc4_vec_get_default_mode(connector);
 }
 
+static int vc4_vec_connector_atomic_check(struct drm_connector *conn,
+					  struct drm_atomic_state *state)
+{
+	struct drm_connector_state *old_state =
+		drm_atomic_get_old_connector_state(state, conn);
+	struct drm_connector_state *new_state =
+		drm_atomic_get_new_connector_state(state, conn);
+
+	const struct vc4_vec_tv_mode *vec_mode =
+		&amp;vc4_vec_tv_modes[new_state-&gt;tv.mode];
+
+	if (new_state-&gt;crtc) {
+		struct drm_crtc_state *crtc_state =
+			drm_atomic_get_new_crtc_state(state, new_state-&gt;crtc);
+
+		if (!drm_mode_equal(vec_mode-&gt;mode, &amp;crtc_state-&gt;mode))
+			return -EINVAL;
+
+		if (old_state-&gt;tv.mode != new_state-&gt;tv.mode)
+			crtc_state-&gt;mode_changed = true;
+	}
+
+	return 0;
+}
+
 static const struct drm_connector_funcs vc4_vec_connector_funcs = {
 	.detect = vc4_vec_connector_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
@@ -402,6 +427,7 @@ static const struct drm_connector_funcs
 
 static const struct drm_connector_helper_funcs vc4_vec_connector_helper_funcs = {
 	.get_modes = vc4_vec_connector_get_modes,
+	.atomic_check = vc4_vec_connector_atomic_check,
 };
 
 static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec)
@@ -550,23 +576,7 @@ err_dev_exit:
 	drm_dev_exit(idx);
 }
 
-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 vc4_vec_tv_mode *vec_mode;
-
-	vec_mode = &amp;vc4_vec_tv_modes[conn_state-&gt;tv.mode];
-
-	if (conn_state-&gt;crtc &amp;&amp;
-	    !drm_mode_equal(vec_mode-&gt;mode, &amp;crtc_state-&gt;adjusted_mode))
-		return -EINVAL;
-
-	return 0;
-}
-
 static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
-	.atomic_check = vc4_vec_encoder_atomic_check,
 	.atomic_disable = vc4_vec_encoder_disable,
 	.atomic_enable = vc4_vec_encoder_enable,
 };
</pre></body></html>