summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/display/intel_panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_panel.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_panel.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index f55e4eafd74e..237a40623dd7 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -71,6 +71,27 @@ intel_panel_fixed_mode(struct intel_connector *connector,
return best_mode;
}
+static bool is_alt_drrs_mode(const struct drm_display_mode *mode,
+ const struct drm_display_mode *preferred_mode)
+{
+ return drm_mode_match(mode, preferred_mode,
+ DRM_MODE_MATCH_TIMINGS |
+ DRM_MODE_MATCH_FLAGS |
+ DRM_MODE_MATCH_3D_FLAGS) &&
+ mode->clock != preferred_mode->clock;
+}
+
+static bool is_alt_vrr_mode(const struct drm_display_mode *mode,
+ const struct drm_display_mode *preferred_mode)
+{
+ return drm_mode_match(mode, preferred_mode,
+ DRM_MODE_MATCH_FLAGS |
+ DRM_MODE_MATCH_3D_FLAGS) &&
+ mode->hdisplay == preferred_mode->hdisplay &&
+ mode->vdisplay == preferred_mode->vdisplay &&
+ mode->clock != preferred_mode->clock;
+}
+
const struct drm_display_mode *
intel_panel_downclock_mode(struct intel_connector *connector,
const struct drm_display_mode *adjusted_mode)
@@ -83,7 +104,8 @@ intel_panel_downclock_mode(struct intel_connector *connector,
list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) {
int vrefresh = drm_mode_vrefresh(fixed_mode);
- if (vrefresh >= min_vrefresh && vrefresh < max_vrefresh) {
+ if (is_alt_drrs_mode(fixed_mode, adjusted_mode) &&
+ vrefresh >= min_vrefresh && vrefresh < max_vrefresh) {
max_vrefresh = vrefresh;
best_mode = fixed_mode;
}
@@ -151,16 +173,18 @@ int intel_panel_compute_config(struct intel_connector *connector,
}
static bool is_alt_fixed_mode(const struct drm_display_mode *mode,
- const struct drm_display_mode *preferred_mode)
+ const struct drm_display_mode *preferred_mode,
+ bool has_vrr)
{
- return drm_mode_match(mode, preferred_mode,
- DRM_MODE_MATCH_TIMINGS |
- DRM_MODE_MATCH_FLAGS |
- DRM_MODE_MATCH_3D_FLAGS) &&
- mode->clock != preferred_mode->clock;
+ /* is_alt_drrs_mode() is a subset of is_alt_vrr_mode() */
+ if (has_vrr)
+ return is_alt_vrr_mode(mode, preferred_mode);
+ else
+ return is_alt_drrs_mode(mode, preferred_mode);
}
-static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector)
+static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector,
+ bool has_vrr)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
const struct drm_display_mode *preferred_mode =
@@ -168,7 +192,7 @@ static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connect
struct drm_display_mode *mode, *next;
list_for_each_entry_safe(mode, next, &connector->base.probed_modes, head) {
- if (!is_alt_fixed_mode(mode, preferred_mode))
+ if (!is_alt_fixed_mode(mode, preferred_mode, has_vrr))
continue;
drm_dbg_kms(&dev_priv->drm,
@@ -226,11 +250,12 @@ static void intel_panel_destroy_probed_modes(struct intel_connector *connector)
}
}
-void intel_panel_add_edid_fixed_modes(struct intel_connector *connector, bool has_drrs)
+void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,
+ bool has_drrs, bool has_vrr)
{
intel_panel_add_edid_preferred_mode(connector);
- if (intel_panel_preferred_fixed_mode(connector) && has_drrs)
- intel_panel_add_edid_alt_fixed_modes(connector);
+ if (intel_panel_preferred_fixed_mode(connector) && (has_drrs || has_vrr))
+ intel_panel_add_edid_alt_fixed_modes(connector, has_vrr);
intel_panel_destroy_probed_modes(connector);
}