From: Wayne Lin <wayne....@amd.com>

[Why]
We incorrectly ack all bytes get written when the reply actually is defer.
When it's defer, means sink is not ready for the request. We should
retry the request.

[How]
Only reply all data get written when receive I2C_ACK|AUX_ACK. Otherwise,
reply the number of actual written bytes received from the sink.
Add some messages to facilitate debugging as well.

Fixes: ad6756b4d773 ("drm/amd/display: Shift dc link aux to aux_payload")
Cc: sta...@vger.kernel.org
Reviewed-by: Ray Wu <ray...@amd.com>
Signed-off-by: Wayne Lin <wayne....@amd.com>
Signed-off-by: Ray Wu <ray...@amd.com>
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 28 ++++++++++++++++---
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index d8dcfb3efaaa..d19aea595722 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -51,6 +51,9 @@
 
 #define PEAK_FACTOR_X1000 1006
 
+/*
+ * This function handles both native AUX and I2C-Over-AUX transactions.
+ */
 static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
                                  struct drm_dp_aux_msg *msg)
 {
@@ -87,15 +90,25 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
        if (adev->dm.aux_hpd_discon_quirk) {
                if (msg->address == DP_SIDEBAND_MSG_DOWN_REQ_BASE &&
                        operation_result == AUX_RET_ERROR_HPD_DISCON) {
-                       result = 0;
+                       result = msg->size;
                        operation_result = AUX_RET_SUCCESS;
                }
        }
 
-       if (payload.write && result >= 0)
-               result = msg->size;
+       /*
+        * result equals to 0 includes the cases of AUX_DEFER/I2C_DEFER
+        */
+       if (payload.write && result >= 0) {
+               if (result) {
+                       /*one byte indicating partially written bytes. Force 0 
to retry*/
+                       drm_info(adev_to_drm(adev), "amdgpu: AUX partially 
written\n");
+                       result = 0;
+               } else if (!payload.reply[0])
+                       /*I2C_ACK|AUX_ACK*/
+                       result = msg->size;
+       }
 
-       if (result < 0)
+       if (result < 0) {
                switch (operation_result) {
                case AUX_RET_SUCCESS:
                        break;
@@ -114,6 +127,13 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
                        break;
                }
 
+               drm_info(adev_to_drm(adev), "amdgpu: DP AUX transfer 
fail:%d\n", operation_result);
+       }
+
+       if (payload.reply[0])
+               drm_info(adev_to_drm(adev), "amdgpu: AUX reply command not ACK: 
0x%02x.",
+                       payload.reply[0]);
+
        return result;
 }
 
-- 
2.43.0

Reply via email to