1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 // Copyright(c) 2015-17 Intel Corporation.
5 * Cadence SoundWire Master module
6 * Used by Master driver
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/interrupt.h>
12 #include <linux/module.h>
13 #include <linux/mod_devicetable.h>
14 #include <linux/soundwire/sdw_registers.h>
15 #include <linux/soundwire/sdw.h>
16 #include <sound/pcm_params.h>
17 #include <sound/soc.h>
19 #include "cadence_master.h"
21 #define CDNS_MCP_CONFIG 0x0
23 #define CDNS_MCP_CONFIG_MCMD_RETRY GENMASK(27, 24)
24 #define CDNS_MCP_CONFIG_MPREQ_DELAY GENMASK(20, 16)
25 #define CDNS_MCP_CONFIG_MMASTER BIT(7)
26 #define CDNS_MCP_CONFIG_BUS_REL BIT(6)
27 #define CDNS_MCP_CONFIG_SNIFFER BIT(5)
28 #define CDNS_MCP_CONFIG_SSPMOD BIT(4)
29 #define CDNS_MCP_CONFIG_CMD BIT(3)
30 #define CDNS_MCP_CONFIG_OP GENMASK(2, 0)
31 #define CDNS_MCP_CONFIG_OP_NORMAL 0
33 #define CDNS_MCP_CONTROL 0x4
35 #define CDNS_MCP_CONTROL_RST_DELAY GENMASK(10, 8)
36 #define CDNS_MCP_CONTROL_CMD_RST BIT(7)
37 #define CDNS_MCP_CONTROL_SOFT_RST BIT(6)
38 #define CDNS_MCP_CONTROL_SW_RST BIT(5)
39 #define CDNS_MCP_CONTROL_HW_RST BIT(4)
40 #define CDNS_MCP_CONTROL_CLK_PAUSE BIT(3)
41 #define CDNS_MCP_CONTROL_CLK_STOP_CLR BIT(2)
42 #define CDNS_MCP_CONTROL_CMD_ACCEPT BIT(1)
43 #define CDNS_MCP_CONTROL_BLOCK_WAKEUP BIT(0)
46 #define CDNS_MCP_CMDCTRL 0x8
47 #define CDNS_MCP_SSPSTAT 0xC
48 #define CDNS_MCP_FRAME_SHAPE 0x10
49 #define CDNS_MCP_FRAME_SHAPE_INIT 0x14
51 #define CDNS_MCP_CONFIG_UPDATE 0x18
52 #define CDNS_MCP_CONFIG_UPDATE_BIT BIT(0)
54 #define CDNS_MCP_PHYCTRL 0x1C
55 #define CDNS_MCP_SSP_CTRL0 0x20
56 #define CDNS_MCP_SSP_CTRL1 0x28
57 #define CDNS_MCP_CLK_CTRL0 0x30
58 #define CDNS_MCP_CLK_CTRL1 0x38
60 #define CDNS_MCP_STAT 0x40
62 #define CDNS_MCP_STAT_ACTIVE_BANK BIT(20)
63 #define CDNS_MCP_STAT_CLK_STOP BIT(16)
65 #define CDNS_MCP_INTSTAT 0x44
66 #define CDNS_MCP_INTMASK 0x48
68 #define CDNS_MCP_INT_IRQ BIT(31)
69 #define CDNS_MCP_INT_WAKEUP BIT(16)
70 #define CDNS_MCP_INT_SLAVE_RSVD BIT(15)
71 #define CDNS_MCP_INT_SLAVE_ALERT BIT(14)
72 #define CDNS_MCP_INT_SLAVE_ATTACH BIT(13)
73 #define CDNS_MCP_INT_SLAVE_NATTACH BIT(12)
74 #define CDNS_MCP_INT_SLAVE_MASK GENMASK(15, 12)
75 #define CDNS_MCP_INT_DPINT BIT(11)
76 #define CDNS_MCP_INT_CTRL_CLASH BIT(10)
77 #define CDNS_MCP_INT_DATA_CLASH BIT(9)
78 #define CDNS_MCP_INT_CMD_ERR BIT(7)
79 #define CDNS_MCP_INT_RX_WL BIT(2)
80 #define CDNS_MCP_INT_TXE BIT(1)
82 #define CDNS_MCP_INTSET 0x4C
84 #define CDNS_MCP_SLAVE_STAT 0x50
85 #define CDNS_MCP_SLAVE_STAT_MASK GENMASK(1, 0)
87 #define CDNS_MCP_SLAVE_INTSTAT0 0x54
88 #define CDNS_MCP_SLAVE_INTSTAT1 0x58
89 #define CDNS_MCP_SLAVE_INTSTAT_NPRESENT BIT(0)
90 #define CDNS_MCP_SLAVE_INTSTAT_ATTACHED BIT(1)
91 #define CDNS_MCP_SLAVE_INTSTAT_ALERT BIT(2)
92 #define CDNS_MCP_SLAVE_INTSTAT_RESERVED BIT(3)
93 #define CDNS_MCP_SLAVE_STATUS_BITS GENMASK(3, 0)
94 #define CDNS_MCP_SLAVE_STATUS_NUM 4
96 #define CDNS_MCP_SLAVE_INTMASK0 0x5C
97 #define CDNS_MCP_SLAVE_INTMASK1 0x60
99 #define CDNS_MCP_SLAVE_INTMASK0_MASK GENMASK(31, 0)
100 #define CDNS_MCP_SLAVE_INTMASK1_MASK GENMASK(15, 0)
102 #define CDNS_MCP_PORT_INTSTAT 0x64
103 #define CDNS_MCP_PDI_STAT 0x6C
105 #define CDNS_MCP_FIFOLEVEL 0x78
106 #define CDNS_MCP_FIFOSTAT 0x7C
107 #define CDNS_MCP_RX_FIFO_AVAIL GENMASK(5, 0)
109 #define CDNS_MCP_CMD_BASE 0x80
110 #define CDNS_MCP_RESP_BASE 0x80
111 #define CDNS_MCP_CMD_LEN 0x20
112 #define CDNS_MCP_CMD_WORD_LEN 0x4
114 #define CDNS_MCP_CMD_SSP_TAG BIT(31)
115 #define CDNS_MCP_CMD_COMMAND GENMASK(30, 28)
116 #define CDNS_MCP_CMD_DEV_ADDR GENMASK(27, 24)
117 #define CDNS_MCP_CMD_REG_ADDR_H GENMASK(23, 16)
118 #define CDNS_MCP_CMD_REG_ADDR_L GENMASK(15, 8)
119 #define CDNS_MCP_CMD_REG_DATA GENMASK(7, 0)
121 #define CDNS_MCP_CMD_READ 2
122 #define CDNS_MCP_CMD_WRITE 3
124 #define CDNS_MCP_RESP_RDATA GENMASK(15, 8)
125 #define CDNS_MCP_RESP_ACK BIT(0)
126 #define CDNS_MCP_RESP_NACK BIT(1)
128 #define CDNS_DP_SIZE 128
130 #define CDNS_DPN_B0_CONFIG(n) (0x100 + CDNS_DP_SIZE * (n))
131 #define CDNS_DPN_B0_CH_EN(n) (0x104 + CDNS_DP_SIZE * (n))
132 #define CDNS_DPN_B0_SAMPLE_CTRL(n) (0x108 + CDNS_DP_SIZE * (n))
133 #define CDNS_DPN_B0_OFFSET_CTRL(n) (0x10C + CDNS_DP_SIZE * (n))
134 #define CDNS_DPN_B0_HCTRL(n) (0x110 + CDNS_DP_SIZE * (n))
135 #define CDNS_DPN_B0_ASYNC_CTRL(n) (0x114 + CDNS_DP_SIZE * (n))
137 #define CDNS_DPN_B1_CONFIG(n) (0x118 + CDNS_DP_SIZE * (n))
138 #define CDNS_DPN_B1_CH_EN(n) (0x11C + CDNS_DP_SIZE * (n))
139 #define CDNS_DPN_B1_SAMPLE_CTRL(n) (0x120 + CDNS_DP_SIZE * (n))
140 #define CDNS_DPN_B1_OFFSET_CTRL(n) (0x124 + CDNS_DP_SIZE * (n))
141 #define CDNS_DPN_B1_HCTRL(n) (0x128 + CDNS_DP_SIZE * (n))
142 #define CDNS_DPN_B1_ASYNC_CTRL(n) (0x12C + CDNS_DP_SIZE * (n))
144 #define CDNS_DPN_CONFIG_BPM BIT(18)
145 #define CDNS_DPN_CONFIG_BGC GENMASK(17, 16)
146 #define CDNS_DPN_CONFIG_WL GENMASK(12, 8)
147 #define CDNS_DPN_CONFIG_PORT_DAT GENMASK(3, 2)
148 #define CDNS_DPN_CONFIG_PORT_FLOW GENMASK(1, 0)
150 #define CDNS_DPN_SAMPLE_CTRL_SI GENMASK(15, 0)
152 #define CDNS_DPN_OFFSET_CTRL_1 GENMASK(7, 0)
153 #define CDNS_DPN_OFFSET_CTRL_2 GENMASK(15, 8)
155 #define CDNS_DPN_HCTRL_HSTOP GENMASK(3, 0)
156 #define CDNS_DPN_HCTRL_HSTART GENMASK(7, 4)
157 #define CDNS_DPN_HCTRL_LCTRL GENMASK(10, 8)
159 #define CDNS_PORTCTRL 0x130
160 #define CDNS_PORTCTRL_DIRN BIT(7)
161 #define CDNS_PORTCTRL_BANK_INVERT BIT(8)
163 #define CDNS_PORT_OFFSET 0x80
165 #define CDNS_PDI_CONFIG(n) (0x1100 + (n) * 16)
167 #define CDNS_PDI_CONFIG_SOFT_RESET BIT(24)
168 #define CDNS_PDI_CONFIG_CHANNEL GENMASK(15, 8)
169 #define CDNS_PDI_CONFIG_PORT GENMASK(4, 0)
171 /* Driver defaults */
173 #define CDNS_DEFAULT_CLK_DIVIDER 0
174 #define CDNS_DEFAULT_FRAME_SHAPE 0x30
175 #define CDNS_DEFAULT_SSP_INTERVAL 0x18
176 #define CDNS_TX_TIMEOUT 2000
178 #define CDNS_PCM_PDI_OFFSET 0x2
179 #define CDNS_PDM_PDI_OFFSET 0x6
181 #define CDNS_SCP_RX_FIFOLEVEL 0x2
184 * register accessor helpers
186 static inline u32
cdns_readl(struct sdw_cdns
*cdns
, int offset
)
188 return readl(cdns
->registers
+ offset
);
191 static inline void cdns_writel(struct sdw_cdns
*cdns
, int offset
, u32 value
)
193 writel(value
, cdns
->registers
+ offset
);
196 static inline void cdns_updatel(struct sdw_cdns
*cdns
,
197 int offset
, u32 mask
, u32 val
)
201 tmp
= cdns_readl(cdns
, offset
);
202 tmp
= (tmp
& ~mask
) | val
;
203 cdns_writel(cdns
, offset
, tmp
);
206 static int cdns_clear_bit(struct sdw_cdns
*cdns
, int offset
, u32 value
)
211 writel(value
, cdns
->registers
+ offset
);
213 /* Wait for bit to be self cleared */
215 reg_read
= readl(cdns
->registers
+ offset
);
216 if ((reg_read
& value
) == 0)
221 } while (timeout
!= 0);
229 static enum sdw_command_response
cdns_fill_msg_resp(
230 struct sdw_cdns
*cdns
,
231 struct sdw_msg
*msg
, int count
, int offset
)
233 int nack
= 0, no_ack
= 0;
236 /* check message response */
237 for (i
= 0; i
< count
; i
++) {
238 if (!(cdns
->response_buf
[i
] & CDNS_MCP_RESP_ACK
)) {
240 dev_dbg(cdns
->dev
, "Msg Ack not received\n");
241 if (cdns
->response_buf
[i
] & CDNS_MCP_RESP_NACK
) {
243 dev_err(cdns
->dev
, "Msg NACK received\n");
249 dev_err(cdns
->dev
, "Msg NACKed for Slave %d\n", msg
->dev_num
);
252 dev_dbg(cdns
->dev
, "Msg ignored for Slave %d\n", msg
->dev_num
);
253 return SDW_CMD_IGNORED
;
257 for (i
= 0; i
< count
; i
++)
258 msg
->buf
[i
+ offset
] = cdns
->response_buf
[i
] >>
259 SDW_REG_SHIFT(CDNS_MCP_RESP_RDATA
);
264 static enum sdw_command_response
265 _cdns_xfer_msg(struct sdw_cdns
*cdns
, struct sdw_msg
*msg
, int cmd
,
266 int offset
, int count
, bool defer
)
272 /* Program the watermark level for RX FIFO */
273 if (cdns
->msg_count
!= count
) {
274 cdns_writel(cdns
, CDNS_MCP_FIFOLEVEL
, count
);
275 cdns
->msg_count
= count
;
278 base
= CDNS_MCP_CMD_BASE
;
281 for (i
= 0; i
< count
; i
++) {
282 data
= msg
->dev_num
<< SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR
);
283 data
|= cmd
<< SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND
);
284 data
|= addr
++ << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L
);
286 if (msg
->flags
== SDW_MSG_FLAG_WRITE
)
287 data
|= msg
->buf
[i
+ offset
];
289 data
|= msg
->ssp_sync
<< SDW_REG_SHIFT(CDNS_MCP_CMD_SSP_TAG
);
290 cdns_writel(cdns
, base
, data
);
291 base
+= CDNS_MCP_CMD_WORD_LEN
;
297 /* wait for timeout or response */
298 time
= wait_for_completion_timeout(&cdns
->tx_complete
,
299 msecs_to_jiffies(CDNS_TX_TIMEOUT
));
301 dev_err(cdns
->dev
, "IO transfer timed out\n");
303 return SDW_CMD_TIMEOUT
;
306 return cdns_fill_msg_resp(cdns
, msg
, count
, offset
);
309 static enum sdw_command_response
cdns_program_scp_addr(
310 struct sdw_cdns
*cdns
, struct sdw_msg
*msg
)
312 int nack
= 0, no_ack
= 0;
317 /* Program the watermark level for RX FIFO */
318 if (cdns
->msg_count
!= CDNS_SCP_RX_FIFOLEVEL
) {
319 cdns_writel(cdns
, CDNS_MCP_FIFOLEVEL
, CDNS_SCP_RX_FIFOLEVEL
);
320 cdns
->msg_count
= CDNS_SCP_RX_FIFOLEVEL
;
323 data
[0] = msg
->dev_num
<< SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR
);
324 data
[0] |= 0x3 << SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND
);
327 data
[0] |= SDW_SCP_ADDRPAGE1
<< SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L
);
328 data
[1] |= SDW_SCP_ADDRPAGE2
<< SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L
);
330 data
[0] |= msg
->addr_page1
;
331 data
[1] |= msg
->addr_page2
;
333 base
= CDNS_MCP_CMD_BASE
;
334 cdns_writel(cdns
, base
, data
[0]);
335 base
+= CDNS_MCP_CMD_WORD_LEN
;
336 cdns_writel(cdns
, base
, data
[1]);
338 time
= wait_for_completion_timeout(&cdns
->tx_complete
,
339 msecs_to_jiffies(CDNS_TX_TIMEOUT
));
341 dev_err(cdns
->dev
, "SCP Msg trf timed out\n");
343 return SDW_CMD_TIMEOUT
;
346 /* check response the writes */
347 for (i
= 0; i
< 2; i
++) {
348 if (!(cdns
->response_buf
[i
] & CDNS_MCP_RESP_ACK
)) {
350 dev_err(cdns
->dev
, "Program SCP Ack not received");
351 if (cdns
->response_buf
[i
] & CDNS_MCP_RESP_NACK
) {
353 dev_err(cdns
->dev
, "Program SCP NACK received");
358 /* For NACK, NO ack, don't return err if we are in Broadcast mode */
361 "SCP_addrpage NACKed for Slave %d", msg
->dev_num
);
365 "SCP_addrpage ignored for Slave %d", msg
->dev_num
);
366 return SDW_CMD_IGNORED
;
372 static int cdns_prep_msg(struct sdw_cdns
*cdns
, struct sdw_msg
*msg
, int *cmd
)
377 ret
= cdns_program_scp_addr(cdns
, msg
);
384 switch (msg
->flags
) {
385 case SDW_MSG_FLAG_READ
:
386 *cmd
= CDNS_MCP_CMD_READ
;
389 case SDW_MSG_FLAG_WRITE
:
390 *cmd
= CDNS_MCP_CMD_WRITE
;
394 dev_err(cdns
->dev
, "Invalid msg cmd: %d\n", msg
->flags
);
401 enum sdw_command_response
402 cdns_xfer_msg(struct sdw_bus
*bus
, struct sdw_msg
*msg
)
404 struct sdw_cdns
*cdns
= bus_to_cdns(bus
);
407 ret
= cdns_prep_msg(cdns
, msg
, &cmd
);
409 return SDW_CMD_FAIL_OTHER
;
411 for (i
= 0; i
< msg
->len
/ CDNS_MCP_CMD_LEN
; i
++) {
412 ret
= _cdns_xfer_msg(cdns
, msg
, cmd
, i
* CDNS_MCP_CMD_LEN
,
413 CDNS_MCP_CMD_LEN
, false);
418 if (!(msg
->len
% CDNS_MCP_CMD_LEN
))
421 ret
= _cdns_xfer_msg(cdns
, msg
, cmd
, i
* CDNS_MCP_CMD_LEN
,
422 msg
->len
% CDNS_MCP_CMD_LEN
, false);
427 EXPORT_SYMBOL(cdns_xfer_msg
);
429 enum sdw_command_response
430 cdns_xfer_msg_defer(struct sdw_bus
*bus
,
431 struct sdw_msg
*msg
, struct sdw_defer
*defer
)
433 struct sdw_cdns
*cdns
= bus_to_cdns(bus
);
436 /* for defer only 1 message is supported */
440 ret
= cdns_prep_msg(cdns
, msg
, &cmd
);
442 return SDW_CMD_FAIL_OTHER
;
445 cdns
->defer
->length
= msg
->len
;
447 return _cdns_xfer_msg(cdns
, msg
, cmd
, 0, msg
->len
, true);
449 EXPORT_SYMBOL(cdns_xfer_msg_defer
);
451 enum sdw_command_response
452 cdns_reset_page_addr(struct sdw_bus
*bus
, unsigned int dev_num
)
454 struct sdw_cdns
*cdns
= bus_to_cdns(bus
);
457 /* Create dummy message with valid device number */
458 memset(&msg
, 0, sizeof(msg
));
459 msg
.dev_num
= dev_num
;
461 return cdns_program_scp_addr(cdns
, &msg
);
463 EXPORT_SYMBOL(cdns_reset_page_addr
);
469 static void cdns_read_response(struct sdw_cdns
*cdns
)
471 u32 num_resp
, cmd_base
;
474 num_resp
= cdns_readl(cdns
, CDNS_MCP_FIFOSTAT
);
475 num_resp
&= CDNS_MCP_RX_FIFO_AVAIL
;
477 cmd_base
= CDNS_MCP_CMD_BASE
;
479 for (i
= 0; i
< num_resp
; i
++) {
480 cdns
->response_buf
[i
] = cdns_readl(cdns
, cmd_base
);
481 cmd_base
+= CDNS_MCP_CMD_WORD_LEN
;
485 static int cdns_update_slave_status(struct sdw_cdns
*cdns
,
486 u32 slave0
, u32 slave1
)
488 enum sdw_slave_status status
[SDW_MAX_DEVICES
+ 1];
489 bool is_slave
= false;
493 /* combine the two status */
494 slave
= ((u64
)slave1
<< 32) | slave0
;
495 memset(status
, 0, sizeof(status
));
497 for (i
= 0; i
<= SDW_MAX_DEVICES
; i
++) {
498 mask
= (slave
>> (i
* CDNS_MCP_SLAVE_STATUS_NUM
)) &
499 CDNS_MCP_SLAVE_STATUS_BITS
;
506 if (mask
& CDNS_MCP_SLAVE_INTSTAT_RESERVED
) {
507 status
[i
] = SDW_SLAVE_RESERVED
;
511 if (mask
& CDNS_MCP_SLAVE_INTSTAT_ATTACHED
) {
512 status
[i
] = SDW_SLAVE_ATTACHED
;
516 if (mask
& CDNS_MCP_SLAVE_INTSTAT_ALERT
) {
517 status
[i
] = SDW_SLAVE_ALERT
;
521 if (mask
& CDNS_MCP_SLAVE_INTSTAT_NPRESENT
) {
522 status
[i
] = SDW_SLAVE_UNATTACHED
;
526 /* first check if Slave reported multiple status */
527 if (set_status
> 1) {
529 "Slave reported multiple Status: %d\n",
532 * TODO: we need to reread the status here by
539 return sdw_handle_slave_status(&cdns
->bus
, status
);
545 * sdw_cdns_irq() - Cadence interrupt handler
547 * @dev_id: irq context
549 irqreturn_t
sdw_cdns_irq(int irq
, void *dev_id
)
551 struct sdw_cdns
*cdns
= dev_id
;
553 int ret
= IRQ_HANDLED
;
555 /* Check if the link is up */
559 int_status
= cdns_readl(cdns
, CDNS_MCP_INTSTAT
);
561 if (!(int_status
& CDNS_MCP_INT_IRQ
))
564 if (int_status
& CDNS_MCP_INT_RX_WL
) {
565 cdns_read_response(cdns
);
568 cdns_fill_msg_resp(cdns
, cdns
->defer
->msg
,
569 cdns
->defer
->length
, 0);
570 complete(&cdns
->defer
->complete
);
573 complete(&cdns
->tx_complete
);
576 if (int_status
& CDNS_MCP_INT_CTRL_CLASH
) {
578 /* Slave is driving bit slot during control word */
579 dev_err_ratelimited(cdns
->dev
, "Bus clash for control word\n");
580 int_status
|= CDNS_MCP_INT_CTRL_CLASH
;
583 if (int_status
& CDNS_MCP_INT_DATA_CLASH
) {
585 * Multiple slaves trying to drive bit slot, or issue with
586 * ownership of data bits or Slave gone bonkers
588 dev_err_ratelimited(cdns
->dev
, "Bus clash for data word\n");
589 int_status
|= CDNS_MCP_INT_DATA_CLASH
;
592 if (int_status
& CDNS_MCP_INT_SLAVE_MASK
) {
593 /* Mask the Slave interrupt and wake thread */
594 cdns_updatel(cdns
, CDNS_MCP_INTMASK
,
595 CDNS_MCP_INT_SLAVE_MASK
, 0);
597 int_status
&= ~CDNS_MCP_INT_SLAVE_MASK
;
598 ret
= IRQ_WAKE_THREAD
;
601 cdns_writel(cdns
, CDNS_MCP_INTSTAT
, int_status
);
604 EXPORT_SYMBOL(sdw_cdns_irq
);
607 * sdw_cdns_thread() - Cadence irq thread handler
609 * @dev_id: irq context
611 irqreturn_t
sdw_cdns_thread(int irq
, void *dev_id
)
613 struct sdw_cdns
*cdns
= dev_id
;
616 dev_dbg(cdns
->dev
, "Slave status change\n");
618 slave0
= cdns_readl(cdns
, CDNS_MCP_SLAVE_INTSTAT0
);
619 slave1
= cdns_readl(cdns
, CDNS_MCP_SLAVE_INTSTAT1
);
621 cdns_update_slave_status(cdns
, slave0
, slave1
);
622 cdns_writel(cdns
, CDNS_MCP_SLAVE_INTSTAT0
, slave0
);
623 cdns_writel(cdns
, CDNS_MCP_SLAVE_INTSTAT1
, slave1
);
625 /* clear and unmask Slave interrupt now */
626 cdns_writel(cdns
, CDNS_MCP_INTSTAT
, CDNS_MCP_INT_SLAVE_MASK
);
627 cdns_updatel(cdns
, CDNS_MCP_INTMASK
,
628 CDNS_MCP_INT_SLAVE_MASK
, CDNS_MCP_INT_SLAVE_MASK
);
632 EXPORT_SYMBOL(sdw_cdns_thread
);
637 static int _cdns_enable_interrupt(struct sdw_cdns
*cdns
)
641 cdns_writel(cdns
, CDNS_MCP_SLAVE_INTMASK0
,
642 CDNS_MCP_SLAVE_INTMASK0_MASK
);
643 cdns_writel(cdns
, CDNS_MCP_SLAVE_INTMASK1
,
644 CDNS_MCP_SLAVE_INTMASK1_MASK
);
646 mask
= CDNS_MCP_INT_SLAVE_RSVD
| CDNS_MCP_INT_SLAVE_ALERT
|
647 CDNS_MCP_INT_SLAVE_ATTACH
| CDNS_MCP_INT_SLAVE_NATTACH
|
648 CDNS_MCP_INT_CTRL_CLASH
| CDNS_MCP_INT_DATA_CLASH
|
649 CDNS_MCP_INT_RX_WL
| CDNS_MCP_INT_IRQ
| CDNS_MCP_INT_DPINT
;
651 cdns_writel(cdns
, CDNS_MCP_INTMASK
, mask
);
657 * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
658 * @cdns: Cadence instance
660 int sdw_cdns_enable_interrupt(struct sdw_cdns
*cdns
)
664 _cdns_enable_interrupt(cdns
);
665 ret
= cdns_clear_bit(cdns
, CDNS_MCP_CONFIG_UPDATE
,
666 CDNS_MCP_CONFIG_UPDATE_BIT
);
668 dev_err(cdns
->dev
, "Config update timedout");
672 EXPORT_SYMBOL(sdw_cdns_enable_interrupt
);
674 static int cdns_allocate_pdi(struct sdw_cdns
*cdns
,
675 struct sdw_cdns_pdi
**stream
,
676 u32 num
, u32 pdi_offset
)
678 struct sdw_cdns_pdi
*pdi
;
684 pdi
= devm_kcalloc(cdns
->dev
, num
, sizeof(*pdi
), GFP_KERNEL
);
688 for (i
= 0; i
< num
; i
++) {
689 pdi
[i
].num
= i
+ pdi_offset
;
690 pdi
[i
].assigned
= false;
698 * sdw_cdns_pdi_init() - PDI initialization routine
700 * @cdns: Cadence instance
701 * @config: Stream configurations
703 int sdw_cdns_pdi_init(struct sdw_cdns
*cdns
,
704 struct sdw_cdns_stream_config config
)
706 struct sdw_cdns_streams
*stream
;
709 cdns
->pcm
.num_bd
= config
.pcm_bd
;
710 cdns
->pcm
.num_in
= config
.pcm_in
;
711 cdns
->pcm
.num_out
= config
.pcm_out
;
712 cdns
->pdm
.num_bd
= config
.pdm_bd
;
713 cdns
->pdm
.num_in
= config
.pdm_in
;
714 cdns
->pdm
.num_out
= config
.pdm_out
;
716 /* Allocate PDIs for PCMs */
719 /* First two PDIs are reserved for bulk transfers */
720 stream
->num_bd
-= CDNS_PCM_PDI_OFFSET
;
721 offset
= CDNS_PCM_PDI_OFFSET
;
723 ret
= cdns_allocate_pdi(cdns
, &stream
->bd
,
724 stream
->num_bd
, offset
);
728 offset
+= stream
->num_bd
;
730 ret
= cdns_allocate_pdi(cdns
, &stream
->in
,
731 stream
->num_in
, offset
);
735 offset
+= stream
->num_in
;
737 ret
= cdns_allocate_pdi(cdns
, &stream
->out
,
738 stream
->num_out
, offset
);
742 /* Update total number of PCM PDIs */
743 stream
->num_pdi
= stream
->num_bd
+ stream
->num_in
+ stream
->num_out
;
744 cdns
->num_ports
= stream
->num_pdi
;
746 /* Allocate PDIs for PDMs */
748 offset
= CDNS_PDM_PDI_OFFSET
;
749 ret
= cdns_allocate_pdi(cdns
, &stream
->bd
,
750 stream
->num_bd
, offset
);
754 offset
+= stream
->num_bd
;
756 ret
= cdns_allocate_pdi(cdns
, &stream
->in
,
757 stream
->num_in
, offset
);
761 offset
+= stream
->num_in
;
763 ret
= cdns_allocate_pdi(cdns
, &stream
->out
,
764 stream
->num_out
, offset
);
768 /* Update total number of PDM PDIs */
769 stream
->num_pdi
= stream
->num_bd
+ stream
->num_in
+ stream
->num_out
;
770 cdns
->num_ports
+= stream
->num_pdi
;
772 cdns
->ports
= devm_kcalloc(cdns
->dev
, cdns
->num_ports
,
773 sizeof(*cdns
->ports
), GFP_KERNEL
);
779 for (i
= 0; i
< cdns
->num_ports
; i
++) {
780 cdns
->ports
[i
].assigned
= false;
781 cdns
->ports
[i
].num
= i
+ 1; /* Port 0 reserved for bulk */
786 EXPORT_SYMBOL(sdw_cdns_pdi_init
);
789 * sdw_cdns_init() - Cadence initialization
790 * @cdns: Cadence instance
792 int sdw_cdns_init(struct sdw_cdns
*cdns
)
797 /* Exit clock stop */
798 ret
= cdns_clear_bit(cdns
, CDNS_MCP_CONTROL
,
799 CDNS_MCP_CONTROL_CLK_STOP_CLR
);
801 dev_err(cdns
->dev
, "Couldn't exit from clock stop\n");
805 /* Set clock divider */
806 val
= cdns_readl(cdns
, CDNS_MCP_CLK_CTRL0
);
807 val
|= CDNS_DEFAULT_CLK_DIVIDER
;
808 cdns_writel(cdns
, CDNS_MCP_CLK_CTRL0
, val
);
810 /* Set the default frame shape */
811 cdns_writel(cdns
, CDNS_MCP_FRAME_SHAPE_INIT
, CDNS_DEFAULT_FRAME_SHAPE
);
813 /* Set SSP interval to default value */
814 cdns_writel(cdns
, CDNS_MCP_SSP_CTRL0
, CDNS_DEFAULT_SSP_INTERVAL
);
815 cdns_writel(cdns
, CDNS_MCP_SSP_CTRL1
, CDNS_DEFAULT_SSP_INTERVAL
);
817 /* Set cmd accept mode */
818 cdns_updatel(cdns
, CDNS_MCP_CONTROL
, CDNS_MCP_CONTROL_CMD_ACCEPT
,
819 CDNS_MCP_CONTROL_CMD_ACCEPT
);
821 /* Configure mcp config */
822 val
= cdns_readl(cdns
, CDNS_MCP_CONFIG
);
824 /* Set Max cmd retry to 15 */
825 val
|= CDNS_MCP_CONFIG_MCMD_RETRY
;
827 /* Set frame delay between PREQ and ping frame to 15 frames */
828 val
|= 0xF << SDW_REG_SHIFT(CDNS_MCP_CONFIG_MPREQ_DELAY
);
830 /* Disable auto bus release */
831 val
&= ~CDNS_MCP_CONFIG_BUS_REL
;
833 /* Disable sniffer mode */
834 val
&= ~CDNS_MCP_CONFIG_SNIFFER
;
836 /* Set cmd mode for Tx and Rx cmds */
837 val
&= ~CDNS_MCP_CONFIG_CMD
;
839 /* Set operation to normal */
840 val
&= ~CDNS_MCP_CONFIG_OP
;
841 val
|= CDNS_MCP_CONFIG_OP_NORMAL
;
843 cdns_writel(cdns
, CDNS_MCP_CONFIG
, val
);
847 EXPORT_SYMBOL(sdw_cdns_init
);
849 int cdns_bus_conf(struct sdw_bus
*bus
, struct sdw_bus_params
*params
)
851 struct sdw_cdns
*cdns
= bus_to_cdns(bus
);
852 int mcp_clkctrl_off
, mcp_clkctrl
;
855 if (!params
->curr_dr_freq
) {
856 dev_err(cdns
->dev
, "NULL curr_dr_freq");
860 divider
= (params
->max_dr_freq
/ params
->curr_dr_freq
) - 1;
862 if (params
->next_bank
)
863 mcp_clkctrl_off
= CDNS_MCP_CLK_CTRL1
;
865 mcp_clkctrl_off
= CDNS_MCP_CLK_CTRL0
;
867 mcp_clkctrl
= cdns_readl(cdns
, mcp_clkctrl_off
);
868 mcp_clkctrl
|= divider
;
869 cdns_writel(cdns
, mcp_clkctrl_off
, mcp_clkctrl
);
873 EXPORT_SYMBOL(cdns_bus_conf
);
875 static int cdns_port_params(struct sdw_bus
*bus
,
876 struct sdw_port_params
*p_params
, unsigned int bank
)
878 struct sdw_cdns
*cdns
= bus_to_cdns(bus
);
879 int dpn_config
= 0, dpn_config_off
;
882 dpn_config_off
= CDNS_DPN_B1_CONFIG(p_params
->num
);
884 dpn_config_off
= CDNS_DPN_B0_CONFIG(p_params
->num
);
886 dpn_config
= cdns_readl(cdns
, dpn_config_off
);
888 dpn_config
|= ((p_params
->bps
- 1) <<
889 SDW_REG_SHIFT(CDNS_DPN_CONFIG_WL
));
890 dpn_config
|= (p_params
->flow_mode
<<
891 SDW_REG_SHIFT(CDNS_DPN_CONFIG_PORT_FLOW
));
892 dpn_config
|= (p_params
->data_mode
<<
893 SDW_REG_SHIFT(CDNS_DPN_CONFIG_PORT_DAT
));
895 cdns_writel(cdns
, dpn_config_off
, dpn_config
);
900 static int cdns_transport_params(struct sdw_bus
*bus
,
901 struct sdw_transport_params
*t_params
,
902 enum sdw_reg_bank bank
)
904 struct sdw_cdns
*cdns
= bus_to_cdns(bus
);
905 int dpn_offsetctrl
= 0, dpn_offsetctrl_off
;
906 int dpn_config
= 0, dpn_config_off
;
907 int dpn_hctrl
= 0, dpn_hctrl_off
;
908 int num
= t_params
->port_num
;
909 int dpn_samplectrl_off
;
912 * Note: Only full data port is supported on the Master side for
913 * both PCM and PDM ports.
917 dpn_config_off
= CDNS_DPN_B1_CONFIG(num
);
918 dpn_samplectrl_off
= CDNS_DPN_B1_SAMPLE_CTRL(num
);
919 dpn_hctrl_off
= CDNS_DPN_B1_HCTRL(num
);
920 dpn_offsetctrl_off
= CDNS_DPN_B1_OFFSET_CTRL(num
);
922 dpn_config_off
= CDNS_DPN_B0_CONFIG(num
);
923 dpn_samplectrl_off
= CDNS_DPN_B0_SAMPLE_CTRL(num
);
924 dpn_hctrl_off
= CDNS_DPN_B0_HCTRL(num
);
925 dpn_offsetctrl_off
= CDNS_DPN_B0_OFFSET_CTRL(num
);
928 dpn_config
= cdns_readl(cdns
, dpn_config_off
);
930 dpn_config
|= (t_params
->blk_grp_ctrl
<<
931 SDW_REG_SHIFT(CDNS_DPN_CONFIG_BGC
));
932 dpn_config
|= (t_params
->blk_pkg_mode
<<
933 SDW_REG_SHIFT(CDNS_DPN_CONFIG_BPM
));
934 cdns_writel(cdns
, dpn_config_off
, dpn_config
);
936 dpn_offsetctrl
|= (t_params
->offset1
<<
937 SDW_REG_SHIFT(CDNS_DPN_OFFSET_CTRL_1
));
938 dpn_offsetctrl
|= (t_params
->offset2
<<
939 SDW_REG_SHIFT(CDNS_DPN_OFFSET_CTRL_2
));
940 cdns_writel(cdns
, dpn_offsetctrl_off
, dpn_offsetctrl
);
942 dpn_hctrl
|= (t_params
->hstart
<<
943 SDW_REG_SHIFT(CDNS_DPN_HCTRL_HSTART
));
944 dpn_hctrl
|= (t_params
->hstop
<< SDW_REG_SHIFT(CDNS_DPN_HCTRL_HSTOP
));
945 dpn_hctrl
|= (t_params
->lane_ctrl
<<
946 SDW_REG_SHIFT(CDNS_DPN_HCTRL_LCTRL
));
948 cdns_writel(cdns
, dpn_hctrl_off
, dpn_hctrl
);
949 cdns_writel(cdns
, dpn_samplectrl_off
, (t_params
->sample_interval
- 1));
954 static int cdns_port_enable(struct sdw_bus
*bus
,
955 struct sdw_enable_ch
*enable_ch
, unsigned int bank
)
957 struct sdw_cdns
*cdns
= bus_to_cdns(bus
);
958 int dpn_chnen_off
, ch_mask
;
961 dpn_chnen_off
= CDNS_DPN_B1_CH_EN(enable_ch
->port_num
);
963 dpn_chnen_off
= CDNS_DPN_B0_CH_EN(enable_ch
->port_num
);
965 ch_mask
= enable_ch
->ch_mask
* enable_ch
->enable
;
966 cdns_writel(cdns
, dpn_chnen_off
, ch_mask
);
971 static const struct sdw_master_port_ops cdns_port_ops
= {
972 .dpn_set_port_params
= cdns_port_params
,
973 .dpn_set_port_transport_params
= cdns_transport_params
,
974 .dpn_port_enable_ch
= cdns_port_enable
,
978 * sdw_cdns_probe() - Cadence probe routine
979 * @cdns: Cadence instance
981 int sdw_cdns_probe(struct sdw_cdns
*cdns
)
983 init_completion(&cdns
->tx_complete
);
984 cdns
->bus
.port_ops
= &cdns_port_ops
;
988 EXPORT_SYMBOL(sdw_cdns_probe
);
990 int cdns_set_sdw_stream(struct snd_soc_dai
*dai
,
991 void *stream
, bool pcm
, int direction
)
993 struct sdw_cdns
*cdns
= snd_soc_dai_get_drvdata(dai
);
994 struct sdw_cdns_dma_data
*dma
;
996 dma
= kzalloc(sizeof(*dma
), GFP_KERNEL
);
1001 dma
->stream_type
= SDW_STREAM_PCM
;
1003 dma
->stream_type
= SDW_STREAM_PDM
;
1005 dma
->bus
= &cdns
->bus
;
1006 dma
->link_id
= cdns
->instance
;
1008 dma
->stream
= stream
;
1010 if (direction
== SNDRV_PCM_STREAM_PLAYBACK
)
1011 dai
->playback_dma_data
= dma
;
1013 dai
->capture_dma_data
= dma
;
1017 EXPORT_SYMBOL(cdns_set_sdw_stream
);
1020 * cdns_find_pdi() - Find a free PDI
1022 * @cdns: Cadence instance
1023 * @num: Number of PDIs
1024 * @pdi: PDI instances
1026 * Find and return a free PDI for a given PDI array
1028 static struct sdw_cdns_pdi
*cdns_find_pdi(struct sdw_cdns
*cdns
,
1029 unsigned int num
, struct sdw_cdns_pdi
*pdi
)
1033 for (i
= 0; i
< num
; i
++) {
1034 if (pdi
[i
].assigned
== true)
1036 pdi
[i
].assigned
= true;
1044 * sdw_cdns_config_stream: Configure a stream
1046 * @cdns: Cadence instance
1047 * @port: Cadence data port
1048 * @ch: Channel count
1049 * @dir: Data direction
1050 * @pdi: PDI to be used
1052 void sdw_cdns_config_stream(struct sdw_cdns
*cdns
,
1053 struct sdw_cdns_port
*port
,
1054 u32 ch
, u32 dir
, struct sdw_cdns_pdi
*pdi
)
1056 u32 offset
, val
= 0;
1058 if (dir
== SDW_DATA_DIR_RX
)
1059 val
= CDNS_PORTCTRL_DIRN
;
1061 offset
= CDNS_PORTCTRL
+ port
->num
* CDNS_PORT_OFFSET
;
1062 cdns_updatel(cdns
, offset
, CDNS_PORTCTRL_DIRN
, val
);
1065 val
|= ((1 << ch
) - 1) << SDW_REG_SHIFT(CDNS_PDI_CONFIG_CHANNEL
);
1066 cdns_writel(cdns
, CDNS_PDI_CONFIG(pdi
->num
), val
);
1068 EXPORT_SYMBOL(sdw_cdns_config_stream
);
1071 * cdns_get_num_pdi() - Get number of PDIs required
1073 * @cdns: Cadence instance
1074 * @pdi: PDI to be used
1075 * @num: Number of PDIs
1076 * @ch_count: Channel count
1078 static int cdns_get_num_pdi(struct sdw_cdns
*cdns
,
1079 struct sdw_cdns_pdi
*pdi
,
1080 unsigned int num
, u32 ch_count
)
1084 for (i
= 0; i
< num
; i
++) {
1085 if (pdi
[i
].assigned
== true)
1088 if (pdi
[i
].ch_count
< ch_count
)
1089 ch_count
-= pdi
[i
].ch_count
;
1106 * sdw_cdns_get_stream() - Get stream information
1108 * @cdns: Cadence instance
1109 * @stream: Stream to be allocated
1110 * @ch: Channel count
1111 * @dir: Data direction
1113 int sdw_cdns_get_stream(struct sdw_cdns
*cdns
,
1114 struct sdw_cdns_streams
*stream
,
1119 if (dir
== SDW_DATA_DIR_RX
)
1120 pdis
= cdns_get_num_pdi(cdns
, stream
->in
, stream
->num_in
, ch
);
1122 pdis
= cdns_get_num_pdi(cdns
, stream
->out
, stream
->num_out
, ch
);
1124 /* check if we found PDI, else find in bi-directional */
1126 pdis
= cdns_get_num_pdi(cdns
, stream
->bd
, stream
->num_bd
, ch
);
1130 EXPORT_SYMBOL(sdw_cdns_get_stream
);
1133 * sdw_cdns_alloc_stream() - Allocate a stream
1135 * @cdns: Cadence instance
1136 * @stream: Stream to be allocated
1137 * @port: Cadence data port
1138 * @ch: Channel count
1139 * @dir: Data direction
1141 int sdw_cdns_alloc_stream(struct sdw_cdns
*cdns
,
1142 struct sdw_cdns_streams
*stream
,
1143 struct sdw_cdns_port
*port
, u32 ch
, u32 dir
)
1145 struct sdw_cdns_pdi
*pdi
= NULL
;
1147 if (dir
== SDW_DATA_DIR_RX
)
1148 pdi
= cdns_find_pdi(cdns
, stream
->num_in
, stream
->in
);
1150 pdi
= cdns_find_pdi(cdns
, stream
->num_out
, stream
->out
);
1152 /* check if we found a PDI, else find in bi-directional */
1154 pdi
= cdns_find_pdi(cdns
, stream
->num_bd
, stream
->bd
);
1161 pdi
->h_ch_num
= ch
- 1;
1167 EXPORT_SYMBOL(sdw_cdns_alloc_stream
);
1169 void sdw_cdns_shutdown(struct snd_pcm_substream
*substream
,
1170 struct snd_soc_dai
*dai
)
1172 struct sdw_cdns_dma_data
*dma
;
1174 dma
= snd_soc_dai_get_dma_data(dai
, substream
);
1178 snd_soc_dai_set_dma_data(dai
, substream
, NULL
);
1181 EXPORT_SYMBOL(sdw_cdns_shutdown
);
1183 MODULE_LICENSE("Dual BSD/GPL");
1184 MODULE_DESCRIPTION("Cadence Soundwire Library");