2 * Copyright 2012-15 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
26 #include <linux/delay.h>
27 #include <linux/slab.h>
29 #include "dm_services.h"
30 #include "core_types.h"
32 #include "dce/dce_11_0_sh_mask.h"
33 #include "dm_event_log.h"
37 #define REG(reg_name)\
38 (aux110->regs->reg_name)
43 #include "reg_helper.h"
46 #define FN(reg_name, field_name) \
47 aux110->shift->field_name, aux110->mask->field_name
49 #define FROM_AUX_ENGINE(ptr) \
50 container_of((ptr), struct aux_engine_dce110, base)
52 #define FROM_ENGINE(ptr) \
53 FROM_AUX_ENGINE(container_of((ptr), struct dce_aux, base))
55 #define FROM_AUX_ENGINE_ENGINE(ptr) \
56 container_of((ptr), struct dce_aux, base)
58 AUX_INVALID_REPLY_RETRY_COUNTER
= 1,
59 AUX_TIMED_OUT_RETRY_COUNTER
= 2,
60 AUX_DEFER_RETRY_COUNTER
= 6
63 #define TIME_OUT_INCREMENT 1016
64 #define TIME_OUT_MULTIPLIER_8 8
65 #define TIME_OUT_MULTIPLIER_16 16
66 #define TIME_OUT_MULTIPLIER_32 32
67 #define TIME_OUT_MULTIPLIER_64 64
68 #define MAX_TIMEOUT_LENGTH 127
69 #define DEFAULT_AUX_ENGINE_MULT 0
70 #define DEFAULT_AUX_ENGINE_LENGTH 69
72 static void release_engine(
73 struct dce_aux
*engine
)
75 struct aux_engine_dce110
*aux110
= FROM_AUX_ENGINE(engine
);
77 dal_ddc_close(engine
->ddc
);
81 REG_UPDATE(AUX_ARB_CONTROL
, AUX_SW_DONE_USING_AUX_REG
, 1);
84 #define SW_CAN_ACCESS_AUX 1
85 #define DMCU_CAN_ACCESS_AUX 2
87 static bool is_engine_available(
88 struct dce_aux
*engine
)
90 struct aux_engine_dce110
*aux110
= FROM_AUX_ENGINE(engine
);
92 uint32_t value
= REG_READ(AUX_ARB_CONTROL
);
93 uint32_t field
= get_reg_field_value(
96 AUX_REG_RW_CNTL_STATUS
);
98 return (field
!= DMCU_CAN_ACCESS_AUX
);
100 static bool acquire_engine(
101 struct dce_aux
*engine
)
103 struct aux_engine_dce110
*aux110
= FROM_AUX_ENGINE(engine
);
105 uint32_t value
= REG_READ(AUX_ARB_CONTROL
);
106 uint32_t field
= get_reg_field_value(
109 AUX_REG_RW_CNTL_STATUS
);
110 if (field
== DMCU_CAN_ACCESS_AUX
)
112 /* enable AUX before request SW to access AUX */
113 value
= REG_READ(AUX_CONTROL
);
114 field
= get_reg_field_value(value
,
125 if (REG(AUX_RESET_MASK
)) {
126 /*DP_AUX block as part of the enable sequence*/
134 REG_WRITE(AUX_CONTROL
, value
);
136 if (REG(AUX_RESET_MASK
)) {
137 /*poll HW to make sure reset it done*/
139 REG_WAIT(AUX_CONTROL
, AUX_RESET_DONE
, 1,
148 REG_WRITE(AUX_CONTROL
, value
);
150 REG_WAIT(AUX_CONTROL
, AUX_RESET_DONE
, 0,
155 /* request SW to access AUX */
156 REG_UPDATE(AUX_ARB_CONTROL
, AUX_SW_USE_AUX_REG_REQ
, 1);
158 value
= REG_READ(AUX_ARB_CONTROL
);
159 field
= get_reg_field_value(
162 AUX_REG_RW_CNTL_STATUS
);
164 return (field
== SW_CAN_ACCESS_AUX
);
167 #define COMPOSE_AUX_SW_DATA_16_20(command, address) \
168 ((command) | ((0xF0000 & (address)) >> 16))
170 #define COMPOSE_AUX_SW_DATA_8_15(address) \
171 ((0xFF00 & (address)) >> 8)
173 #define COMPOSE_AUX_SW_DATA_0_7(address) \
176 static void submit_channel_request(
177 struct dce_aux
*engine
,
178 struct aux_request_transaction_data
*request
)
180 struct aux_engine_dce110
*aux110
= FROM_AUX_ENGINE(engine
);
185 ((request
->type
== AUX_TRANSACTION_TYPE_DP
) &&
186 (request
->action
== I2CAUX_TRANSACTION_ACTION_DP_WRITE
)) ||
187 ((request
->type
== AUX_TRANSACTION_TYPE_I2C
) &&
188 ((request
->action
== I2CAUX_TRANSACTION_ACTION_I2C_WRITE
) ||
189 (request
->action
== I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT
)));
190 if (REG(AUXN_IMPCAL
)) {
191 /* clear_aux_error */
192 REG_UPDATE_SEQ_2(AUXN_IMPCAL
,
193 AUXN_CALOUT_ERROR_AK
, 1,
194 AUXN_CALOUT_ERROR_AK
, 0);
196 REG_UPDATE_SEQ_2(AUXP_IMPCAL
,
197 AUXP_CALOUT_ERROR_AK
, 1,
198 AUXP_CALOUT_ERROR_AK
, 0);
200 /* force_default_calibrate */
201 REG_UPDATE_SEQ_2(AUXN_IMPCAL
,
202 AUXN_IMPCAL_ENABLE
, 1,
203 AUXN_IMPCAL_OVERRIDE_ENABLE
, 0);
205 /* bug? why AUXN update EN and OVERRIDE_EN 1 by 1 while AUX P toggles OVERRIDE? */
207 REG_UPDATE_SEQ_2(AUXP_IMPCAL
,
208 AUXP_IMPCAL_OVERRIDE_ENABLE
, 1,
209 AUXP_IMPCAL_OVERRIDE_ENABLE
, 0);
212 REG_UPDATE(AUX_INTERRUPT_CONTROL
, AUX_SW_DONE_ACK
, 1);
214 REG_WAIT(AUX_SW_STATUS
, AUX_SW_DONE
, 0,
215 10, aux110
->polling_timeout_period
/10);
217 /* set the delay and the number of bytes to write */
219 /* The length include
220 * the 4 bit header and the 20 bit address
222 * If the requested length is non zero this means
223 * an addition byte specifying the length is required.
226 length
= request
->length
? 4 : 3;
228 length
+= request
->length
;
230 REG_UPDATE_2(AUX_SW_CONTROL
,
231 AUX_SW_START_DELAY
, request
->delay
,
232 AUX_SW_WR_BYTES
, length
);
234 /* program action and address and payload data (if 'is_write') */
235 value
= REG_UPDATE_4(AUX_SW_DATA
,
238 AUX_SW_AUTOINCREMENT_DISABLE
, 1,
239 AUX_SW_DATA
, COMPOSE_AUX_SW_DATA_16_20(request
->action
, request
->address
));
241 value
= REG_SET_2(AUX_SW_DATA
, value
,
242 AUX_SW_AUTOINCREMENT_DISABLE
, 0,
243 AUX_SW_DATA
, COMPOSE_AUX_SW_DATA_8_15(request
->address
));
245 value
= REG_SET(AUX_SW_DATA
, value
,
246 AUX_SW_DATA
, COMPOSE_AUX_SW_DATA_0_7(request
->address
));
248 if (request
->length
) {
249 value
= REG_SET(AUX_SW_DATA
, value
,
250 AUX_SW_DATA
, request
->length
- 1);
254 /* Load the HW buffer with the Data to be sent.
255 * This is relevant for write operation.
256 * For read, the data recived data will be
257 * processed in process_channel_reply().
261 while (i
< request
->length
) {
262 value
= REG_SET(AUX_SW_DATA
, value
,
263 AUX_SW_DATA
, request
->data
[i
]);
269 REG_UPDATE(AUX_SW_CONTROL
, AUX_SW_GO
, 1);
270 EVENT_LOG_AUX_REQ(engine
->ddc
->pin_data
->en
, EVENT_LOG_AUX_ORIGIN_NATIVE
,
271 request
->action
, request
->address
, request
->length
, request
->data
);
274 static int read_channel_reply(struct dce_aux
*engine
, uint32_t size
,
275 uint8_t *buffer
, uint8_t *reply_result
,
278 struct aux_engine_dce110
*aux110
= FROM_AUX_ENGINE(engine
);
279 uint32_t bytes_replied
;
280 uint32_t reply_result_32
;
282 *sw_status
= REG_GET(AUX_SW_STATUS
, AUX_SW_REPLY_BYTE_COUNT
,
285 /* In case HPD is LOW, exit AUX transaction */
286 if ((*sw_status
& AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK
))
289 /* Need at least the status byte */
293 REG_UPDATE_SEQ_3(AUX_SW_DATA
,
295 AUX_SW_AUTOINCREMENT_DISABLE
, 1,
298 REG_GET(AUX_SW_DATA
, AUX_SW_DATA
, &reply_result_32
);
299 reply_result_32
= reply_result_32
>> 4;
300 if (reply_result
!= NULL
)
301 *reply_result
= (uint8_t)reply_result_32
;
303 if (reply_result_32
== 0) { /* ACK */
306 /* First byte was already used to get the command status */
309 /* Do not overflow buffer */
310 if (bytes_replied
> size
)
313 while (i
< bytes_replied
) {
314 uint32_t aux_sw_data_val
;
316 REG_GET(AUX_SW_DATA
, AUX_SW_DATA
, &aux_sw_data_val
);
317 buffer
[i
] = aux_sw_data_val
;
327 static enum aux_channel_operation_result
get_channel_status(
328 struct dce_aux
*engine
,
329 uint8_t *returned_bytes
)
331 struct aux_engine_dce110
*aux110
= FROM_AUX_ENGINE(engine
);
335 if (returned_bytes
== NULL
) {
336 /*caller pass NULL pointer*/
337 ASSERT_CRITICAL(false);
338 return AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN
;
342 /* poll to make sure that SW_DONE is asserted */
343 REG_WAIT(AUX_SW_STATUS
, AUX_SW_DONE
, 1,
344 10, aux110
->polling_timeout_period
/10);
346 value
= REG_READ(AUX_SW_STATUS
);
347 /* in case HPD is LOW, exit AUX transaction */
348 if ((value
& AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK
))
349 return AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON
;
351 /* Note that the following bits are set in 'status.bits'
352 * during CTS 4.2.1.2 (FW 3.3.1):
353 * AUX_SW_RX_MIN_COUNT_VIOL, AUX_SW_RX_INVALID_STOP,
354 * AUX_SW_RX_RECV_NO_DET, AUX_SW_RX_RECV_INVALID_H.
356 * AUX_SW_RX_MIN_COUNT_VIOL is an internal,
357 * HW debugging bit and should be ignored.
359 if (value
& AUX_SW_STATUS__AUX_SW_DONE_MASK
) {
360 if ((value
& AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_STATE_MASK
) ||
361 (value
& AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_MASK
))
362 return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT
;
364 else if ((value
& AUX_SW_STATUS__AUX_SW_RX_INVALID_STOP_MASK
) ||
365 (value
& AUX_SW_STATUS__AUX_SW_RX_RECV_NO_DET_MASK
) ||
367 AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_H_MASK
) ||
368 (value
& AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_L_MASK
))
369 return AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY
;
371 *returned_bytes
= get_reg_field_value(value
,
373 AUX_SW_REPLY_BYTE_COUNT
);
375 if (*returned_bytes
== 0)
377 AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY
;
379 *returned_bytes
-= 1;
380 return AUX_CHANNEL_OPERATION_SUCCEEDED
;
383 /*time_elapsed >= aux_engine->timeout_period
384 * AUX_SW_STATUS__AUX_SW_HPD_DISCON = at this point
386 ASSERT_CRITICAL(false);
387 return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT
;
391 enum i2caux_engine_type
get_engine_type(
392 const struct dce_aux
*engine
)
394 return I2CAUX_ENGINE_TYPE_AUX
;
398 struct dce_aux
*engine
,
401 enum gpio_result result
;
403 if ((engine
== NULL
) || !is_engine_available(engine
))
406 result
= dal_ddc_open(ddc
, GPIO_MODE_HARDWARE
,
407 GPIO_DDC_CONFIG_TYPE_MODE_AUX
);
409 if (result
!= GPIO_RESULT_OK
)
412 if (!acquire_engine(engine
)) {
422 void dce110_engine_destroy(struct dce_aux
**engine
)
425 struct aux_engine_dce110
*engine110
= FROM_AUX_ENGINE(*engine
);
432 static uint32_t dce_aux_configure_timeout(struct ddc_service
*ddc
,
433 uint32_t timeout_in_us
)
435 uint32_t multiplier
= 0;
437 uint32_t prev_length
= 0;
438 uint32_t prev_mult
= 0;
439 uint32_t prev_timeout_val
= 0;
440 struct ddc
*ddc_pin
= ddc
->ddc_pin
;
441 struct dce_aux
*aux_engine
= ddc
->ctx
->dc
->res_pool
->engines
[ddc_pin
->pin_data
->en
];
442 struct aux_engine_dce110
*aux110
= FROM_AUX_ENGINE(aux_engine
);
444 /* 1-Update polling timeout period */
445 aux110
->polling_timeout_period
= timeout_in_us
* SW_AUX_TIMEOUT_PERIOD_MULTIPLIER
;
447 /* 2-Update aux timeout period length and multiplier */
448 if (timeout_in_us
== 0) {
449 multiplier
= DEFAULT_AUX_ENGINE_MULT
;
450 length
= DEFAULT_AUX_ENGINE_LENGTH
;
451 } else if (timeout_in_us
<= TIME_OUT_INCREMENT
) {
453 length
= timeout_in_us
/TIME_OUT_MULTIPLIER_8
;
454 if (timeout_in_us
% TIME_OUT_MULTIPLIER_8
!= 0)
456 } else if (timeout_in_us
<= 2 * TIME_OUT_INCREMENT
) {
458 length
= timeout_in_us
/TIME_OUT_MULTIPLIER_16
;
459 if (timeout_in_us
% TIME_OUT_MULTIPLIER_16
!= 0)
461 } else if (timeout_in_us
<= 4 * TIME_OUT_INCREMENT
) {
463 length
= timeout_in_us
/TIME_OUT_MULTIPLIER_32
;
464 if (timeout_in_us
% TIME_OUT_MULTIPLIER_32
!= 0)
466 } else if (timeout_in_us
> 4 * TIME_OUT_INCREMENT
) {
468 length
= timeout_in_us
/TIME_OUT_MULTIPLIER_64
;
469 if (timeout_in_us
% TIME_OUT_MULTIPLIER_64
!= 0)
473 length
= (length
< MAX_TIMEOUT_LENGTH
) ? length
: MAX_TIMEOUT_LENGTH
;
475 REG_GET_2(AUX_DPHY_RX_CONTROL1
, AUX_RX_TIMEOUT_LEN
, &prev_length
, AUX_RX_TIMEOUT_LEN_MUL
, &prev_mult
);
479 prev_timeout_val
= prev_length
* TIME_OUT_MULTIPLIER_8
;
482 prev_timeout_val
= prev_length
* TIME_OUT_MULTIPLIER_16
;
485 prev_timeout_val
= prev_length
* TIME_OUT_MULTIPLIER_32
;
488 prev_timeout_val
= prev_length
* TIME_OUT_MULTIPLIER_64
;
491 prev_timeout_val
= DEFAULT_AUX_ENGINE_LENGTH
* TIME_OUT_MULTIPLIER_8
;
495 REG_UPDATE_SEQ_2(AUX_DPHY_RX_CONTROL1
, AUX_RX_TIMEOUT_LEN
, length
, AUX_RX_TIMEOUT_LEN_MUL
, multiplier
);
497 return prev_timeout_val
;
500 static struct dce_aux_funcs aux_functions
= {
501 .configure_timeout
= NULL
,
505 struct dce_aux
*dce110_aux_engine_construct(struct aux_engine_dce110
*aux_engine110
,
506 struct dc_context
*ctx
,
508 uint32_t timeout_period
,
509 const struct dce110_aux_registers
*regs
,
510 const struct dce110_aux_registers_mask
*mask
,
511 const struct dce110_aux_registers_shift
*shift
,
512 bool is_ext_aux_timeout_configurable
)
514 aux_engine110
->base
.ddc
= NULL
;
515 aux_engine110
->base
.ctx
= ctx
;
516 aux_engine110
->base
.delay
= 0;
517 aux_engine110
->base
.max_defer_write_retry
= 0;
518 aux_engine110
->base
.inst
= inst
;
519 aux_engine110
->polling_timeout_period
= timeout_period
;
520 aux_engine110
->regs
= regs
;
522 aux_engine110
->mask
= mask
;
523 aux_engine110
->shift
= shift
;
524 aux_engine110
->base
.funcs
= &aux_functions
;
525 if (is_ext_aux_timeout_configurable
)
526 aux_engine110
->base
.funcs
->configure_timeout
= &dce_aux_configure_timeout
;
528 return &aux_engine110
->base
;
531 static enum i2caux_transaction_action
i2caux_action_from_payload(struct aux_payload
*payload
)
533 if (payload
->i2c_over_aux
) {
534 if (payload
->write
) {
536 return I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT
;
537 return I2CAUX_TRANSACTION_ACTION_I2C_WRITE
;
540 return I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT
;
541 return I2CAUX_TRANSACTION_ACTION_I2C_READ
;
544 return I2CAUX_TRANSACTION_ACTION_DP_WRITE
;
545 return I2CAUX_TRANSACTION_ACTION_DP_READ
;
548 int dce_aux_transfer_raw(struct ddc_service
*ddc
,
549 struct aux_payload
*payload
,
550 enum aux_channel_operation_result
*operation_result
)
552 struct ddc
*ddc_pin
= ddc
->ddc_pin
;
553 struct dce_aux
*aux_engine
;
554 struct aux_request_transaction_data aux_req
;
555 struct aux_reply_transaction_data aux_rep
;
556 uint8_t returned_bytes
= 0;
560 memset(&aux_req
, 0, sizeof(aux_req
));
561 memset(&aux_rep
, 0, sizeof(aux_rep
));
563 aux_engine
= ddc
->ctx
->dc
->res_pool
->engines
[ddc_pin
->pin_data
->en
];
564 if (!acquire(aux_engine
, ddc_pin
)) {
565 *operation_result
= AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE
;
569 if (payload
->i2c_over_aux
)
570 aux_req
.type
= AUX_TRANSACTION_TYPE_I2C
;
572 aux_req
.type
= AUX_TRANSACTION_TYPE_DP
;
574 aux_req
.action
= i2caux_action_from_payload(payload
);
576 aux_req
.address
= payload
->address
;
578 aux_req
.length
= payload
->length
;
579 aux_req
.data
= payload
->data
;
581 submit_channel_request(aux_engine
, &aux_req
);
582 *operation_result
= get_channel_status(aux_engine
, &returned_bytes
);
584 if (*operation_result
== AUX_CHANNEL_OPERATION_SUCCEEDED
) {
585 int bytes_replied
= 0;
586 bytes_replied
= read_channel_reply(aux_engine
, payload
->length
,
587 payload
->data
, payload
->reply
,
589 EVENT_LOG_AUX_REP(aux_engine
->ddc
->pin_data
->en
,
590 EVENT_LOG_AUX_ORIGIN_NATIVE
, *payload
->reply
,
591 bytes_replied
, payload
->data
);
592 res
= returned_bytes
;
597 release_engine(aux_engine
);
601 #define AUX_MAX_RETRIES 7
602 #define AUX_MAX_DEFER_RETRIES 7
603 #define AUX_MAX_I2C_DEFER_RETRIES 7
604 #define AUX_MAX_INVALID_REPLY_RETRIES 2
605 #define AUX_MAX_TIMEOUT_RETRIES 3
607 bool dce_aux_transfer_with_retries(struct ddc_service
*ddc
,
608 struct aux_payload
*payload
)
612 bool payload_reply
= true;
613 enum aux_channel_operation_result operation_result
;
614 bool retry_on_defer
= false;
616 int aux_ack_retries
= 0,
617 aux_defer_retries
= 0,
618 aux_i2c_defer_retries
= 0,
619 aux_timeout_retries
= 0,
620 aux_invalid_reply_retries
= 0;
622 if (!payload
->reply
) {
623 payload_reply
= false;
624 payload
->reply
= &reply
;
627 for (i
= 0; i
< AUX_MAX_RETRIES
; i
++) {
628 ret
= dce_aux_transfer_raw(ddc
, payload
, &operation_result
);
629 switch (operation_result
) {
630 case AUX_CHANNEL_OPERATION_SUCCEEDED
:
631 aux_timeout_retries
= 0;
632 aux_invalid_reply_retries
= 0;
634 switch (*payload
->reply
) {
635 case AUX_TRANSACTION_REPLY_AUX_ACK
:
636 if (!payload
->write
&& payload
->length
!= ret
) {
637 if (++aux_ack_retries
>= AUX_MAX_RETRIES
)
645 case AUX_TRANSACTION_REPLY_AUX_DEFER
:
646 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER
:
647 retry_on_defer
= true;
649 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK
:
650 if (++aux_defer_retries
>= AUX_MAX_DEFER_RETRIES
) {
653 if ((*payload
->reply
== AUX_TRANSACTION_REPLY_AUX_DEFER
) ||
654 (*payload
->reply
== AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER
)) {
655 if (payload
->defer_delay
> 1)
656 msleep(payload
->defer_delay
);
657 else if (payload
->defer_delay
<= 1)
658 udelay(payload
->defer_delay
* 1000);
663 case AUX_TRANSACTION_REPLY_I2C_DEFER
:
664 aux_defer_retries
= 0;
665 if (++aux_i2c_defer_retries
>= AUX_MAX_I2C_DEFER_RETRIES
)
669 case AUX_TRANSACTION_REPLY_AUX_NACK
:
670 case AUX_TRANSACTION_REPLY_HPD_DISCON
:
676 case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY
:
677 if (++aux_invalid_reply_retries
>= AUX_MAX_INVALID_REPLY_RETRIES
)
683 case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT
:
684 // Check whether a DEFER had occurred before the timeout.
685 // If so, treat timeout as a DEFER.
686 if (retry_on_defer
) {
687 if (++aux_defer_retries
>= AUX_MAX_DEFER_RETRIES
)
689 else if (payload
->defer_delay
> 0)
690 msleep(payload
->defer_delay
);
692 if (++aux_timeout_retries
>= AUX_MAX_TIMEOUT_RETRIES
)
696 * DP 1.4, 2.8.2: AUX Transaction Response/Reply Timeouts
697 * According to the DP spec there should be 3 retries total
698 * with a 400us wait inbetween each. Hardware already waits
699 * for 550us therefore no wait is required here.
705 case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON
:
706 case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE
:
707 case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN
:
715 payload
->reply
= NULL
;