edp_aux.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  2. * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include "edp.h"
  14. #include "edp.xml.h"
  15. #define AUX_CMD_FIFO_LEN 144
  16. #define AUX_CMD_NATIVE_MAX 16
  17. #define AUX_CMD_I2C_MAX 128
  18. #define EDP_INTR_AUX_I2C_ERR \
  19. (EDP_INTERRUPT_REG_1_WRONG_ADDR | EDP_INTERRUPT_REG_1_TIMEOUT | \
  20. EDP_INTERRUPT_REG_1_NACK_DEFER | EDP_INTERRUPT_REG_1_WRONG_DATA_CNT | \
  21. EDP_INTERRUPT_REG_1_I2C_NACK | EDP_INTERRUPT_REG_1_I2C_DEFER)
  22. #define EDP_INTR_TRANS_STATUS \
  23. (EDP_INTERRUPT_REG_1_AUX_I2C_DONE | EDP_INTR_AUX_I2C_ERR)
  24. struct edp_aux {
  25. void __iomem *base;
  26. bool msg_err;
  27. struct completion msg_comp;
  28. /* To prevent the message transaction routine from reentry. */
  29. struct mutex msg_mutex;
  30. struct drm_dp_aux drm_aux;
  31. };
  32. #define to_edp_aux(x) container_of(x, struct edp_aux, drm_aux)
  33. static int edp_msg_fifo_tx(struct edp_aux *aux, struct drm_dp_aux_msg *msg)
  34. {
  35. u32 data[4];
  36. u32 reg, len;
  37. bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
  38. bool read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
  39. u8 *msgdata = msg->buffer;
  40. int i;
  41. if (read)
  42. len = 4;
  43. else
  44. len = msg->size + 4;
  45. /*
  46. * cmd fifo only has depth of 144 bytes
  47. */
  48. if (len > AUX_CMD_FIFO_LEN)
  49. return -EINVAL;
  50. /* Pack cmd and write to HW */
  51. data[0] = (msg->address >> 16) & 0xf; /* addr[19:16] */
  52. if (read)
  53. data[0] |= BIT(4); /* R/W */
  54. data[1] = (msg->address >> 8) & 0xff; /* addr[15:8] */
  55. data[2] = msg->address & 0xff; /* addr[7:0] */
  56. data[3] = (msg->size - 1) & 0xff; /* len[7:0] */
  57. for (i = 0; i < len; i++) {
  58. reg = (i < 4) ? data[i] : msgdata[i - 4];
  59. reg = EDP_AUX_DATA_DATA(reg); /* index = 0, write */
  60. if (i == 0)
  61. reg |= EDP_AUX_DATA_INDEX_WRITE;
  62. edp_write(aux->base + REG_EDP_AUX_DATA, reg);
  63. }
  64. reg = 0; /* Transaction number is always 1 */
  65. if (!native) /* i2c */
  66. reg |= EDP_AUX_TRANS_CTRL_I2C;
  67. reg |= EDP_AUX_TRANS_CTRL_GO;
  68. edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, reg);
  69. return 0;
  70. }
  71. static int edp_msg_fifo_rx(struct edp_aux *aux, struct drm_dp_aux_msg *msg)
  72. {
  73. u32 data;
  74. u8 *dp;
  75. int i;
  76. u32 len = msg->size;
  77. edp_write(aux->base + REG_EDP_AUX_DATA,
  78. EDP_AUX_DATA_INDEX_WRITE | EDP_AUX_DATA_READ); /* index = 0 */
  79. dp = msg->buffer;
  80. /* discard first byte */
  81. data = edp_read(aux->base + REG_EDP_AUX_DATA);
  82. for (i = 0; i < len; i++) {
  83. data = edp_read(aux->base + REG_EDP_AUX_DATA);
  84. dp[i] = (u8)((data >> 8) & 0xff);
  85. }
  86. return 0;
  87. }
  88. /*
  89. * This function does the real job to process an AUX transaction.
  90. * It will call msm_edp_aux_ctrl() function to reset the AUX channel,
  91. * if the waiting is timeout.
  92. * The caller who triggers the transaction should avoid the
  93. * msm_edp_aux_ctrl() running concurrently in other threads, i.e.
  94. * start transaction only when AUX channel is fully enabled.
  95. */
  96. ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, struct drm_dp_aux_msg *msg)
  97. {
  98. struct edp_aux *aux = to_edp_aux(drm_aux);
  99. ssize_t ret;
  100. bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
  101. bool read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
  102. /* Ignore address only message */
  103. if ((msg->size == 0) || (msg->buffer == NULL)) {
  104. msg->reply = native ?
  105. DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
  106. return msg->size;
  107. }
  108. /* msg sanity check */
  109. if ((native && (msg->size > AUX_CMD_NATIVE_MAX)) ||
  110. (msg->size > AUX_CMD_I2C_MAX)) {
  111. pr_err("%s: invalid msg: size(%zu), request(%x)\n",
  112. __func__, msg->size, msg->request);
  113. return -EINVAL;
  114. }
  115. mutex_lock(&aux->msg_mutex);
  116. aux->msg_err = false;
  117. reinit_completion(&aux->msg_comp);
  118. ret = edp_msg_fifo_tx(aux, msg);
  119. if (ret < 0)
  120. goto unlock_exit;
  121. DBG("wait_for_completion");
  122. ret = wait_for_completion_timeout(&aux->msg_comp, 300);
  123. if (ret <= 0) {
  124. /*
  125. * Clear GO and reset AUX channel
  126. * to cancel the current transaction.
  127. */
  128. edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0);
  129. msm_edp_aux_ctrl(aux, 1);
  130. pr_err("%s: aux timeout, %zd\n", __func__, ret);
  131. goto unlock_exit;
  132. }
  133. DBG("completion");
  134. if (!aux->msg_err) {
  135. if (read) {
  136. ret = edp_msg_fifo_rx(aux, msg);
  137. if (ret < 0)
  138. goto unlock_exit;
  139. }
  140. msg->reply = native ?
  141. DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
  142. } else {
  143. /* Reply defer to retry */
  144. msg->reply = native ?
  145. DP_AUX_NATIVE_REPLY_DEFER : DP_AUX_I2C_REPLY_DEFER;
  146. /*
  147. * The sleep time in caller is not long enough to make sure
  148. * our H/W completes transactions. Add more defer time here.
  149. */
  150. msleep(100);
  151. }
  152. /* Return requested size for success or retry */
  153. ret = msg->size;
  154. unlock_exit:
  155. mutex_unlock(&aux->msg_mutex);
  156. return ret;
  157. }
  158. void *msm_edp_aux_init(struct device *dev, void __iomem *regbase,
  159. struct drm_dp_aux **drm_aux)
  160. {
  161. struct edp_aux *aux = NULL;
  162. int ret;
  163. DBG("");
  164. aux = devm_kzalloc(dev, sizeof(*aux), GFP_KERNEL);
  165. if (!aux)
  166. return NULL;
  167. aux->base = regbase;
  168. mutex_init(&aux->msg_mutex);
  169. init_completion(&aux->msg_comp);
  170. aux->drm_aux.name = "msm_edp_aux";
  171. aux->drm_aux.dev = dev;
  172. aux->drm_aux.transfer = edp_aux_transfer;
  173. ret = drm_dp_aux_register(&aux->drm_aux);
  174. if (ret) {
  175. pr_err("%s: failed to register drm aux: %d\n", __func__, ret);
  176. mutex_destroy(&aux->msg_mutex);
  177. }
  178. if (drm_aux && aux)
  179. *drm_aux = &aux->drm_aux;
  180. return aux;
  181. }
  182. void msm_edp_aux_destroy(struct device *dev, struct edp_aux *aux)
  183. {
  184. if (aux) {
  185. drm_dp_aux_unregister(&aux->drm_aux);
  186. mutex_destroy(&aux->msg_mutex);
  187. }
  188. }
  189. irqreturn_t msm_edp_aux_irq(struct edp_aux *aux, u32 isr)
  190. {
  191. if (isr & EDP_INTR_TRANS_STATUS) {
  192. DBG("isr=%x", isr);
  193. edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0);
  194. if (isr & EDP_INTR_AUX_I2C_ERR)
  195. aux->msg_err = true;
  196. else
  197. aux->msg_err = false;
  198. complete(&aux->msg_comp);
  199. }
  200. return IRQ_HANDLED;
  201. }
  202. void msm_edp_aux_ctrl(struct edp_aux *aux, int enable)
  203. {
  204. u32 data;
  205. DBG("enable=%d", enable);
  206. data = edp_read(aux->base + REG_EDP_AUX_CTRL);
  207. if (enable) {
  208. data |= EDP_AUX_CTRL_RESET;
  209. edp_write(aux->base + REG_EDP_AUX_CTRL, data);
  210. /* Make sure full reset */
  211. wmb();
  212. usleep_range(500, 1000);
  213. data &= ~EDP_AUX_CTRL_RESET;
  214. data |= EDP_AUX_CTRL_ENABLE;
  215. edp_write(aux->base + REG_EDP_AUX_CTRL, data);
  216. } else {
  217. data &= ~EDP_AUX_CTRL_ENABLE;
  218. edp_write(aux->base + REG_EDP_AUX_CTRL, data);
  219. }
  220. }