1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. 4 */ 5 6 #include <linux/delay.h> 7 #include <linux/iopoll.h> 8 #include <linux/phy/phy.h> 9 #include <drm/drm_print.h> 10 11 #include "dp_reg.h" 12 #include "dp_aux.h" 13 14 enum msm_dp_aux_err { 15 DP_AUX_ERR_NONE, 16 DP_AUX_ERR_ADDR, 17 DP_AUX_ERR_TOUT, 18 DP_AUX_ERR_NACK, 19 DP_AUX_ERR_DEFER, 20 DP_AUX_ERR_NACK_DEFER, 21 DP_AUX_ERR_PHY, 22 }; 23 24 struct msm_dp_aux_private { 25 struct device *dev; 26 void __iomem *aux_base; 27 28 struct phy *phy; 29 30 struct mutex mutex; 31 struct completion comp; 32 33 enum msm_dp_aux_err aux_error_num; 34 u32 retry_cnt; 35 bool cmd_busy; 36 bool native; 37 bool read; 38 bool no_send_addr; 39 bool no_send_stop; 40 bool initted; 41 bool is_edp; 42 bool enable_xfers; 43 u32 offset; 44 u32 segment; 45 46 struct drm_dp_aux msm_dp_aux; 47 }; 48 49 static inline u32 msm_dp_read_aux(struct msm_dp_aux_private *aux, u32 offset) 50 { 51 return readl_relaxed(aux->aux_base + offset); 52 } 53 54 static inline void msm_dp_write_aux(struct msm_dp_aux_private *aux, 55 u32 offset, u32 data) 56 { 57 /* 58 * To make sure aux reg writes happens before any other operation, 59 * this function uses writel() instread of writel_relaxed() 60 */ 61 writel(data, aux->aux_base + offset); 62 } 63 64 static void msm_dp_aux_clear_hw_interrupts(struct msm_dp_aux_private *aux) 65 { 66 msm_dp_read_aux(aux, REG_DP_PHY_AUX_INTERRUPT_STATUS); 67 msm_dp_write_aux(aux, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f); 68 msm_dp_write_aux(aux, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f); 69 msm_dp_write_aux(aux, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0); 70 } 71 72 /* 73 * NOTE: resetting AUX controller will also clear any pending HPD related interrupts 74 */ 75 static void msm_dp_aux_reset(struct msm_dp_aux_private *aux) 76 { 77 u32 aux_ctrl; 78 79 aux_ctrl = msm_dp_read_aux(aux, REG_DP_AUX_CTRL); 80 81 aux_ctrl |= DP_AUX_CTRL_RESET; 82 msm_dp_write_aux(aux, REG_DP_AUX_CTRL, aux_ctrl); 83 usleep_range(1000, 1100); /* h/w recommended delay */ 84 85 aux_ctrl &= ~DP_AUX_CTRL_RESET; 86 msm_dp_write_aux(aux, REG_DP_AUX_CTRL, aux_ctrl); 87 } 88 89 static void msm_dp_aux_enable(struct msm_dp_aux_private *aux) 90 { 91 u32 aux_ctrl; 92 93 aux_ctrl = msm_dp_read_aux(aux, REG_DP_AUX_CTRL); 94 95 msm_dp_write_aux(aux, REG_DP_TIMEOUT_COUNT, 0xffff); 96 msm_dp_write_aux(aux, REG_DP_AUX_LIMITS, 0xffff); 97 98 aux_ctrl |= DP_AUX_CTRL_ENABLE; 99 msm_dp_write_aux(aux, REG_DP_AUX_CTRL, aux_ctrl); 100 } 101 102 static void msm_dp_aux_disable(struct msm_dp_aux_private *aux) 103 { 104 u32 aux_ctrl; 105 106 aux_ctrl = msm_dp_read_aux(aux, REG_DP_AUX_CTRL); 107 aux_ctrl &= ~DP_AUX_CTRL_ENABLE; 108 msm_dp_write_aux(aux, REG_DP_AUX_CTRL, aux_ctrl); 109 } 110 111 static int msm_dp_aux_wait_for_hpd_connect_state(struct msm_dp_aux_private *aux, 112 unsigned long wait_us) 113 { 114 u32 state; 115 116 /* poll for hpd connected status every 2ms and timeout after wait_us */ 117 return readl_poll_timeout(aux->aux_base + 118 REG_DP_DP_HPD_INT_STATUS, 119 state, state & DP_DP_HPD_STATE_STATUS_CONNECTED, 120 min(wait_us, 2000), wait_us); 121 } 122 123 #define MAX_AUX_RETRIES 5 124 125 static ssize_t msm_dp_aux_write(struct msm_dp_aux_private *aux, 126 struct drm_dp_aux_msg *msg) 127 { 128 u8 data[4]; 129 u32 reg; 130 ssize_t len; 131 u8 *msgdata = msg->buffer; 132 int const AUX_CMD_FIFO_LEN = 128; 133 int i = 0; 134 135 if (aux->read) 136 len = 0; 137 else 138 len = msg->size; 139 140 /* 141 * cmd fifo only has depth of 144 bytes 142 * limit buf length to 128 bytes here 143 */ 144 if (len > AUX_CMD_FIFO_LEN - 4) { 145 DRM_ERROR("buf size greater than allowed size of 128 bytes\n"); 146 return -EINVAL; 147 } 148 149 /* Pack cmd and write to HW */ 150 data[0] = (msg->address >> 16) & 0xf; /* addr[19:16] */ 151 if (aux->read) 152 data[0] |= BIT(4); /* R/W */ 153 154 data[1] = msg->address >> 8; /* addr[15:8] */ 155 data[2] = msg->address; /* addr[7:0] */ 156 data[3] = msg->size - 1; /* len[7:0] */ 157 158 for (i = 0; i < len + 4; i++) { 159 reg = (i < 4) ? data[i] : msgdata[i - 4]; 160 reg <<= DP_AUX_DATA_OFFSET; 161 reg &= DP_AUX_DATA_MASK; 162 reg |= DP_AUX_DATA_WRITE; 163 /* index = 0, write */ 164 if (i == 0) 165 reg |= DP_AUX_DATA_INDEX_WRITE; 166 msm_dp_write_aux(aux, REG_DP_AUX_DATA, reg); 167 } 168 169 msm_dp_write_aux(aux, REG_DP_AUX_TRANS_CTRL, 0); 170 msm_dp_aux_clear_hw_interrupts(aux); 171 172 reg = 0; /* Transaction number == 1 */ 173 if (!aux->native) { /* i2c */ 174 reg |= DP_AUX_TRANS_CTRL_I2C; 175 176 if (aux->no_send_addr) 177 reg |= DP_AUX_TRANS_CTRL_NO_SEND_ADDR; 178 179 if (aux->no_send_stop) 180 reg |= DP_AUX_TRANS_CTRL_NO_SEND_STOP; 181 } 182 183 reg |= DP_AUX_TRANS_CTRL_GO; 184 msm_dp_write_aux(aux, REG_DP_AUX_TRANS_CTRL, reg); 185 186 return len; 187 } 188 189 static ssize_t msm_dp_aux_cmd_fifo_tx(struct msm_dp_aux_private *aux, 190 struct drm_dp_aux_msg *msg) 191 { 192 ssize_t ret; 193 unsigned long time_left; 194 195 reinit_completion(&aux->comp); 196 197 ret = msm_dp_aux_write(aux, msg); 198 if (ret < 0) 199 return ret; 200 201 time_left = wait_for_completion_timeout(&aux->comp, 202 msecs_to_jiffies(250)); 203 if (!time_left) 204 return -ETIMEDOUT; 205 206 return ret; 207 } 208 209 static ssize_t msm_dp_aux_cmd_fifo_rx(struct msm_dp_aux_private *aux, 210 struct drm_dp_aux_msg *msg) 211 { 212 u32 data; 213 u8 *dp; 214 u32 i, actual_i; 215 u32 len = msg->size; 216 217 data = msm_dp_read_aux(aux, REG_DP_AUX_TRANS_CTRL); 218 data &= ~DP_AUX_TRANS_CTRL_GO; 219 msm_dp_write_aux(aux, REG_DP_AUX_TRANS_CTRL, data); 220 221 data = DP_AUX_DATA_INDEX_WRITE; /* INDEX_WRITE */ 222 data |= DP_AUX_DATA_READ; /* read */ 223 224 msm_dp_write_aux(aux, REG_DP_AUX_DATA, data); 225 226 dp = msg->buffer; 227 228 /* discard first byte */ 229 data = msm_dp_read_aux(aux, REG_DP_AUX_DATA); 230 231 for (i = 0; i < len; i++) { 232 data = msm_dp_read_aux(aux, REG_DP_AUX_DATA); 233 *dp++ = (u8)((data >> DP_AUX_DATA_OFFSET) & 0xff); 234 235 actual_i = (data >> DP_AUX_DATA_INDEX_OFFSET) & 0xFF; 236 if (i != actual_i) 237 break; 238 } 239 240 return i; 241 } 242 243 static void msm_dp_aux_update_offset_and_segment(struct msm_dp_aux_private *aux, 244 struct drm_dp_aux_msg *input_msg) 245 { 246 u32 edid_address = 0x50; 247 u32 segment_address = 0x30; 248 bool i2c_read = input_msg->request & 249 (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ); 250 u8 *data; 251 252 if (aux->native || i2c_read || ((input_msg->address != edid_address) && 253 (input_msg->address != segment_address))) 254 return; 255 256 257 data = input_msg->buffer; 258 if (input_msg->address == segment_address) 259 aux->segment = *data; 260 else 261 aux->offset = *data; 262 } 263 264 /** 265 * msm_dp_aux_transfer_helper() - helper function for EDID read transactions 266 * 267 * @aux: DP AUX private structure 268 * @input_msg: input message from DRM upstream APIs 269 * @send_seg: send the segment to sink 270 * 271 * return: void 272 * 273 * This helper function is used to fix EDID reads for non-compliant 274 * sinks that do not handle the i2c middle-of-transaction flag correctly. 275 */ 276 static void msm_dp_aux_transfer_helper(struct msm_dp_aux_private *aux, 277 struct drm_dp_aux_msg *input_msg, 278 bool send_seg) 279 { 280 struct drm_dp_aux_msg helper_msg; 281 u32 message_size = 0x10; 282 u32 segment_address = 0x30; 283 u32 const edid_block_length = 0x80; 284 bool i2c_mot = input_msg->request & DP_AUX_I2C_MOT; 285 bool i2c_read = input_msg->request & 286 (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ); 287 288 if (!i2c_mot || !i2c_read || (input_msg->size == 0)) 289 return; 290 291 /* 292 * Sending the segment value and EDID offset will be performed 293 * from the DRM upstream EDID driver for each block. Avoid 294 * duplicate AUX transactions related to this while reading the 295 * first 16 bytes of each block. 296 */ 297 if (!(aux->offset % edid_block_length) || !send_seg) 298 goto end; 299 300 aux->read = false; 301 aux->cmd_busy = true; 302 aux->no_send_addr = true; 303 aux->no_send_stop = true; 304 305 /* 306 * Send the segment address for every i2c read in which the 307 * middle-of-tranaction flag is set. This is required to support EDID 308 * reads of more than 2 blocks as the segment address is reset to 0 309 * since we are overriding the middle-of-transaction flag for read 310 * transactions. 311 */ 312 313 if (aux->segment) { 314 memset(&helper_msg, 0, sizeof(helper_msg)); 315 helper_msg.address = segment_address; 316 helper_msg.buffer = &aux->segment; 317 helper_msg.size = 1; 318 msm_dp_aux_cmd_fifo_tx(aux, &helper_msg); 319 } 320 321 /* 322 * Send the offset address for every i2c read in which the 323 * middle-of-transaction flag is set. This will ensure that the sink 324 * will update its read pointer and return the correct portion of the 325 * EDID buffer in the subsequent i2c read trasntion triggered in the 326 * native AUX transfer function. 327 */ 328 memset(&helper_msg, 0, sizeof(helper_msg)); 329 helper_msg.address = input_msg->address; 330 helper_msg.buffer = &aux->offset; 331 helper_msg.size = 1; 332 msm_dp_aux_cmd_fifo_tx(aux, &helper_msg); 333 334 end: 335 aux->offset += message_size; 336 if (aux->offset == 0x80 || aux->offset == 0x100) 337 aux->segment = 0x0; /* reset segment at end of block */ 338 } 339 340 /* 341 * This function does the real job to process an AUX transaction. 342 * It will call aux_reset() function to reset the AUX channel, 343 * if the waiting is timeout. 344 */ 345 static ssize_t msm_dp_aux_transfer(struct drm_dp_aux *msm_dp_aux, 346 struct drm_dp_aux_msg *msg) 347 { 348 ssize_t ret; 349 int const aux_cmd_native_max = 16; 350 int const aux_cmd_i2c_max = 128; 351 struct msm_dp_aux_private *aux; 352 353 aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 354 355 aux->native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ); 356 357 /* Ignore address only message */ 358 if (msg->size == 0 || !msg->buffer) { 359 msg->reply = aux->native ? 360 DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK; 361 return msg->size; 362 } 363 364 /* msg sanity check */ 365 if ((aux->native && msg->size > aux_cmd_native_max) || 366 msg->size > aux_cmd_i2c_max) { 367 DRM_ERROR("%s: invalid msg: size(%zu), request(%x)\n", 368 __func__, msg->size, msg->request); 369 return -EINVAL; 370 } 371 372 ret = pm_runtime_resume_and_get(msm_dp_aux->dev); 373 if (ret) 374 return ret; 375 376 mutex_lock(&aux->mutex); 377 if (!aux->initted) { 378 ret = -EIO; 379 goto exit; 380 } 381 382 /* 383 * If we're using DP and an external display isn't connected then the 384 * transfer won't succeed. Return right away. If we don't do this we 385 * can end up with long timeouts if someone tries to access the DP AUX 386 * character device when no DP device is connected. 387 */ 388 if (!aux->is_edp && !aux->enable_xfers) { 389 ret = -ENXIO; 390 goto exit; 391 } 392 393 msm_dp_aux_update_offset_and_segment(aux, msg); 394 msm_dp_aux_transfer_helper(aux, msg, true); 395 396 aux->read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ); 397 aux->cmd_busy = true; 398 399 if (aux->read) { 400 aux->no_send_addr = true; 401 aux->no_send_stop = false; 402 } else { 403 aux->no_send_addr = true; 404 aux->no_send_stop = true; 405 } 406 407 ret = msm_dp_aux_cmd_fifo_tx(aux, msg); 408 if (ret < 0) { 409 if (aux->native) { 410 aux->retry_cnt++; 411 if (!(aux->retry_cnt % MAX_AUX_RETRIES)) 412 phy_calibrate(aux->phy); 413 } 414 /* reset aux if link is in connected state */ 415 if (msm_dp_aux_is_link_connected(msm_dp_aux)) 416 msm_dp_aux_reset(aux); 417 } else { 418 aux->retry_cnt = 0; 419 switch (aux->aux_error_num) { 420 case DP_AUX_ERR_NONE: 421 if (aux->read) 422 ret = msm_dp_aux_cmd_fifo_rx(aux, msg); 423 msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK; 424 break; 425 case DP_AUX_ERR_DEFER: 426 msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_DEFER : DP_AUX_I2C_REPLY_DEFER; 427 break; 428 case DP_AUX_ERR_PHY: 429 case DP_AUX_ERR_ADDR: 430 case DP_AUX_ERR_NACK: 431 case DP_AUX_ERR_NACK_DEFER: 432 msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_NACK : DP_AUX_I2C_REPLY_NACK; 433 break; 434 case DP_AUX_ERR_TOUT: 435 ret = -ETIMEDOUT; 436 break; 437 } 438 } 439 440 aux->cmd_busy = false; 441 442 exit: 443 mutex_unlock(&aux->mutex); 444 pm_runtime_put_sync(msm_dp_aux->dev); 445 446 return ret; 447 } 448 449 irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux, u32 isr) 450 { 451 struct msm_dp_aux_private *aux; 452 453 if (!msm_dp_aux) { 454 DRM_ERROR("invalid input\n"); 455 return IRQ_NONE; 456 } 457 458 aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 459 460 if (!aux->cmd_busy) { 461 DRM_ERROR("Unexpected DP AUX IRQ %#010x when not busy\n", isr); 462 return IRQ_NONE; 463 } 464 465 /* 466 * The logic below assumes only one error bit is set (other than "done" 467 * which can apparently be set at the same time as some of the other 468 * bits). Warn if more than one get set so we know we need to improve 469 * the logic. 470 */ 471 if (hweight32(isr & ~DP_INTR_AUX_XFER_DONE) > 1) 472 DRM_WARN("Some DP AUX interrupts unhandled: %#010x\n", isr); 473 474 if (isr & DP_INTR_AUX_ERROR) { 475 aux->aux_error_num = DP_AUX_ERR_PHY; 476 msm_dp_aux_clear_hw_interrupts(aux); 477 } else if (isr & DP_INTR_NACK_DEFER) { 478 aux->aux_error_num = DP_AUX_ERR_NACK_DEFER; 479 } else if (isr & DP_INTR_WRONG_ADDR) { 480 aux->aux_error_num = DP_AUX_ERR_ADDR; 481 } else if (isr & DP_INTR_TIMEOUT) { 482 aux->aux_error_num = DP_AUX_ERR_TOUT; 483 } else if (!aux->native && (isr & DP_INTR_I2C_NACK)) { 484 aux->aux_error_num = DP_AUX_ERR_NACK; 485 } else if (!aux->native && (isr & DP_INTR_I2C_DEFER)) { 486 if (isr & DP_INTR_AUX_XFER_DONE) 487 aux->aux_error_num = DP_AUX_ERR_NACK; 488 else 489 aux->aux_error_num = DP_AUX_ERR_DEFER; 490 } else if (isr & DP_INTR_AUX_XFER_DONE) { 491 aux->aux_error_num = DP_AUX_ERR_NONE; 492 } else { 493 DRM_WARN("Unexpected interrupt: %#010x\n", isr); 494 return IRQ_NONE; 495 } 496 497 complete(&aux->comp); 498 499 return IRQ_HANDLED; 500 } 501 502 void msm_dp_aux_enable_xfers(struct drm_dp_aux *msm_dp_aux, bool enabled) 503 { 504 struct msm_dp_aux_private *aux; 505 506 aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 507 aux->enable_xfers = enabled; 508 } 509 510 void msm_dp_aux_reconfig(struct drm_dp_aux *msm_dp_aux) 511 { 512 struct msm_dp_aux_private *aux; 513 514 aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 515 516 phy_calibrate(aux->phy); 517 msm_dp_aux_reset(aux); 518 } 519 520 void msm_dp_aux_init(struct drm_dp_aux *msm_dp_aux) 521 { 522 struct msm_dp_aux_private *aux; 523 524 if (!msm_dp_aux) { 525 DRM_ERROR("invalid input\n"); 526 return; 527 } 528 529 aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 530 531 mutex_lock(&aux->mutex); 532 533 msm_dp_aux_enable(aux); 534 aux->retry_cnt = 0; 535 aux->initted = true; 536 537 mutex_unlock(&aux->mutex); 538 } 539 540 void msm_dp_aux_deinit(struct drm_dp_aux *msm_dp_aux) 541 { 542 struct msm_dp_aux_private *aux; 543 544 aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 545 546 mutex_lock(&aux->mutex); 547 548 aux->initted = false; 549 msm_dp_aux_disable(aux); 550 551 mutex_unlock(&aux->mutex); 552 } 553 554 int msm_dp_aux_register(struct drm_dp_aux *msm_dp_aux) 555 { 556 int ret; 557 558 if (!msm_dp_aux) { 559 DRM_ERROR("invalid input\n"); 560 return -EINVAL; 561 } 562 563 ret = drm_dp_aux_register(msm_dp_aux); 564 if (ret) { 565 DRM_ERROR("%s: failed to register drm aux: %d\n", __func__, 566 ret); 567 return ret; 568 } 569 570 return 0; 571 } 572 573 void msm_dp_aux_unregister(struct drm_dp_aux *msm_dp_aux) 574 { 575 drm_dp_aux_unregister(msm_dp_aux); 576 } 577 578 static int msm_dp_wait_hpd_asserted(struct drm_dp_aux *msm_dp_aux, 579 unsigned long wait_us) 580 { 581 int ret; 582 struct msm_dp_aux_private *aux; 583 584 aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 585 586 ret = pm_runtime_resume_and_get(aux->dev); 587 if (ret) 588 return ret; 589 590 ret = msm_dp_aux_wait_for_hpd_connect_state(aux, wait_us); 591 pm_runtime_put_sync(aux->dev); 592 593 return ret; 594 } 595 596 void msm_dp_aux_hpd_enable(struct drm_dp_aux *msm_dp_aux) 597 { 598 struct msm_dp_aux_private *aux = 599 container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 600 u32 reg; 601 602 /* Configure REFTIMER and enable it */ 603 reg = msm_dp_read_aux(aux, REG_DP_DP_HPD_REFTIMER); 604 reg |= DP_DP_HPD_REFTIMER_ENABLE; 605 msm_dp_write_aux(aux, REG_DP_DP_HPD_REFTIMER, reg); 606 607 /* Enable HPD */ 608 msm_dp_write_aux(aux, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); 609 } 610 611 void msm_dp_aux_hpd_disable(struct drm_dp_aux *msm_dp_aux) 612 { 613 struct msm_dp_aux_private *aux = 614 container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 615 u32 reg; 616 617 reg = msm_dp_read_aux(aux, REG_DP_DP_HPD_REFTIMER); 618 reg &= ~DP_DP_HPD_REFTIMER_ENABLE; 619 msm_dp_write_aux(aux, REG_DP_DP_HPD_REFTIMER, reg); 620 621 msm_dp_write_aux(aux, REG_DP_DP_HPD_CTRL, 0); 622 } 623 624 void msm_dp_aux_hpd_intr_enable(struct drm_dp_aux *msm_dp_aux) 625 { 626 struct msm_dp_aux_private *aux = 627 container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 628 u32 reg; 629 630 reg = msm_dp_read_aux(aux, REG_DP_DP_HPD_INT_MASK); 631 reg |= DP_DP_HPD_INT_MASK; 632 msm_dp_write_aux(aux, REG_DP_DP_HPD_INT_MASK, 633 reg & DP_DP_HPD_INT_MASK); 634 } 635 636 void msm_dp_aux_hpd_intr_disable(struct drm_dp_aux *msm_dp_aux) 637 { 638 struct msm_dp_aux_private *aux = 639 container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 640 u32 reg; 641 642 reg = msm_dp_read_aux(aux, REG_DP_DP_HPD_INT_MASK); 643 reg &= ~DP_DP_HPD_INT_MASK; 644 msm_dp_write_aux(aux, REG_DP_DP_HPD_INT_MASK, 645 reg & DP_DP_HPD_INT_MASK); 646 } 647 648 u32 msm_dp_aux_get_hpd_intr_status(struct drm_dp_aux *msm_dp_aux) 649 { 650 struct msm_dp_aux_private *aux = 651 container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 652 int isr, mask; 653 654 isr = msm_dp_read_aux(aux, REG_DP_DP_HPD_INT_STATUS); 655 msm_dp_write_aux(aux, REG_DP_DP_HPD_INT_ACK, 656 (isr & DP_DP_HPD_INT_MASK)); 657 mask = msm_dp_read_aux(aux, REG_DP_DP_HPD_INT_MASK); 658 659 /* 660 * We only want to return interrupts that are unmasked to the caller. 661 * However, the interrupt status field also contains other 662 * informational bits about the HPD state status, so we only mask 663 * out the part of the register that tells us about which interrupts 664 * are pending. 665 */ 666 return isr & (mask | ~DP_DP_HPD_INT_MASK); 667 } 668 669 u32 msm_dp_aux_is_link_connected(struct drm_dp_aux *msm_dp_aux) 670 { 671 struct msm_dp_aux_private *aux = 672 container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 673 u32 status; 674 675 status = msm_dp_read_aux(aux, REG_DP_DP_HPD_INT_STATUS); 676 status >>= DP_DP_HPD_STATE_STATUS_BITS_SHIFT; 677 status &= DP_DP_HPD_STATE_STATUS_BITS_MASK; 678 679 return status; 680 } 681 682 struct drm_dp_aux *msm_dp_aux_get(struct device *dev, 683 struct phy *phy, 684 bool is_edp, 685 void __iomem *aux_base) 686 { 687 struct msm_dp_aux_private *aux; 688 689 aux = devm_kzalloc(dev, sizeof(*aux), GFP_KERNEL); 690 if (!aux) 691 return ERR_PTR(-ENOMEM); 692 693 init_completion(&aux->comp); 694 aux->cmd_busy = false; 695 aux->is_edp = is_edp; 696 mutex_init(&aux->mutex); 697 698 aux->dev = dev; 699 aux->phy = phy; 700 aux->retry_cnt = 0; 701 aux->aux_base = aux_base; 702 703 /* 704 * Use the drm_dp_aux_init() to use the aux adapter 705 * before registering AUX with the DRM device so that 706 * msm eDP panel can be detected by generic_dep_panel_probe(). 707 */ 708 aux->msm_dp_aux.name = "dpu_dp_aux"; 709 aux->msm_dp_aux.dev = dev; 710 aux->msm_dp_aux.transfer = msm_dp_aux_transfer; 711 aux->msm_dp_aux.wait_hpd_asserted = msm_dp_wait_hpd_asserted; 712 drm_dp_aux_init(&aux->msm_dp_aux); 713 714 return &aux->msm_dp_aux; 715 } 716 717 void msm_dp_aux_put(struct drm_dp_aux *msm_dp_aux) 718 { 719 struct msm_dp_aux_private *aux; 720 721 if (!msm_dp_aux) 722 return; 723 724 aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux); 725 726 mutex_destroy(&aux->mutex); 727 728 devm_kfree(aux->dev, aux); 729 } 730