dp_aux.c 23 KB

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