root/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. release_engine
  2. is_engine_available
  3. acquire_engine
  4. submit_channel_request
  5. read_channel_reply
  6. get_channel_status
  7. get_engine_type
  8. acquire
  9. dce110_engine_destroy
  10. dce110_aux_engine_construct
  11. i2caux_action_from_payload
  12. dce_aux_transfer_raw
  13. dce_aux_transfer_with_retries

   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 ((engine == NULL) || !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 }

/* [<][>][^][v][top][bottom][index][help] */