]> xenbits.xensource.com Git - people/aperard/linux-chromebook.git/commitdiff
Wake up DP sinks for DPCD read-based detection.
authorStuart Abercrombie <sabercrombie@chromium.org>
Wed, 6 Feb 2013 22:39:59 +0000 (14:39 -0800)
committerChromeBot <chrome-bot@google.com>
Fri, 8 Feb 2013 18:54:30 +0000 (10:54 -0800)
When in DPMS sleep state the Apple mini DP->VGA adapter doesn't respond.
This led to no external display on boot.

v2: Avoid DPCD check and keep AUX awake for EDID read.

BUG=chrome-os-partner:17063
TEST=Straight DP and various adapters on mini-DP and DP platforms.

Change-Id: I90bea73006ae9c99464b0b5bc57f3803918313a8
Reviewed-on: https://gerrit.chromium.org/gerrit/42583
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Commit-Queue: Stuart Abercrombie <sabercrombie@chromium.org>
Tested-by: Stuart Abercrombie <sabercrombie@chromium.org>
drivers/gpu/drm/i915/intel_dp.c

index 9837f9050c67959d9cdb546c7555fedf7a82b114..239f142f545abd9c0707bba38227d336ace21090 100644 (file)
@@ -1248,14 +1248,10 @@ static void ironlake_edp_pll_off(struct drm_encoder *encoder)
 }
 
 /* If the sink supports it, try to set the power state appropriately */
-static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
+static void intel_dp_do_sink_dpms(struct intel_dp *intel_dp, int mode)
 {
        int ret, i;
 
-       /* Should have a valid DPCD by this point */
-       if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
-               return;
-
        if (mode != DRM_MODE_DPMS_ON) {
                ret = intel_dp_aux_native_write_1(intel_dp, DP_SET_POWER,
                                                  DP_SET_POWER_D3);
@@ -1277,6 +1273,16 @@ static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
        }
 }
 
+/* If we have a valid DPCD, set the power state. */
+static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
+{
+       /* Should have a valid DPCD by this point */
+       if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
+               return;
+
+       intel_dp_do_sink_dpms(intel_dp, mode);
+}
+
 static void intel_dp_prepare(struct drm_encoder *encoder)
 {
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -2154,6 +2160,12 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 
        intel_dp->has_audio = false;
 
+       /* Ensure the sink is awake for DPCD/EDID reads. */
+       if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) {
+               /* Bypass DPCD check, since we obtain it during detection. */
+               intel_dp_do_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+       }
+
        if (HAS_PCH_SPLIT(dev))
                status = ironlake_dp_detect(intel_dp);
        else
@@ -2164,8 +2176,11 @@ intel_dp_detect(struct drm_connector *connector, bool force)
                      intel_dp->dpcd[3], intel_dp->dpcd[4], intel_dp->dpcd[5],
                      intel_dp->dpcd[6], intel_dp->dpcd[7]);
 
-       if (status != connector_status_connected)
+       if (status != connector_status_connected) {
+               if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON)
+                       intel_dp_do_sink_dpms(intel_dp, intel_dp->dpms_mode);
                return status;
+       }
 
        if (intel_dp->force_audio != HDMI_AUDIO_AUTO) {
                intel_dp->has_audio = (intel_dp->force_audio == HDMI_AUDIO_ON);
@@ -2178,6 +2193,9 @@ intel_dp_detect(struct drm_connector *connector, bool force)
                }
        }
 
+       if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON)
+               intel_dp_do_sink_dpms(intel_dp, intel_dp->dpms_mode);
+
        return connector_status_connected;
 }