dp_aux.c 18 KB

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