dp_aux.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/soc/qcom/fsa4480-i2c.h>
  6. #include <linux/delay.h>
  7. #include "dp_aux.h"
  8. #include "dp_hpd.h"
  9. #include "dp_debug.h"
  10. #define DP_AUX_ENUM_STR(x) #x
  11. enum {
  12. DP_AUX_DATA_INDEX_WRITE = BIT(31),
  13. };
  14. struct dp_aux_private {
  15. struct device *dev;
  16. struct dp_aux dp_aux;
  17. struct dp_catalog_aux *catalog;
  18. struct dp_aux_cfg *cfg;
  19. struct device_node *aux_switch_node;
  20. struct mutex mutex;
  21. struct completion comp;
  22. struct drm_dp_aux drm_aux;
  23. bool cmd_busy;
  24. bool native;
  25. bool read;
  26. bool no_send_addr;
  27. bool no_send_stop;
  28. bool enabled;
  29. u32 offset;
  30. u32 segment;
  31. u32 aux_error_num;
  32. u32 retry_cnt;
  33. atomic_t aborted;
  34. u8 *dpcd;
  35. u8 *edid;
  36. };
  37. #ifdef CONFIG_DYNAMIC_DEBUG
  38. static void dp_aux_hex_dump(struct drm_dp_aux *drm_aux,
  39. struct drm_dp_aux_msg *msg)
  40. {
  41. char prefix[64];
  42. int i, linelen, remaining = msg->size;
  43. const int rowsize = 16;
  44. u8 linebuf[64];
  45. struct dp_aux_private *aux = container_of(drm_aux,
  46. struct dp_aux_private, drm_aux);
  47. snprintf(prefix, sizeof(prefix), "%s %s %4xh(%2zu): ",
  48. aux->native ? "NAT" : "I2C",
  49. aux->read ? "RD" : "WR",
  50. msg->address, msg->size);
  51. for (i = 0; i < msg->size; i += rowsize) {
  52. linelen = min(remaining, rowsize);
  53. remaining -= rowsize;
  54. hex_dump_to_buffer(msg->buffer + i, linelen, rowsize, 1,
  55. linebuf, sizeof(linebuf), false);
  56. DP_DEBUG("%s%s\n", prefix, linebuf);
  57. }
  58. }
  59. #else
  60. static void dp_aux_hex_dump(struct drm_dp_aux *drm_aux,
  61. struct drm_dp_aux_msg *msg)
  62. {
  63. }
  64. #endif
  65. static char *dp_aux_get_error(u32 aux_error)
  66. {
  67. switch (aux_error) {
  68. case DP_AUX_ERR_NONE:
  69. return DP_AUX_ENUM_STR(DP_AUX_ERR_NONE);
  70. case DP_AUX_ERR_ADDR:
  71. return DP_AUX_ENUM_STR(DP_AUX_ERR_ADDR);
  72. case DP_AUX_ERR_TOUT:
  73. return DP_AUX_ENUM_STR(DP_AUX_ERR_TOUT);
  74. case DP_AUX_ERR_NACK:
  75. return DP_AUX_ENUM_STR(DP_AUX_ERR_NACK);
  76. case DP_AUX_ERR_DEFER:
  77. return DP_AUX_ENUM_STR(DP_AUX_ERR_DEFER);
  78. case DP_AUX_ERR_NACK_DEFER:
  79. return DP_AUX_ENUM_STR(DP_AUX_ERR_NACK_DEFER);
  80. default:
  81. return "unknown";
  82. }
  83. }
  84. static u32 dp_aux_write(struct dp_aux_private *aux,
  85. struct drm_dp_aux_msg *msg)
  86. {
  87. u32 data[4], reg, len;
  88. u8 *msgdata = msg->buffer;
  89. int const aux_cmd_fifo_len = 128;
  90. int i = 0;
  91. if (aux->read)
  92. len = 4;
  93. else
  94. len = msg->size + 4;
  95. /*
  96. * cmd fifo only has depth of 144 bytes
  97. * limit buf length to 128 bytes here
  98. */
  99. if (len > aux_cmd_fifo_len) {
  100. DP_ERR("buf len error\n");
  101. return 0;
  102. }
  103. /* Pack cmd and write to HW */
  104. data[0] = (msg->address >> 16) & 0xf; /* addr[19:16] */
  105. if (aux->read)
  106. data[0] |= BIT(4); /* R/W */
  107. data[1] = (msg->address >> 8) & 0xff; /* addr[15:8] */
  108. data[2] = msg->address & 0xff; /* addr[7:0] */
  109. data[3] = (msg->size - 1) & 0xff; /* len[7:0] */
  110. for (i = 0; i < len; i++) {
  111. reg = (i < 4) ? data[i] : msgdata[i - 4];
  112. reg = ((reg) << 8) & 0x0000ff00; /* index = 0, write */
  113. if (i == 0)
  114. reg |= DP_AUX_DATA_INDEX_WRITE;
  115. aux->catalog->data = reg;
  116. aux->catalog->write_data(aux->catalog);
  117. }
  118. aux->catalog->clear_trans(aux->catalog, false);
  119. aux->catalog->clear_hw_interrupts(aux->catalog);
  120. reg = 0; /* Transaction number == 1 */
  121. if (!aux->native) { /* i2c */
  122. reg |= BIT(8);
  123. if (aux->no_send_addr)
  124. reg |= BIT(10);
  125. if (aux->no_send_stop)
  126. reg |= BIT(11);
  127. }
  128. reg |= BIT(9);
  129. aux->catalog->data = reg;
  130. aux->catalog->write_trans(aux->catalog);
  131. return len;
  132. }
  133. static int dp_aux_cmd_fifo_tx(struct dp_aux_private *aux,
  134. struct drm_dp_aux_msg *msg)
  135. {
  136. u32 ret = 0, len = 0, timeout;
  137. int const aux_timeout_ms = HZ/4;
  138. reinit_completion(&aux->comp);
  139. len = dp_aux_write(aux, msg);
  140. if (len == 0) {
  141. DP_ERR("DP AUX write failed\n");
  142. return -EINVAL;
  143. }
  144. timeout = wait_for_completion_timeout(&aux->comp, aux_timeout_ms);
  145. if (!timeout) {
  146. DP_ERR("aux %s timeout\n", (aux->read ? "read" : "write"));
  147. return -ETIMEDOUT;
  148. }
  149. if (aux->aux_error_num == DP_AUX_ERR_NONE) {
  150. ret = len;
  151. } else {
  152. pr_err_ratelimited("aux err: %s\n",
  153. dp_aux_get_error(aux->aux_error_num));
  154. ret = -EINVAL;
  155. }
  156. return ret;
  157. }
  158. static void dp_aux_cmd_fifo_rx(struct dp_aux_private *aux,
  159. struct drm_dp_aux_msg *msg)
  160. {
  161. u32 data;
  162. u8 *dp;
  163. u32 i, actual_i;
  164. u32 len = msg->size;
  165. aux->catalog->clear_trans(aux->catalog, true);
  166. data = 0;
  167. data |= DP_AUX_DATA_INDEX_WRITE; /* INDEX_WRITE */
  168. data |= BIT(0); /* read */
  169. aux->catalog->data = data;
  170. aux->catalog->write_data(aux->catalog);
  171. dp = msg->buffer;
  172. /* discard first byte */
  173. data = aux->catalog->read_data(aux->catalog);
  174. for (i = 0; i < len; i++) {
  175. data = aux->catalog->read_data(aux->catalog);
  176. *dp++ = (u8)((data >> 8) & 0xff);
  177. actual_i = (data >> 16) & 0xFF;
  178. if (i != actual_i)
  179. DP_WARN("Index mismatch: expected %d, found %d\n",
  180. i, actual_i);
  181. }
  182. }
  183. static void dp_aux_native_handler(struct dp_aux_private *aux)
  184. {
  185. u32 isr = aux->catalog->isr;
  186. if (isr & DP_INTR_AUX_I2C_DONE)
  187. aux->aux_error_num = DP_AUX_ERR_NONE;
  188. else if (isr & DP_INTR_WRONG_ADDR)
  189. aux->aux_error_num = DP_AUX_ERR_ADDR;
  190. else if (isr & DP_INTR_TIMEOUT)
  191. aux->aux_error_num = DP_AUX_ERR_TOUT;
  192. if (isr & DP_INTR_NACK_DEFER)
  193. aux->aux_error_num = DP_AUX_ERR_NACK;
  194. if (isr & DP_INTR_AUX_ERROR) {
  195. aux->aux_error_num = DP_AUX_ERR_PHY;
  196. aux->catalog->clear_hw_interrupts(aux->catalog);
  197. }
  198. complete(&aux->comp);
  199. }
  200. static void dp_aux_i2c_handler(struct dp_aux_private *aux)
  201. {
  202. u32 isr = aux->catalog->isr;
  203. if (isr & DP_INTR_AUX_I2C_DONE) {
  204. if (isr & (DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER))
  205. aux->aux_error_num = DP_AUX_ERR_NACK;
  206. else
  207. aux->aux_error_num = DP_AUX_ERR_NONE;
  208. } else {
  209. if (isr & DP_INTR_WRONG_ADDR)
  210. aux->aux_error_num = DP_AUX_ERR_ADDR;
  211. else if (isr & DP_INTR_TIMEOUT)
  212. aux->aux_error_num = DP_AUX_ERR_TOUT;
  213. if (isr & DP_INTR_NACK_DEFER)
  214. aux->aux_error_num = DP_AUX_ERR_NACK_DEFER;
  215. if (isr & DP_INTR_I2C_NACK)
  216. aux->aux_error_num = DP_AUX_ERR_NACK;
  217. if (isr & DP_INTR_I2C_DEFER)
  218. aux->aux_error_num = DP_AUX_ERR_DEFER;
  219. if (isr & DP_INTR_AUX_ERROR) {
  220. aux->aux_error_num = DP_AUX_ERR_PHY;
  221. aux->catalog->clear_hw_interrupts(aux->catalog);
  222. }
  223. }
  224. complete(&aux->comp);
  225. }
  226. static void dp_aux_isr(struct dp_aux *dp_aux)
  227. {
  228. struct dp_aux_private *aux;
  229. if (!dp_aux) {
  230. DP_ERR("invalid input\n");
  231. return;
  232. }
  233. aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
  234. aux->catalog->get_irq(aux->catalog, aux->cmd_busy);
  235. if (!aux->cmd_busy)
  236. return;
  237. if (aux->native)
  238. dp_aux_native_handler(aux);
  239. else
  240. dp_aux_i2c_handler(aux);
  241. }
  242. static void dp_aux_reconfig(struct dp_aux *dp_aux)
  243. {
  244. struct dp_aux_private *aux;
  245. if (!dp_aux) {
  246. DP_ERR("invalid input\n");
  247. return;
  248. }
  249. aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
  250. aux->catalog->update_aux_cfg(aux->catalog,
  251. aux->cfg, PHY_AUX_CFG1);
  252. aux->catalog->reset(aux->catalog);
  253. }
  254. static void dp_aux_abort_transaction(struct dp_aux *dp_aux, bool abort)
  255. {
  256. struct dp_aux_private *aux;
  257. if (!dp_aux) {
  258. DP_ERR("invalid input\n");
  259. return;
  260. }
  261. aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
  262. atomic_set(&aux->aborted, abort);
  263. }
  264. static void dp_aux_update_offset_and_segment(struct dp_aux_private *aux,
  265. struct drm_dp_aux_msg *input_msg)
  266. {
  267. u32 const edid_address = 0x50;
  268. u32 const segment_address = 0x30;
  269. bool i2c_read = input_msg->request &
  270. (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
  271. u8 *data = NULL;
  272. if (aux->native || i2c_read || ((input_msg->address != edid_address) &&
  273. (input_msg->address != segment_address)))
  274. return;
  275. data = input_msg->buffer;
  276. if (input_msg->address == segment_address)
  277. aux->segment = *data;
  278. else
  279. aux->offset = *data;
  280. }
  281. /**
  282. * dp_aux_transfer_helper() - helper function for EDID read transactions
  283. *
  284. * @aux: DP AUX private structure
  285. * @input_msg: input message from DRM upstream APIs
  286. * @send_seg: send the seg to sink
  287. *
  288. * return: void
  289. *
  290. * This helper function is used to fix EDID reads for non-compliant
  291. * sinks that do not handle the i2c middle-of-transaction flag correctly.
  292. */
  293. static void dp_aux_transfer_helper(struct dp_aux_private *aux,
  294. struct drm_dp_aux_msg *input_msg, bool send_seg)
  295. {
  296. struct drm_dp_aux_msg helper_msg;
  297. u32 const message_size = 0x10;
  298. u32 const segment_address = 0x30;
  299. u32 const edid_block_length = 0x80;
  300. bool i2c_mot = input_msg->request & DP_AUX_I2C_MOT;
  301. bool i2c_read = input_msg->request &
  302. (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
  303. if (!i2c_mot || !i2c_read || (input_msg->size == 0))
  304. return;
  305. /*
  306. * Sending the segment value and EDID offset will be performed
  307. * from the DRM upstream EDID driver for each block. Avoid
  308. * duplicate AUX transactions related to this while reading the
  309. * first 16 bytes of each block.
  310. */
  311. if (!(aux->offset % edid_block_length) || !send_seg)
  312. goto end;
  313. aux->read = false;
  314. aux->cmd_busy = true;
  315. aux->no_send_addr = true;
  316. aux->no_send_stop = true;
  317. /*
  318. * Send the segment address for i2c reads for segment > 0 and for which
  319. * the middle-of-transaction flag is set. This is required to support
  320. * EDID reads of more than 2 blocks as the segment address is reset to 0
  321. * since we are overriding the middle-of-transaction flag for read
  322. * transactions.
  323. */
  324. if (aux->segment) {
  325. memset(&helper_msg, 0, sizeof(helper_msg));
  326. helper_msg.address = segment_address;
  327. helper_msg.buffer = &aux->segment;
  328. helper_msg.size = 1;
  329. dp_aux_cmd_fifo_tx(aux, &helper_msg);
  330. }
  331. /*
  332. * Send the offset address for every i2c read in which the
  333. * middle-of-transaction flag is set. This will ensure that the sink
  334. * will update its read pointer and return the correct portion of the
  335. * EDID buffer in the subsequent i2c read trasntion triggered in the
  336. * native AUX transfer function.
  337. */
  338. memset(&helper_msg, 0, sizeof(helper_msg));
  339. helper_msg.address = input_msg->address;
  340. helper_msg.buffer = &aux->offset;
  341. helper_msg.size = 1;
  342. dp_aux_cmd_fifo_tx(aux, &helper_msg);
  343. end:
  344. aux->offset += message_size;
  345. if (aux->offset == 0x80 || aux->offset == 0x100)
  346. aux->segment = 0x0; /* reset segment at end of block */
  347. }
  348. static int dp_aux_transfer_ready(struct dp_aux_private *aux,
  349. struct drm_dp_aux_msg *msg, bool send_seg)
  350. {
  351. int ret = 0;
  352. int const aux_cmd_native_max = 16;
  353. int const aux_cmd_i2c_max = 128;
  354. if (atomic_read(&aux->aborted)) {
  355. ret = -ETIMEDOUT;
  356. goto error;
  357. }
  358. aux->native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
  359. /* Ignore address only message */
  360. if ((msg->size == 0) || (msg->buffer == NULL)) {
  361. msg->reply = aux->native ?
  362. DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
  363. goto error;
  364. }
  365. /* msg sanity check */
  366. if ((aux->native && (msg->size > aux_cmd_native_max)) ||
  367. (msg->size > aux_cmd_i2c_max)) {
  368. DP_ERR("%s: invalid msg: size(%zu), request(%x)\n",
  369. __func__, msg->size, msg->request);
  370. ret = -EINVAL;
  371. goto error;
  372. }
  373. dp_aux_update_offset_and_segment(aux, msg);
  374. dp_aux_transfer_helper(aux, msg, send_seg);
  375. aux->read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
  376. if (aux->read) {
  377. aux->no_send_addr = true;
  378. aux->no_send_stop = false;
  379. } else {
  380. aux->no_send_addr = true;
  381. aux->no_send_stop = true;
  382. }
  383. aux->cmd_busy = true;
  384. error:
  385. return ret;
  386. }
  387. static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux,
  388. struct drm_dp_aux_msg *msg)
  389. {
  390. u32 timeout;
  391. ssize_t ret;
  392. struct dp_aux_private *aux = container_of(drm_aux,
  393. struct dp_aux_private, drm_aux);
  394. mutex_lock(&aux->mutex);
  395. ret = dp_aux_transfer_ready(aux, msg, false);
  396. if (ret)
  397. goto end;
  398. aux->aux_error_num = DP_AUX_ERR_NONE;
  399. if (!aux->dpcd || !aux->edid) {
  400. DP_ERR("invalid aux/dpcd structure\n");
  401. goto end;
  402. }
  403. if ((msg->address + msg->size) > SZ_4K) {
  404. DP_DEBUG("invalid dpcd access: addr=0x%x, size=0x%lx\n",
  405. msg->address, msg->size);
  406. goto address_error;
  407. }
  408. if (aux->native) {
  409. mutex_lock(aux->dp_aux.access_lock);
  410. aux->dp_aux.reg = msg->address;
  411. aux->dp_aux.read = aux->read;
  412. aux->dp_aux.size = msg->size;
  413. if (!aux->read)
  414. memcpy(aux->dpcd + msg->address,
  415. msg->buffer, msg->size);
  416. reinit_completion(&aux->comp);
  417. mutex_unlock(aux->dp_aux.access_lock);
  418. timeout = wait_for_completion_timeout(&aux->comp, HZ * 2);
  419. if (!timeout) {
  420. DP_ERR("%s timeout: 0x%x\n",
  421. aux->read ? "read" : "write",
  422. msg->address);
  423. atomic_set(&aux->aborted, 1);
  424. ret = -ETIMEDOUT;
  425. goto end;
  426. }
  427. mutex_lock(aux->dp_aux.access_lock);
  428. if (aux->read)
  429. memcpy(msg->buffer, aux->dpcd + msg->address,
  430. msg->size);
  431. mutex_unlock(aux->dp_aux.access_lock);
  432. aux->aux_error_num = DP_AUX_ERR_NONE;
  433. } else {
  434. if (aux->read && msg->address == 0x50) {
  435. memcpy(msg->buffer,
  436. aux->edid + aux->offset - 16,
  437. msg->size);
  438. }
  439. }
  440. if (aux->aux_error_num == DP_AUX_ERR_NONE) {
  441. dp_aux_hex_dump(drm_aux, msg);
  442. if (!aux->read)
  443. memset(msg->buffer, 0, msg->size);
  444. msg->reply = aux->native ?
  445. DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
  446. } else {
  447. /* Reply defer to retry */
  448. msg->reply = aux->native ?
  449. DP_AUX_NATIVE_REPLY_DEFER : DP_AUX_I2C_REPLY_DEFER;
  450. }
  451. ret = msg->size;
  452. goto end;
  453. address_error:
  454. memset(msg->buffer, 0, msg->size);
  455. ret = msg->size;
  456. end:
  457. if (ret == -ETIMEDOUT)
  458. aux->dp_aux.state |= DP_STATE_AUX_TIMEOUT;
  459. aux->dp_aux.reg = 0xFFFF;
  460. aux->dp_aux.read = true;
  461. aux->dp_aux.size = 0;
  462. mutex_unlock(&aux->mutex);
  463. return ret;
  464. }
  465. /*
  466. * This function does the real job to process an AUX transaction.
  467. * It will call aux_reset() function to reset the AUX channel,
  468. * if the waiting is timeout.
  469. */
  470. static ssize_t dp_aux_transfer(struct drm_dp_aux *drm_aux,
  471. struct drm_dp_aux_msg *msg)
  472. {
  473. ssize_t ret;
  474. int const retry_count = 5;
  475. struct dp_aux_private *aux = container_of(drm_aux,
  476. struct dp_aux_private, drm_aux);
  477. mutex_lock(&aux->mutex);
  478. ret = dp_aux_transfer_ready(aux, msg, true);
  479. if (ret)
  480. goto unlock_exit;
  481. if (!aux->cmd_busy) {
  482. ret = msg->size;
  483. goto unlock_exit;
  484. }
  485. ret = dp_aux_cmd_fifo_tx(aux, msg);
  486. if ((ret < 0) && !atomic_read(&aux->aborted)) {
  487. aux->retry_cnt++;
  488. if (!(aux->retry_cnt % retry_count))
  489. aux->catalog->update_aux_cfg(aux->catalog,
  490. aux->cfg, PHY_AUX_CFG1);
  491. aux->catalog->reset(aux->catalog);
  492. goto unlock_exit;
  493. } else if (ret < 0) {
  494. goto unlock_exit;
  495. }
  496. if (aux->aux_error_num == DP_AUX_ERR_NONE) {
  497. if (aux->read)
  498. dp_aux_cmd_fifo_rx(aux, msg);
  499. dp_aux_hex_dump(drm_aux, msg);
  500. msg->reply = aux->native ?
  501. DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
  502. } else {
  503. /* Reply defer to retry */
  504. msg->reply = aux->native ?
  505. DP_AUX_NATIVE_REPLY_DEFER : DP_AUX_I2C_REPLY_DEFER;
  506. }
  507. /* Return requested size for success or retry */
  508. ret = msg->size;
  509. aux->retry_cnt = 0;
  510. unlock_exit:
  511. aux->cmd_busy = false;
  512. mutex_unlock(&aux->mutex);
  513. return ret;
  514. }
  515. static void dp_aux_reset_phy_config_indices(struct dp_aux_cfg *aux_cfg)
  516. {
  517. int i = 0;
  518. for (i = 0; i < PHY_AUX_CFG_MAX; i++)
  519. aux_cfg[i].current_index = 0;
  520. }
  521. static void dp_aux_init(struct dp_aux *dp_aux, struct dp_aux_cfg *aux_cfg)
  522. {
  523. struct dp_aux_private *aux;
  524. if (!dp_aux || !aux_cfg) {
  525. DP_ERR("invalid input\n");
  526. return;
  527. }
  528. aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
  529. if (aux->enabled)
  530. return;
  531. dp_aux_reset_phy_config_indices(aux_cfg);
  532. aux->catalog->setup(aux->catalog, aux_cfg);
  533. aux->catalog->reset(aux->catalog);
  534. aux->catalog->enable(aux->catalog, true);
  535. atomic_set(&aux->aborted, 0);
  536. aux->retry_cnt = 0;
  537. aux->enabled = true;
  538. }
  539. static void dp_aux_deinit(struct dp_aux *dp_aux)
  540. {
  541. struct dp_aux_private *aux;
  542. if (!dp_aux) {
  543. DP_ERR("invalid input\n");
  544. return;
  545. }
  546. aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
  547. if (!aux->enabled)
  548. return;
  549. atomic_set(&aux->aborted, 1);
  550. aux->catalog->enable(aux->catalog, false);
  551. aux->enabled = false;
  552. }
  553. static int dp_aux_register(struct dp_aux *dp_aux)
  554. {
  555. struct dp_aux_private *aux;
  556. int ret = 0;
  557. if (!dp_aux) {
  558. DP_ERR("invalid input\n");
  559. ret = -EINVAL;
  560. goto exit;
  561. }
  562. aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
  563. aux->drm_aux.name = "sde_dp_aux";
  564. aux->drm_aux.dev = aux->dev;
  565. aux->drm_aux.transfer = dp_aux_transfer;
  566. ret = drm_dp_aux_register(&aux->drm_aux);
  567. if (ret) {
  568. DP_ERR("%s: failed to register drm aux: %d\n", __func__, ret);
  569. goto exit;
  570. }
  571. dp_aux->drm_aux = &aux->drm_aux;
  572. exit:
  573. return ret;
  574. }
  575. static void dp_aux_deregister(struct dp_aux *dp_aux)
  576. {
  577. struct dp_aux_private *aux;
  578. if (!dp_aux) {
  579. DP_ERR("invalid input\n");
  580. return;
  581. }
  582. aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
  583. drm_dp_aux_unregister(&aux->drm_aux);
  584. }
  585. static void dp_aux_dpcd_updated(struct dp_aux *dp_aux)
  586. {
  587. struct dp_aux_private *aux;
  588. if (!dp_aux) {
  589. DP_ERR("invalid input\n");
  590. return;
  591. }
  592. aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
  593. /* make sure wait has started */
  594. usleep_range(20, 30);
  595. complete(&aux->comp);
  596. }
  597. static void dp_aux_set_sim_mode(struct dp_aux *dp_aux, bool en,
  598. u8 *edid, u8 *dpcd)
  599. {
  600. struct dp_aux_private *aux;
  601. if (!dp_aux) {
  602. DP_ERR("invalid input\n");
  603. return;
  604. }
  605. aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
  606. mutex_lock(&aux->mutex);
  607. aux->edid = edid;
  608. aux->dpcd = dpcd;
  609. if (en) {
  610. atomic_set(&aux->aborted, 0);
  611. aux->drm_aux.transfer = dp_aux_transfer_debug;
  612. } else {
  613. aux->drm_aux.transfer = dp_aux_transfer;
  614. }
  615. mutex_unlock(&aux->mutex);
  616. }
  617. static int dp_aux_configure_aux_switch(struct dp_aux *dp_aux,
  618. bool enable, int orientation)
  619. {
  620. struct dp_aux_private *aux;
  621. int rc = 0;
  622. enum fsa_function event = FSA_USBC_DISPLAYPORT_DISCONNECTED;
  623. if (!dp_aux) {
  624. DP_ERR("invalid input\n");
  625. rc = -EINVAL;
  626. goto end;
  627. }
  628. aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
  629. if (!aux->aux_switch_node) {
  630. DP_DEBUG("undefined fsa4480 handle\n");
  631. rc = -EINVAL;
  632. goto end;
  633. }
  634. if (enable) {
  635. switch (orientation) {
  636. case ORIENTATION_CC1:
  637. event = FSA_USBC_ORIENTATION_CC1;
  638. break;
  639. case ORIENTATION_CC2:
  640. event = FSA_USBC_ORIENTATION_CC2;
  641. break;
  642. default:
  643. DP_ERR("invalid orientation\n");
  644. rc = -EINVAL;
  645. goto end;
  646. }
  647. }
  648. DP_DEBUG("enable=%d, orientation=%d, event=%d\n",
  649. enable, orientation, event);
  650. rc = fsa4480_switch_event(aux->aux_switch_node, event);
  651. if (rc)
  652. DP_ERR("failed to configure fsa4480 i2c device (%d)\n", rc);
  653. end:
  654. return rc;
  655. }
  656. struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
  657. struct dp_parser *parser, struct device_node *aux_switch)
  658. {
  659. int rc = 0;
  660. struct dp_aux_private *aux;
  661. struct dp_aux *dp_aux;
  662. if (!catalog || !parser ||
  663. (!parser->no_aux_switch &&
  664. !aux_switch &&
  665. !parser->gpio_aux_switch)) {
  666. DP_ERR("invalid input\n");
  667. rc = -ENODEV;
  668. goto error;
  669. }
  670. aux = devm_kzalloc(dev, sizeof(*aux), GFP_KERNEL);
  671. if (!aux) {
  672. rc = -ENOMEM;
  673. goto error;
  674. }
  675. init_completion(&aux->comp);
  676. aux->cmd_busy = false;
  677. mutex_init(&aux->mutex);
  678. aux->dev = dev;
  679. aux->catalog = catalog;
  680. aux->cfg = parser->aux_cfg;
  681. aux->aux_switch_node = aux_switch;
  682. dp_aux = &aux->dp_aux;
  683. aux->retry_cnt = 0;
  684. aux->dp_aux.reg = 0xFFFF;
  685. dp_aux->isr = dp_aux_isr;
  686. dp_aux->init = dp_aux_init;
  687. dp_aux->deinit = dp_aux_deinit;
  688. dp_aux->drm_aux_register = dp_aux_register;
  689. dp_aux->drm_aux_deregister = dp_aux_deregister;
  690. dp_aux->reconfig = dp_aux_reconfig;
  691. dp_aux->abort = dp_aux_abort_transaction;
  692. dp_aux->dpcd_updated = dp_aux_dpcd_updated;
  693. dp_aux->set_sim_mode = dp_aux_set_sim_mode;
  694. dp_aux->aux_switch = dp_aux_configure_aux_switch;
  695. return dp_aux;
  696. error:
  697. return ERR_PTR(rc);
  698. }
  699. void dp_aux_put(struct dp_aux *dp_aux)
  700. {
  701. struct dp_aux_private *aux;
  702. if (!dp_aux)
  703. return;
  704. aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
  705. mutex_destroy(&aux->mutex);
  706. devm_kfree(aux->dev, aux);
  707. }