Again, let's be slightly more clever here.

Signed-Off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
---
 drivers/gpu/drm/i915/intel_dp.c |   47 ++++++++++++++++++--------------------
 1 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 3bbd754..1c84a97 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -67,6 +67,7 @@ struct intel_dp {
        struct drm_display_mode *panel_fixed_mode;  /* for eDP */
        struct delayed_work panel_vdd_work;
        bool want_panel_vdd;
+       struct edid *cached_edid;
 };

 /**
@@ -2089,30 +2090,19 @@ g4x_dp_detect(struct intel_dp *intel_dp)
 }

 static struct edid *
-intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
+intel_dp_get_edid(struct drm_connector *connector)
 {
        struct intel_dp *intel_dp = intel_attached_dp(connector);
-       struct edid     *edid;
-
-       ironlake_edp_panel_vdd_on(intel_dp);
-       edid = drm_get_edid(connector, adapter);
-       ironlake_edp_panel_vdd_off(intel_dp, false);
-       return edid;
-}

-static int
-intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter 
*adapter)
-{
-       struct intel_dp *intel_dp = intel_attached_dp(connector);
-       int     ret;
+       if (!intel_dp->cached_edid) {
+               ironlake_edp_panel_vdd_on(intel_dp);
+               intel_dp->cached_edid = drm_get_edid(connector, 
&intel_dp->adapter);
+               ironlake_edp_panel_vdd_off(intel_dp, false);
+       }

-       ironlake_edp_panel_vdd_on(intel_dp);
-       ret = intel_ddc_get_modes(connector, adapter);
-       ironlake_edp_panel_vdd_off(intel_dp, false);
-       return ret;
+       return intel_dp->cached_edid;
 }

-
 /**
  * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection.
  *
@@ -2127,6 +2117,10 @@ intel_dp_detect(struct drm_connector *connector, bool 
force)
        enum drm_connector_status status;
        struct edid *edid = NULL;

+       /* Clean the edid cache. */
+       kfree(intel_dp->cached_edid);
+       intel_dp->cached_edid = NULL;
+
        intel_dp->has_audio = false;

        if (HAS_PCH_SPLIT(dev))
@@ -2145,11 +2139,10 @@ intel_dp_detect(struct drm_connector *connector, bool 
force)
        if (intel_dp->force_audio != HDMI_AUDIO_AUTO) {
                intel_dp->has_audio = (intel_dp->force_audio == HDMI_AUDIO_ON);
        } else {
-               edid = intel_dp_get_edid(connector, &intel_dp->adapter);
+               edid = intel_dp_get_edid(connector);
                if (edid) {
                        intel_dp->has_audio = drm_detect_monitor_audio(edid);
                        connector->display_info.raw_edid = NULL;
-                       kfree(edid);
                }
        }

@@ -2161,12 +2154,16 @@ static int intel_dp_get_modes(struct drm_connector 
*connector)
        struct intel_dp *intel_dp = intel_attached_dp(connector);
        struct drm_device *dev = intel_dp->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int ret;
+       struct edid     *edid;
+       int ret = 0;

        /* We should parse the EDID data and find out if it has an audio sink
         */

-       ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter);
+       edid = intel_dp_get_edid(connector);
+       if (edid)
+               ret = intel_edid_get_modes(connector, edid);
+
        if (ret) {
                if (is_edp(intel_dp) && !intel_dp->panel_fixed_mode) {
                        struct drm_display_mode *newmode;
@@ -2206,16 +2203,14 @@ static int intel_dp_get_modes(struct drm_connector 
*connector)
 static bool
 intel_dp_detect_audio(struct drm_connector *connector)
 {
-       struct intel_dp *intel_dp = intel_attached_dp(connector);
        struct edid *edid;
        bool has_audio = false;

-       edid = intel_dp_get_edid(connector, &intel_dp->adapter);
+       edid = intel_dp_get_edid(connector);
        if (edid) {
                has_audio = drm_detect_monitor_audio(edid);

                connector->display_info.raw_edid = NULL;
-               kfree(edid);
        }

        return has_audio;
@@ -2279,6 +2274,7 @@ done:
 static void
 intel_dp_destroy(struct drm_connector *connector)
 {
+       struct intel_dp *intel_dp = intel_attached_dp(connector);
        struct drm_device *dev = connector->dev;

        if (intel_dpd_is_edp(dev))
@@ -2286,6 +2282,7 @@ intel_dp_destroy(struct drm_connector *connector)

        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
+       kfree(intel_dp->cached_edid);
        kfree(connector);
 }

-- 
1.7.7.6

Reply via email to