dp_aux.c 19 KB

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