Blob Blame History Raw
From a66a613502c0e82aa16c49703c733064c2df8162 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
Date: Fri, 11 Mar 2022 19:24:27 +0200
Subject: drm/i915: Implement static DRRS
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: c5ee23437cae2cffadc1a96ebd444ae2504e0408
Patch-mainline: v5.19-rc1
References: jsc#PED-1166 jsc#PED-1168 jsc#PED-1170 jsc#PED-1218 jsc#PED-1220 jsc#PED-1222 jsc#PED-1223 jsc#PED-1225

Let's start supporting static DRRS by trying to match the refresh
rate the user has requested, assuming the panel supports suitable
timings.

For now we stick to just our current two timings:
- fixed_mode: the panel's preferred mode
- downclock_mode: the lowest refresh rate mode we found
Some panels may support more timings than that, but we'll
have to convert our fixed_mode/downclock_mode pointers
into a full list before we can handle that.

v2: Rebase due to intel_panel_get_modes()

Reviewed-by: Jani Nikula <jani.nikula@intel.com> #v1
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220311172428.14685-16-ville.syrjala@linux.intel.com
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 drivers/gpu/drm/i915/display/intel_drrs.c  |  2 +-
 drivers/gpu/drm/i915/display/intel_panel.c | 31 ++++++++++++++++++++--
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
index 981eb37d613e..2bbc0388263a 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.c
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -390,7 +390,7 @@ intel_drrs_init(struct intel_connector *connector,
 		return NULL;
 	}
 
-	if (dev_priv->vbt.drrs_type != DRRS_TYPE_SEAMLESS) {
+	if (dev_priv->vbt.drrs_type == DRRS_TYPE_NONE) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "[CONNECTOR:%d:%s] DRRS not supported according to VBT\n",
 			    connector->base.base.id, connector->base.name);
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index c15f5e3d53d1..08a0612edd60 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -55,14 +55,30 @@ const struct drm_display_mode *
 intel_panel_fixed_mode(struct intel_connector *connector,
 		       const struct drm_display_mode *mode)
 {
-	return connector->panel.fixed_mode;
+	const struct drm_display_mode *fixed_mode = connector->panel.fixed_mode;
+	const struct drm_display_mode *downclock_mode = connector->panel.downclock_mode;
+
+	/* pick the one that is closer in terms of vrefresh */
+	/* FIXME make this a a list of modes so we can have more than two */
+	if (fixed_mode && downclock_mode &&
+	    abs(drm_mode_vrefresh(downclock_mode) - drm_mode_vrefresh(mode)) <
+	    abs(drm_mode_vrefresh(fixed_mode) - drm_mode_vrefresh(mode)))
+		return downclock_mode;
+	else
+		return fixed_mode;
 }
 
 const struct drm_display_mode *
 intel_panel_downclock_mode(struct intel_connector *connector,
 			   const struct drm_display_mode *adjusted_mode)
 {
-	return connector->panel.downclock_mode;
+	const struct drm_display_mode *downclock_mode = connector->panel.downclock_mode;
+
+	if (downclock_mode &&
+	    drm_mode_vrefresh(downclock_mode) < drm_mode_vrefresh(adjusted_mode))
+		return downclock_mode;
+	else
+		return NULL;
 }
 
 int intel_panel_get_modes(struct intel_connector *connector)
@@ -80,6 +96,17 @@ int intel_panel_get_modes(struct intel_connector *connector)
 		}
 	}
 
+	if (connector->panel.downclock_mode) {
+		struct drm_display_mode *mode;
+
+		mode = drm_mode_duplicate(connector->base.dev,
+					  connector->panel.downclock_mode);
+		if (mode) {
+			drm_mode_probed_add(&connector->base, mode);
+			num_modes++;
+		}
+	}
+
 	return num_modes;
 }
 
-- 
2.38.1