From: Ville Syrjälä Date: Fri, 27 Oct 2017 09:45:23 +0000 (+0300) Subject: drm/i915: Improve DP downstream HPD handling X-Git-Tag: v5.15~6763^2~28^2~2405 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=857c416e58dc306b15b7919117b6225544662bfa;p=platform%2Fkernel%2Flinux-starfive.git drm/i915: Improve DP downstream HPD handling DP dongles may signal downstream HPD via short HPD pulses. Setting the sink to DPMS off apparently kills the downstream HPD (at least on my DP->VGA dongle), so skip the DPMS off for such dongles when we turn off the port. v2: Deal with DDI as well by moving the check into intel_dp_sink_dpms() (Dhinakaran) Cc: Dhinakaran Pandiyan Cc: David Woodhouse Cc: Imre Deak Cc: Pablo Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103472 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99114 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171027094523.9317-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 73b1ed8cff..8d25a01 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2505,6 +2505,21 @@ static void ironlake_edp_pll_off(struct intel_dp *intel_dp) udelay(200); } +static bool downstream_hpd_needs_d0(struct intel_dp *intel_dp) +{ + /* + * DPCD 1.2+ should support BRANCH_DEVICE_CTRL, and thus + * be capable of signalling downstream hpd with a long pulse. + * Whether or not that means D3 is safe to use is not clear, + * but let's assume so until proven otherwise. + * + * FIXME should really check all downstream ports... + */ + return intel_dp->dpcd[DP_DPCD_REV] == 0x11 && + intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT && + intel_dp->downstream_ports[0] & DP_DS_PORT_HPD; +} + /* If the sink supports it, try to set the power state appropriately */ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) { @@ -2515,6 +2530,9 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) return; if (mode != DRM_MODE_DPMS_ON) { + if (downstream_hpd_needs_d0(intel_dp)) + return; + ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D3); } else {