cadence_master.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
  2. // Copyright(c) 2015-17 Intel Corporation.
  3. /*
  4. * Cadence SoundWire Master module
  5. * Used by Master driver
  6. */
  7. #include <linux/delay.h>
  8. #include <linux/device.h>
  9. #include <linux/interrupt.h>
  10. #include <linux/module.h>
  11. #include <linux/mod_devicetable.h>
  12. #include <linux/soundwire/sdw_registers.h>
  13. #include <linux/soundwire/sdw.h>
  14. #include "bus.h"
  15. #include "cadence_master.h"
  16. #define CDNS_MCP_CONFIG 0x0
  17. #define CDNS_MCP_CONFIG_MCMD_RETRY GENMASK(27, 24)
  18. #define CDNS_MCP_CONFIG_MPREQ_DELAY GENMASK(20, 16)
  19. #define CDNS_MCP_CONFIG_MMASTER BIT(7)
  20. #define CDNS_MCP_CONFIG_BUS_REL BIT(6)
  21. #define CDNS_MCP_CONFIG_SNIFFER BIT(5)
  22. #define CDNS_MCP_CONFIG_SSPMOD BIT(4)
  23. #define CDNS_MCP_CONFIG_CMD BIT(3)
  24. #define CDNS_MCP_CONFIG_OP GENMASK(2, 0)
  25. #define CDNS_MCP_CONFIG_OP_NORMAL 0
  26. #define CDNS_MCP_CONTROL 0x4
  27. #define CDNS_MCP_CONTROL_RST_DELAY GENMASK(10, 8)
  28. #define CDNS_MCP_CONTROL_CMD_RST BIT(7)
  29. #define CDNS_MCP_CONTROL_SOFT_RST BIT(6)
  30. #define CDNS_MCP_CONTROL_SW_RST BIT(5)
  31. #define CDNS_MCP_CONTROL_HW_RST BIT(4)
  32. #define CDNS_MCP_CONTROL_CLK_PAUSE BIT(3)
  33. #define CDNS_MCP_CONTROL_CLK_STOP_CLR BIT(2)
  34. #define CDNS_MCP_CONTROL_CMD_ACCEPT BIT(1)
  35. #define CDNS_MCP_CONTROL_BLOCK_WAKEUP BIT(0)
  36. #define CDNS_MCP_CMDCTRL 0x8
  37. #define CDNS_MCP_SSPSTAT 0xC
  38. #define CDNS_MCP_FRAME_SHAPE 0x10
  39. #define CDNS_MCP_FRAME_SHAPE_INIT 0x14
  40. #define CDNS_MCP_CONFIG_UPDATE 0x18
  41. #define CDNS_MCP_CONFIG_UPDATE_BIT BIT(0)
  42. #define CDNS_MCP_PHYCTRL 0x1C
  43. #define CDNS_MCP_SSP_CTRL0 0x20
  44. #define CDNS_MCP_SSP_CTRL1 0x28
  45. #define CDNS_MCP_CLK_CTRL0 0x30
  46. #define CDNS_MCP_CLK_CTRL1 0x38
  47. #define CDNS_MCP_STAT 0x40
  48. #define CDNS_MCP_STAT_ACTIVE_BANK BIT(20)
  49. #define CDNS_MCP_STAT_CLK_STOP BIT(16)
  50. #define CDNS_MCP_INTSTAT 0x44
  51. #define CDNS_MCP_INTMASK 0x48
  52. #define CDNS_MCP_INT_IRQ BIT(31)
  53. #define CDNS_MCP_INT_WAKEUP BIT(16)
  54. #define CDNS_MCP_INT_SLAVE_RSVD BIT(15)
  55. #define CDNS_MCP_INT_SLAVE_ALERT BIT(14)
  56. #define CDNS_MCP_INT_SLAVE_ATTACH BIT(13)
  57. #define CDNS_MCP_INT_SLAVE_NATTACH BIT(12)
  58. #define CDNS_MCP_INT_SLAVE_MASK GENMASK(15, 12)
  59. #define CDNS_MCP_INT_DPINT BIT(11)
  60. #define CDNS_MCP_INT_CTRL_CLASH BIT(10)
  61. #define CDNS_MCP_INT_DATA_CLASH BIT(9)
  62. #define CDNS_MCP_INT_CMD_ERR BIT(7)
  63. #define CDNS_MCP_INT_RX_WL BIT(2)
  64. #define CDNS_MCP_INT_TXE BIT(1)
  65. #define CDNS_MCP_INTSET 0x4C
  66. #define CDNS_SDW_SLAVE_STAT 0x50
  67. #define CDNS_MCP_SLAVE_STAT_MASK BIT(1, 0)
  68. #define CDNS_MCP_SLAVE_INTSTAT0 0x54
  69. #define CDNS_MCP_SLAVE_INTSTAT1 0x58
  70. #define CDNS_MCP_SLAVE_INTSTAT_NPRESENT BIT(0)
  71. #define CDNS_MCP_SLAVE_INTSTAT_ATTACHED BIT(1)
  72. #define CDNS_MCP_SLAVE_INTSTAT_ALERT BIT(2)
  73. #define CDNS_MCP_SLAVE_INTSTAT_RESERVED BIT(3)
  74. #define CDNS_MCP_SLAVE_STATUS_BITS GENMASK(3, 0)
  75. #define CDNS_MCP_SLAVE_STATUS_NUM 4
  76. #define CDNS_MCP_SLAVE_INTMASK0 0x5C
  77. #define CDNS_MCP_SLAVE_INTMASK1 0x60
  78. #define CDNS_MCP_SLAVE_INTMASK0_MASK GENMASK(30, 0)
  79. #define CDNS_MCP_SLAVE_INTMASK1_MASK GENMASK(16, 0)
  80. #define CDNS_MCP_PORT_INTSTAT 0x64
  81. #define CDNS_MCP_PDI_STAT 0x6C
  82. #define CDNS_MCP_FIFOLEVEL 0x78
  83. #define CDNS_MCP_FIFOSTAT 0x7C
  84. #define CDNS_MCP_RX_FIFO_AVAIL GENMASK(5, 0)
  85. #define CDNS_MCP_CMD_BASE 0x80
  86. #define CDNS_MCP_RESP_BASE 0x80
  87. #define CDNS_MCP_CMD_LEN 0x20
  88. #define CDNS_MCP_CMD_WORD_LEN 0x4
  89. #define CDNS_MCP_CMD_SSP_TAG BIT(31)
  90. #define CDNS_MCP_CMD_COMMAND GENMASK(30, 28)
  91. #define CDNS_MCP_CMD_DEV_ADDR GENMASK(27, 24)
  92. #define CDNS_MCP_CMD_REG_ADDR_H GENMASK(23, 16)
  93. #define CDNS_MCP_CMD_REG_ADDR_L GENMASK(15, 8)
  94. #define CDNS_MCP_CMD_REG_DATA GENMASK(7, 0)
  95. #define CDNS_MCP_CMD_READ 2
  96. #define CDNS_MCP_CMD_WRITE 3
  97. #define CDNS_MCP_RESP_RDATA GENMASK(15, 8)
  98. #define CDNS_MCP_RESP_ACK BIT(0)
  99. #define CDNS_MCP_RESP_NACK BIT(1)
  100. #define CDNS_DP_SIZE 128
  101. #define CDNS_DPN_B0_CONFIG(n) (0x100 + CDNS_DP_SIZE * (n))
  102. #define CDNS_DPN_B0_CH_EN(n) (0x104 + CDNS_DP_SIZE * (n))
  103. #define CDNS_DPN_B0_SAMPLE_CTRL(n) (0x108 + CDNS_DP_SIZE * (n))
  104. #define CDNS_DPN_B0_OFFSET_CTRL(n) (0x10C + CDNS_DP_SIZE * (n))
  105. #define CDNS_DPN_B0_HCTRL(n) (0x110 + CDNS_DP_SIZE * (n))
  106. #define CDNS_DPN_B0_ASYNC_CTRL(n) (0x114 + CDNS_DP_SIZE * (n))
  107. #define CDNS_DPN_B1_CONFIG(n) (0x118 + CDNS_DP_SIZE * (n))
  108. #define CDNS_DPN_B1_CH_EN(n) (0x11C + CDNS_DP_SIZE * (n))
  109. #define CDNS_DPN_B1_SAMPLE_CTRL(n) (0x120 + CDNS_DP_SIZE * (n))
  110. #define CDNS_DPN_B1_OFFSET_CTRL(n) (0x124 + CDNS_DP_SIZE * (n))
  111. #define CDNS_DPN_B1_HCTRL(n) (0x128 + CDNS_DP_SIZE * (n))
  112. #define CDNS_DPN_B1_ASYNC_CTRL(n) (0x12C + CDNS_DP_SIZE * (n))
  113. #define CDNS_DPN_CONFIG_BPM BIT(18)
  114. #define CDNS_DPN_CONFIG_BGC GENMASK(17, 16)
  115. #define CDNS_DPN_CONFIG_WL GENMASK(12, 8)
  116. #define CDNS_DPN_CONFIG_PORT_DAT GENMASK(3, 2)
  117. #define CDNS_DPN_CONFIG_PORT_FLOW GENMASK(1, 0)
  118. #define CDNS_DPN_SAMPLE_CTRL_SI GENMASK(15, 0)
  119. #define CDNS_DPN_OFFSET_CTRL_1 GENMASK(7, 0)
  120. #define CDNS_DPN_OFFSET_CTRL_2 GENMASK(15, 8)
  121. #define CDNS_DPN_HCTRL_HSTOP GENMASK(3, 0)
  122. #define CDNS_DPN_HCTRL_HSTART GENMASK(7, 4)
  123. #define CDNS_DPN_HCTRL_LCTRL GENMASK(10, 8)
  124. #define CDNS_PORTCTRL 0x130
  125. #define CDNS_PORTCTRL_DIRN BIT(7)
  126. #define CDNS_PORTCTRL_BANK_INVERT BIT(8)
  127. #define CDNS_PORT_OFFSET 0x80
  128. #define CDNS_PDI_CONFIG(n) (0x1100 + (n) * 16)
  129. #define CDNS_PDI_CONFIG_SOFT_RESET BIT(24)
  130. #define CDNS_PDI_CONFIG_CHANNEL GENMASK(15, 8)
  131. #define CDNS_PDI_CONFIG_PORT GENMASK(4, 0)
  132. /* Driver defaults */
  133. #define CDNS_DEFAULT_CLK_DIVIDER 0
  134. #define CDNS_DEFAULT_FRAME_SHAPE 0x30
  135. #define CDNS_DEFAULT_SSP_INTERVAL 0x18
  136. #define CDNS_TX_TIMEOUT 2000
  137. #define CDNS_PCM_PDI_OFFSET 0x2
  138. #define CDNS_PDM_PDI_OFFSET 0x6
  139. #define CDNS_SCP_RX_FIFOLEVEL 0x2
  140. /*
  141. * register accessor helpers
  142. */
  143. static inline u32 cdns_readl(struct sdw_cdns *cdns, int offset)
  144. {
  145. return readl(cdns->registers + offset);
  146. }
  147. static inline void cdns_writel(struct sdw_cdns *cdns, int offset, u32 value)
  148. {
  149. writel(value, cdns->registers + offset);
  150. }
  151. static inline void cdns_updatel(struct sdw_cdns *cdns,
  152. int offset, u32 mask, u32 val)
  153. {
  154. u32 tmp;
  155. tmp = cdns_readl(cdns, offset);
  156. tmp = (tmp & ~mask) | val;
  157. cdns_writel(cdns, offset, tmp);
  158. }
  159. static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
  160. {
  161. int timeout = 10;
  162. u32 reg_read;
  163. writel(value, cdns->registers + offset);
  164. /* Wait for bit to be self cleared */
  165. do {
  166. reg_read = readl(cdns->registers + offset);
  167. if ((reg_read & value) == 0)
  168. return 0;
  169. timeout--;
  170. udelay(50);
  171. } while (timeout != 0);
  172. return -EAGAIN;
  173. }
  174. /*
  175. * IO Calls
  176. */
  177. static enum sdw_command_response cdns_fill_msg_resp(
  178. struct sdw_cdns *cdns,
  179. struct sdw_msg *msg, int count, int offset)
  180. {
  181. int nack = 0, no_ack = 0;
  182. int i;
  183. /* check message response */
  184. for (i = 0; i < count; i++) {
  185. if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
  186. no_ack = 1;
  187. dev_dbg(cdns->dev, "Msg Ack not received\n");
  188. if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
  189. nack = 1;
  190. dev_err(cdns->dev, "Msg NACK received\n");
  191. }
  192. }
  193. }
  194. if (nack) {
  195. dev_err(cdns->dev, "Msg NACKed for Slave %d\n", msg->dev_num);
  196. return SDW_CMD_FAIL;
  197. } else if (no_ack) {
  198. dev_dbg(cdns->dev, "Msg ignored for Slave %d\n", msg->dev_num);
  199. return SDW_CMD_IGNORED;
  200. }
  201. /* fill response */
  202. for (i = 0; i < count; i++)
  203. msg->buf[i + offset] = cdns->response_buf[i] >>
  204. SDW_REG_SHIFT(CDNS_MCP_RESP_RDATA);
  205. return SDW_CMD_OK;
  206. }
  207. static enum sdw_command_response
  208. _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
  209. int offset, int count, bool defer)
  210. {
  211. unsigned long time;
  212. u32 base, i, data;
  213. u16 addr;
  214. /* Program the watermark level for RX FIFO */
  215. if (cdns->msg_count != count) {
  216. cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, count);
  217. cdns->msg_count = count;
  218. }
  219. base = CDNS_MCP_CMD_BASE;
  220. addr = msg->addr;
  221. for (i = 0; i < count; i++) {
  222. data = msg->dev_num << SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR);
  223. data |= cmd << SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND);
  224. data |= addr++ << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
  225. if (msg->flags == SDW_MSG_FLAG_WRITE)
  226. data |= msg->buf[i + offset];
  227. data |= msg->ssp_sync << SDW_REG_SHIFT(CDNS_MCP_CMD_SSP_TAG);
  228. cdns_writel(cdns, base, data);
  229. base += CDNS_MCP_CMD_WORD_LEN;
  230. }
  231. if (defer)
  232. return SDW_CMD_OK;
  233. /* wait for timeout or response */
  234. time = wait_for_completion_timeout(&cdns->tx_complete,
  235. msecs_to_jiffies(CDNS_TX_TIMEOUT));
  236. if (!time) {
  237. dev_err(cdns->dev, "IO transfer timed out\n");
  238. msg->len = 0;
  239. return SDW_CMD_TIMEOUT;
  240. }
  241. return cdns_fill_msg_resp(cdns, msg, count, offset);
  242. }
  243. static enum sdw_command_response cdns_program_scp_addr(
  244. struct sdw_cdns *cdns, struct sdw_msg *msg)
  245. {
  246. int nack = 0, no_ack = 0;
  247. unsigned long time;
  248. u32 data[2], base;
  249. int i;
  250. /* Program the watermark level for RX FIFO */
  251. if (cdns->msg_count != CDNS_SCP_RX_FIFOLEVEL) {
  252. cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, CDNS_SCP_RX_FIFOLEVEL);
  253. cdns->msg_count = CDNS_SCP_RX_FIFOLEVEL;
  254. }
  255. data[0] = msg->dev_num << SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR);
  256. data[0] |= 0x3 << SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND);
  257. data[1] = data[0];
  258. data[0] |= SDW_SCP_ADDRPAGE1 << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
  259. data[1] |= SDW_SCP_ADDRPAGE2 << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
  260. data[0] |= msg->addr_page1;
  261. data[1] |= msg->addr_page2;
  262. base = CDNS_MCP_CMD_BASE;
  263. cdns_writel(cdns, base, data[0]);
  264. base += CDNS_MCP_CMD_WORD_LEN;
  265. cdns_writel(cdns, base, data[1]);
  266. time = wait_for_completion_timeout(&cdns->tx_complete,
  267. msecs_to_jiffies(CDNS_TX_TIMEOUT));
  268. if (!time) {
  269. dev_err(cdns->dev, "SCP Msg trf timed out\n");
  270. msg->len = 0;
  271. return SDW_CMD_TIMEOUT;
  272. }
  273. /* check response the writes */
  274. for (i = 0; i < 2; i++) {
  275. if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
  276. no_ack = 1;
  277. dev_err(cdns->dev, "Program SCP Ack not received");
  278. if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
  279. nack = 1;
  280. dev_err(cdns->dev, "Program SCP NACK received");
  281. }
  282. }
  283. }
  284. /* For NACK, NO ack, don't return err if we are in Broadcast mode */
  285. if (nack) {
  286. dev_err(cdns->dev,
  287. "SCP_addrpage NACKed for Slave %d", msg->dev_num);
  288. return SDW_CMD_FAIL;
  289. } else if (no_ack) {
  290. dev_dbg(cdns->dev,
  291. "SCP_addrpage ignored for Slave %d", msg->dev_num);
  292. return SDW_CMD_IGNORED;
  293. }
  294. return SDW_CMD_OK;
  295. }
  296. static int cdns_prep_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int *cmd)
  297. {
  298. int ret;
  299. if (msg->page) {
  300. ret = cdns_program_scp_addr(cdns, msg);
  301. if (ret) {
  302. msg->len = 0;
  303. return ret;
  304. }
  305. }
  306. switch (msg->flags) {
  307. case SDW_MSG_FLAG_READ:
  308. *cmd = CDNS_MCP_CMD_READ;
  309. break;
  310. case SDW_MSG_FLAG_WRITE:
  311. *cmd = CDNS_MCP_CMD_WRITE;
  312. break;
  313. default:
  314. dev_err(cdns->dev, "Invalid msg cmd: %d\n", msg->flags);
  315. return -EINVAL;
  316. }
  317. return 0;
  318. }
  319. enum sdw_command_response
  320. cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg)
  321. {
  322. struct sdw_cdns *cdns = bus_to_cdns(bus);
  323. int cmd = 0, ret, i;
  324. ret = cdns_prep_msg(cdns, msg, &cmd);
  325. if (ret)
  326. return SDW_CMD_FAIL_OTHER;
  327. for (i = 0; i < msg->len / CDNS_MCP_CMD_LEN; i++) {
  328. ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
  329. CDNS_MCP_CMD_LEN, false);
  330. if (ret < 0)
  331. goto exit;
  332. }
  333. if (!(msg->len % CDNS_MCP_CMD_LEN))
  334. goto exit;
  335. ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
  336. msg->len % CDNS_MCP_CMD_LEN, false);
  337. exit:
  338. return ret;
  339. }
  340. EXPORT_SYMBOL(cdns_xfer_msg);
  341. enum sdw_command_response
  342. cdns_xfer_msg_defer(struct sdw_bus *bus,
  343. struct sdw_msg *msg, struct sdw_defer *defer)
  344. {
  345. struct sdw_cdns *cdns = bus_to_cdns(bus);
  346. int cmd = 0, ret;
  347. /* for defer only 1 message is supported */
  348. if (msg->len > 1)
  349. return -ENOTSUPP;
  350. ret = cdns_prep_msg(cdns, msg, &cmd);
  351. if (ret)
  352. return SDW_CMD_FAIL_OTHER;
  353. cdns->defer = defer;
  354. cdns->defer->length = msg->len;
  355. return _cdns_xfer_msg(cdns, msg, cmd, 0, msg->len, true);
  356. }
  357. EXPORT_SYMBOL(cdns_xfer_msg_defer);
  358. enum sdw_command_response
  359. cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num)
  360. {
  361. struct sdw_cdns *cdns = bus_to_cdns(bus);
  362. struct sdw_msg msg;
  363. /* Create dummy message with valid device number */
  364. memset(&msg, 0, sizeof(msg));
  365. msg.dev_num = dev_num;
  366. return cdns_program_scp_addr(cdns, &msg);
  367. }
  368. EXPORT_SYMBOL(cdns_reset_page_addr);
  369. /*
  370. * IRQ handling
  371. */
  372. static void cdns_read_response(struct sdw_cdns *cdns)
  373. {
  374. u32 num_resp, cmd_base;
  375. int i;
  376. num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
  377. num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
  378. cmd_base = CDNS_MCP_CMD_BASE;
  379. for (i = 0; i < num_resp; i++) {
  380. cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
  381. cmd_base += CDNS_MCP_CMD_WORD_LEN;
  382. }
  383. }
  384. static int cdns_update_slave_status(struct sdw_cdns *cdns,
  385. u32 slave0, u32 slave1)
  386. {
  387. enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
  388. bool is_slave = false;
  389. u64 slave, mask;
  390. int i, set_status;
  391. /* combine the two status */
  392. slave = ((u64)slave1 << 32) | slave0;
  393. memset(status, 0, sizeof(status));
  394. for (i = 0; i <= SDW_MAX_DEVICES; i++) {
  395. mask = (slave >> (i * CDNS_MCP_SLAVE_STATUS_NUM)) &
  396. CDNS_MCP_SLAVE_STATUS_BITS;
  397. if (!mask)
  398. continue;
  399. is_slave = true;
  400. set_status = 0;
  401. if (mask & CDNS_MCP_SLAVE_INTSTAT_RESERVED) {
  402. status[i] = SDW_SLAVE_RESERVED;
  403. set_status++;
  404. }
  405. if (mask & CDNS_MCP_SLAVE_INTSTAT_ATTACHED) {
  406. status[i] = SDW_SLAVE_ATTACHED;
  407. set_status++;
  408. }
  409. if (mask & CDNS_MCP_SLAVE_INTSTAT_ALERT) {
  410. status[i] = SDW_SLAVE_ALERT;
  411. set_status++;
  412. }
  413. if (mask & CDNS_MCP_SLAVE_INTSTAT_NPRESENT) {
  414. status[i] = SDW_SLAVE_UNATTACHED;
  415. set_status++;
  416. }
  417. /* first check if Slave reported multiple status */
  418. if (set_status > 1) {
  419. dev_warn(cdns->dev,
  420. "Slave reported multiple Status: %d\n",
  421. status[i]);
  422. /*
  423. * TODO: we need to reread the status here by
  424. * issuing a PING cmd
  425. */
  426. }
  427. }
  428. if (is_slave)
  429. return sdw_handle_slave_status(&cdns->bus, status);
  430. return 0;
  431. }
  432. /**
  433. * sdw_cdns_irq() - Cadence interrupt handler
  434. * @irq: irq number
  435. * @dev_id: irq context
  436. */
  437. irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
  438. {
  439. struct sdw_cdns *cdns = dev_id;
  440. u32 int_status;
  441. int ret = IRQ_HANDLED;
  442. /* Check if the link is up */
  443. if (!cdns->link_up)
  444. return IRQ_NONE;
  445. int_status = cdns_readl(cdns, CDNS_MCP_INTSTAT);
  446. if (!(int_status & CDNS_MCP_INT_IRQ))
  447. return IRQ_NONE;
  448. if (int_status & CDNS_MCP_INT_RX_WL) {
  449. cdns_read_response(cdns);
  450. if (cdns->defer) {
  451. cdns_fill_msg_resp(cdns, cdns->defer->msg,
  452. cdns->defer->length, 0);
  453. complete(&cdns->defer->complete);
  454. cdns->defer = NULL;
  455. } else
  456. complete(&cdns->tx_complete);
  457. }
  458. if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
  459. /* Slave is driving bit slot during control word */
  460. dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
  461. int_status |= CDNS_MCP_INT_CTRL_CLASH;
  462. }
  463. if (int_status & CDNS_MCP_INT_DATA_CLASH) {
  464. /*
  465. * Multiple slaves trying to drive bit slot, or issue with
  466. * ownership of data bits or Slave gone bonkers
  467. */
  468. dev_err_ratelimited(cdns->dev, "Bus clash for data word\n");
  469. int_status |= CDNS_MCP_INT_DATA_CLASH;
  470. }
  471. if (int_status & CDNS_MCP_INT_SLAVE_MASK) {
  472. /* Mask the Slave interrupt and wake thread */
  473. cdns_updatel(cdns, CDNS_MCP_INTMASK,
  474. CDNS_MCP_INT_SLAVE_MASK, 0);
  475. int_status &= ~CDNS_MCP_INT_SLAVE_MASK;
  476. ret = IRQ_WAKE_THREAD;
  477. }
  478. cdns_writel(cdns, CDNS_MCP_INTSTAT, int_status);
  479. return ret;
  480. }
  481. EXPORT_SYMBOL(sdw_cdns_irq);
  482. /**
  483. * sdw_cdns_thread() - Cadence irq thread handler
  484. * @irq: irq number
  485. * @dev_id: irq context
  486. */
  487. irqreturn_t sdw_cdns_thread(int irq, void *dev_id)
  488. {
  489. struct sdw_cdns *cdns = dev_id;
  490. u32 slave0, slave1;
  491. dev_dbg(cdns->dev, "Slave status change\n");
  492. slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
  493. slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
  494. cdns_update_slave_status(cdns, slave0, slave1);
  495. cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0);
  496. cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1);
  497. /* clear and unmask Slave interrupt now */
  498. cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK);
  499. cdns_updatel(cdns, CDNS_MCP_INTMASK,
  500. CDNS_MCP_INT_SLAVE_MASK, CDNS_MCP_INT_SLAVE_MASK);
  501. return IRQ_HANDLED;
  502. }
  503. EXPORT_SYMBOL(sdw_cdns_thread);
  504. /*
  505. * init routines
  506. */
  507. static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
  508. {
  509. u32 mask;
  510. cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
  511. CDNS_MCP_SLAVE_INTMASK0_MASK);
  512. cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
  513. CDNS_MCP_SLAVE_INTMASK1_MASK);
  514. mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
  515. CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH |
  516. CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
  517. CDNS_MCP_INT_RX_WL | CDNS_MCP_INT_IRQ | CDNS_MCP_INT_DPINT;
  518. cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
  519. return 0;
  520. }
  521. /**
  522. * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
  523. * @cdns: Cadence instance
  524. */
  525. int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
  526. {
  527. int ret;
  528. _cdns_enable_interrupt(cdns);
  529. ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
  530. CDNS_MCP_CONFIG_UPDATE_BIT);
  531. if (ret < 0)
  532. dev_err(cdns->dev, "Config update timedout");
  533. return ret;
  534. }
  535. EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
  536. static int cdns_allocate_pdi(struct sdw_cdns *cdns,
  537. struct sdw_cdns_pdi **stream,
  538. u32 num, u32 pdi_offset)
  539. {
  540. struct sdw_cdns_pdi *pdi;
  541. int i;
  542. if (!num)
  543. return 0;
  544. pdi = devm_kcalloc(cdns->dev, num, sizeof(*pdi), GFP_KERNEL);
  545. if (!pdi)
  546. return -ENOMEM;
  547. for (i = 0; i < num; i++) {
  548. pdi[i].num = i + pdi_offset;
  549. pdi[i].assigned = false;
  550. }
  551. *stream = pdi;
  552. return 0;
  553. }
  554. /**
  555. * sdw_cdns_pdi_init() - PDI initialization routine
  556. *
  557. * @cdns: Cadence instance
  558. * @config: Stream configurations
  559. */
  560. int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
  561. struct sdw_cdns_stream_config config)
  562. {
  563. struct sdw_cdns_streams *stream;
  564. int offset, i, ret;
  565. cdns->pcm.num_bd = config.pcm_bd;
  566. cdns->pcm.num_in = config.pcm_in;
  567. cdns->pcm.num_out = config.pcm_out;
  568. cdns->pdm.num_bd = config.pdm_bd;
  569. cdns->pdm.num_in = config.pdm_in;
  570. cdns->pdm.num_out = config.pdm_out;
  571. /* Allocate PDIs for PCMs */
  572. stream = &cdns->pcm;
  573. /* First two PDIs are reserved for bulk transfers */
  574. stream->num_bd -= CDNS_PCM_PDI_OFFSET;
  575. offset = CDNS_PCM_PDI_OFFSET;
  576. ret = cdns_allocate_pdi(cdns, &stream->bd,
  577. stream->num_bd, offset);
  578. if (ret)
  579. return ret;
  580. offset += stream->num_bd;
  581. ret = cdns_allocate_pdi(cdns, &stream->in,
  582. stream->num_in, offset);
  583. if (ret)
  584. return ret;
  585. offset += stream->num_in;
  586. ret = cdns_allocate_pdi(cdns, &stream->out,
  587. stream->num_out, offset);
  588. if (ret)
  589. return ret;
  590. /* Update total number of PCM PDIs */
  591. stream->num_pdi = stream->num_bd + stream->num_in + stream->num_out;
  592. cdns->num_ports = stream->num_pdi;
  593. /* Allocate PDIs for PDMs */
  594. stream = &cdns->pdm;
  595. offset = CDNS_PDM_PDI_OFFSET;
  596. ret = cdns_allocate_pdi(cdns, &stream->bd,
  597. stream->num_bd, offset);
  598. if (ret)
  599. return ret;
  600. offset += stream->num_bd;
  601. ret = cdns_allocate_pdi(cdns, &stream->in,
  602. stream->num_in, offset);
  603. if (ret)
  604. return ret;
  605. offset += stream->num_in;
  606. ret = cdns_allocate_pdi(cdns, &stream->out,
  607. stream->num_out, offset);
  608. if (ret)
  609. return ret;
  610. /* Update total number of PDM PDIs */
  611. stream->num_pdi = stream->num_bd + stream->num_in + stream->num_out;
  612. cdns->num_ports += stream->num_pdi;
  613. cdns->ports = devm_kcalloc(cdns->dev, cdns->num_ports,
  614. sizeof(*cdns->ports), GFP_KERNEL);
  615. if (!cdns->ports) {
  616. ret = -ENOMEM;
  617. return ret;
  618. }
  619. for (i = 0; i < cdns->num_ports; i++) {
  620. cdns->ports[i].assigned = false;
  621. cdns->ports[i].num = i + 1; /* Port 0 reserved for bulk */
  622. }
  623. return 0;
  624. }
  625. EXPORT_SYMBOL(sdw_cdns_pdi_init);
  626. /**
  627. * sdw_cdns_init() - Cadence initialization
  628. * @cdns: Cadence instance
  629. */
  630. int sdw_cdns_init(struct sdw_cdns *cdns)
  631. {
  632. u32 val;
  633. int ret;
  634. /* Exit clock stop */
  635. ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
  636. CDNS_MCP_CONTROL_CLK_STOP_CLR);
  637. if (ret < 0) {
  638. dev_err(cdns->dev, "Couldn't exit from clock stop\n");
  639. return ret;
  640. }
  641. /* Set clock divider */
  642. val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
  643. val |= CDNS_DEFAULT_CLK_DIVIDER;
  644. cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
  645. /* Set the default frame shape */
  646. cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, CDNS_DEFAULT_FRAME_SHAPE);
  647. /* Set SSP interval to default value */
  648. cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
  649. cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL);
  650. /* Set cmd accept mode */
  651. cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
  652. CDNS_MCP_CONTROL_CMD_ACCEPT);
  653. /* Configure mcp config */
  654. val = cdns_readl(cdns, CDNS_MCP_CONFIG);
  655. /* Set Max cmd retry to 15 */
  656. val |= CDNS_MCP_CONFIG_MCMD_RETRY;
  657. /* Set frame delay between PREQ and ping frame to 15 frames */
  658. val |= 0xF << SDW_REG_SHIFT(CDNS_MCP_CONFIG_MPREQ_DELAY);
  659. /* Disable auto bus release */
  660. val &= ~CDNS_MCP_CONFIG_BUS_REL;
  661. /* Disable sniffer mode */
  662. val &= ~CDNS_MCP_CONFIG_SNIFFER;
  663. /* Set cmd mode for Tx and Rx cmds */
  664. val &= ~CDNS_MCP_CONFIG_CMD;
  665. /* Set operation to normal */
  666. val &= ~CDNS_MCP_CONFIG_OP;
  667. val |= CDNS_MCP_CONFIG_OP_NORMAL;
  668. cdns_writel(cdns, CDNS_MCP_CONFIG, val);
  669. return 0;
  670. }
  671. EXPORT_SYMBOL(sdw_cdns_init);
  672. int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
  673. {
  674. struct sdw_cdns *cdns = bus_to_cdns(bus);
  675. int mcp_clkctrl_off, mcp_clkctrl;
  676. int divider;
  677. if (!params->curr_dr_freq) {
  678. dev_err(cdns->dev, "NULL curr_dr_freq");
  679. return -EINVAL;
  680. }
  681. divider = (params->max_dr_freq / params->curr_dr_freq) - 1;
  682. if (params->next_bank)
  683. mcp_clkctrl_off = CDNS_MCP_CLK_CTRL1;
  684. else
  685. mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
  686. mcp_clkctrl = cdns_readl(cdns, mcp_clkctrl_off);
  687. mcp_clkctrl |= divider;
  688. cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
  689. return 0;
  690. }
  691. EXPORT_SYMBOL(cdns_bus_conf);
  692. static int cdns_port_params(struct sdw_bus *bus,
  693. struct sdw_port_params *p_params, unsigned int bank)
  694. {
  695. struct sdw_cdns *cdns = bus_to_cdns(bus);
  696. int dpn_config = 0, dpn_config_off;
  697. if (bank)
  698. dpn_config_off = CDNS_DPN_B1_CONFIG(p_params->num);
  699. else
  700. dpn_config_off = CDNS_DPN_B0_CONFIG(p_params->num);
  701. dpn_config = cdns_readl(cdns, dpn_config_off);
  702. dpn_config |= ((p_params->bps - 1) <<
  703. SDW_REG_SHIFT(CDNS_DPN_CONFIG_WL));
  704. dpn_config |= (p_params->flow_mode <<
  705. SDW_REG_SHIFT(CDNS_DPN_CONFIG_PORT_FLOW));
  706. dpn_config |= (p_params->data_mode <<
  707. SDW_REG_SHIFT(CDNS_DPN_CONFIG_PORT_DAT));
  708. cdns_writel(cdns, dpn_config_off, dpn_config);
  709. return 0;
  710. }
  711. static int cdns_transport_params(struct sdw_bus *bus,
  712. struct sdw_transport_params *t_params,
  713. enum sdw_reg_bank bank)
  714. {
  715. struct sdw_cdns *cdns = bus_to_cdns(bus);
  716. int dpn_offsetctrl = 0, dpn_offsetctrl_off;
  717. int dpn_config = 0, dpn_config_off;
  718. int dpn_hctrl = 0, dpn_hctrl_off;
  719. int num = t_params->port_num;
  720. int dpn_samplectrl_off;
  721. /*
  722. * Note: Only full data port is supported on the Master side for
  723. * both PCM and PDM ports.
  724. */
  725. if (bank) {
  726. dpn_config_off = CDNS_DPN_B1_CONFIG(num);
  727. dpn_samplectrl_off = CDNS_DPN_B1_SAMPLE_CTRL(num);
  728. dpn_hctrl_off = CDNS_DPN_B1_HCTRL(num);
  729. dpn_offsetctrl_off = CDNS_DPN_B1_OFFSET_CTRL(num);
  730. } else {
  731. dpn_config_off = CDNS_DPN_B0_CONFIG(num);
  732. dpn_samplectrl_off = CDNS_DPN_B0_SAMPLE_CTRL(num);
  733. dpn_hctrl_off = CDNS_DPN_B0_HCTRL(num);
  734. dpn_offsetctrl_off = CDNS_DPN_B0_OFFSET_CTRL(num);
  735. }
  736. dpn_config = cdns_readl(cdns, dpn_config_off);
  737. dpn_config |= (t_params->blk_grp_ctrl <<
  738. SDW_REG_SHIFT(CDNS_DPN_CONFIG_BGC));
  739. dpn_config |= (t_params->blk_pkg_mode <<
  740. SDW_REG_SHIFT(CDNS_DPN_CONFIG_BPM));
  741. cdns_writel(cdns, dpn_config_off, dpn_config);
  742. dpn_offsetctrl |= (t_params->offset1 <<
  743. SDW_REG_SHIFT(CDNS_DPN_OFFSET_CTRL_1));
  744. dpn_offsetctrl |= (t_params->offset2 <<
  745. SDW_REG_SHIFT(CDNS_DPN_OFFSET_CTRL_2));
  746. cdns_writel(cdns, dpn_offsetctrl_off, dpn_offsetctrl);
  747. dpn_hctrl |= (t_params->hstart <<
  748. SDW_REG_SHIFT(CDNS_DPN_HCTRL_HSTART));
  749. dpn_hctrl |= (t_params->hstop << SDW_REG_SHIFT(CDNS_DPN_HCTRL_HSTOP));
  750. dpn_hctrl |= (t_params->lane_ctrl <<
  751. SDW_REG_SHIFT(CDNS_DPN_HCTRL_LCTRL));
  752. cdns_writel(cdns, dpn_hctrl_off, dpn_hctrl);
  753. cdns_writel(cdns, dpn_samplectrl_off, (t_params->sample_interval - 1));
  754. return 0;
  755. }
  756. static int cdns_port_enable(struct sdw_bus *bus,
  757. struct sdw_enable_ch *enable_ch, unsigned int bank)
  758. {
  759. struct sdw_cdns *cdns = bus_to_cdns(bus);
  760. int dpn_chnen_off, ch_mask;
  761. if (bank)
  762. dpn_chnen_off = CDNS_DPN_B1_CH_EN(enable_ch->port_num);
  763. else
  764. dpn_chnen_off = CDNS_DPN_B0_CH_EN(enable_ch->port_num);
  765. ch_mask = enable_ch->ch_mask * enable_ch->enable;
  766. cdns_writel(cdns, dpn_chnen_off, ch_mask);
  767. return 0;
  768. }
  769. static const struct sdw_master_port_ops cdns_port_ops = {
  770. .dpn_set_port_params = cdns_port_params,
  771. .dpn_set_port_transport_params = cdns_transport_params,
  772. .dpn_port_enable_ch = cdns_port_enable,
  773. };
  774. /**
  775. * sdw_cdns_probe() - Cadence probe routine
  776. * @cdns: Cadence instance
  777. */
  778. int sdw_cdns_probe(struct sdw_cdns *cdns)
  779. {
  780. init_completion(&cdns->tx_complete);
  781. cdns->bus.port_ops = &cdns_port_ops;
  782. return 0;
  783. }
  784. EXPORT_SYMBOL(sdw_cdns_probe);
  785. MODULE_LICENSE("Dual BSD/GPL");
  786. MODULE_DESCRIPTION("Cadence Soundwire Library");