[PATCH 1/4][Artful][linux-oem] drm/i915/edp: Allow alternate fixed mode for eDP if available.
AceLan Kao
acelan.kao at canonical.com
Thu Apr 12 07:28:38 UTC 2018
From: Jim Bride <jim.bride at linux.intel.com>
BugLink: https://bugs.launchpad.net/bugs/1763271
Some fixed resolution panels actually support more than one mode,
with the only thing different being the refresh rate. Having this
alternate mode available to us is desirable, because it allows us to
test PSR on panels whose setup time at the preferred mode is too long.
With this patch we allow the use of the alternate mode if it's
available and it was specifically requested.
v2 and v3: Rebase
v4: * Fix up some leaky mode stuff (Chris)
* Rebase
v5: * Fix a NULL pointer derefrence (David Weinehall)
v6: * Whitespace / spelling / checkpatch clean-up; no functional
change. (David)
* Rebase
Cc: David Weinehall <david.weinehall at linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi at intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni at intel.com>
Cc: Jani Nikula <jani.nikula at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Reviewed-by: David Weinehall <david.weinehall at linux.intel.com>
Signed-off-by: Jim Bride <jim.bride at linux.intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1502308133-26892-1-git-send-email-jim.bride@linux.intel.com
(cherry picked from commit dc911f5bd8aacfcf8aabd5c26c88e04c837a938e)
Signed-off-by: AceLan Kao <acelan.kao at canonical.com>
---
drivers/gpu/drm/i915/intel_dp.c | 38 +++++++++++++++++++++++++++++++++-----
drivers/gpu/drm/i915/intel_drv.h | 2 ++
drivers/gpu/drm/i915/intel_dsi.c | 2 +-
drivers/gpu/drm/i915/intel_dvo.c | 2 +-
drivers/gpu/drm/i915/intel_lvds.c | 3 ++-
drivers/gpu/drm/i915/intel_panel.c | 6 ++++++
6 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index b629e2b..3a24b0e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1606,6 +1606,23 @@ static int intel_dp_compute_bpp(struct intel_dp *intel_dp,
return bpp;
}
+static bool intel_edp_compare_alt_mode(struct drm_display_mode *m1,
+ struct drm_display_mode *m2)
+{
+ bool bres = false;
+
+ if (m1 && m2)
+ bres = (m1->hdisplay == m2->hdisplay &&
+ m1->hsync_start == m2->hsync_start &&
+ m1->hsync_end == m2->hsync_end &&
+ m1->htotal == m2->htotal &&
+ m1->vdisplay == m2->vdisplay &&
+ m1->vsync_start == m2->vsync_start &&
+ m1->vsync_end == m2->vsync_end &&
+ m1->vtotal == m2->vtotal);
+ return bres;
+}
+
bool
intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
@@ -1652,8 +1669,16 @@ intel_dp_compute_config(struct intel_encoder *encoder,
pipe_config->has_audio = intel_conn_state->force_audio == HDMI_AUDIO_ON;
if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
- intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
- adjusted_mode);
+ struct drm_display_mode *panel_mode =
+ intel_connector->panel.alt_fixed_mode;
+ struct drm_display_mode *req_mode = &pipe_config->base.mode;
+
+ if (!intel_edp_compare_alt_mode(req_mode, panel_mode))
+ panel_mode = intel_connector->panel.fixed_mode;
+
+ drm_mode_debug_printmodeline(panel_mode);
+
+ intel_fixed_panel_mode(panel_mode, adjusted_mode);
if (INTEL_GEN(dev_priv) >= 9) {
int ret;
@@ -5722,6 +5747,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_display_mode *fixed_mode = NULL;
+ struct drm_display_mode *alt_fixed_mode = NULL;
struct drm_display_mode *downclock_mode = NULL;
bool has_dpcd;
struct drm_display_mode *scan;
@@ -5777,13 +5803,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
}
intel_connector->edid = edid;
- /* prefer fixed mode from EDID if available */
+ /* prefer fixed mode from EDID if available, save an alt mode also */
list_for_each_entry(scan, &connector->probed_modes, head) {
if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
fixed_mode = drm_mode_duplicate(dev, scan);
downclock_mode = intel_dp_drrs_init(
intel_connector, fixed_mode);
- break;
+ } else if (!alt_fixed_mode) {
+ alt_fixed_mode = drm_mode_duplicate(dev, scan);
}
}
@@ -5820,7 +5847,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
pipe_name(pipe));
}
- intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
+ intel_panel_init(&intel_connector->panel, fixed_mode, alt_fixed_mode,
+ downclock_mode);
intel_connector->panel.backlight.power = intel_edp_backlight_power;
intel_panel_setup_backlight(connector, pipe);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a350c6b..9833e5e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -265,6 +265,7 @@ struct intel_encoder {
struct intel_panel {
struct drm_display_mode *fixed_mode;
+ struct drm_display_mode *alt_fixed_mode;
struct drm_display_mode *downclock_mode;
/* backlight */
@@ -1697,6 +1698,7 @@ void intel_overlay_reset(struct drm_i915_private *dev_priv);
/* intel_panel.c */
int intel_panel_init(struct intel_panel *panel,
struct drm_display_mode *fixed_mode,
+ struct drm_display_mode *alt_fixed_mode,
struct drm_display_mode *downclock_mode);
void intel_panel_fini(struct intel_panel *panel);
void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 4b8f6e0..0fdd4f1 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1840,7 +1840,7 @@ void intel_dsi_init(struct drm_i915_private *dev_priv)
connector->display_info.width_mm = fixed_mode->width_mm;
connector->display_info.height_mm = fixed_mode->height_mm;
- intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
+ intel_panel_init(&intel_connector->panel, fixed_mode, NULL, NULL);
intel_panel_setup_backlight(connector, INVALID_PIPE);
intel_dsi_add_properties(intel_connector);
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index c1544a5..39fd4f3 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -554,7 +554,7 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
*/
intel_panel_init(&intel_connector->panel,
intel_dvo_get_current_mode(connector),
- NULL);
+ NULL, NULL);
intel_dvo->panel_wants_dither = true;
}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 6fe5d7c..a995ccb 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -1140,7 +1140,8 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
out:
mutex_unlock(&dev->mode_config.mutex);
- intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
+ intel_panel_init(&intel_connector->panel, fixed_mode, NULL,
+ downclock_mode);
intel_panel_setup_backlight(connector, INVALID_PIPE);
lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder);
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 593349b..cf395cd 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1919,11 +1919,13 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
int intel_panel_init(struct intel_panel *panel,
struct drm_display_mode *fixed_mode,
+ struct drm_display_mode *alt_fixed_mode,
struct drm_display_mode *downclock_mode)
{
intel_panel_init_backlight_funcs(panel);
panel->fixed_mode = fixed_mode;
+ panel->alt_fixed_mode = alt_fixed_mode;
panel->downclock_mode = downclock_mode;
return 0;
@@ -1937,6 +1939,10 @@ void intel_panel_fini(struct intel_panel *panel)
if (panel->fixed_mode)
drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
+ if (panel->alt_fixed_mode)
+ drm_mode_destroy(intel_connector->base.dev,
+ panel->alt_fixed_mode);
+
if (panel->downclock_mode)
drm_mode_destroy(intel_connector->base.dev,
panel->downclock_mode);
--
2.7.4
More information about the kernel-team
mailing list