[Intel-gfx] [PATCH v2 9/9] drm/i915/dp: Avoid concurrent access when HW is using aux ch

José Roberto de Souza jose.souza at intel.com
Wed Apr 18 22:43:11 UTC 2018


This will avoid some cases of concurrent access to aux ch registers when
hardware is using it(HW uses it when PSR, GTC and aux frame is enabled).

It is just first step to see if this scenario happens, if so it will be
properly handled as described in bspec.

Signed-off-by: José Roberto de Souza <jose.souza at intel.com>
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan at intel.com>
---

New patch in this series, this is replacing to the patches in this series that
was exiting PSR before a aux transaction.
As discussed with Dhinakaran, let's check first if this scenary happens if
so I will bring those patches back.

 drivers/gpu/drm/i915/intel_dp.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 258e23961456..74abd4cd93dd 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1062,7 +1062,7 @@ static uint32_t skl_get_aux_send_ctl(struct intel_dp *intel_dp,
 	       DP_AUX_CH_CTL_SYNC_PULSE_SKL(32);
 }
 
-static bool intel_dp_aux_is_busy(struct intel_dp *intel_dp)
+static bool intel_dp_aux_is_busy(struct intel_dp *intel_dp, unsigned int tries)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_i915_private *dev_priv =
@@ -1073,7 +1073,7 @@ static bool intel_dp_aux_is_busy(struct intel_dp *intel_dp)
 
 	ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
 
-	for (try = 3; try; try--) {
+	for (try = tries; try; try--) {
 		status = I915_READ_NOTRACE(ch_ctl);
 		if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0)
 			return false;
@@ -1127,7 +1127,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
 	intel_dp_check_edp(intel_dp);
 
 	/* Try to wait for any previous AUX channel activity */
-	if (intel_dp_aux_is_busy(intel_dp)) {
+	if (intel_dp_aux_is_busy(intel_dp, 3)) {
 		ret = -EBUSY;
 		goto out;
 	}
@@ -1148,6 +1148,18 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
 
 		/* Must try at least 3 times according to DP spec */
 		for (try = 0; try < 5; try++) {
+			/* WA: try to avoid concurrent access to aux ch
+			 * registers while hardware is using it, the other
+			 * way is not handled at all.
+			 */
+			if (intel_dp_aux_is_busy(intel_dp, 1)) {
+				DRM_ERROR("Aux ch %c is busy, hw is using it",
+					  aux_ch_name(intel_dp->aux_ch));
+				/* sleep for a transaction time */
+				usleep_range(400, 500);
+				continue;
+			}
+
 			/* Load the send data into the aux channel data registers */
 			for (i = 0; i < send_bytes; i += 4)
 				I915_WRITE(ch_data[i >> 2],
-- 
2.17.0



More information about the Intel-gfx mailing list