| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
- From: Imre Deak <[email protected]>
- Date: Mon, 28 Oct 2019 20:15:17 +0200
- Subject: [PATCH] drm/i915: Avoid HPD poll detect triggering a new detect cycle
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- For the HPD interrupt functionality the HW depends on power wells in the
- display core domain to be on. Accordingly when enabling these power
- wells the HPD polling logic will force an HPD detection cycle to account
- for hotplug events that may have happened when such a power well was
- off.
- Thus a detect cycle started by polling could start a new detect cycle if
- a power well in the display core domain gets enabled during detect and
- stays enabled after detect completes. That in turn can lead to a
- detection cycle runaway.
- To prevent re-triggering a poll-detect cycle make sure we drop all power
- references we acquired during detect synchronously by the end of detect.
- This will let the poll-detect logic continue with polling (matching the
- off state of the corresponding power wells) instead of scheduling a new
- detection cycle.
- Fixes: 6cfe7ec02e85 ("drm/i915: Remove the unneeded AUX power ref from intel_dp_detect()")
- Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112125
- Reported-and-tested-by: Val Kulkov <[email protected]>
- Reported-and-tested-by: wangqr <[email protected]>
- Cc: Val Kulkov <[email protected]>
- Cc: wangqr <[email protected]>
- Cc: Ville Syrjälä <[email protected]>
- Signed-off-by: Imre Deak <[email protected]>
- Reviewed-by: Ville Syrjälä <[email protected]>
- Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
- (cherry picked from commit a8ddac7c9f06a12227a4f5febd1cbe0575a33179)
- Signed-off-by: Thomas Lamprecht <[email protected]>
- ---
- drivers/gpu/drm/i915/display/intel_crt.c | 7 +++++++
- drivers/gpu/drm/i915/display/intel_dp.c | 6 ++++++
- drivers/gpu/drm/i915/display/intel_hdmi.c | 6 ++++++
- 3 files changed, 19 insertions(+)
- diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c
- index 3fcf2f84bcce..da1d6be46a0c 100644
- --- a/drivers/gpu/drm/i915/display/intel_crt.c
- +++ b/drivers/gpu/drm/i915/display/intel_crt.c
- @@ -867,6 +867,13 @@ intel_crt_detect(struct drm_connector *connector,
-
- out:
- intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
- +
- + /*
- + * Make sure the refs for power wells enabled during detect are
- + * dropped to avoid a new detect cycle triggered by HPD polling.
- + */
- + intel_display_power_flush_work(dev_priv);
- +
- return status;
- }
-
- diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
- index 305abddc274a..dbdd46ba9bfe 100644
- --- a/drivers/gpu/drm/i915/display/intel_dp.c
- +++ b/drivers/gpu/drm/i915/display/intel_dp.c
- @@ -5649,6 +5649,12 @@ intel_dp_detect(struct drm_connector *connector,
- if (status != connector_status_connected && !intel_dp->is_mst)
- intel_dp_unset_edid(intel_dp);
-
- + /*
- + * Make sure the refs for power wells enabled during detect are
- + * dropped to avoid a new detect cycle triggered by HPD polling.
- + */
- + intel_display_power_flush_work(dev_priv);
- +
- return status;
- }
-
- diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
- index 7ffdfaae7188..5d5453461a6f 100644
- --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
- +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
- @@ -2571,6 +2571,12 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
- if (status != connector_status_connected)
- cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier);
-
- + /*
- + * Make sure the refs for power wells enabled during detect are
- + * dropped to avoid a new detect cycle triggered by HPD polling.
- + */
- + intel_display_power_flush_work(dev_priv);
- +
- return status;
- }
-
|