1 /* 2 * Copyright 2012-15 Advanced Micro Devices, Inc. 3 * 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: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 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. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 #include <linux/delay.h> 27 #include <linux/slab.h> 28 29 #include "dm_services.h" 30 #include "core_types.h" 31 #include "dce_aux.h" 32 #include "dce/dce_11_0_sh_mask.h" 33 #include "dm_event_log.h" 34 35 #define CTX \ 36 aux110->base.ctx 37 #define REG(reg_name)\ 38 (aux110->regs->reg_name) 39 40 #define DC_LOGGER \ 41 engine->ctx->logger 42 43 #include "reg_helper.h" 44 45 #undef FN 46 #define FN(reg_name, field_name) \ 47 aux110->shift->field_name, aux110->mask->field_name 48 49 #define FROM_AUX_ENGINE(ptr) \ 50 container_of((ptr), struct aux_engine_dce110, base) 51 52 #define FROM_ENGINE(ptr) \ 53 FROM_AUX_ENGINE(container_of((ptr), struct dce_aux, base)) 54 55 #define FROM_AUX_ENGINE_ENGINE(ptr) \ 56 container_of((ptr), struct dce_aux, base) 57 enum { 58 AUX_INVALID_REPLY_RETRY_COUNTER = 1, 59 AUX_TIMED_OUT_RETRY_COUNTER = 2, 60 AUX_DEFER_RETRY_COUNTER = 6 61 }; 62 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 71 72 static void release_engine( 73 struct dce_aux *engine) 74 { 75 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 76 77 dal_ddc_close(engine->ddc); 78 79 engine->ddc = NULL; 80 81 REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, 1); 82 } 83 84 #define SW_CAN_ACCESS_AUX 1 85 #define DMCU_CAN_ACCESS_AUX 2 86 87 static bool is_engine_available( 88 struct dce_aux *engine) 89 { 90 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 91 92 uint32_t value = REG_READ(AUX_ARB_CONTROL); 93 uint32_t field = get_reg_field_value( 94 value, 95 AUX_ARB_CONTROL, 96 AUX_REG_RW_CNTL_STATUS); 97 98 return (field != DMCU_CAN_ACCESS_AUX); 99 } 100 static bool acquire_engine( 101 struct dce_aux *engine) 102 { 103 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 104 105 uint32_t value = REG_READ(AUX_ARB_CONTROL); 106 uint32_t field = get_reg_field_value( 107 value, 108 AUX_ARB_CONTROL, 109 AUX_REG_RW_CNTL_STATUS); 110 if (field == DMCU_CAN_ACCESS_AUX) 111 return false; 112 /* enable AUX before request SW to access AUX */ 113 value = REG_READ(AUX_CONTROL); 114 field = get_reg_field_value(value, 115 AUX_CONTROL, 116 AUX_EN); 117 118 if (field == 0) { 119 set_reg_field_value( 120 value, 121 1, 122 AUX_CONTROL, 123 AUX_EN); 124 125 if (REG(AUX_RESET_MASK)) { 126 /*DP_AUX block as part of the enable sequence*/ 127 set_reg_field_value( 128 value, 129 1, 130 AUX_CONTROL, 131 AUX_RESET); 132 } 133 134 REG_WRITE(AUX_CONTROL, value); 135 136 if (REG(AUX_RESET_MASK)) { 137 /*poll HW to make sure reset it done*/ 138 139 REG_WAIT(AUX_CONTROL, AUX_RESET_DONE, 1, 140 1, 11); 141 142 set_reg_field_value( 143 value, 144 0, 145 AUX_CONTROL, 146 AUX_RESET); 147 148 REG_WRITE(AUX_CONTROL, value); 149 150 REG_WAIT(AUX_CONTROL, AUX_RESET_DONE, 0, 151 1, 11); 152 } 153 } /*if (field)*/ 154 155 /* request SW to access AUX */ 156 REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, 1); 157 158 value = REG_READ(AUX_ARB_CONTROL); 159 field = get_reg_field_value( 160 value, 161 AUX_ARB_CONTROL, 162 AUX_REG_RW_CNTL_STATUS); 163 164 return (field == SW_CAN_ACCESS_AUX); 165 } 166 167 #define COMPOSE_AUX_SW_DATA_16_20(command, address) \ 168 ((command) | ((0xF0000 & (address)) >> 16)) 169 170 #define COMPOSE_AUX_SW_DATA_8_15(address) \ 171 ((0xFF00 & (address)) >> 8) 172 173 #define COMPOSE_AUX_SW_DATA_0_7(address) \ 174 (0xFF & (address)) 175 176 static void submit_channel_request( 177 struct dce_aux *engine, 178 struct aux_request_transaction_data *request) 179 { 180 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 181 uint32_t value; 182 uint32_t length; 183 184 bool is_write = 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); 195 196 REG_UPDATE_SEQ_2(AUXP_IMPCAL, 197 AUXP_CALOUT_ERROR_AK, 1, 198 AUXP_CALOUT_ERROR_AK, 0); 199 200 /* force_default_calibrate */ 201 REG_UPDATE_SEQ_2(AUXN_IMPCAL, 202 AUXN_IMPCAL_ENABLE, 1, 203 AUXN_IMPCAL_OVERRIDE_ENABLE, 0); 204 205 /* bug? why AUXN update EN and OVERRIDE_EN 1 by 1 while AUX P toggles OVERRIDE? */ 206 207 REG_UPDATE_SEQ_2(AUXP_IMPCAL, 208 AUXP_IMPCAL_OVERRIDE_ENABLE, 1, 209 AUXP_IMPCAL_OVERRIDE_ENABLE, 0); 210 } 211 212 REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1); 213 214 REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0, 215 10, aux110->polling_timeout_period/10); 216 217 /* set the delay and the number of bytes to write */ 218 219 /* The length include 220 * the 4 bit header and the 20 bit address 221 * (that is 3 byte). 222 * If the requested length is non zero this means 223 * an addition byte specifying the length is required. 224 */ 225 226 length = request->length ? 4 : 3; 227 if (is_write) 228 length += request->length; 229 230 REG_UPDATE_2(AUX_SW_CONTROL, 231 AUX_SW_START_DELAY, request->delay, 232 AUX_SW_WR_BYTES, length); 233 234 /* program action and address and payload data (if 'is_write') */ 235 value = REG_UPDATE_4(AUX_SW_DATA, 236 AUX_SW_INDEX, 0, 237 AUX_SW_DATA_RW, 0, 238 AUX_SW_AUTOINCREMENT_DISABLE, 1, 239 AUX_SW_DATA, COMPOSE_AUX_SW_DATA_16_20(request->action, request->address)); 240 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)); 244 245 value = REG_SET(AUX_SW_DATA, value, 246 AUX_SW_DATA, COMPOSE_AUX_SW_DATA_0_7(request->address)); 247 248 if (request->length) { 249 value = REG_SET(AUX_SW_DATA, value, 250 AUX_SW_DATA, request->length - 1); 251 } 252 253 if (is_write) { 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(). 258 */ 259 uint32_t i = 0; 260 261 while (i < request->length) { 262 value = REG_SET(AUX_SW_DATA, value, 263 AUX_SW_DATA, request->data[i]); 264 265 ++i; 266 } 267 } 268 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); 272 } 273 274 static int read_channel_reply(struct dce_aux *engine, uint32_t size, 275 uint8_t *buffer, uint8_t *reply_result, 276 uint32_t *sw_status) 277 { 278 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 279 uint32_t bytes_replied; 280 uint32_t reply_result_32; 281 282 *sw_status = REG_GET(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, 283 &bytes_replied); 284 285 /* In case HPD is LOW, exit AUX transaction */ 286 if ((*sw_status & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) 287 return -1; 288 289 /* Need at least the status byte */ 290 if (!bytes_replied) 291 return -1; 292 293 REG_UPDATE_SEQ_3(AUX_SW_DATA, 294 AUX_SW_INDEX, 0, 295 AUX_SW_AUTOINCREMENT_DISABLE, 1, 296 AUX_SW_DATA_RW, 1); 297 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; 302 303 if (reply_result_32 == 0) { /* ACK */ 304 uint32_t i = 0; 305 306 /* First byte was already used to get the command status */ 307 --bytes_replied; 308 309 /* Do not overflow buffer */ 310 if (bytes_replied > size) 311 return -1; 312 313 while (i < bytes_replied) { 314 uint32_t aux_sw_data_val; 315 316 REG_GET(AUX_SW_DATA, AUX_SW_DATA, &aux_sw_data_val); 317 buffer[i] = aux_sw_data_val; 318 ++i; 319 } 320 321 return i; 322 } 323 324 return 0; 325 } 326 327 static enum aux_channel_operation_result get_channel_status( 328 struct dce_aux *engine, 329 uint8_t *returned_bytes) 330 { 331 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 332 333 uint32_t value; 334 335 if (returned_bytes == NULL) { 336 /*caller pass NULL pointer*/ 337 ASSERT_CRITICAL(false); 338 return AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN; 339 } 340 *returned_bytes = 0; 341 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); 345 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; 350 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. 355 * 356 * AUX_SW_RX_MIN_COUNT_VIOL is an internal, 357 * HW debugging bit and should be ignored. 358 */ 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; 363 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) || 366 (value & 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; 370 371 *returned_bytes = get_reg_field_value(value, 372 AUX_SW_STATUS, 373 AUX_SW_REPLY_BYTE_COUNT); 374 375 if (*returned_bytes == 0) 376 return 377 AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY; 378 else { 379 *returned_bytes -= 1; 380 return AUX_CHANNEL_OPERATION_SUCCEEDED; 381 } 382 } else { 383 /*time_elapsed >= aux_engine->timeout_period 384 * AUX_SW_STATUS__AUX_SW_HPD_DISCON = at this point 385 */ 386 ASSERT_CRITICAL(false); 387 return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT; 388 } 389 } 390 391 enum i2caux_engine_type get_engine_type( 392 const struct dce_aux *engine) 393 { 394 return I2CAUX_ENGINE_TYPE_AUX; 395 } 396 397 static bool acquire( 398 struct dce_aux *engine, 399 struct ddc *ddc) 400 { 401 enum gpio_result result; 402 403 if ((engine == NULL) || !is_engine_available(engine)) 404 return false; 405 406 result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE, 407 GPIO_DDC_CONFIG_TYPE_MODE_AUX); 408 409 if (result != GPIO_RESULT_OK) 410 return false; 411 412 if (!acquire_engine(engine)) { 413 dal_ddc_close(ddc); 414 return false; 415 } 416 417 engine->ddc = ddc; 418 419 return true; 420 } 421 422 void dce110_engine_destroy(struct dce_aux **engine) 423 { 424 425 struct aux_engine_dce110 *engine110 = FROM_AUX_ENGINE(*engine); 426 427 kfree(engine110); 428 *engine = NULL; 429 430 } 431 432 static uint32_t dce_aux_configure_timeout(struct ddc_service *ddc, 433 uint32_t timeout_in_us) 434 { 435 uint32_t multiplier = 0; 436 uint32_t length = 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); 443 444 /* 1-Update polling timeout period */ 445 aux110->polling_timeout_period = timeout_in_us * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER; 446 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) { 452 multiplier = 0; 453 length = timeout_in_us/TIME_OUT_MULTIPLIER_8; 454 if (timeout_in_us % TIME_OUT_MULTIPLIER_8 != 0) 455 length++; 456 } else if (timeout_in_us <= 2 * TIME_OUT_INCREMENT) { 457 multiplier = 1; 458 length = timeout_in_us/TIME_OUT_MULTIPLIER_16; 459 if (timeout_in_us % TIME_OUT_MULTIPLIER_16 != 0) 460 length++; 461 } else if (timeout_in_us <= 4 * TIME_OUT_INCREMENT) { 462 multiplier = 2; 463 length = timeout_in_us/TIME_OUT_MULTIPLIER_32; 464 if (timeout_in_us % TIME_OUT_MULTIPLIER_32 != 0) 465 length++; 466 } else if (timeout_in_us > 4 * TIME_OUT_INCREMENT) { 467 multiplier = 3; 468 length = timeout_in_us/TIME_OUT_MULTIPLIER_64; 469 if (timeout_in_us % TIME_OUT_MULTIPLIER_64 != 0) 470 length++; 471 } 472 473 length = (length < MAX_TIMEOUT_LENGTH) ? length : MAX_TIMEOUT_LENGTH; 474 475 REG_GET_2(AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, &prev_length, AUX_RX_TIMEOUT_LEN_MUL, &prev_mult); 476 477 switch (prev_mult) { 478 case 0: 479 prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_8; 480 break; 481 case 1: 482 prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_16; 483 break; 484 case 2: 485 prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_32; 486 break; 487 case 3: 488 prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_64; 489 break; 490 default: 491 prev_timeout_val = DEFAULT_AUX_ENGINE_LENGTH * TIME_OUT_MULTIPLIER_8; 492 break; 493 } 494 495 REG_UPDATE_SEQ_2(AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, length, AUX_RX_TIMEOUT_LEN_MUL, multiplier); 496 497 return prev_timeout_val; 498 } 499 500 static struct dce_aux_funcs aux_functions = { 501 .configure_timeout = NULL, 502 .destroy = NULL, 503 }; 504 505 struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110, 506 struct dc_context *ctx, 507 uint32_t inst, 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) 513 { 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; 521 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; 527 528 return &aux_engine110->base; 529 } 530 531 static enum i2caux_transaction_action i2caux_action_from_payload(struct aux_payload *payload) 532 { 533 if (payload->i2c_over_aux) { 534 if (payload->write) { 535 if (payload->mot) 536 return I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT; 537 return I2CAUX_TRANSACTION_ACTION_I2C_WRITE; 538 } 539 if (payload->mot) 540 return I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT; 541 return I2CAUX_TRANSACTION_ACTION_I2C_READ; 542 } 543 if (payload->write) 544 return I2CAUX_TRANSACTION_ACTION_DP_WRITE; 545 return I2CAUX_TRANSACTION_ACTION_DP_READ; 546 } 547 548 int dce_aux_transfer_raw(struct ddc_service *ddc, 549 struct aux_payload *payload, 550 enum aux_channel_operation_result *operation_result) 551 { 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; 557 int res = -1; 558 uint32_t status; 559 560 memset(&aux_req, 0, sizeof(aux_req)); 561 memset(&aux_rep, 0, sizeof(aux_rep)); 562 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; 566 return -1; 567 } 568 569 if (payload->i2c_over_aux) 570 aux_req.type = AUX_TRANSACTION_TYPE_I2C; 571 else 572 aux_req.type = AUX_TRANSACTION_TYPE_DP; 573 574 aux_req.action = i2caux_action_from_payload(payload); 575 576 aux_req.address = payload->address; 577 aux_req.delay = 0; 578 aux_req.length = payload->length; 579 aux_req.data = payload->data; 580 581 submit_channel_request(aux_engine, &aux_req); 582 *operation_result = get_channel_status(aux_engine, &returned_bytes); 583 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, 588 &status); 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; 593 } else { 594 res = -1; 595 } 596 597 release_engine(aux_engine); 598 return res; 599 } 600 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 606 607 bool dce_aux_transfer_with_retries(struct ddc_service *ddc, 608 struct aux_payload *payload) 609 { 610 int i, ret = 0; 611 uint8_t reply; 612 bool payload_reply = true; 613 enum aux_channel_operation_result operation_result; 614 bool retry_on_defer = false; 615 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; 621 622 if (!payload->reply) { 623 payload_reply = false; 624 payload->reply = &reply; 625 } 626 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; 633 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) 638 goto fail; 639 else 640 udelay(300); 641 } else 642 return true; 643 break; 644 645 case AUX_TRANSACTION_REPLY_AUX_DEFER: 646 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER: 647 retry_on_defer = true; 648 fallthrough; 649 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK: 650 if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) { 651 goto fail; 652 } else { 653 if ((*payload->reply == AUX_TRANSACTION_REPLY_AUX_DEFER) || 654 (*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER)) { 655 if (payload->defer_delay > 0) 656 msleep(payload->defer_delay); 657 } 658 } 659 break; 660 661 case AUX_TRANSACTION_REPLY_I2C_DEFER: 662 aux_defer_retries = 0; 663 if (++aux_i2c_defer_retries >= AUX_MAX_I2C_DEFER_RETRIES) 664 goto fail; 665 break; 666 667 case AUX_TRANSACTION_REPLY_AUX_NACK: 668 case AUX_TRANSACTION_REPLY_HPD_DISCON: 669 default: 670 goto fail; 671 } 672 break; 673 674 case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY: 675 if (++aux_invalid_reply_retries >= AUX_MAX_INVALID_REPLY_RETRIES) 676 goto fail; 677 else 678 udelay(400); 679 break; 680 681 case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT: 682 // Check whether a DEFER had occurred before the timeout. 683 // If so, treat timeout as a DEFER. 684 if (retry_on_defer) { 685 if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) 686 goto fail; 687 else if (payload->defer_delay > 0) 688 msleep(payload->defer_delay); 689 } else { 690 if (++aux_timeout_retries >= AUX_MAX_TIMEOUT_RETRIES) 691 goto fail; 692 else { 693 /* 694 * DP 1.4, 2.8.2: AUX Transaction Response/Reply Timeouts 695 * According to the DP spec there should be 3 retries total 696 * with a 400us wait inbetween each. Hardware already waits 697 * for 550us therefore no wait is required here. 698 */ 699 } 700 } 701 break; 702 703 case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: 704 case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE: 705 case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN: 706 default: 707 goto fail; 708 } 709 } 710 711 fail: 712 if (!payload_reply) 713 payload->reply = NULL; 714 return false; 715 } 716