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