drm/amd/display: 7 retries + 50 ms timeout on AUX DEFER
[WHY] DP 2.0 SCR specifies that TX devices must retry at least 7 times when receiving an AUX DEFER reply from RX. In addition, the specification states that the TX shall not retry indefinitely, and gives a suggestive timeout interval of 50ms. [HOW] Keep retrying until both 7 or more retries have been made, and the 50ms interval has passed. Signed-off-by: Wesley Chalmers <Wesley.Chalmers@amd.com> Reviewed-by: Jun Lei <Jun.Lei@amd.com> Acked-by: Anson Jacob <Anson.Jacob@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
d307ce4b6c
commit
1d5b15f77e
@@ -616,6 +616,7 @@ int dce_aux_transfer_dmub_raw(struct ddc_service *ddc,
|
|||||||
|
|
||||||
#define AUX_MAX_RETRIES 7
|
#define AUX_MAX_RETRIES 7
|
||||||
#define AUX_MIN_DEFER_RETRIES 7
|
#define AUX_MIN_DEFER_RETRIES 7
|
||||||
|
#define AUX_MAX_DEFER_TIMEOUT_MS 50
|
||||||
#define AUX_MAX_I2C_DEFER_RETRIES 7
|
#define AUX_MAX_I2C_DEFER_RETRIES 7
|
||||||
#define AUX_MAX_INVALID_REPLY_RETRIES 2
|
#define AUX_MAX_INVALID_REPLY_RETRIES 2
|
||||||
#define AUX_MAX_TIMEOUT_RETRIES 3
|
#define AUX_MAX_TIMEOUT_RETRIES 3
|
||||||
@@ -628,6 +629,10 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
|
|||||||
bool payload_reply = true;
|
bool payload_reply = true;
|
||||||
enum aux_return_code_type operation_result;
|
enum aux_return_code_type operation_result;
|
||||||
bool retry_on_defer = false;
|
bool retry_on_defer = false;
|
||||||
|
struct ddc *ddc_pin = ddc->ddc_pin;
|
||||||
|
struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
|
||||||
|
struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine);
|
||||||
|
uint32_t defer_time_in_ms = 0;
|
||||||
|
|
||||||
int aux_ack_retries = 0,
|
int aux_ack_retries = 0,
|
||||||
aux_defer_retries = 0,
|
aux_defer_retries = 0,
|
||||||
@@ -660,19 +665,26 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AUX_TRANSACTION_REPLY_AUX_DEFER:
|
case AUX_TRANSACTION_REPLY_AUX_DEFER:
|
||||||
|
/* polling_timeout_period is in us */
|
||||||
|
defer_time_in_ms += aux110->polling_timeout_period / 1000;
|
||||||
|
/* fall through */
|
||||||
case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER:
|
case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER:
|
||||||
retry_on_defer = true;
|
retry_on_defer = true;
|
||||||
fallthrough;
|
fallthrough;
|
||||||
case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK:
|
case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK:
|
||||||
if (++aux_defer_retries >= AUX_MIN_DEFER_RETRIES) {
|
if (++aux_defer_retries >= AUX_MIN_DEFER_RETRIES
|
||||||
|
&& defer_time_in_ms >= AUX_MAX_DEFER_TIMEOUT_MS) {
|
||||||
goto fail;
|
goto fail;
|
||||||
} else {
|
} else {
|
||||||
if ((*payload->reply == AUX_TRANSACTION_REPLY_AUX_DEFER) ||
|
if ((*payload->reply == AUX_TRANSACTION_REPLY_AUX_DEFER) ||
|
||||||
(*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER)) {
|
(*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER)) {
|
||||||
if (payload->defer_delay > 1)
|
if (payload->defer_delay > 1) {
|
||||||
msleep(payload->defer_delay);
|
msleep(payload->defer_delay);
|
||||||
else if (payload->defer_delay <= 1)
|
defer_time_in_ms += payload->defer_delay;
|
||||||
|
} else if (payload->defer_delay <= 1) {
|
||||||
udelay(payload->defer_delay * 1000);
|
udelay(payload->defer_delay * 1000);
|
||||||
|
defer_time_in_ms += payload->defer_delay;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user