1
2
3
4
5
6
7
8
9#include <linux/delay.h>
10#include <linux/device.h>
11#include <linux/debugfs.h>
12#include <linux/interrupt.h>
13#include <linux/io.h>
14#include <linux/module.h>
15#include <linux/mod_devicetable.h>
16#include <linux/pm_runtime.h>
17#include <linux/soundwire/sdw_registers.h>
18#include <linux/soundwire/sdw.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <linux/workqueue.h>
22#include "bus.h"
23#include "cadence_master.h"
24
25static int interrupt_mask;
26module_param_named(cnds_mcp_int_mask, interrupt_mask, int, 0444);
27MODULE_PARM_DESC(cdns_mcp_int_mask, "Cadence MCP IntMask");
28
29#define CDNS_MCP_CONFIG 0x0
30
31#define CDNS_MCP_CONFIG_MCMD_RETRY GENMASK(27, 24)
32#define CDNS_MCP_CONFIG_MPREQ_DELAY GENMASK(20, 16)
33#define CDNS_MCP_CONFIG_MMASTER BIT(7)
34#define CDNS_MCP_CONFIG_BUS_REL BIT(6)
35#define CDNS_MCP_CONFIG_SNIFFER BIT(5)
36#define CDNS_MCP_CONFIG_SSPMOD BIT(4)
37#define CDNS_MCP_CONFIG_CMD BIT(3)
38#define CDNS_MCP_CONFIG_OP GENMASK(2, 0)
39#define CDNS_MCP_CONFIG_OP_NORMAL 0
40
41#define CDNS_MCP_CONTROL 0x4
42
43#define CDNS_MCP_CONTROL_RST_DELAY GENMASK(10, 8)
44#define CDNS_MCP_CONTROL_CMD_RST BIT(7)
45#define CDNS_MCP_CONTROL_SOFT_RST BIT(6)
46#define CDNS_MCP_CONTROL_SW_RST BIT(5)
47#define CDNS_MCP_CONTROL_HW_RST BIT(4)
48#define CDNS_MCP_CONTROL_CLK_PAUSE BIT(3)
49#define CDNS_MCP_CONTROL_CLK_STOP_CLR BIT(2)
50#define CDNS_MCP_CONTROL_CMD_ACCEPT BIT(1)
51#define CDNS_MCP_CONTROL_BLOCK_WAKEUP BIT(0)
52
53#define CDNS_MCP_CMDCTRL 0x8
54
55#define CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR BIT(2)
56
57#define CDNS_MCP_SSPSTAT 0xC
58#define CDNS_MCP_FRAME_SHAPE 0x10
59#define CDNS_MCP_FRAME_SHAPE_INIT 0x14
60#define CDNS_MCP_FRAME_SHAPE_COL_MASK GENMASK(2, 0)
61#define CDNS_MCP_FRAME_SHAPE_ROW_MASK GENMASK(7, 3)
62
63#define CDNS_MCP_CONFIG_UPDATE 0x18
64#define CDNS_MCP_CONFIG_UPDATE_BIT BIT(0)
65
66#define CDNS_MCP_PHYCTRL 0x1C
67#define CDNS_MCP_SSP_CTRL0 0x20
68#define CDNS_MCP_SSP_CTRL1 0x28
69#define CDNS_MCP_CLK_CTRL0 0x30
70#define CDNS_MCP_CLK_CTRL1 0x38
71#define CDNS_MCP_CLK_MCLKD_MASK GENMASK(7, 0)
72
73#define CDNS_MCP_STAT 0x40
74
75#define CDNS_MCP_STAT_ACTIVE_BANK BIT(20)
76#define CDNS_MCP_STAT_CLK_STOP BIT(16)
77
78#define CDNS_MCP_INTSTAT 0x44
79#define CDNS_MCP_INTMASK 0x48
80
81#define CDNS_MCP_INT_IRQ BIT(31)
82#define CDNS_MCP_INT_RESERVED1 GENMASK(30, 17)
83#define CDNS_MCP_INT_WAKEUP BIT(16)
84#define CDNS_MCP_INT_SLAVE_RSVD BIT(15)
85#define CDNS_MCP_INT_SLAVE_ALERT BIT(14)
86#define CDNS_MCP_INT_SLAVE_ATTACH BIT(13)
87#define CDNS_MCP_INT_SLAVE_NATTACH BIT(12)
88#define CDNS_MCP_INT_SLAVE_MASK GENMASK(15, 12)
89#define CDNS_MCP_INT_DPINT BIT(11)
90#define CDNS_MCP_INT_CTRL_CLASH BIT(10)
91#define CDNS_MCP_INT_DATA_CLASH BIT(9)
92#define CDNS_MCP_INT_PARITY BIT(8)
93#define CDNS_MCP_INT_CMD_ERR BIT(7)
94#define CDNS_MCP_INT_RESERVED2 GENMASK(6, 4)
95#define CDNS_MCP_INT_RX_NE BIT(3)
96#define CDNS_MCP_INT_RX_WL BIT(2)
97#define CDNS_MCP_INT_TXE BIT(1)
98#define CDNS_MCP_INT_TXF BIT(0)
99#define CDNS_MCP_INT_RESERVED (CDNS_MCP_INT_RESERVED1 | CDNS_MCP_INT_RESERVED2)
100
101#define CDNS_MCP_INTSET 0x4C
102
103#define CDNS_MCP_SLAVE_STAT 0x50
104#define CDNS_MCP_SLAVE_STAT_MASK GENMASK(1, 0)
105
106#define CDNS_MCP_SLAVE_INTSTAT0 0x54
107#define CDNS_MCP_SLAVE_INTSTAT1 0x58
108#define CDNS_MCP_SLAVE_INTSTAT_NPRESENT BIT(0)
109#define CDNS_MCP_SLAVE_INTSTAT_ATTACHED BIT(1)
110#define CDNS_MCP_SLAVE_INTSTAT_ALERT BIT(2)
111#define CDNS_MCP_SLAVE_INTSTAT_RESERVED BIT(3)
112#define CDNS_MCP_SLAVE_STATUS_BITS GENMASK(3, 0)
113#define CDNS_MCP_SLAVE_STATUS_NUM 4
114
115#define CDNS_MCP_SLAVE_INTMASK0 0x5C
116#define CDNS_MCP_SLAVE_INTMASK1 0x60
117
118#define CDNS_MCP_SLAVE_INTMASK0_MASK GENMASK(31, 0)
119#define CDNS_MCP_SLAVE_INTMASK1_MASK GENMASK(15, 0)
120
121#define CDNS_MCP_PORT_INTSTAT 0x64
122#define CDNS_MCP_PDI_STAT 0x6C
123
124#define CDNS_MCP_FIFOLEVEL 0x78
125#define CDNS_MCP_FIFOSTAT 0x7C
126#define CDNS_MCP_RX_FIFO_AVAIL GENMASK(5, 0)
127
128#define CDNS_MCP_CMD_BASE 0x80
129#define CDNS_MCP_RESP_BASE 0x80
130#define CDNS_MCP_CMD_LEN 0x20
131#define CDNS_MCP_CMD_WORD_LEN 0x4
132
133#define CDNS_MCP_CMD_SSP_TAG BIT(31)
134#define CDNS_MCP_CMD_COMMAND GENMASK(30, 28)
135#define CDNS_MCP_CMD_DEV_ADDR GENMASK(27, 24)
136#define CDNS_MCP_CMD_REG_ADDR GENMASK(23, 8)
137#define CDNS_MCP_CMD_REG_DATA GENMASK(7, 0)
138
139#define CDNS_MCP_CMD_READ 2
140#define CDNS_MCP_CMD_WRITE 3
141
142#define CDNS_MCP_RESP_RDATA GENMASK(15, 8)
143#define CDNS_MCP_RESP_ACK BIT(0)
144#define CDNS_MCP_RESP_NACK BIT(1)
145
146#define CDNS_DP_SIZE 128
147
148#define CDNS_DPN_B0_CONFIG(n) (0x100 + CDNS_DP_SIZE * (n))
149#define CDNS_DPN_B0_CH_EN(n) (0x104 + CDNS_DP_SIZE * (n))
150#define CDNS_DPN_B0_SAMPLE_CTRL(n) (0x108 + CDNS_DP_SIZE * (n))
151#define CDNS_DPN_B0_OFFSET_CTRL(n) (0x10C + CDNS_DP_SIZE * (n))
152#define CDNS_DPN_B0_HCTRL(n) (0x110 + CDNS_DP_SIZE * (n))
153#define CDNS_DPN_B0_ASYNC_CTRL(n) (0x114 + CDNS_DP_SIZE * (n))
154
155#define CDNS_DPN_B1_CONFIG(n) (0x118 + CDNS_DP_SIZE * (n))
156#define CDNS_DPN_B1_CH_EN(n) (0x11C + CDNS_DP_SIZE * (n))
157#define CDNS_DPN_B1_SAMPLE_CTRL(n) (0x120 + CDNS_DP_SIZE * (n))
158#define CDNS_DPN_B1_OFFSET_CTRL(n) (0x124 + CDNS_DP_SIZE * (n))
159#define CDNS_DPN_B1_HCTRL(n) (0x128 + CDNS_DP_SIZE * (n))
160#define CDNS_DPN_B1_ASYNC_CTRL(n) (0x12C + CDNS_DP_SIZE * (n))
161
162#define CDNS_DPN_CONFIG_BPM BIT(18)
163#define CDNS_DPN_CONFIG_BGC GENMASK(17, 16)
164#define CDNS_DPN_CONFIG_WL GENMASK(12, 8)
165#define CDNS_DPN_CONFIG_PORT_DAT GENMASK(3, 2)
166#define CDNS_DPN_CONFIG_PORT_FLOW GENMASK(1, 0)
167
168#define CDNS_DPN_SAMPLE_CTRL_SI GENMASK(15, 0)
169
170#define CDNS_DPN_OFFSET_CTRL_1 GENMASK(7, 0)
171#define CDNS_DPN_OFFSET_CTRL_2 GENMASK(15, 8)
172
173#define CDNS_DPN_HCTRL_HSTOP GENMASK(3, 0)
174#define CDNS_DPN_HCTRL_HSTART GENMASK(7, 4)
175#define CDNS_DPN_HCTRL_LCTRL GENMASK(10, 8)
176
177#define CDNS_PORTCTRL 0x130
178#define CDNS_PORTCTRL_TEST_FAILED BIT(1)
179#define CDNS_PORTCTRL_DIRN BIT(7)
180#define CDNS_PORTCTRL_BANK_INVERT BIT(8)
181
182#define CDNS_PORT_OFFSET 0x80
183
184#define CDNS_PDI_CONFIG(n) (0x1100 + (n) * 16)
185
186#define CDNS_PDI_CONFIG_SOFT_RESET BIT(24)
187#define CDNS_PDI_CONFIG_CHANNEL GENMASK(15, 8)
188#define CDNS_PDI_CONFIG_PORT GENMASK(4, 0)
189
190
191#define CDNS_TX_TIMEOUT 500
192
193#define CDNS_SCP_RX_FIFOLEVEL 0x2
194
195
196
197
198static inline u32 cdns_readl(struct sdw_cdns *cdns, int offset)
199{
200 return readl(cdns->registers + offset);
201}
202
203static inline void cdns_writel(struct sdw_cdns *cdns, int offset, u32 value)
204{
205 writel(value, cdns->registers + offset);
206}
207
208static inline void cdns_updatel(struct sdw_cdns *cdns,
209 int offset, u32 mask, u32 val)
210{
211 u32 tmp;
212
213 tmp = cdns_readl(cdns, offset);
214 tmp = (tmp & ~mask) | val;
215 cdns_writel(cdns, offset, tmp);
216}
217
218static int cdns_set_wait(struct sdw_cdns *cdns, int offset, u32 mask, u32 value)
219{
220 int timeout = 10;
221 u32 reg_read;
222
223
224 do {
225 reg_read = readl(cdns->registers + offset);
226 if ((reg_read & mask) == value)
227 return 0;
228
229 timeout--;
230 usleep_range(50, 100);
231 } while (timeout != 0);
232
233 return -ETIMEDOUT;
234}
235
236static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
237{
238 writel(value, cdns->registers + offset);
239
240
241 return cdns_set_wait(cdns, offset, value, 0);
242}
243
244
245
246
247
248static int cdns_config_update(struct sdw_cdns *cdns)
249{
250 int ret;
251
252 if (sdw_cdns_is_clock_stop(cdns)) {
253 dev_err(cdns->dev, "Cannot program MCP_CONFIG_UPDATE in ClockStopMode\n");
254 return -EINVAL;
255 }
256
257 ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
258 CDNS_MCP_CONFIG_UPDATE_BIT);
259 if (ret < 0)
260 dev_err(cdns->dev, "Config update timedout\n");
261
262 return ret;
263}
264
265
266
267
268#ifdef CONFIG_DEBUG_FS
269
270#define RD_BUF (2 * PAGE_SIZE)
271
272static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
273 char *buf, size_t pos, unsigned int reg)
274{
275 return scnprintf(buf + pos, RD_BUF - pos,
276 "%4x\t%8x\n", reg, cdns_readl(cdns, reg));
277}
278
279static int cdns_reg_show(struct seq_file *s, void *data)
280{
281 struct sdw_cdns *cdns = s->private;
282 char *buf;
283 ssize_t ret;
284 int num_ports;
285 int i, j;
286
287 buf = kzalloc(RD_BUF, GFP_KERNEL);
288 if (!buf)
289 return -ENOMEM;
290
291 ret = scnprintf(buf, RD_BUF, "Register Value\n");
292 ret += scnprintf(buf + ret, RD_BUF - ret, "\nMCP Registers\n");
293
294 for (i = CDNS_MCP_CONFIG; i <= CDNS_MCP_PHYCTRL; i += sizeof(u32))
295 ret += cdns_sprintf(cdns, buf, ret, i);
296
297 ret += scnprintf(buf + ret, RD_BUF - ret,
298 "\nStatus & Intr Registers\n");
299
300 for (i = CDNS_MCP_STAT; i <= CDNS_MCP_FIFOSTAT; i += sizeof(u32))
301 ret += cdns_sprintf(cdns, buf, ret, i);
302
303 ret += scnprintf(buf + ret, RD_BUF - ret,
304 "\nSSP & Clk ctrl Registers\n");
305 ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL0);
306 ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL1);
307 ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL0);
308 ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL1);
309
310 ret += scnprintf(buf + ret, RD_BUF - ret,
311 "\nDPn B0 Registers\n");
312
313 num_ports = cdns->num_ports;
314
315 for (i = 0; i < num_ports; i++) {
316 ret += scnprintf(buf + ret, RD_BUF - ret,
317 "\nDP-%d\n", i);
318 for (j = CDNS_DPN_B0_CONFIG(i);
319 j < CDNS_DPN_B0_ASYNC_CTRL(i); j += sizeof(u32))
320 ret += cdns_sprintf(cdns, buf, ret, j);
321 }
322
323 ret += scnprintf(buf + ret, RD_BUF - ret,
324 "\nDPn B1 Registers\n");
325 for (i = 0; i < num_ports; i++) {
326 ret += scnprintf(buf + ret, RD_BUF - ret,
327 "\nDP-%d\n", i);
328
329 for (j = CDNS_DPN_B1_CONFIG(i);
330 j < CDNS_DPN_B1_ASYNC_CTRL(i); j += sizeof(u32))
331 ret += cdns_sprintf(cdns, buf, ret, j);
332 }
333
334 ret += scnprintf(buf + ret, RD_BUF - ret,
335 "\nDPn Control Registers\n");
336 for (i = 0; i < num_ports; i++)
337 ret += cdns_sprintf(cdns, buf, ret,
338 CDNS_PORTCTRL + i * CDNS_PORT_OFFSET);
339
340 ret += scnprintf(buf + ret, RD_BUF - ret,
341 "\nPDIn Config Registers\n");
342
343
344 for (i = 0; i < num_ports; i++)
345 ret += cdns_sprintf(cdns, buf, ret, CDNS_PDI_CONFIG(i));
346
347 seq_printf(s, "%s", buf);
348 kfree(buf);
349
350 return 0;
351}
352DEFINE_SHOW_ATTRIBUTE(cdns_reg);
353
354static int cdns_hw_reset(void *data, u64 value)
355{
356 struct sdw_cdns *cdns = data;
357 int ret;
358
359 if (value != 1)
360 return -EINVAL;
361
362
363 add_taint(TAINT_USER, LOCKDEP_STILL_OK);
364
365 ret = sdw_cdns_exit_reset(cdns);
366
367 dev_dbg(cdns->dev, "link hw_reset done: %d\n", ret);
368
369 return ret;
370}
371
372DEFINE_DEBUGFS_ATTRIBUTE(cdns_hw_reset_fops, NULL, cdns_hw_reset, "%llu\n");
373
374static int cdns_parity_error_injection(void *data, u64 value)
375{
376 struct sdw_cdns *cdns = data;
377 struct sdw_bus *bus;
378 int ret;
379
380 if (value != 1)
381 return -EINVAL;
382
383 bus = &cdns->bus;
384
385
386
387
388
389 ret = pm_runtime_get_sync(bus->dev);
390 if (ret < 0 && ret != -EACCES) {
391 dev_err_ratelimited(cdns->dev,
392 "pm_runtime_get_sync failed in %s, ret %d\n",
393 __func__, ret);
394 pm_runtime_put_noidle(bus->dev);
395 return ret;
396 }
397
398
399
400
401
402 msleep(200);
403
404
405
406
407
408 mutex_lock(&bus->bus_lock);
409
410
411 cdns_updatel(cdns, CDNS_MCP_CMDCTRL,
412 CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR,
413 CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR);
414
415
416 cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
417 CDNS_MCP_CONFIG_UPDATE_BIT,
418 CDNS_MCP_CONFIG_UPDATE_BIT);
419
420
421 ret = sdw_bread_no_pm_unlocked(&cdns->bus, 0xf, SDW_SCP_DEVID_0);
422 dev_info(cdns->dev, "parity error injection, read: %d\n", ret);
423
424
425 cdns_updatel(cdns, CDNS_MCP_CMDCTRL,
426 CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR,
427 0);
428
429
430 cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
431 CDNS_MCP_CONFIG_UPDATE_BIT,
432 CDNS_MCP_CONFIG_UPDATE_BIT);
433
434
435 mutex_unlock(&bus->bus_lock);
436
437
438 add_taint(TAINT_USER, LOCKDEP_STILL_OK);
439
440
441
442
443
444 pm_runtime_mark_last_busy(bus->dev);
445 pm_runtime_put_autosuspend(bus->dev);
446
447 return 0;
448}
449
450DEFINE_DEBUGFS_ATTRIBUTE(cdns_parity_error_fops, NULL,
451 cdns_parity_error_injection, "%llu\n");
452
453
454
455
456
457
458void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root)
459{
460 debugfs_create_file("cdns-registers", 0400, root, cdns, &cdns_reg_fops);
461
462 debugfs_create_file("cdns-hw-reset", 0200, root, cdns,
463 &cdns_hw_reset_fops);
464
465 debugfs_create_file("cdns-parity-error-injection", 0200, root, cdns,
466 &cdns_parity_error_fops);
467}
468EXPORT_SYMBOL_GPL(sdw_cdns_debugfs_init);
469
470#endif
471
472
473
474
475static enum sdw_command_response
476cdns_fill_msg_resp(struct sdw_cdns *cdns,
477 struct sdw_msg *msg, int count, int offset)
478{
479 int nack = 0, no_ack = 0;
480 int i;
481
482
483 for (i = 0; i < count; i++) {
484 if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
485 no_ack = 1;
486 dev_vdbg(cdns->dev, "Msg Ack not received, cmd %d\n", i);
487 }
488 if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
489 nack = 1;
490 dev_err_ratelimited(cdns->dev, "Msg NACK received, cmd %d\n", i);
491 }
492 }
493
494 if (nack) {
495 dev_err_ratelimited(cdns->dev, "Msg NACKed for Slave %d\n", msg->dev_num);
496 return SDW_CMD_FAIL;
497 }
498
499 if (no_ack) {
500 dev_dbg_ratelimited(cdns->dev, "Msg ignored for Slave %d\n", msg->dev_num);
501 return SDW_CMD_IGNORED;
502 }
503
504
505 for (i = 0; i < count; i++)
506 msg->buf[i + offset] = FIELD_GET(CDNS_MCP_RESP_RDATA, cdns->response_buf[i]);
507
508 return SDW_CMD_OK;
509}
510
511static enum sdw_command_response
512_cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
513 int offset, int count, bool defer)
514{
515 unsigned long time;
516 u32 base, i, data;
517 u16 addr;
518
519
520 if (cdns->msg_count != count) {
521 cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, count);
522 cdns->msg_count = count;
523 }
524
525 base = CDNS_MCP_CMD_BASE;
526 addr = msg->addr;
527
528 for (i = 0; i < count; i++) {
529 data = FIELD_PREP(CDNS_MCP_CMD_DEV_ADDR, msg->dev_num);
530 data |= FIELD_PREP(CDNS_MCP_CMD_COMMAND, cmd);
531 data |= FIELD_PREP(CDNS_MCP_CMD_REG_ADDR, addr);
532 addr++;
533
534 if (msg->flags == SDW_MSG_FLAG_WRITE)
535 data |= msg->buf[i + offset];
536
537 data |= FIELD_PREP(CDNS_MCP_CMD_SSP_TAG, msg->ssp_sync);
538 cdns_writel(cdns, base, data);
539 base += CDNS_MCP_CMD_WORD_LEN;
540 }
541
542 if (defer)
543 return SDW_CMD_OK;
544
545
546 time = wait_for_completion_timeout(&cdns->tx_complete,
547 msecs_to_jiffies(CDNS_TX_TIMEOUT));
548 if (!time) {
549 dev_err(cdns->dev, "IO transfer timed out, cmd %d device %d addr %x len %d\n",
550 cmd, msg->dev_num, msg->addr, msg->len);
551 msg->len = 0;
552 return SDW_CMD_TIMEOUT;
553 }
554
555 return cdns_fill_msg_resp(cdns, msg, count, offset);
556}
557
558static enum sdw_command_response
559cdns_program_scp_addr(struct sdw_cdns *cdns, struct sdw_msg *msg)
560{
561 int nack = 0, no_ack = 0;
562 unsigned long time;
563 u32 data[2], base;
564 int i;
565
566
567 if (cdns->msg_count != CDNS_SCP_RX_FIFOLEVEL) {
568 cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, CDNS_SCP_RX_FIFOLEVEL);
569 cdns->msg_count = CDNS_SCP_RX_FIFOLEVEL;
570 }
571
572 data[0] = FIELD_PREP(CDNS_MCP_CMD_DEV_ADDR, msg->dev_num);
573 data[0] |= FIELD_PREP(CDNS_MCP_CMD_COMMAND, 0x3);
574 data[1] = data[0];
575
576 data[0] |= FIELD_PREP(CDNS_MCP_CMD_REG_ADDR, SDW_SCP_ADDRPAGE1);
577 data[1] |= FIELD_PREP(CDNS_MCP_CMD_REG_ADDR, SDW_SCP_ADDRPAGE2);
578
579 data[0] |= msg->addr_page1;
580 data[1] |= msg->addr_page2;
581
582 base = CDNS_MCP_CMD_BASE;
583 cdns_writel(cdns, base, data[0]);
584 base += CDNS_MCP_CMD_WORD_LEN;
585 cdns_writel(cdns, base, data[1]);
586
587 time = wait_for_completion_timeout(&cdns->tx_complete,
588 msecs_to_jiffies(CDNS_TX_TIMEOUT));
589 if (!time) {
590 dev_err(cdns->dev, "SCP Msg trf timed out\n");
591 msg->len = 0;
592 return SDW_CMD_TIMEOUT;
593 }
594
595
596 for (i = 0; i < 2; i++) {
597 if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
598 no_ack = 1;
599 dev_err(cdns->dev, "Program SCP Ack not received\n");
600 if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
601 nack = 1;
602 dev_err(cdns->dev, "Program SCP NACK received\n");
603 }
604 }
605 }
606
607
608 if (nack) {
609 dev_err_ratelimited(cdns->dev,
610 "SCP_addrpage NACKed for Slave %d\n", msg->dev_num);
611 return SDW_CMD_FAIL;
612 }
613
614 if (no_ack) {
615 dev_dbg_ratelimited(cdns->dev,
616 "SCP_addrpage ignored for Slave %d\n", msg->dev_num);
617 return SDW_CMD_IGNORED;
618 }
619
620 return SDW_CMD_OK;
621}
622
623static int cdns_prep_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int *cmd)
624{
625 int ret;
626
627 if (msg->page) {
628 ret = cdns_program_scp_addr(cdns, msg);
629 if (ret) {
630 msg->len = 0;
631 return ret;
632 }
633 }
634
635 switch (msg->flags) {
636 case SDW_MSG_FLAG_READ:
637 *cmd = CDNS_MCP_CMD_READ;
638 break;
639
640 case SDW_MSG_FLAG_WRITE:
641 *cmd = CDNS_MCP_CMD_WRITE;
642 break;
643
644 default:
645 dev_err(cdns->dev, "Invalid msg cmd: %d\n", msg->flags);
646 return -EINVAL;
647 }
648
649 return 0;
650}
651
652enum sdw_command_response
653cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg)
654{
655 struct sdw_cdns *cdns = bus_to_cdns(bus);
656 int cmd = 0, ret, i;
657
658 ret = cdns_prep_msg(cdns, msg, &cmd);
659 if (ret)
660 return SDW_CMD_FAIL_OTHER;
661
662 for (i = 0; i < msg->len / CDNS_MCP_CMD_LEN; i++) {
663 ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
664 CDNS_MCP_CMD_LEN, false);
665 if (ret < 0)
666 goto exit;
667 }
668
669 if (!(msg->len % CDNS_MCP_CMD_LEN))
670 goto exit;
671
672 ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
673 msg->len % CDNS_MCP_CMD_LEN, false);
674
675exit:
676 return ret;
677}
678EXPORT_SYMBOL(cdns_xfer_msg);
679
680enum sdw_command_response
681cdns_xfer_msg_defer(struct sdw_bus *bus,
682 struct sdw_msg *msg, struct sdw_defer *defer)
683{
684 struct sdw_cdns *cdns = bus_to_cdns(bus);
685 int cmd = 0, ret;
686
687
688 if (msg->len > 1)
689 return -ENOTSUPP;
690
691 ret = cdns_prep_msg(cdns, msg, &cmd);
692 if (ret)
693 return SDW_CMD_FAIL_OTHER;
694
695 cdns->defer = defer;
696 cdns->defer->length = msg->len;
697
698 return _cdns_xfer_msg(cdns, msg, cmd, 0, msg->len, true);
699}
700EXPORT_SYMBOL(cdns_xfer_msg_defer);
701
702enum sdw_command_response
703cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num)
704{
705 struct sdw_cdns *cdns = bus_to_cdns(bus);
706 struct sdw_msg msg;
707
708
709 memset(&msg, 0, sizeof(msg));
710 msg.dev_num = dev_num;
711
712 return cdns_program_scp_addr(cdns, &msg);
713}
714EXPORT_SYMBOL(cdns_reset_page_addr);
715
716
717
718
719
720static void cdns_read_response(struct sdw_cdns *cdns)
721{
722 u32 num_resp, cmd_base;
723 int i;
724
725 num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
726 num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
727
728 cmd_base = CDNS_MCP_CMD_BASE;
729
730 for (i = 0; i < num_resp; i++) {
731 cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
732 cmd_base += CDNS_MCP_CMD_WORD_LEN;
733 }
734}
735
736static int cdns_update_slave_status(struct sdw_cdns *cdns,
737 u64 slave_intstat)
738{
739 enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
740 bool is_slave = false;
741 u32 mask;
742 int i, set_status;
743
744 memset(status, 0, sizeof(status));
745
746 for (i = 0; i <= SDW_MAX_DEVICES; i++) {
747 mask = (slave_intstat >> (i * CDNS_MCP_SLAVE_STATUS_NUM)) &
748 CDNS_MCP_SLAVE_STATUS_BITS;
749 if (!mask)
750 continue;
751
752 is_slave = true;
753 set_status = 0;
754
755 if (mask & CDNS_MCP_SLAVE_INTSTAT_RESERVED) {
756 status[i] = SDW_SLAVE_RESERVED;
757 set_status++;
758 }
759
760 if (mask & CDNS_MCP_SLAVE_INTSTAT_ATTACHED) {
761 status[i] = SDW_SLAVE_ATTACHED;
762 set_status++;
763 }
764
765 if (mask & CDNS_MCP_SLAVE_INTSTAT_ALERT) {
766 status[i] = SDW_SLAVE_ALERT;
767 set_status++;
768 }
769
770 if (mask & CDNS_MCP_SLAVE_INTSTAT_NPRESENT) {
771 status[i] = SDW_SLAVE_UNATTACHED;
772 set_status++;
773 }
774
775
776 if (set_status > 1) {
777 u32 val;
778
779 dev_warn_ratelimited(cdns->dev,
780 "Slave %d reported multiple Status: %d\n",
781 i, mask);
782
783
784 val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
785 val >>= (i * 2);
786
787 switch (val & 0x3) {
788 case 0:
789 status[i] = SDW_SLAVE_UNATTACHED;
790 break;
791 case 1:
792 status[i] = SDW_SLAVE_ATTACHED;
793 break;
794 case 2:
795 status[i] = SDW_SLAVE_ALERT;
796 break;
797 case 3:
798 default:
799 status[i] = SDW_SLAVE_RESERVED;
800 break;
801 }
802
803 dev_warn_ratelimited(cdns->dev,
804 "Slave %d status updated to %d\n",
805 i, status[i]);
806
807 }
808 }
809
810 if (is_slave)
811 return sdw_handle_slave_status(&cdns->bus, status);
812
813 return 0;
814}
815
816
817
818
819
820
821irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
822{
823 struct sdw_cdns *cdns = dev_id;
824 u32 int_status;
825 int ret = IRQ_HANDLED;
826
827
828 if (!cdns->link_up)
829 return IRQ_NONE;
830
831 int_status = cdns_readl(cdns, CDNS_MCP_INTSTAT);
832
833
834 if (int_status & CDNS_MCP_INT_RESERVED)
835 return IRQ_NONE;
836
837 if (!(int_status & CDNS_MCP_INT_IRQ))
838 return IRQ_NONE;
839
840 if (int_status & CDNS_MCP_INT_RX_WL) {
841 cdns_read_response(cdns);
842
843 if (cdns->defer) {
844 cdns_fill_msg_resp(cdns, cdns->defer->msg,
845 cdns->defer->length, 0);
846 complete(&cdns->defer->complete);
847 cdns->defer = NULL;
848 } else {
849 complete(&cdns->tx_complete);
850 }
851 }
852
853 if (int_status & CDNS_MCP_INT_PARITY) {
854
855 dev_err_ratelimited(cdns->dev, "Parity error\n");
856 }
857
858 if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
859
860 dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
861 }
862
863 if (int_status & CDNS_MCP_INT_DATA_CLASH) {
864
865
866
867
868 dev_err_ratelimited(cdns->dev, "Bus clash for data word\n");
869 }
870
871 if (cdns->bus.params.m_data_mode != SDW_PORT_DATA_MODE_NORMAL &&
872 int_status & CDNS_MCP_INT_DPINT) {
873 u32 port_intstat;
874
875
876 port_intstat = cdns_readl(cdns, CDNS_MCP_PORT_INTSTAT);
877 dev_err_ratelimited(cdns->dev, "DP interrupt: PortIntStat %8x\n",
878 port_intstat);
879
880
881 cdns_writel(cdns, CDNS_MCP_PORT_INTSTAT, port_intstat);
882 }
883
884 if (int_status & CDNS_MCP_INT_SLAVE_MASK) {
885
886 cdns_updatel(cdns, CDNS_MCP_INTMASK,
887 CDNS_MCP_INT_SLAVE_MASK, 0);
888
889 int_status &= ~CDNS_MCP_INT_SLAVE_MASK;
890
891
892
893
894
895
896
897
898 if (cdns->interrupt_enabled)
899 schedule_work(&cdns->work);
900 }
901
902 cdns_writel(cdns, CDNS_MCP_INTSTAT, int_status);
903 return ret;
904}
905EXPORT_SYMBOL(sdw_cdns_irq);
906
907
908
909
910
911
912
913static void cdns_update_slave_status_work(struct work_struct *work)
914{
915 struct sdw_cdns *cdns =
916 container_of(work, struct sdw_cdns, work);
917 u32 slave0, slave1;
918 u64 slave_intstat;
919
920 slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
921 slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
922
923
924 slave_intstat = ((u64)slave1 << 32) | slave0;
925
926 dev_dbg_ratelimited(cdns->dev, "Slave status change: 0x%llx\n", slave_intstat);
927
928 cdns_update_slave_status(cdns, slave_intstat);
929 cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0);
930 cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1);
931
932
933 cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK);
934 cdns_updatel(cdns, CDNS_MCP_INTMASK,
935 CDNS_MCP_INT_SLAVE_MASK, CDNS_MCP_INT_SLAVE_MASK);
936
937}
938
939
940
941
942
943
944
945
946
947int sdw_cdns_exit_reset(struct sdw_cdns *cdns)
948{
949
950 cdns_updatel(cdns, CDNS_MCP_CONTROL,
951 CDNS_MCP_CONTROL_RST_DELAY,
952 CDNS_MCP_CONTROL_RST_DELAY);
953
954
955 cdns_updatel(cdns, CDNS_MCP_CONTROL,
956 CDNS_MCP_CONTROL_HW_RST,
957 CDNS_MCP_CONTROL_HW_RST);
958
959
960 cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
961 CDNS_MCP_CONFIG_UPDATE_BIT,
962 CDNS_MCP_CONFIG_UPDATE_BIT);
963
964
965 return 0;
966
967}
968EXPORT_SYMBOL(sdw_cdns_exit_reset);
969
970
971
972
973
974
975static void cdns_enable_slave_interrupts(struct sdw_cdns *cdns, bool state)
976{
977 u32 mask;
978
979 mask = cdns_readl(cdns, CDNS_MCP_INTMASK);
980 if (state)
981 mask |= CDNS_MCP_INT_SLAVE_MASK;
982 else
983 mask &= ~CDNS_MCP_INT_SLAVE_MASK;
984
985 cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
986}
987
988
989
990
991
992
993int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state)
994{
995 u32 slave_intmask0 = 0;
996 u32 slave_intmask1 = 0;
997 u32 mask = 0;
998
999 if (!state)
1000 goto update_masks;
1001
1002 slave_intmask0 = CDNS_MCP_SLAVE_INTMASK0_MASK;
1003 slave_intmask1 = CDNS_MCP_SLAVE_INTMASK1_MASK;
1004
1005
1006 mask = CDNS_MCP_INT_SLAVE_MASK;
1007
1008
1009 mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
1010 CDNS_MCP_INT_PARITY;
1011
1012
1013 if (cdns->bus.params.m_data_mode != SDW_PORT_DATA_MODE_NORMAL)
1014 mask |= CDNS_MCP_INT_DPINT;
1015
1016
1017 mask |= CDNS_MCP_INT_RX_WL;
1018
1019
1020
1021
1022
1023 mask |= CDNS_MCP_INT_IRQ;
1024
1025 if (interrupt_mask)
1026 mask = interrupt_mask;
1027
1028update_masks:
1029
1030 if (state) {
1031 u32 slave_state;
1032
1033 slave_state = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
1034 cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave_state);
1035 slave_state = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
1036 cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave_state);
1037 }
1038 cdns->interrupt_enabled = state;
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 if (!state)
1050 cancel_work_sync(&cdns->work);
1051
1052 cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0, slave_intmask0);
1053 cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1, slave_intmask1);
1054 cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
1055
1056 return 0;
1057}
1058EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
1059
1060static int cdns_allocate_pdi(struct sdw_cdns *cdns,
1061 struct sdw_cdns_pdi **stream,
1062 u32 num, u32 pdi_offset)
1063{
1064 struct sdw_cdns_pdi *pdi;
1065 int i;
1066
1067 if (!num)
1068 return 0;
1069
1070 pdi = devm_kcalloc(cdns->dev, num, sizeof(*pdi), GFP_KERNEL);
1071 if (!pdi)
1072 return -ENOMEM;
1073
1074 for (i = 0; i < num; i++) {
1075 pdi[i].num = i + pdi_offset;
1076 }
1077
1078 *stream = pdi;
1079 return 0;
1080}
1081
1082
1083
1084
1085
1086
1087
1088int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
1089 struct sdw_cdns_stream_config config)
1090{
1091 struct sdw_cdns_streams *stream;
1092 int offset;
1093 int ret;
1094
1095 cdns->pcm.num_bd = config.pcm_bd;
1096 cdns->pcm.num_in = config.pcm_in;
1097 cdns->pcm.num_out = config.pcm_out;
1098 cdns->pdm.num_bd = config.pdm_bd;
1099 cdns->pdm.num_in = config.pdm_in;
1100 cdns->pdm.num_out = config.pdm_out;
1101
1102
1103 stream = &cdns->pcm;
1104
1105
1106 offset = 0;
1107
1108 ret = cdns_allocate_pdi(cdns, &stream->bd,
1109 stream->num_bd, offset);
1110 if (ret)
1111 return ret;
1112
1113 offset += stream->num_bd;
1114
1115 ret = cdns_allocate_pdi(cdns, &stream->in,
1116 stream->num_in, offset);
1117 if (ret)
1118 return ret;
1119
1120 offset += stream->num_in;
1121
1122 ret = cdns_allocate_pdi(cdns, &stream->out,
1123 stream->num_out, offset);
1124 if (ret)
1125 return ret;
1126
1127
1128 stream->num_pdi = stream->num_bd + stream->num_in + stream->num_out;
1129 cdns->num_ports = stream->num_pdi;
1130
1131
1132 stream = &cdns->pdm;
1133 ret = cdns_allocate_pdi(cdns, &stream->bd,
1134 stream->num_bd, offset);
1135 if (ret)
1136 return ret;
1137
1138 offset += stream->num_bd;
1139
1140 ret = cdns_allocate_pdi(cdns, &stream->in,
1141 stream->num_in, offset);
1142 if (ret)
1143 return ret;
1144
1145 offset += stream->num_in;
1146
1147 ret = cdns_allocate_pdi(cdns, &stream->out,
1148 stream->num_out, offset);
1149
1150 if (ret)
1151 return ret;
1152
1153
1154 stream->num_pdi = stream->num_bd + stream->num_in + stream->num_out;
1155 cdns->num_ports += stream->num_pdi;
1156
1157 return 0;
1158}
1159EXPORT_SYMBOL(sdw_cdns_pdi_init);
1160
1161static u32 cdns_set_initial_frame_shape(int n_rows, int n_cols)
1162{
1163 u32 val;
1164 int c;
1165 int r;
1166
1167 r = sdw_find_row_index(n_rows);
1168 c = sdw_find_col_index(n_cols);
1169
1170 val = FIELD_PREP(CDNS_MCP_FRAME_SHAPE_ROW_MASK, r);
1171 val |= FIELD_PREP(CDNS_MCP_FRAME_SHAPE_COL_MASK, c);
1172
1173 return val;
1174}
1175
1176static void cdns_init_clock_ctrl(struct sdw_cdns *cdns)
1177{
1178 struct sdw_bus *bus = &cdns->bus;
1179 struct sdw_master_prop *prop = &bus->prop;
1180 u32 val;
1181 u32 ssp_interval;
1182 int divider;
1183
1184
1185 divider = (prop->mclk_freq / prop->max_clk_freq) - 1;
1186
1187 cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0,
1188 CDNS_MCP_CLK_MCLKD_MASK, divider);
1189 cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1,
1190 CDNS_MCP_CLK_MCLKD_MASK, divider);
1191
1192
1193
1194
1195
1196 val = cdns_set_initial_frame_shape(prop->default_row,
1197 prop->default_col);
1198 cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, val);
1199
1200
1201 ssp_interval = prop->default_frame_rate / SDW_CADENCE_GSYNC_HZ;
1202 cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, ssp_interval);
1203 cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, ssp_interval);
1204}
1205
1206
1207
1208
1209
1210int sdw_cdns_init(struct sdw_cdns *cdns)
1211{
1212 u32 val;
1213
1214 cdns_init_clock_ctrl(cdns);
1215
1216
1217 cdns->msg_count = cdns_readl(cdns, CDNS_MCP_FIFOLEVEL);
1218
1219
1220 cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_RST,
1221 CDNS_MCP_CONTROL_CMD_RST);
1222
1223
1224 cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
1225 CDNS_MCP_CONTROL_CMD_ACCEPT);
1226
1227
1228 val = cdns_readl(cdns, CDNS_MCP_CONFIG);
1229
1230
1231 val &= ~CDNS_MCP_CONFIG_OP;
1232 val |= CDNS_MCP_CONFIG_OP_NORMAL;
1233
1234
1235 val &= ~CDNS_MCP_CONFIG_CMD;
1236
1237
1238 val &= ~CDNS_MCP_CONFIG_SNIFFER;
1239
1240
1241 val &= ~CDNS_MCP_CONFIG_BUS_REL;
1242
1243 if (cdns->bus.multi_link)
1244
1245 val |= CDNS_MCP_CONFIG_MMASTER;
1246
1247
1248
1249
1250
1251 cdns_writel(cdns, CDNS_MCP_CONFIG, val);
1252
1253
1254 return 0;
1255}
1256EXPORT_SYMBOL(sdw_cdns_init);
1257
1258int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
1259{
1260 struct sdw_master_prop *prop = &bus->prop;
1261 struct sdw_cdns *cdns = bus_to_cdns(bus);
1262 int mcp_clkctrl_off;
1263 int divider;
1264
1265 if (!params->curr_dr_freq) {
1266 dev_err(cdns->dev, "NULL curr_dr_freq\n");
1267 return -EINVAL;
1268 }
1269
1270 divider = prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR /
1271 params->curr_dr_freq;
1272 divider--;
1273
1274 if (params->next_bank)
1275 mcp_clkctrl_off = CDNS_MCP_CLK_CTRL1;
1276 else
1277 mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
1278
1279 cdns_updatel(cdns, mcp_clkctrl_off, CDNS_MCP_CLK_MCLKD_MASK, divider);
1280
1281 return 0;
1282}
1283EXPORT_SYMBOL(cdns_bus_conf);
1284
1285static int cdns_port_params(struct sdw_bus *bus,
1286 struct sdw_port_params *p_params, unsigned int bank)
1287{
1288 struct sdw_cdns *cdns = bus_to_cdns(bus);
1289 int dpn_config = 0, dpn_config_off;
1290
1291 if (bank)
1292 dpn_config_off = CDNS_DPN_B1_CONFIG(p_params->num);
1293 else
1294 dpn_config_off = CDNS_DPN_B0_CONFIG(p_params->num);
1295
1296 dpn_config = cdns_readl(cdns, dpn_config_off);
1297
1298 u32p_replace_bits(&dpn_config, (p_params->bps - 1), CDNS_DPN_CONFIG_WL);
1299 u32p_replace_bits(&dpn_config, p_params->flow_mode, CDNS_DPN_CONFIG_PORT_FLOW);
1300 u32p_replace_bits(&dpn_config, p_params->data_mode, CDNS_DPN_CONFIG_PORT_DAT);
1301
1302 cdns_writel(cdns, dpn_config_off, dpn_config);
1303
1304 return 0;
1305}
1306
1307static int cdns_transport_params(struct sdw_bus *bus,
1308 struct sdw_transport_params *t_params,
1309 enum sdw_reg_bank bank)
1310{
1311 struct sdw_cdns *cdns = bus_to_cdns(bus);
1312 int dpn_offsetctrl = 0, dpn_offsetctrl_off;
1313 int dpn_config = 0, dpn_config_off;
1314 int dpn_hctrl = 0, dpn_hctrl_off;
1315 int num = t_params->port_num;
1316 int dpn_samplectrl_off;
1317
1318
1319
1320
1321
1322
1323 if (bank) {
1324 dpn_config_off = CDNS_DPN_B1_CONFIG(num);
1325 dpn_samplectrl_off = CDNS_DPN_B1_SAMPLE_CTRL(num);
1326 dpn_hctrl_off = CDNS_DPN_B1_HCTRL(num);
1327 dpn_offsetctrl_off = CDNS_DPN_B1_OFFSET_CTRL(num);
1328 } else {
1329 dpn_config_off = CDNS_DPN_B0_CONFIG(num);
1330 dpn_samplectrl_off = CDNS_DPN_B0_SAMPLE_CTRL(num);
1331 dpn_hctrl_off = CDNS_DPN_B0_HCTRL(num);
1332 dpn_offsetctrl_off = CDNS_DPN_B0_OFFSET_CTRL(num);
1333 }
1334
1335 dpn_config = cdns_readl(cdns, dpn_config_off);
1336 u32p_replace_bits(&dpn_config, t_params->blk_grp_ctrl, CDNS_DPN_CONFIG_BGC);
1337 u32p_replace_bits(&dpn_config, t_params->blk_pkg_mode, CDNS_DPN_CONFIG_BPM);
1338 cdns_writel(cdns, dpn_config_off, dpn_config);
1339
1340 u32p_replace_bits(&dpn_offsetctrl, t_params->offset1, CDNS_DPN_OFFSET_CTRL_1);
1341 u32p_replace_bits(&dpn_offsetctrl, t_params->offset2, CDNS_DPN_OFFSET_CTRL_2);
1342 cdns_writel(cdns, dpn_offsetctrl_off, dpn_offsetctrl);
1343
1344 u32p_replace_bits(&dpn_hctrl, t_params->hstart, CDNS_DPN_HCTRL_HSTART);
1345 u32p_replace_bits(&dpn_hctrl, t_params->hstop, CDNS_DPN_HCTRL_HSTOP);
1346 u32p_replace_bits(&dpn_hctrl, t_params->lane_ctrl, CDNS_DPN_HCTRL_LCTRL);
1347
1348 cdns_writel(cdns, dpn_hctrl_off, dpn_hctrl);
1349 cdns_writel(cdns, dpn_samplectrl_off, (t_params->sample_interval - 1));
1350
1351 return 0;
1352}
1353
1354static int cdns_port_enable(struct sdw_bus *bus,
1355 struct sdw_enable_ch *enable_ch, unsigned int bank)
1356{
1357 struct sdw_cdns *cdns = bus_to_cdns(bus);
1358 int dpn_chnen_off, ch_mask;
1359
1360 if (bank)
1361 dpn_chnen_off = CDNS_DPN_B1_CH_EN(enable_ch->port_num);
1362 else
1363 dpn_chnen_off = CDNS_DPN_B0_CH_EN(enable_ch->port_num);
1364
1365 ch_mask = enable_ch->ch_mask * enable_ch->enable;
1366 cdns_writel(cdns, dpn_chnen_off, ch_mask);
1367
1368 return 0;
1369}
1370
1371static const struct sdw_master_port_ops cdns_port_ops = {
1372 .dpn_set_port_params = cdns_port_params,
1373 .dpn_set_port_transport_params = cdns_transport_params,
1374 .dpn_port_enable_ch = cdns_port_enable,
1375};
1376
1377
1378
1379
1380
1381
1382bool sdw_cdns_is_clock_stop(struct sdw_cdns *cdns)
1383{
1384 return !!(cdns_readl(cdns, CDNS_MCP_STAT) & CDNS_MCP_STAT_CLK_STOP);
1385}
1386EXPORT_SYMBOL(sdw_cdns_is_clock_stop);
1387
1388
1389
1390
1391
1392
1393
1394int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
1395{
1396 bool slave_present = false;
1397 struct sdw_slave *slave;
1398 int ret;
1399
1400
1401 if (sdw_cdns_is_clock_stop(cdns)) {
1402 dev_dbg(cdns->dev, "Clock is already stopped\n");
1403 return 0;
1404 }
1405
1406
1407
1408
1409
1410
1411 cdns_enable_slave_interrupts(cdns, false);
1412
1413
1414
1415
1416
1417
1418 if (block_wake)
1419 cdns_updatel(cdns, CDNS_MCP_CONTROL,
1420 CDNS_MCP_CONTROL_BLOCK_WAKEUP,
1421 CDNS_MCP_CONTROL_BLOCK_WAKEUP);
1422
1423 list_for_each_entry(slave, &cdns->bus.slaves, node) {
1424 if (slave->status == SDW_SLAVE_ATTACHED ||
1425 slave->status == SDW_SLAVE_ALERT) {
1426 slave_present = true;
1427 break;
1428 }
1429 }
1430
1431
1432 ret = cdns_config_update(cdns);
1433 if (ret < 0) {
1434 dev_err(cdns->dev, "%s: config_update failed\n", __func__);
1435 return ret;
1436 }
1437
1438
1439 if (slave_present) {
1440 ret = sdw_bus_prep_clk_stop(&cdns->bus);
1441 if (ret < 0 && ret != -ENODATA) {
1442 dev_err(cdns->dev, "prepare clock stop failed %d\n", ret);
1443 return ret;
1444 }
1445 }
1446
1447
1448
1449
1450
1451 ret = sdw_bus_clk_stop(&cdns->bus);
1452 if (ret < 0 && slave_present && ret != -ENODATA) {
1453 dev_err(cdns->dev, "bus clock stop failed %d\n", ret);
1454 return ret;
1455 }
1456
1457 ret = cdns_set_wait(cdns, CDNS_MCP_STAT,
1458 CDNS_MCP_STAT_CLK_STOP,
1459 CDNS_MCP_STAT_CLK_STOP);
1460 if (ret < 0)
1461 dev_err(cdns->dev, "Clock stop failed %d\n", ret);
1462
1463 return ret;
1464}
1465EXPORT_SYMBOL(sdw_cdns_clock_stop);
1466
1467
1468
1469
1470
1471
1472
1473
1474int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset)
1475{
1476 int ret;
1477
1478
1479 cdns_enable_slave_interrupts(cdns, true);
1480
1481 ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
1482 CDNS_MCP_CONTROL_CLK_STOP_CLR);
1483 if (ret < 0) {
1484 dev_err(cdns->dev, "Couldn't exit from clock stop\n");
1485 return ret;
1486 }
1487
1488 ret = cdns_set_wait(cdns, CDNS_MCP_STAT, CDNS_MCP_STAT_CLK_STOP, 0);
1489 if (ret < 0) {
1490 dev_err(cdns->dev, "clock stop exit failed %d\n", ret);
1491 return ret;
1492 }
1493
1494 cdns_updatel(cdns, CDNS_MCP_CONTROL,
1495 CDNS_MCP_CONTROL_BLOCK_WAKEUP, 0);
1496
1497 cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
1498 CDNS_MCP_CONTROL_CMD_ACCEPT);
1499
1500 if (!bus_reset) {
1501
1502
1503 cdns_updatel(cdns, CDNS_MCP_CONFIG,
1504 CDNS_MCP_CONFIG_OP,
1505 CDNS_MCP_CONFIG_OP_NORMAL);
1506
1507 ret = cdns_config_update(cdns);
1508 if (ret < 0) {
1509 dev_err(cdns->dev, "%s: config_update failed\n", __func__);
1510 return ret;
1511 }
1512
1513 ret = sdw_bus_exit_clk_stop(&cdns->bus);
1514 if (ret < 0)
1515 dev_err(cdns->dev, "bus failed to exit clock stop %d\n", ret);
1516 }
1517
1518 return ret;
1519}
1520EXPORT_SYMBOL(sdw_cdns_clock_restart);
1521
1522
1523
1524
1525
1526int sdw_cdns_probe(struct sdw_cdns *cdns)
1527{
1528 init_completion(&cdns->tx_complete);
1529 cdns->bus.port_ops = &cdns_port_ops;
1530
1531 INIT_WORK(&cdns->work, cdns_update_slave_status_work);
1532 return 0;
1533}
1534EXPORT_SYMBOL(sdw_cdns_probe);
1535
1536int cdns_set_sdw_stream(struct snd_soc_dai *dai,
1537 void *stream, bool pcm, int direction)
1538{
1539 struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
1540 struct sdw_cdns_dma_data *dma;
1541
1542 if (stream) {
1543
1544 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
1545 dma = dai->playback_dma_data;
1546 else
1547 dma = dai->capture_dma_data;
1548
1549 if (dma) {
1550 dev_err(dai->dev,
1551 "dma_data already allocated for dai %s\n",
1552 dai->name);
1553 return -EINVAL;
1554 }
1555
1556
1557 dma = kzalloc(sizeof(*dma), GFP_KERNEL);
1558 if (!dma)
1559 return -ENOMEM;
1560
1561 if (pcm)
1562 dma->stream_type = SDW_STREAM_PCM;
1563 else
1564 dma->stream_type = SDW_STREAM_PDM;
1565
1566 dma->bus = &cdns->bus;
1567 dma->link_id = cdns->instance;
1568
1569 dma->stream = stream;
1570
1571 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
1572 dai->playback_dma_data = dma;
1573 else
1574 dai->capture_dma_data = dma;
1575 } else {
1576
1577 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
1578 kfree(dai->playback_dma_data);
1579 dai->playback_dma_data = NULL;
1580 } else {
1581 kfree(dai->capture_dma_data);
1582 dai->capture_dma_data = NULL;
1583 }
1584 }
1585 return 0;
1586}
1587EXPORT_SYMBOL(cdns_set_sdw_stream);
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601static struct sdw_cdns_pdi *cdns_find_pdi(struct sdw_cdns *cdns,
1602 unsigned int offset,
1603 unsigned int num,
1604 struct sdw_cdns_pdi *pdi,
1605 int dai_id)
1606{
1607 int i;
1608
1609 for (i = offset; i < offset + num; i++)
1610 if (pdi[i].num == dai_id)
1611 return &pdi[i];
1612
1613 return NULL;
1614}
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624void sdw_cdns_config_stream(struct sdw_cdns *cdns,
1625 u32 ch, u32 dir, struct sdw_cdns_pdi *pdi)
1626{
1627 u32 offset, val = 0;
1628
1629 if (dir == SDW_DATA_DIR_RX) {
1630 val = CDNS_PORTCTRL_DIRN;
1631
1632 if (cdns->bus.params.m_data_mode != SDW_PORT_DATA_MODE_NORMAL)
1633 val |= CDNS_PORTCTRL_TEST_FAILED;
1634 }
1635 offset = CDNS_PORTCTRL + pdi->num * CDNS_PORT_OFFSET;
1636 cdns_updatel(cdns, offset,
1637 CDNS_PORTCTRL_DIRN | CDNS_PORTCTRL_TEST_FAILED,
1638 val);
1639
1640 val = pdi->num;
1641 val |= CDNS_PDI_CONFIG_SOFT_RESET;
1642 val |= FIELD_PREP(CDNS_PDI_CONFIG_CHANNEL, (1 << ch) - 1);
1643 cdns_writel(cdns, CDNS_PDI_CONFIG(pdi->num), val);
1644}
1645EXPORT_SYMBOL(sdw_cdns_config_stream);
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns,
1657 struct sdw_cdns_streams *stream,
1658 u32 ch, u32 dir, int dai_id)
1659{
1660 struct sdw_cdns_pdi *pdi = NULL;
1661
1662 if (dir == SDW_DATA_DIR_RX)
1663 pdi = cdns_find_pdi(cdns, 0, stream->num_in, stream->in,
1664 dai_id);
1665 else
1666 pdi = cdns_find_pdi(cdns, 0, stream->num_out, stream->out,
1667 dai_id);
1668
1669
1670 if (!pdi)
1671 pdi = cdns_find_pdi(cdns, 2, stream->num_bd, stream->bd,
1672 dai_id);
1673
1674 if (pdi) {
1675 pdi->l_ch_num = 0;
1676 pdi->h_ch_num = ch - 1;
1677 pdi->dir = dir;
1678 pdi->ch_count = ch;
1679 }
1680
1681 return pdi;
1682}
1683EXPORT_SYMBOL(sdw_cdns_alloc_pdi);
1684
1685MODULE_LICENSE("Dual BSD/GPL");
1686MODULE_DESCRIPTION("Cadence Soundwire Library");
1687