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

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

 



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@xxxxxxxxx>
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@xxxxxxxxx>
---

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://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