]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
drm/i915/edp: Allow alternate fixed mode for eDP if available.
authorJim Bride <jim.bride@linux.intel.com>
Thu, 12 Apr 2018 07:28:00 +0000 (09:28 +0200)
committerStefan Bader <stefan.bader@canonical.com>
Fri, 20 Apr 2018 11:53:30 +0000 (13:53 +0200)
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@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: David Weinehall <david.weinehall@linux.intel.com>
Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@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@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dsi.c
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_panel.c

index b629e2baf725b0289eac144f52e14dd91d19692b..3a24b0e367e30b24c74e6a2d728030a7db53841b 100644 (file)
@@ -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);
 
index 954e9454625ed6b5f0cb1a360058fc1fbb80cb09..789b2fcf6d7dc28d7fcdef6a826caf21159dd961 100644 (file)
@@ -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 */
@@ -1695,6 +1696,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,
index 4b8f6e070b5f78520773ec01d0facffbf8e0d537..0fdd4f184160978c100c5036417da438f4cb33d4 100644 (file)
@@ -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);
index c1544a53095ddb353430f9468b2e644dff4ea673..39fd4f3b4c971d5f4fc7ca527f885620b469767c 100644 (file)
@@ -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;
                }
 
index 6fe5d7c3bc23bf149e67ab4af228efbd5bf0642c..a995ccb9bd821fcc8bec546fd91185ad78f54f76 100644 (file)
@@ -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);
index 593349be8b9dfce328d20ea3ca5d1b22e41da320..cf395cdd47e735bf9e97f973931e5ae8bbd92461 100644 (file)
@@ -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);