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 #define FROM_AUX_ENGINE(ptr) \ 46 container_of((ptr), struct aux_engine_dce110, base) 47 48 #define FROM_ENGINE(ptr) \ 49 FROM_AUX_ENGINE(container_of((ptr), struct dce_aux, base)) 50 51 #define FROM_AUX_ENGINE_ENGINE(ptr) \ 52 container_of((ptr), struct dce_aux, base) 53 enum { 54 AUX_INVALID_REPLY_RETRY_COUNTER = 1, 55 AUX_TIMED_OUT_RETRY_COUNTER = 2, 56 AUX_DEFER_RETRY_COUNTER = 6 57 }; 58 static void release_engine( 59 struct dce_aux *engine) 60 { 61 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 62 63 dal_ddc_close(engine->ddc); 64 65 engine->ddc = NULL; 66 67 REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, 1); 68 } 69 70 #define SW_CAN_ACCESS_AUX 1 71 #define DMCU_CAN_ACCESS_AUX 2 72 73 static bool is_engine_available( 74 struct dce_aux *engine) 75 { 76 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 77 78 uint32_t value = REG_READ(AUX_ARB_CONTROL); 79 uint32_t field = get_reg_field_value( 80 value, 81 AUX_ARB_CONTROL, 82 AUX_REG_RW_CNTL_STATUS); 83 84 return (field != DMCU_CAN_ACCESS_AUX); 85 } 86 static bool acquire_engine( 87 struct dce_aux *engine) 88 { 89 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 90 91 uint32_t value = REG_READ(AUX_ARB_CONTROL); 92 uint32_t field = get_reg_field_value( 93 value, 94 AUX_ARB_CONTROL, 95 AUX_REG_RW_CNTL_STATUS); 96 if (field == DMCU_CAN_ACCESS_AUX) 97 return false; 98 /* enable AUX before request SW to access AUX */ 99 value = REG_READ(AUX_CONTROL); 100 field = get_reg_field_value(value, 101 AUX_CONTROL, 102 AUX_EN); 103 104 if (field == 0) { 105 set_reg_field_value( 106 value, 107 1, 108 AUX_CONTROL, 109 AUX_EN); 110 111 if (REG(AUX_RESET_MASK)) { 112 /*DP_AUX block as part of the enable sequence*/ 113 set_reg_field_value( 114 value, 115 1, 116 AUX_CONTROL, 117 AUX_RESET); 118 } 119 120 REG_WRITE(AUX_CONTROL, value); 121 122 if (REG(AUX_RESET_MASK)) { 123 /*poll HW to make sure reset it done*/ 124 125 REG_WAIT(AUX_CONTROL, AUX_RESET_DONE, 1, 126 1, 11); 127 128 set_reg_field_value( 129 value, 130 0, 131 AUX_CONTROL, 132 AUX_RESET); 133 134 REG_WRITE(AUX_CONTROL, value); 135 136 REG_WAIT(AUX_CONTROL, AUX_RESET_DONE, 0, 137 1, 11); 138 } 139 } /*if (field)*/ 140 141 /* request SW to access AUX */ 142 REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, 1); 143 144 value = REG_READ(AUX_ARB_CONTROL); 145 field = get_reg_field_value( 146 value, 147 AUX_ARB_CONTROL, 148 AUX_REG_RW_CNTL_STATUS); 149 150 return (field == SW_CAN_ACCESS_AUX); 151 } 152 153 #define COMPOSE_AUX_SW_DATA_16_20(command, address) \ 154 ((command) | ((0xF0000 & (address)) >> 16)) 155 156 #define COMPOSE_AUX_SW_DATA_8_15(address) \ 157 ((0xFF00 & (address)) >> 8) 158 159 #define COMPOSE_AUX_SW_DATA_0_7(address) \ 160 (0xFF & (address)) 161 162 static void submit_channel_request( 163 struct dce_aux *engine, 164 struct aux_request_transaction_data *request) 165 { 166 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 167 uint32_t value; 168 uint32_t length; 169 170 bool is_write = 171 ((request->type == AUX_TRANSACTION_TYPE_DP) && 172 (request->action == I2CAUX_TRANSACTION_ACTION_DP_WRITE)) || 173 ((request->type == AUX_TRANSACTION_TYPE_I2C) && 174 ((request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) || 175 (request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT))); 176 if (REG(AUXN_IMPCAL)) { 177 /* clear_aux_error */ 178 REG_UPDATE_SEQ_2(AUXN_IMPCAL, 179 AUXN_CALOUT_ERROR_AK, 1, 180 AUXN_CALOUT_ERROR_AK, 0); 181 182 REG_UPDATE_SEQ_2(AUXP_IMPCAL, 183 AUXP_CALOUT_ERROR_AK, 1, 184 AUXP_CALOUT_ERROR_AK, 0); 185 186 /* force_default_calibrate */ 187 REG_UPDATE_SEQ_2(AUXN_IMPCAL, 188 AUXN_IMPCAL_ENABLE, 1, 189 AUXN_IMPCAL_OVERRIDE_ENABLE, 0); 190 191 /* bug? why AUXN update EN and OVERRIDE_EN 1 by 1 while AUX P toggles OVERRIDE? */ 192 193 REG_UPDATE_SEQ_2(AUXP_IMPCAL, 194 AUXP_IMPCAL_OVERRIDE_ENABLE, 1, 195 AUXP_IMPCAL_OVERRIDE_ENABLE, 0); 196 } 197 198 REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1); 199 200 REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0, 201 10, aux110->timeout_period/10); 202 203 /* set the delay and the number of bytes to write */ 204 205 /* The length include 206 * the 4 bit header and the 20 bit address 207 * (that is 3 byte). 208 * If the requested length is non zero this means 209 * an addition byte specifying the length is required. 210 */ 211 212 length = request->length ? 4 : 3; 213 if (is_write) 214 length += request->length; 215 216 REG_UPDATE_2(AUX_SW_CONTROL, 217 AUX_SW_START_DELAY, request->delay, 218 AUX_SW_WR_BYTES, length); 219 220 /* program action and address and payload data (if 'is_write') */ 221 value = REG_UPDATE_4(AUX_SW_DATA, 222 AUX_SW_INDEX, 0, 223 AUX_SW_DATA_RW, 0, 224 AUX_SW_AUTOINCREMENT_DISABLE, 1, 225 AUX_SW_DATA, COMPOSE_AUX_SW_DATA_16_20(request->action, request->address)); 226 227 value = REG_SET_2(AUX_SW_DATA, value, 228 AUX_SW_AUTOINCREMENT_DISABLE, 0, 229 AUX_SW_DATA, COMPOSE_AUX_SW_DATA_8_15(request->address)); 230 231 value = REG_SET(AUX_SW_DATA, value, 232 AUX_SW_DATA, COMPOSE_AUX_SW_DATA_0_7(request->address)); 233 234 if (request->length) { 235 value = REG_SET(AUX_SW_DATA, value, 236 AUX_SW_DATA, request->length - 1); 237 } 238 239 if (is_write) { 240 /* Load the HW buffer with the Data to be sent. 241 * This is relevant for write operation. 242 * For read, the data recived data will be 243 * processed in process_channel_reply(). 244 */ 245 uint32_t i = 0; 246 247 while (i < request->length) { 248 value = REG_SET(AUX_SW_DATA, value, 249 AUX_SW_DATA, request->data[i]); 250 251 ++i; 252 } 253 } 254 255 REG_UPDATE(AUX_SW_CONTROL, AUX_SW_GO, 1); 256 EVENT_LOG_AUX_REQ(engine->ddc->pin_data->en, EVENT_LOG_AUX_ORIGIN_NATIVE, 257 request->action, request->address, request->length, request->data); 258 } 259 260 static int read_channel_reply(struct dce_aux *engine, uint32_t size, 261 uint8_t *buffer, uint8_t *reply_result, 262 uint32_t *sw_status) 263 { 264 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 265 uint32_t bytes_replied; 266 uint32_t reply_result_32; 267 268 *sw_status = REG_GET(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, 269 &bytes_replied); 270 271 /* In case HPD is LOW, exit AUX transaction */ 272 if ((*sw_status & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) 273 return -1; 274 275 /* Need at least the status byte */ 276 if (!bytes_replied) 277 return -1; 278 279 REG_UPDATE_SEQ_3(AUX_SW_DATA, 280 AUX_SW_INDEX, 0, 281 AUX_SW_AUTOINCREMENT_DISABLE, 1, 282 AUX_SW_DATA_RW, 1); 283 284 REG_GET(AUX_SW_DATA, AUX_SW_DATA, &reply_result_32); 285 reply_result_32 = reply_result_32 >> 4; 286 if (reply_result != NULL) 287 *reply_result = (uint8_t)reply_result_32; 288 289 if (reply_result_32 == 0) { /* ACK */ 290 uint32_t i = 0; 291 292 /* First byte was already used to get the command status */ 293 --bytes_replied; 294 295 /* Do not overflow buffer */ 296 if (bytes_replied > size) 297 return -1; 298 299 while (i < bytes_replied) { 300 uint32_t aux_sw_data_val; 301 302 REG_GET(AUX_SW_DATA, AUX_SW_DATA, &aux_sw_data_val); 303 buffer[i] = aux_sw_data_val; 304 ++i; 305 } 306 307 return i; 308 } 309 310 return 0; 311 } 312 313 static enum aux_channel_operation_result get_channel_status( 314 struct dce_aux *engine, 315 uint8_t *returned_bytes) 316 { 317 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); 318 319 uint32_t value; 320 321 if (returned_bytes == NULL) { 322 /*caller pass NULL pointer*/ 323 ASSERT_CRITICAL(false); 324 return AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN; 325 } 326 *returned_bytes = 0; 327 328 /* poll to make sure that SW_DONE is asserted */ 329 REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1, 330 10, aux110->timeout_period/10); 331 332 value = REG_READ(AUX_SW_STATUS); 333 /* in case HPD is LOW, exit AUX transaction */ 334 if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) 335 return AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON; 336 337 /* Note that the following bits are set in 'status.bits' 338 * during CTS 4.2.1.2 (FW 3.3.1): 339 * AUX_SW_RX_MIN_COUNT_VIOL, AUX_SW_RX_INVALID_STOP, 340 * AUX_SW_RX_RECV_NO_DET, AUX_SW_RX_RECV_INVALID_H. 341 * 342 * AUX_SW_RX_MIN_COUNT_VIOL is an internal, 343 * HW debugging bit and should be ignored. 344 */ 345 if (value & AUX_SW_STATUS__AUX_SW_DONE_MASK) { 346 if ((value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_STATE_MASK) || 347 (value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_MASK)) 348 return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT; 349 350 else if ((value & AUX_SW_STATUS__AUX_SW_RX_INVALID_STOP_MASK) || 351 (value & AUX_SW_STATUS__AUX_SW_RX_RECV_NO_DET_MASK) || 352 (value & 353 AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_H_MASK) || 354 (value & AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_L_MASK)) 355 return AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY; 356 357 *returned_bytes = get_reg_field_value(value, 358 AUX_SW_STATUS, 359 AUX_SW_REPLY_BYTE_COUNT); 360 361 if (*returned_bytes == 0) 362 return 363 AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY; 364 else { 365 *returned_bytes -= 1; 366 return AUX_CHANNEL_OPERATION_SUCCEEDED; 367 } 368 } else { 369 /*time_elapsed >= aux_engine->timeout_period 370 * AUX_SW_STATUS__AUX_SW_HPD_DISCON = at this point 371 */ 372 ASSERT_CRITICAL(false); 373 return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT; 374 } 375 } 376 377 enum i2caux_engine_type get_engine_type( 378 const struct dce_aux *engine) 379 { 380 return I2CAUX_ENGINE_TYPE_AUX; 381 } 382 383 static bool acquire( 384 struct dce_aux *engine, 385 struct ddc *ddc) 386 { 387 enum gpio_result result; 388 389 if (!is_engine_available(engine)) 390 return false; 391 392 result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE, 393 GPIO_DDC_CONFIG_TYPE_MODE_AUX); 394 395 if (result != GPIO_RESULT_OK) 396 return false; 397 398 if (!acquire_engine(engine)) { 399 dal_ddc_close(ddc); 400 return false; 401 } 402 403 engine->ddc = ddc; 404 405 return true; 406 } 407 408 void dce110_engine_destroy(struct dce_aux **engine) 409 { 410 411 struct aux_engine_dce110 *engine110 = FROM_AUX_ENGINE(*engine); 412 413 kfree(engine110); 414 *engine = NULL; 415 416 } 417 struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110, 418 struct dc_context *ctx, 419 uint32_t inst, 420 uint32_t timeout_period, 421 const struct dce110_aux_registers *regs) 422 { 423 aux_engine110->base.ddc = NULL; 424 aux_engine110->base.ctx = ctx; 425 aux_engine110->base.delay = 0; 426 aux_engine110->base.max_defer_write_retry = 0; 427 aux_engine110->base.inst = inst; 428 aux_engine110->timeout_period = timeout_period; 429 aux_engine110->regs = regs; 430 431 return &aux_engine110->base; 432 } 433 434 static enum i2caux_transaction_action i2caux_action_from_payload(struct aux_payload *payload) 435 { 436 if (payload->i2c_over_aux) { 437 if (payload->write) { 438 if (payload->mot) 439 return I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT; 440 return I2CAUX_TRANSACTION_ACTION_I2C_WRITE; 441 } 442 if (payload->mot) 443 return I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT; 444 return I2CAUX_TRANSACTION_ACTION_I2C_READ; 445 } 446 if (payload->write) 447 return I2CAUX_TRANSACTION_ACTION_DP_WRITE; 448 return I2CAUX_TRANSACTION_ACTION_DP_READ; 449 } 450 451 int dce_aux_transfer_raw(struct ddc_service *ddc, 452 struct aux_payload *payload, 453 enum aux_channel_operation_result *operation_result) 454 { 455 struct ddc *ddc_pin = ddc->ddc_pin; 456 struct dce_aux *aux_engine; 457 struct aux_request_transaction_data aux_req; 458 struct aux_reply_transaction_data aux_rep; 459 uint8_t returned_bytes = 0; 460 int res = -1; 461 uint32_t status; 462 463 memset(&aux_req, 0, sizeof(aux_req)); 464 memset(&aux_rep, 0, sizeof(aux_rep)); 465 466 aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]; 467 if (!acquire(aux_engine, ddc_pin)) 468 return -1; 469 470 if (payload->i2c_over_aux) 471 aux_req.type = AUX_TRANSACTION_TYPE_I2C; 472 else 473 aux_req.type = AUX_TRANSACTION_TYPE_DP; 474 475 aux_req.action = i2caux_action_from_payload(payload); 476 477 aux_req.address = payload->address; 478 aux_req.delay = payload->defer_delay * 10; 479 aux_req.length = payload->length; 480 aux_req.data = payload->data; 481 482 submit_channel_request(aux_engine, &aux_req); 483 *operation_result = get_channel_status(aux_engine, &returned_bytes); 484 485 if (*operation_result == AUX_CHANNEL_OPERATION_SUCCEEDED) { 486 int bytes_replied = 0; 487 bytes_replied = read_channel_reply(aux_engine, payload->length, 488 payload->data, payload->reply, 489 &status); 490 EVENT_LOG_AUX_REP(aux_engine->ddc->pin_data->en, 491 EVENT_LOG_AUX_ORIGIN_NATIVE, *payload->reply, 492 bytes_replied, payload->data); 493 res = returned_bytes; 494 } else { 495 res = -1; 496 } 497 498 release_engine(aux_engine); 499 return res; 500 } 501 502 #define AUX_MAX_RETRIES 7 503 #define AUX_MAX_DEFER_RETRIES 7 504 #define AUX_MAX_I2C_DEFER_RETRIES 7 505 #define AUX_MAX_INVALID_REPLY_RETRIES 2 506 #define AUX_MAX_TIMEOUT_RETRIES 3 507 508 bool dce_aux_transfer_with_retries(struct ddc_service *ddc, 509 struct aux_payload *payload) 510 { 511 int i, ret = 0; 512 uint8_t reply; 513 bool payload_reply = true; 514 enum aux_channel_operation_result operation_result; 515 int aux_ack_retries = 0, 516 aux_defer_retries = 0, 517 aux_i2c_defer_retries = 0, 518 aux_timeout_retries = 0, 519 aux_invalid_reply_retries = 0; 520 521 if (!payload->reply) { 522 payload_reply = false; 523 payload->reply = &reply; 524 } 525 526 for (i = 0; i < AUX_MAX_RETRIES; i++) { 527 ret = dce_aux_transfer_raw(ddc, payload, &operation_result); 528 switch (operation_result) { 529 case AUX_CHANNEL_OPERATION_SUCCEEDED: 530 aux_timeout_retries = 0; 531 aux_invalid_reply_retries = 0; 532 533 switch (*payload->reply) { 534 case AUX_TRANSACTION_REPLY_AUX_ACK: 535 if (!payload->write && payload->length != ret) { 536 if (++aux_ack_retries >= AUX_MAX_RETRIES) 537 goto fail; 538 else 539 udelay(300); 540 } else 541 return true; 542 break; 543 544 case AUX_TRANSACTION_REPLY_AUX_DEFER: 545 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK: 546 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER: 547 if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) 548 goto fail; 549 break; 550 551 case AUX_TRANSACTION_REPLY_I2C_DEFER: 552 aux_defer_retries = 0; 553 if (++aux_i2c_defer_retries >= AUX_MAX_I2C_DEFER_RETRIES) 554 goto fail; 555 break; 556 557 case AUX_TRANSACTION_REPLY_AUX_NACK: 558 case AUX_TRANSACTION_REPLY_HPD_DISCON: 559 default: 560 goto fail; 561 } 562 break; 563 564 case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY: 565 if (++aux_invalid_reply_retries >= AUX_MAX_INVALID_REPLY_RETRIES) 566 goto fail; 567 else 568 udelay(400); 569 break; 570 571 case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT: 572 if (++aux_timeout_retries >= AUX_MAX_TIMEOUT_RETRIES) 573 goto fail; 574 else { 575 /* 576 * DP 1.4, 2.8.2: AUX Transaction Response/Reply Timeouts 577 * According to the DP spec there should be 3 retries total 578 * with a 400us wait inbetween each. Hardware already waits 579 * for 550us therefore no wait is required here. 580 */ 581 } 582 break; 583 584 case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: 585 case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN: 586 default: 587 goto fail; 588 } 589 } 590 591 fail: 592 if (!payload_reply) 593 payload->reply = NULL; 594 return false; 595 } 596