[PATCH] Wake up DP sinks for DPCD read-based detection.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Stuart Abercrombie <sabercrombie@xxxxxxxxxxxx>

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@xxxxxxxxxxxx>
Commit-Queue: Stuart Abercrombie <sabercrombie@xxxxxxxxxxxx>
Tested-by: Stuart Abercrombie <sabercrombie@xxxxxxxxxxxx>
[marcheu: fixups for 3.8]
Signed-off-by: Stéphane Marchesin <marcheu@xxxxxxxxxxxx>
---
 drivers/gpu/drm/i915/intel_dp.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index c271c05..f886ae9 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1290,14 +1290,10 @@ static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
 }
 
 /* If the sink supports it, try to set the power state appropriately */
-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);
@@ -1319,6 +1315,16 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
 	}
 }
 
+/* If we have a valid DPCD, set the power state. */
+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 bool intel_dp_get_hw_state(struct intel_encoder *encoder,
 				  enum pipe *pipe)
 {
@@ -2330,6 +2336,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 (connector->dpms != 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
@@ -2339,8 +2351,11 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 			   32, 1, dpcd_hex_dump, sizeof(dpcd_hex_dump), false);
 	DRM_DEBUG_KMS("DPCD: %s\n", dpcd_hex_dump);
 
-	if (status != connector_status_connected)
+	if (status != connector_status_connected) {
+		if (connector->dpms != DRM_MODE_DPMS_ON)
+			intel_dp_do_sink_dpms(intel_dp, connector->dpms);
 		return status;
+	}
 
 	intel_dp_probe_oui(intel_dp);
 
@@ -2356,6 +2371,11 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 
 	if (intel_encoder->type != INTEL_OUTPUT_EDP)
 		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
+
+	/* Restore the sink state */
+	if (connector->dpms != DRM_MODE_DPMS_ON)
+		intel_dp_do_sink_dpms(intel_dp, connector->dpms);
+
 	return connector_status_connected;
 }
 
-- 
1.8.3.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx





[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux