OSDN Git Service

drm/amd/display: Increase the number of retries after AUX DEFER
authorGeorge Shen <george.shen@amd.com>
Fri, 15 Nov 2019 23:56:57 +0000 (18:56 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 5 Dec 2019 21:32:45 +0000 (16:32 -0500)
[Why]
When a timeout occurs after a DEFER, some devices require more retries
than in the case of a regular timeout.

[How]
In a timeout occurrence, check whether a DEFER has occurred before the
timeout and retry MAX_DEFER_RETRIES retries times instead of
MAX_TIMEOUT_RETRIES.

Signed-off-by: George Shen <george.shen@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Abdoulaye Berthe <Abdoulaye.Berthe@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dce/dce_aux.c

index f7626cd..191b68b 100644 (file)
@@ -611,6 +611,8 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
        uint8_t reply;
        bool payload_reply = true;
        enum aux_channel_operation_result operation_result;
+       bool retry_on_defer = false;
+
        int aux_ack_retries = 0,
                aux_defer_retries = 0,
                aux_i2c_defer_retries = 0,
@@ -641,8 +643,9 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
                        break;
 
                        case AUX_TRANSACTION_REPLY_AUX_DEFER:
-                       case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK:
                        case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER:
+                               retry_on_defer = true;
+                       case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK:
                                if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) {
                                        goto fail;
                                } else {
@@ -675,15 +678,24 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
                        break;
 
                case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT:
-                       if (++aux_timeout_retries >= AUX_MAX_TIMEOUT_RETRIES)
-                               goto fail;
-                       else {
-                               /*
-                                * DP 1.4, 2.8.2:  AUX Transaction Response/Reply Timeouts
-                                * According to the DP spec there should be 3 retries total
-                                * with a 400us wait inbetween each. Hardware already waits
-                                * for 550us therefore no wait is required here.
-                                */
+                       // Check whether a DEFER had occurred before the timeout.
+                       // If so, treat timeout as a DEFER.
+                       if (retry_on_defer) {
+                               if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES)
+                                       goto fail;
+                               else if (payload->defer_delay > 0)
+                                       msleep(payload->defer_delay);
+                       } else {
+                               if (++aux_timeout_retries >= AUX_MAX_TIMEOUT_RETRIES)
+                                       goto fail;
+                               else {
+                                       /*
+                                        * DP 1.4, 2.8.2:  AUX Transaction Response/Reply Timeouts
+                                        * According to the DP spec there should be 3 retries total
+                                        * with a 400us wait inbetween each. Hardware already waits
+                                        * for 550us therefore no wait is required here.
+                                        */
+                               }
                        }
                        break;