root/drivers/soundwire/cadence_master.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cdns_readl
  2. cdns_writel
  3. cdns_updatel
  4. cdns_clear_bit
  5. cdns_sprintf
  6. cdns_reg_show
  7. sdw_cdns_debugfs_init
  8. cdns_fill_msg_resp
  9. _cdns_xfer_msg
  10. cdns_program_scp_addr
  11. cdns_prep_msg
  12. cdns_xfer_msg
  13. cdns_xfer_msg_defer
  14. cdns_reset_page_addr
  15. cdns_read_response
  16. cdns_update_slave_status
  17. sdw_cdns_irq
  18. sdw_cdns_thread
  19. _cdns_enable_interrupt
  20. sdw_cdns_enable_interrupt
  21. cdns_allocate_pdi
  22. sdw_cdns_pdi_init
  23. cdns_set_initial_frame_shape
  24. sdw_cdns_init
  25. cdns_bus_conf
  26. cdns_port_params
  27. cdns_transport_params
  28. cdns_port_enable
  29. sdw_cdns_probe
  30. cdns_set_sdw_stream
  31. cdns_find_pdi
  32. sdw_cdns_config_stream
  33. cdns_get_num_pdi
  34. sdw_cdns_get_stream
  35. sdw_cdns_alloc_stream

   1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
   2 // Copyright(c) 2015-17 Intel Corporation.
   3 
   4 /*
   5  * Cadence SoundWire Master module
   6  * Used by Master driver
   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/soundwire/sdw_registers.h>
  17 #include <linux/soundwire/sdw.h>
  18 #include <sound/pcm_params.h>
  19 #include <sound/soc.h>
  20 #include "bus.h"
  21 #include "cadence_master.h"
  22 
  23 static int interrupt_mask;
  24 module_param_named(cnds_mcp_int_mask, interrupt_mask, int, 0444);
  25 MODULE_PARM_DESC(cdns_mcp_int_mask, "Cadence MCP IntMask");
  26 
  27 #define CDNS_MCP_CONFIG                         0x0
  28 
  29 #define CDNS_MCP_CONFIG_MCMD_RETRY              GENMASK(27, 24)
  30 #define CDNS_MCP_CONFIG_MPREQ_DELAY             GENMASK(20, 16)
  31 #define CDNS_MCP_CONFIG_MMASTER                 BIT(7)
  32 #define CDNS_MCP_CONFIG_BUS_REL                 BIT(6)
  33 #define CDNS_MCP_CONFIG_SNIFFER                 BIT(5)
  34 #define CDNS_MCP_CONFIG_SSPMOD                  BIT(4)
  35 #define CDNS_MCP_CONFIG_CMD                     BIT(3)
  36 #define CDNS_MCP_CONFIG_OP                      GENMASK(2, 0)
  37 #define CDNS_MCP_CONFIG_OP_NORMAL               0
  38 
  39 #define CDNS_MCP_CONTROL                        0x4
  40 
  41 #define CDNS_MCP_CONTROL_RST_DELAY              GENMASK(10, 8)
  42 #define CDNS_MCP_CONTROL_CMD_RST                BIT(7)
  43 #define CDNS_MCP_CONTROL_SOFT_RST               BIT(6)
  44 #define CDNS_MCP_CONTROL_SW_RST                 BIT(5)
  45 #define CDNS_MCP_CONTROL_HW_RST                 BIT(4)
  46 #define CDNS_MCP_CONTROL_CLK_PAUSE              BIT(3)
  47 #define CDNS_MCP_CONTROL_CLK_STOP_CLR           BIT(2)
  48 #define CDNS_MCP_CONTROL_CMD_ACCEPT             BIT(1)
  49 #define CDNS_MCP_CONTROL_BLOCK_WAKEUP           BIT(0)
  50 
  51 #define CDNS_MCP_CMDCTRL                        0x8
  52 #define CDNS_MCP_SSPSTAT                        0xC
  53 #define CDNS_MCP_FRAME_SHAPE                    0x10
  54 #define CDNS_MCP_FRAME_SHAPE_INIT               0x14
  55 #define CDNS_MCP_FRAME_SHAPE_COL_MASK           GENMASK(2, 0)
  56 #define CDNS_MCP_FRAME_SHAPE_ROW_OFFSET         3
  57 
  58 #define CDNS_MCP_CONFIG_UPDATE                  0x18
  59 #define CDNS_MCP_CONFIG_UPDATE_BIT              BIT(0)
  60 
  61 #define CDNS_MCP_PHYCTRL                        0x1C
  62 #define CDNS_MCP_SSP_CTRL0                      0x20
  63 #define CDNS_MCP_SSP_CTRL1                      0x28
  64 #define CDNS_MCP_CLK_CTRL0                      0x30
  65 #define CDNS_MCP_CLK_CTRL1                      0x38
  66 #define CDNS_MCP_CLK_MCLKD_MASK         GENMASK(7, 0)
  67 
  68 #define CDNS_MCP_STAT                           0x40
  69 
  70 #define CDNS_MCP_STAT_ACTIVE_BANK               BIT(20)
  71 #define CDNS_MCP_STAT_CLK_STOP                  BIT(16)
  72 
  73 #define CDNS_MCP_INTSTAT                        0x44
  74 #define CDNS_MCP_INTMASK                        0x48
  75 
  76 #define CDNS_MCP_INT_IRQ                        BIT(31)
  77 #define CDNS_MCP_INT_WAKEUP                     BIT(16)
  78 #define CDNS_MCP_INT_SLAVE_RSVD                 BIT(15)
  79 #define CDNS_MCP_INT_SLAVE_ALERT                BIT(14)
  80 #define CDNS_MCP_INT_SLAVE_ATTACH               BIT(13)
  81 #define CDNS_MCP_INT_SLAVE_NATTACH              BIT(12)
  82 #define CDNS_MCP_INT_SLAVE_MASK                 GENMASK(15, 12)
  83 #define CDNS_MCP_INT_DPINT                      BIT(11)
  84 #define CDNS_MCP_INT_CTRL_CLASH                 BIT(10)
  85 #define CDNS_MCP_INT_DATA_CLASH                 BIT(9)
  86 #define CDNS_MCP_INT_PARITY                     BIT(8)
  87 #define CDNS_MCP_INT_CMD_ERR                    BIT(7)
  88 #define CDNS_MCP_INT_RX_NE                      BIT(3)
  89 #define CDNS_MCP_INT_RX_WL                      BIT(2)
  90 #define CDNS_MCP_INT_TXE                        BIT(1)
  91 #define CDNS_MCP_INT_TXF                        BIT(0)
  92 
  93 #define CDNS_MCP_INTSET                         0x4C
  94 
  95 #define CDNS_MCP_SLAVE_STAT                     0x50
  96 #define CDNS_MCP_SLAVE_STAT_MASK                GENMASK(1, 0)
  97 
  98 #define CDNS_MCP_SLAVE_INTSTAT0                 0x54
  99 #define CDNS_MCP_SLAVE_INTSTAT1                 0x58
 100 #define CDNS_MCP_SLAVE_INTSTAT_NPRESENT         BIT(0)
 101 #define CDNS_MCP_SLAVE_INTSTAT_ATTACHED         BIT(1)
 102 #define CDNS_MCP_SLAVE_INTSTAT_ALERT            BIT(2)
 103 #define CDNS_MCP_SLAVE_INTSTAT_RESERVED         BIT(3)
 104 #define CDNS_MCP_SLAVE_STATUS_BITS              GENMASK(3, 0)
 105 #define CDNS_MCP_SLAVE_STATUS_NUM               4
 106 
 107 #define CDNS_MCP_SLAVE_INTMASK0                 0x5C
 108 #define CDNS_MCP_SLAVE_INTMASK1                 0x60
 109 
 110 #define CDNS_MCP_SLAVE_INTMASK0_MASK            GENMASK(31, 0)
 111 #define CDNS_MCP_SLAVE_INTMASK1_MASK            GENMASK(15, 0)
 112 
 113 #define CDNS_MCP_PORT_INTSTAT                   0x64
 114 #define CDNS_MCP_PDI_STAT                       0x6C
 115 
 116 #define CDNS_MCP_FIFOLEVEL                      0x78
 117 #define CDNS_MCP_FIFOSTAT                       0x7C
 118 #define CDNS_MCP_RX_FIFO_AVAIL                  GENMASK(5, 0)
 119 
 120 #define CDNS_MCP_CMD_BASE                       0x80
 121 #define CDNS_MCP_RESP_BASE                      0x80
 122 #define CDNS_MCP_CMD_LEN                        0x20
 123 #define CDNS_MCP_CMD_WORD_LEN                   0x4
 124 
 125 #define CDNS_MCP_CMD_SSP_TAG                    BIT(31)
 126 #define CDNS_MCP_CMD_COMMAND                    GENMASK(30, 28)
 127 #define CDNS_MCP_CMD_DEV_ADDR                   GENMASK(27, 24)
 128 #define CDNS_MCP_CMD_REG_ADDR_H                 GENMASK(23, 16)
 129 #define CDNS_MCP_CMD_REG_ADDR_L                 GENMASK(15, 8)
 130 #define CDNS_MCP_CMD_REG_DATA                   GENMASK(7, 0)
 131 
 132 #define CDNS_MCP_CMD_READ                       2
 133 #define CDNS_MCP_CMD_WRITE                      3
 134 
 135 #define CDNS_MCP_RESP_RDATA                     GENMASK(15, 8)
 136 #define CDNS_MCP_RESP_ACK                       BIT(0)
 137 #define CDNS_MCP_RESP_NACK                      BIT(1)
 138 
 139 #define CDNS_DP_SIZE                            128
 140 
 141 #define CDNS_DPN_B0_CONFIG(n)                   (0x100 + CDNS_DP_SIZE * (n))
 142 #define CDNS_DPN_B0_CH_EN(n)                    (0x104 + CDNS_DP_SIZE * (n))
 143 #define CDNS_DPN_B0_SAMPLE_CTRL(n)              (0x108 + CDNS_DP_SIZE * (n))
 144 #define CDNS_DPN_B0_OFFSET_CTRL(n)              (0x10C + CDNS_DP_SIZE * (n))
 145 #define CDNS_DPN_B0_HCTRL(n)                    (0x110 + CDNS_DP_SIZE * (n))
 146 #define CDNS_DPN_B0_ASYNC_CTRL(n)               (0x114 + CDNS_DP_SIZE * (n))
 147 
 148 #define CDNS_DPN_B1_CONFIG(n)                   (0x118 + CDNS_DP_SIZE * (n))
 149 #define CDNS_DPN_B1_CH_EN(n)                    (0x11C + CDNS_DP_SIZE * (n))
 150 #define CDNS_DPN_B1_SAMPLE_CTRL(n)              (0x120 + CDNS_DP_SIZE * (n))
 151 #define CDNS_DPN_B1_OFFSET_CTRL(n)              (0x124 + CDNS_DP_SIZE * (n))
 152 #define CDNS_DPN_B1_HCTRL(n)                    (0x128 + CDNS_DP_SIZE * (n))
 153 #define CDNS_DPN_B1_ASYNC_CTRL(n)               (0x12C + CDNS_DP_SIZE * (n))
 154 
 155 #define CDNS_DPN_CONFIG_BPM                     BIT(18)
 156 #define CDNS_DPN_CONFIG_BGC                     GENMASK(17, 16)
 157 #define CDNS_DPN_CONFIG_WL                      GENMASK(12, 8)
 158 #define CDNS_DPN_CONFIG_PORT_DAT                GENMASK(3, 2)
 159 #define CDNS_DPN_CONFIG_PORT_FLOW               GENMASK(1, 0)
 160 
 161 #define CDNS_DPN_SAMPLE_CTRL_SI                 GENMASK(15, 0)
 162 
 163 #define CDNS_DPN_OFFSET_CTRL_1                  GENMASK(7, 0)
 164 #define CDNS_DPN_OFFSET_CTRL_2                  GENMASK(15, 8)
 165 
 166 #define CDNS_DPN_HCTRL_HSTOP                    GENMASK(3, 0)
 167 #define CDNS_DPN_HCTRL_HSTART                   GENMASK(7, 4)
 168 #define CDNS_DPN_HCTRL_LCTRL                    GENMASK(10, 8)
 169 
 170 #define CDNS_PORTCTRL                           0x130
 171 #define CDNS_PORTCTRL_DIRN                      BIT(7)
 172 #define CDNS_PORTCTRL_BANK_INVERT               BIT(8)
 173 
 174 #define CDNS_PORT_OFFSET                        0x80
 175 
 176 #define CDNS_PDI_CONFIG(n)                      (0x1100 + (n) * 16)
 177 
 178 #define CDNS_PDI_CONFIG_SOFT_RESET              BIT(24)
 179 #define CDNS_PDI_CONFIG_CHANNEL                 GENMASK(15, 8)
 180 #define CDNS_PDI_CONFIG_PORT                    GENMASK(4, 0)
 181 
 182 /* Driver defaults */
 183 #define CDNS_DEFAULT_SSP_INTERVAL               0x18
 184 #define CDNS_TX_TIMEOUT                         2000
 185 
 186 #define CDNS_PCM_PDI_OFFSET                     0x2
 187 #define CDNS_PDM_PDI_OFFSET                     0x6
 188 
 189 #define CDNS_SCP_RX_FIFOLEVEL                   0x2
 190 
 191 /*
 192  * register accessor helpers
 193  */
 194 static inline u32 cdns_readl(struct sdw_cdns *cdns, int offset)
 195 {
 196         return readl(cdns->registers + offset);
 197 }
 198 
 199 static inline void cdns_writel(struct sdw_cdns *cdns, int offset, u32 value)
 200 {
 201         writel(value, cdns->registers + offset);
 202 }
 203 
 204 static inline void cdns_updatel(struct sdw_cdns *cdns,
 205                                 int offset, u32 mask, u32 val)
 206 {
 207         u32 tmp;
 208 
 209         tmp = cdns_readl(cdns, offset);
 210         tmp = (tmp & ~mask) | val;
 211         cdns_writel(cdns, offset, tmp);
 212 }
 213 
 214 static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
 215 {
 216         int timeout = 10;
 217         u32 reg_read;
 218 
 219         writel(value, cdns->registers + offset);
 220 
 221         /* Wait for bit to be self cleared */
 222         do {
 223                 reg_read = readl(cdns->registers + offset);
 224                 if ((reg_read & value) == 0)
 225                         return 0;
 226 
 227                 timeout--;
 228                 udelay(50);
 229         } while (timeout != 0);
 230 
 231         return -EAGAIN;
 232 }
 233 
 234 /*
 235  * debugfs
 236  */
 237 #ifdef CONFIG_DEBUG_FS
 238 
 239 #define RD_BUF (2 * PAGE_SIZE)
 240 
 241 static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
 242                             char *buf, size_t pos, unsigned int reg)
 243 {
 244         return scnprintf(buf + pos, RD_BUF - pos,
 245                          "%4x\t%8x\n", reg, cdns_readl(cdns, reg));
 246 }
 247 
 248 static int cdns_reg_show(struct seq_file *s, void *data)
 249 {
 250         struct sdw_cdns *cdns = s->private;
 251         char *buf;
 252         ssize_t ret;
 253         int num_ports;
 254         int i, j;
 255 
 256         buf = kzalloc(RD_BUF, GFP_KERNEL);
 257         if (!buf)
 258                 return -ENOMEM;
 259 
 260         ret = scnprintf(buf, RD_BUF, "Register  Value\n");
 261         ret += scnprintf(buf + ret, RD_BUF - ret, "\nMCP Registers\n");
 262         /* 8 MCP registers */
 263         for (i = CDNS_MCP_CONFIG; i <= CDNS_MCP_PHYCTRL; i += sizeof(u32))
 264                 ret += cdns_sprintf(cdns, buf, ret, i);
 265 
 266         ret += scnprintf(buf + ret, RD_BUF - ret,
 267                          "\nStatus & Intr Registers\n");
 268         /* 13 Status & Intr registers (offsets 0x70 and 0x74 not defined) */
 269         for (i = CDNS_MCP_STAT; i <=  CDNS_MCP_FIFOSTAT; i += sizeof(u32))
 270                 ret += cdns_sprintf(cdns, buf, ret, i);
 271 
 272         ret += scnprintf(buf + ret, RD_BUF - ret,
 273                          "\nSSP & Clk ctrl Registers\n");
 274         ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL0);
 275         ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL1);
 276         ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL0);
 277         ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL1);
 278 
 279         ret += scnprintf(buf + ret, RD_BUF - ret,
 280                          "\nDPn B0 Registers\n");
 281 
 282         /*
 283          * in sdw_cdns_pdi_init() we filter out the Bulk PDIs,
 284          * so the indices need to be corrected again
 285          */
 286         num_ports = cdns->num_ports + CDNS_PCM_PDI_OFFSET;
 287 
 288         for (i = 0; i < num_ports; i++) {
 289                 ret += scnprintf(buf + ret, RD_BUF - ret,
 290                                  "\nDP-%d\n", i);
 291                 for (j = CDNS_DPN_B0_CONFIG(i);
 292                      j < CDNS_DPN_B0_ASYNC_CTRL(i); j += sizeof(u32))
 293                         ret += cdns_sprintf(cdns, buf, ret, j);
 294         }
 295 
 296         ret += scnprintf(buf + ret, RD_BUF - ret,
 297                          "\nDPn B1 Registers\n");
 298         for (i = 0; i < num_ports; i++) {
 299                 ret += scnprintf(buf + ret, RD_BUF - ret,
 300                                  "\nDP-%d\n", i);
 301 
 302                 for (j = CDNS_DPN_B1_CONFIG(i);
 303                      j < CDNS_DPN_B1_ASYNC_CTRL(i); j += sizeof(u32))
 304                         ret += cdns_sprintf(cdns, buf, ret, j);
 305         }
 306 
 307         ret += scnprintf(buf + ret, RD_BUF - ret,
 308                          "\nDPn Control Registers\n");
 309         for (i = 0; i < num_ports; i++)
 310                 ret += cdns_sprintf(cdns, buf, ret,
 311                                 CDNS_PORTCTRL + i * CDNS_PORT_OFFSET);
 312 
 313         ret += scnprintf(buf + ret, RD_BUF - ret,
 314                          "\nPDIn Config Registers\n");
 315 
 316         /* number of PDI and ports is interchangeable */
 317         for (i = 0; i < num_ports; i++)
 318                 ret += cdns_sprintf(cdns, buf, ret, CDNS_PDI_CONFIG(i));
 319 
 320         seq_printf(s, "%s", buf);
 321         kfree(buf);
 322 
 323         return 0;
 324 }
 325 DEFINE_SHOW_ATTRIBUTE(cdns_reg);
 326 
 327 /**
 328  * sdw_cdns_debugfs_init() - Cadence debugfs init
 329  * @cdns: Cadence instance
 330  * @root: debugfs root
 331  */
 332 void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root)
 333 {
 334         debugfs_create_file("cdns-registers", 0400, root, cdns, &cdns_reg_fops);
 335 }
 336 EXPORT_SYMBOL_GPL(sdw_cdns_debugfs_init);
 337 
 338 #endif /* CONFIG_DEBUG_FS */
 339 
 340 /*
 341  * IO Calls
 342  */
 343 static enum sdw_command_response
 344 cdns_fill_msg_resp(struct sdw_cdns *cdns,
 345                    struct sdw_msg *msg, int count, int offset)
 346 {
 347         int nack = 0, no_ack = 0;
 348         int i;
 349 
 350         /* check message response */
 351         for (i = 0; i < count; i++) {
 352                 if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
 353                         no_ack = 1;
 354                         dev_dbg_ratelimited(cdns->dev, "Msg Ack not received\n");
 355                         if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
 356                                 nack = 1;
 357                                 dev_err_ratelimited(cdns->dev, "Msg NACK received\n");
 358                         }
 359                 }
 360         }
 361 
 362         if (nack) {
 363                 dev_err_ratelimited(cdns->dev, "Msg NACKed for Slave %d\n", msg->dev_num);
 364                 return SDW_CMD_FAIL;
 365         } else if (no_ack) {
 366                 dev_dbg_ratelimited(cdns->dev, "Msg ignored for Slave %d\n", msg->dev_num);
 367                 return SDW_CMD_IGNORED;
 368         }
 369 
 370         /* fill response */
 371         for (i = 0; i < count; i++)
 372                 msg->buf[i + offset] = cdns->response_buf[i] >>
 373                                 SDW_REG_SHIFT(CDNS_MCP_RESP_RDATA);
 374 
 375         return SDW_CMD_OK;
 376 }
 377 
 378 static enum sdw_command_response
 379 _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
 380                int offset, int count, bool defer)
 381 {
 382         unsigned long time;
 383         u32 base, i, data;
 384         u16 addr;
 385 
 386         /* Program the watermark level for RX FIFO */
 387         if (cdns->msg_count != count) {
 388                 cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, count);
 389                 cdns->msg_count = count;
 390         }
 391 
 392         base = CDNS_MCP_CMD_BASE;
 393         addr = msg->addr;
 394 
 395         for (i = 0; i < count; i++) {
 396                 data = msg->dev_num << SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR);
 397                 data |= cmd << SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND);
 398                 data |= addr++  << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
 399 
 400                 if (msg->flags == SDW_MSG_FLAG_WRITE)
 401                         data |= msg->buf[i + offset];
 402 
 403                 data |= msg->ssp_sync << SDW_REG_SHIFT(CDNS_MCP_CMD_SSP_TAG);
 404                 cdns_writel(cdns, base, data);
 405                 base += CDNS_MCP_CMD_WORD_LEN;
 406         }
 407 
 408         if (defer)
 409                 return SDW_CMD_OK;
 410 
 411         /* wait for timeout or response */
 412         time = wait_for_completion_timeout(&cdns->tx_complete,
 413                                            msecs_to_jiffies(CDNS_TX_TIMEOUT));
 414         if (!time) {
 415                 dev_err(cdns->dev, "IO transfer timed out\n");
 416                 msg->len = 0;
 417                 return SDW_CMD_TIMEOUT;
 418         }
 419 
 420         return cdns_fill_msg_resp(cdns, msg, count, offset);
 421 }
 422 
 423 static enum sdw_command_response
 424 cdns_program_scp_addr(struct sdw_cdns *cdns, struct sdw_msg *msg)
 425 {
 426         int nack = 0, no_ack = 0;
 427         unsigned long time;
 428         u32 data[2], base;
 429         int i;
 430 
 431         /* Program the watermark level for RX FIFO */
 432         if (cdns->msg_count != CDNS_SCP_RX_FIFOLEVEL) {
 433                 cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, CDNS_SCP_RX_FIFOLEVEL);
 434                 cdns->msg_count = CDNS_SCP_RX_FIFOLEVEL;
 435         }
 436 
 437         data[0] = msg->dev_num << SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR);
 438         data[0] |= 0x3 << SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND);
 439         data[1] = data[0];
 440 
 441         data[0] |= SDW_SCP_ADDRPAGE1 << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
 442         data[1] |= SDW_SCP_ADDRPAGE2 << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
 443 
 444         data[0] |= msg->addr_page1;
 445         data[1] |= msg->addr_page2;
 446 
 447         base = CDNS_MCP_CMD_BASE;
 448         cdns_writel(cdns, base, data[0]);
 449         base += CDNS_MCP_CMD_WORD_LEN;
 450         cdns_writel(cdns, base, data[1]);
 451 
 452         time = wait_for_completion_timeout(&cdns->tx_complete,
 453                                            msecs_to_jiffies(CDNS_TX_TIMEOUT));
 454         if (!time) {
 455                 dev_err(cdns->dev, "SCP Msg trf timed out\n");
 456                 msg->len = 0;
 457                 return SDW_CMD_TIMEOUT;
 458         }
 459 
 460         /* check response the writes */
 461         for (i = 0; i < 2; i++) {
 462                 if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
 463                         no_ack = 1;
 464                         dev_err(cdns->dev, "Program SCP Ack not received\n");
 465                         if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
 466                                 nack = 1;
 467                                 dev_err(cdns->dev, "Program SCP NACK received\n");
 468                         }
 469                 }
 470         }
 471 
 472         /* For NACK, NO ack, don't return err if we are in Broadcast mode */
 473         if (nack) {
 474                 dev_err_ratelimited(cdns->dev,
 475                                     "SCP_addrpage NACKed for Slave %d\n", msg->dev_num);
 476                 return SDW_CMD_FAIL;
 477         } else if (no_ack) {
 478                 dev_dbg_ratelimited(cdns->dev,
 479                                     "SCP_addrpage ignored for Slave %d\n", msg->dev_num);
 480                 return SDW_CMD_IGNORED;
 481         }
 482 
 483         return SDW_CMD_OK;
 484 }
 485 
 486 static int cdns_prep_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int *cmd)
 487 {
 488         int ret;
 489 
 490         if (msg->page) {
 491                 ret = cdns_program_scp_addr(cdns, msg);
 492                 if (ret) {
 493                         msg->len = 0;
 494                         return ret;
 495                 }
 496         }
 497 
 498         switch (msg->flags) {
 499         case SDW_MSG_FLAG_READ:
 500                 *cmd = CDNS_MCP_CMD_READ;
 501                 break;
 502 
 503         case SDW_MSG_FLAG_WRITE:
 504                 *cmd = CDNS_MCP_CMD_WRITE;
 505                 break;
 506 
 507         default:
 508                 dev_err(cdns->dev, "Invalid msg cmd: %d\n", msg->flags);
 509                 return -EINVAL;
 510         }
 511 
 512         return 0;
 513 }
 514 
 515 enum sdw_command_response
 516 cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg)
 517 {
 518         struct sdw_cdns *cdns = bus_to_cdns(bus);
 519         int cmd = 0, ret, i;
 520 
 521         ret = cdns_prep_msg(cdns, msg, &cmd);
 522         if (ret)
 523                 return SDW_CMD_FAIL_OTHER;
 524 
 525         for (i = 0; i < msg->len / CDNS_MCP_CMD_LEN; i++) {
 526                 ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
 527                                      CDNS_MCP_CMD_LEN, false);
 528                 if (ret < 0)
 529                         goto exit;
 530         }
 531 
 532         if (!(msg->len % CDNS_MCP_CMD_LEN))
 533                 goto exit;
 534 
 535         ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
 536                              msg->len % CDNS_MCP_CMD_LEN, false);
 537 
 538 exit:
 539         return ret;
 540 }
 541 EXPORT_SYMBOL(cdns_xfer_msg);
 542 
 543 enum sdw_command_response
 544 cdns_xfer_msg_defer(struct sdw_bus *bus,
 545                     struct sdw_msg *msg, struct sdw_defer *defer)
 546 {
 547         struct sdw_cdns *cdns = bus_to_cdns(bus);
 548         int cmd = 0, ret;
 549 
 550         /* for defer only 1 message is supported */
 551         if (msg->len > 1)
 552                 return -ENOTSUPP;
 553 
 554         ret = cdns_prep_msg(cdns, msg, &cmd);
 555         if (ret)
 556                 return SDW_CMD_FAIL_OTHER;
 557 
 558         cdns->defer = defer;
 559         cdns->defer->length = msg->len;
 560 
 561         return _cdns_xfer_msg(cdns, msg, cmd, 0, msg->len, true);
 562 }
 563 EXPORT_SYMBOL(cdns_xfer_msg_defer);
 564 
 565 enum sdw_command_response
 566 cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num)
 567 {
 568         struct sdw_cdns *cdns = bus_to_cdns(bus);
 569         struct sdw_msg msg;
 570 
 571         /* Create dummy message with valid device number */
 572         memset(&msg, 0, sizeof(msg));
 573         msg.dev_num = dev_num;
 574 
 575         return cdns_program_scp_addr(cdns, &msg);
 576 }
 577 EXPORT_SYMBOL(cdns_reset_page_addr);
 578 
 579 /*
 580  * IRQ handling
 581  */
 582 
 583 static void cdns_read_response(struct sdw_cdns *cdns)
 584 {
 585         u32 num_resp, cmd_base;
 586         int i;
 587 
 588         num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
 589         num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
 590 
 591         cmd_base = CDNS_MCP_CMD_BASE;
 592 
 593         for (i = 0; i < num_resp; i++) {
 594                 cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
 595                 cmd_base += CDNS_MCP_CMD_WORD_LEN;
 596         }
 597 }
 598 
 599 static int cdns_update_slave_status(struct sdw_cdns *cdns,
 600                                     u32 slave0, u32 slave1)
 601 {
 602         enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
 603         bool is_slave = false;
 604         u64 slave;
 605         u32 mask;
 606         int i, set_status;
 607 
 608         /* combine the two status */
 609         slave = ((u64)slave1 << 32) | slave0;
 610         memset(status, 0, sizeof(status));
 611 
 612         for (i = 0; i <= SDW_MAX_DEVICES; i++) {
 613                 mask = (slave >> (i * CDNS_MCP_SLAVE_STATUS_NUM)) &
 614                                 CDNS_MCP_SLAVE_STATUS_BITS;
 615                 if (!mask)
 616                         continue;
 617 
 618                 is_slave = true;
 619                 set_status = 0;
 620 
 621                 if (mask & CDNS_MCP_SLAVE_INTSTAT_RESERVED) {
 622                         status[i] = SDW_SLAVE_RESERVED;
 623                         set_status++;
 624                 }
 625 
 626                 if (mask & CDNS_MCP_SLAVE_INTSTAT_ATTACHED) {
 627                         status[i] = SDW_SLAVE_ATTACHED;
 628                         set_status++;
 629                 }
 630 
 631                 if (mask & CDNS_MCP_SLAVE_INTSTAT_ALERT) {
 632                         status[i] = SDW_SLAVE_ALERT;
 633                         set_status++;
 634                 }
 635 
 636                 if (mask & CDNS_MCP_SLAVE_INTSTAT_NPRESENT) {
 637                         status[i] = SDW_SLAVE_UNATTACHED;
 638                         set_status++;
 639                 }
 640 
 641                 /* first check if Slave reported multiple status */
 642                 if (set_status > 1) {
 643                         dev_warn_ratelimited(cdns->dev,
 644                                              "Slave reported multiple Status: %d\n",
 645                                              mask);
 646                         /*
 647                          * TODO: we need to reread the status here by
 648                          * issuing a PING cmd
 649                          */
 650                 }
 651         }
 652 
 653         if (is_slave)
 654                 return sdw_handle_slave_status(&cdns->bus, status);
 655 
 656         return 0;
 657 }
 658 
 659 /**
 660  * sdw_cdns_irq() - Cadence interrupt handler
 661  * @irq: irq number
 662  * @dev_id: irq context
 663  */
 664 irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
 665 {
 666         struct sdw_cdns *cdns = dev_id;
 667         u32 int_status;
 668         int ret = IRQ_HANDLED;
 669 
 670         /* Check if the link is up */
 671         if (!cdns->link_up)
 672                 return IRQ_NONE;
 673 
 674         int_status = cdns_readl(cdns, CDNS_MCP_INTSTAT);
 675 
 676         if (!(int_status & CDNS_MCP_INT_IRQ))
 677                 return IRQ_NONE;
 678 
 679         if (int_status & CDNS_MCP_INT_RX_WL) {
 680                 cdns_read_response(cdns);
 681 
 682                 if (cdns->defer) {
 683                         cdns_fill_msg_resp(cdns, cdns->defer->msg,
 684                                            cdns->defer->length, 0);
 685                         complete(&cdns->defer->complete);
 686                         cdns->defer = NULL;
 687                 } else {
 688                         complete(&cdns->tx_complete);
 689                 }
 690         }
 691 
 692         if (int_status & CDNS_MCP_INT_PARITY) {
 693                 /* Parity error detected by Master */
 694                 dev_err_ratelimited(cdns->dev, "Parity error\n");
 695         }
 696 
 697         if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
 698                 /* Slave is driving bit slot during control word */
 699                 dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
 700         }
 701 
 702         if (int_status & CDNS_MCP_INT_DATA_CLASH) {
 703                 /*
 704                  * Multiple slaves trying to drive bit slot, or issue with
 705                  * ownership of data bits or Slave gone bonkers
 706                  */
 707                 dev_err_ratelimited(cdns->dev, "Bus clash for data word\n");
 708         }
 709 
 710         if (int_status & CDNS_MCP_INT_SLAVE_MASK) {
 711                 /* Mask the Slave interrupt and wake thread */
 712                 cdns_updatel(cdns, CDNS_MCP_INTMASK,
 713                              CDNS_MCP_INT_SLAVE_MASK, 0);
 714 
 715                 int_status &= ~CDNS_MCP_INT_SLAVE_MASK;
 716                 ret = IRQ_WAKE_THREAD;
 717         }
 718 
 719         cdns_writel(cdns, CDNS_MCP_INTSTAT, int_status);
 720         return ret;
 721 }
 722 EXPORT_SYMBOL(sdw_cdns_irq);
 723 
 724 /**
 725  * sdw_cdns_thread() - Cadence irq thread handler
 726  * @irq: irq number
 727  * @dev_id: irq context
 728  */
 729 irqreturn_t sdw_cdns_thread(int irq, void *dev_id)
 730 {
 731         struct sdw_cdns *cdns = dev_id;
 732         u32 slave0, slave1;
 733 
 734         dev_dbg_ratelimited(cdns->dev, "Slave status change\n");
 735 
 736         slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
 737         slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
 738 
 739         cdns_update_slave_status(cdns, slave0, slave1);
 740         cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0);
 741         cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1);
 742 
 743         /* clear and unmask Slave interrupt now */
 744         cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK);
 745         cdns_updatel(cdns, CDNS_MCP_INTMASK,
 746                      CDNS_MCP_INT_SLAVE_MASK, CDNS_MCP_INT_SLAVE_MASK);
 747 
 748         return IRQ_HANDLED;
 749 }
 750 EXPORT_SYMBOL(sdw_cdns_thread);
 751 
 752 /*
 753  * init routines
 754  */
 755 static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
 756 {
 757         u32 mask;
 758 
 759         cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
 760                     CDNS_MCP_SLAVE_INTMASK0_MASK);
 761         cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
 762                     CDNS_MCP_SLAVE_INTMASK1_MASK);
 763 
 764         /* enable detection of all slave state changes */
 765         mask = CDNS_MCP_INT_SLAVE_MASK;
 766 
 767         /* enable detection of bus issues */
 768         mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
 769                 CDNS_MCP_INT_PARITY;
 770 
 771         /* no detection of port interrupts for now */
 772 
 773         /* enable detection of RX fifo level */
 774         mask |= CDNS_MCP_INT_RX_WL;
 775 
 776         /*
 777          * CDNS_MCP_INT_IRQ needs to be set otherwise all previous
 778          * settings are irrelevant
 779          */
 780         mask |= CDNS_MCP_INT_IRQ;
 781 
 782         if (interrupt_mask) /* parameter override */
 783                 mask = interrupt_mask;
 784 
 785         cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
 786 
 787         return 0;
 788 }
 789 
 790 /**
 791  * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
 792  * @cdns: Cadence instance
 793  */
 794 int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
 795 {
 796         int ret;
 797 
 798         _cdns_enable_interrupt(cdns);
 799         ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
 800                              CDNS_MCP_CONFIG_UPDATE_BIT);
 801         if (ret < 0)
 802                 dev_err(cdns->dev, "Config update timedout\n");
 803 
 804         return ret;
 805 }
 806 EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
 807 
 808 static int cdns_allocate_pdi(struct sdw_cdns *cdns,
 809                              struct sdw_cdns_pdi **stream,
 810                              u32 num, u32 pdi_offset)
 811 {
 812         struct sdw_cdns_pdi *pdi;
 813         int i;
 814 
 815         if (!num)
 816                 return 0;
 817 
 818         pdi = devm_kcalloc(cdns->dev, num, sizeof(*pdi), GFP_KERNEL);
 819         if (!pdi)
 820                 return -ENOMEM;
 821 
 822         for (i = 0; i < num; i++) {
 823                 pdi[i].num = i + pdi_offset;
 824                 pdi[i].assigned = false;
 825         }
 826 
 827         *stream = pdi;
 828         return 0;
 829 }
 830 
 831 /**
 832  * sdw_cdns_pdi_init() - PDI initialization routine
 833  *
 834  * @cdns: Cadence instance
 835  * @config: Stream configurations
 836  */
 837 int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
 838                       struct sdw_cdns_stream_config config)
 839 {
 840         struct sdw_cdns_streams *stream;
 841         int offset, i, ret;
 842 
 843         cdns->pcm.num_bd = config.pcm_bd;
 844         cdns->pcm.num_in = config.pcm_in;
 845         cdns->pcm.num_out = config.pcm_out;
 846         cdns->pdm.num_bd = config.pdm_bd;
 847         cdns->pdm.num_in = config.pdm_in;
 848         cdns->pdm.num_out = config.pdm_out;
 849 
 850         /* Allocate PDIs for PCMs */
 851         stream = &cdns->pcm;
 852 
 853         /* First two PDIs are reserved for bulk transfers */
 854         if (stream->num_bd < CDNS_PCM_PDI_OFFSET)
 855                 return -EINVAL;
 856         stream->num_bd -= CDNS_PCM_PDI_OFFSET;
 857         offset = CDNS_PCM_PDI_OFFSET;
 858 
 859         ret = cdns_allocate_pdi(cdns, &stream->bd,
 860                                 stream->num_bd, offset);
 861         if (ret)
 862                 return ret;
 863 
 864         offset += stream->num_bd;
 865 
 866         ret = cdns_allocate_pdi(cdns, &stream->in,
 867                                 stream->num_in, offset);
 868         if (ret)
 869                 return ret;
 870 
 871         offset += stream->num_in;
 872 
 873         ret = cdns_allocate_pdi(cdns, &stream->out,
 874                                 stream->num_out, offset);
 875         if (ret)
 876                 return ret;
 877 
 878         /* Update total number of PCM PDIs */
 879         stream->num_pdi = stream->num_bd + stream->num_in + stream->num_out;
 880         cdns->num_ports = stream->num_pdi;
 881 
 882         /* Allocate PDIs for PDMs */
 883         stream = &cdns->pdm;
 884         offset = CDNS_PDM_PDI_OFFSET;
 885         ret = cdns_allocate_pdi(cdns, &stream->bd,
 886                                 stream->num_bd, offset);
 887         if (ret)
 888                 return ret;
 889 
 890         offset += stream->num_bd;
 891 
 892         ret = cdns_allocate_pdi(cdns, &stream->in,
 893                                 stream->num_in, offset);
 894         if (ret)
 895                 return ret;
 896 
 897         offset += stream->num_in;
 898 
 899         ret = cdns_allocate_pdi(cdns, &stream->out,
 900                                 stream->num_out, offset);
 901         if (ret)
 902                 return ret;
 903 
 904         /* Update total number of PDM PDIs */
 905         stream->num_pdi = stream->num_bd + stream->num_in + stream->num_out;
 906         cdns->num_ports += stream->num_pdi;
 907 
 908         cdns->ports = devm_kcalloc(cdns->dev, cdns->num_ports,
 909                                    sizeof(*cdns->ports), GFP_KERNEL);
 910         if (!cdns->ports) {
 911                 ret = -ENOMEM;
 912                 return ret;
 913         }
 914 
 915         for (i = 0; i < cdns->num_ports; i++) {
 916                 cdns->ports[i].assigned = false;
 917                 cdns->ports[i].num = i + 1; /* Port 0 reserved for bulk */
 918         }
 919 
 920         return 0;
 921 }
 922 EXPORT_SYMBOL(sdw_cdns_pdi_init);
 923 
 924 static u32 cdns_set_initial_frame_shape(int n_rows, int n_cols)
 925 {
 926         u32 val;
 927         int c;
 928         int r;
 929 
 930         r = sdw_find_row_index(n_rows);
 931         c = sdw_find_col_index(n_cols) & CDNS_MCP_FRAME_SHAPE_COL_MASK;
 932 
 933         val = (r << CDNS_MCP_FRAME_SHAPE_ROW_OFFSET) | c;
 934 
 935         return val;
 936 }
 937 
 938 /**
 939  * sdw_cdns_init() - Cadence initialization
 940  * @cdns: Cadence instance
 941  */
 942 int sdw_cdns_init(struct sdw_cdns *cdns)
 943 {
 944         struct sdw_bus *bus = &cdns->bus;
 945         struct sdw_master_prop *prop = &bus->prop;
 946         u32 val;
 947         int divider;
 948         int ret;
 949 
 950         /* Exit clock stop */
 951         ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
 952                              CDNS_MCP_CONTROL_CLK_STOP_CLR);
 953         if (ret < 0) {
 954                 dev_err(cdns->dev, "Couldn't exit from clock stop\n");
 955                 return ret;
 956         }
 957 
 958         /* Set clock divider */
 959         divider = (prop->mclk_freq / prop->max_clk_freq) - 1;
 960 
 961         cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0,
 962                      CDNS_MCP_CLK_MCLKD_MASK, divider);
 963         cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1,
 964                      CDNS_MCP_CLK_MCLKD_MASK, divider);
 965 
 966         /*
 967          * Frame shape changes after initialization have to be done
 968          * with the bank switch mechanism
 969          */
 970         val = cdns_set_initial_frame_shape(prop->default_row,
 971                                            prop->default_col);
 972         cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, val);
 973 
 974         /* Set SSP interval to default value */
 975         cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
 976         cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL);
 977 
 978         /* Set cmd accept mode */
 979         cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
 980                      CDNS_MCP_CONTROL_CMD_ACCEPT);
 981 
 982         /* Configure mcp config */
 983         val = cdns_readl(cdns, CDNS_MCP_CONFIG);
 984 
 985         /* Set Max cmd retry to 15 */
 986         val |= CDNS_MCP_CONFIG_MCMD_RETRY;
 987 
 988         /* Set frame delay between PREQ and ping frame to 15 frames */
 989         val |= 0xF << SDW_REG_SHIFT(CDNS_MCP_CONFIG_MPREQ_DELAY);
 990 
 991         /* Disable auto bus release */
 992         val &= ~CDNS_MCP_CONFIG_BUS_REL;
 993 
 994         /* Disable sniffer mode */
 995         val &= ~CDNS_MCP_CONFIG_SNIFFER;
 996 
 997         /* Set cmd mode for Tx and Rx cmds */
 998         val &= ~CDNS_MCP_CONFIG_CMD;
 999 
1000         /* Set operation to normal */
1001         val &= ~CDNS_MCP_CONFIG_OP;
1002         val |= CDNS_MCP_CONFIG_OP_NORMAL;
1003 
1004         cdns_writel(cdns, CDNS_MCP_CONFIG, val);
1005 
1006         return 0;
1007 }
1008 EXPORT_SYMBOL(sdw_cdns_init);
1009 
1010 int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
1011 {
1012         struct sdw_master_prop *prop = &bus->prop;
1013         struct sdw_cdns *cdns = bus_to_cdns(bus);
1014         int mcp_clkctrl_off;
1015         int divider;
1016 
1017         if (!params->curr_dr_freq) {
1018                 dev_err(cdns->dev, "NULL curr_dr_freq\n");
1019                 return -EINVAL;
1020         }
1021 
1022         divider = prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR /
1023                 params->curr_dr_freq;
1024         divider--; /* divider is 1/(N+1) */
1025 
1026         if (params->next_bank)
1027                 mcp_clkctrl_off = CDNS_MCP_CLK_CTRL1;
1028         else
1029                 mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
1030 
1031         cdns_updatel(cdns, mcp_clkctrl_off, CDNS_MCP_CLK_MCLKD_MASK, divider);
1032 
1033         return 0;
1034 }
1035 EXPORT_SYMBOL(cdns_bus_conf);
1036 
1037 static int cdns_port_params(struct sdw_bus *bus,
1038                             struct sdw_port_params *p_params, unsigned int bank)
1039 {
1040         struct sdw_cdns *cdns = bus_to_cdns(bus);
1041         int dpn_config = 0, dpn_config_off;
1042 
1043         if (bank)
1044                 dpn_config_off = CDNS_DPN_B1_CONFIG(p_params->num);
1045         else
1046                 dpn_config_off = CDNS_DPN_B0_CONFIG(p_params->num);
1047 
1048         dpn_config = cdns_readl(cdns, dpn_config_off);
1049 
1050         dpn_config |= ((p_params->bps - 1) <<
1051                                 SDW_REG_SHIFT(CDNS_DPN_CONFIG_WL));
1052         dpn_config |= (p_params->flow_mode <<
1053                                 SDW_REG_SHIFT(CDNS_DPN_CONFIG_PORT_FLOW));
1054         dpn_config |= (p_params->data_mode <<
1055                                 SDW_REG_SHIFT(CDNS_DPN_CONFIG_PORT_DAT));
1056 
1057         cdns_writel(cdns, dpn_config_off, dpn_config);
1058 
1059         return 0;
1060 }
1061 
1062 static int cdns_transport_params(struct sdw_bus *bus,
1063                                  struct sdw_transport_params *t_params,
1064                                  enum sdw_reg_bank bank)
1065 {
1066         struct sdw_cdns *cdns = bus_to_cdns(bus);
1067         int dpn_offsetctrl = 0, dpn_offsetctrl_off;
1068         int dpn_config = 0, dpn_config_off;
1069         int dpn_hctrl = 0, dpn_hctrl_off;
1070         int num = t_params->port_num;
1071         int dpn_samplectrl_off;
1072 
1073         /*
1074          * Note: Only full data port is supported on the Master side for
1075          * both PCM and PDM ports.
1076          */
1077 
1078         if (bank) {
1079                 dpn_config_off = CDNS_DPN_B1_CONFIG(num);
1080                 dpn_samplectrl_off = CDNS_DPN_B1_SAMPLE_CTRL(num);
1081                 dpn_hctrl_off = CDNS_DPN_B1_HCTRL(num);
1082                 dpn_offsetctrl_off = CDNS_DPN_B1_OFFSET_CTRL(num);
1083         } else {
1084                 dpn_config_off = CDNS_DPN_B0_CONFIG(num);
1085                 dpn_samplectrl_off = CDNS_DPN_B0_SAMPLE_CTRL(num);
1086                 dpn_hctrl_off = CDNS_DPN_B0_HCTRL(num);
1087                 dpn_offsetctrl_off = CDNS_DPN_B0_OFFSET_CTRL(num);
1088         }
1089 
1090         dpn_config = cdns_readl(cdns, dpn_config_off);
1091 
1092         dpn_config |= (t_params->blk_grp_ctrl <<
1093                                 SDW_REG_SHIFT(CDNS_DPN_CONFIG_BGC));
1094         dpn_config |= (t_params->blk_pkg_mode <<
1095                                 SDW_REG_SHIFT(CDNS_DPN_CONFIG_BPM));
1096         cdns_writel(cdns, dpn_config_off, dpn_config);
1097 
1098         dpn_offsetctrl |= (t_params->offset1 <<
1099                                 SDW_REG_SHIFT(CDNS_DPN_OFFSET_CTRL_1));
1100         dpn_offsetctrl |= (t_params->offset2 <<
1101                                 SDW_REG_SHIFT(CDNS_DPN_OFFSET_CTRL_2));
1102         cdns_writel(cdns, dpn_offsetctrl_off,  dpn_offsetctrl);
1103 
1104         dpn_hctrl |= (t_params->hstart <<
1105                                 SDW_REG_SHIFT(CDNS_DPN_HCTRL_HSTART));
1106         dpn_hctrl |= (t_params->hstop << SDW_REG_SHIFT(CDNS_DPN_HCTRL_HSTOP));
1107         dpn_hctrl |= (t_params->lane_ctrl <<
1108                                 SDW_REG_SHIFT(CDNS_DPN_HCTRL_LCTRL));
1109 
1110         cdns_writel(cdns, dpn_hctrl_off, dpn_hctrl);
1111         cdns_writel(cdns, dpn_samplectrl_off, (t_params->sample_interval - 1));
1112 
1113         return 0;
1114 }
1115 
1116 static int cdns_port_enable(struct sdw_bus *bus,
1117                             struct sdw_enable_ch *enable_ch, unsigned int bank)
1118 {
1119         struct sdw_cdns *cdns = bus_to_cdns(bus);
1120         int dpn_chnen_off, ch_mask;
1121 
1122         if (bank)
1123                 dpn_chnen_off = CDNS_DPN_B1_CH_EN(enable_ch->port_num);
1124         else
1125                 dpn_chnen_off = CDNS_DPN_B0_CH_EN(enable_ch->port_num);
1126 
1127         ch_mask = enable_ch->ch_mask * enable_ch->enable;
1128         cdns_writel(cdns, dpn_chnen_off, ch_mask);
1129 
1130         return 0;
1131 }
1132 
1133 static const struct sdw_master_port_ops cdns_port_ops = {
1134         .dpn_set_port_params = cdns_port_params,
1135         .dpn_set_port_transport_params = cdns_transport_params,
1136         .dpn_port_enable_ch = cdns_port_enable,
1137 };
1138 
1139 /**
1140  * sdw_cdns_probe() - Cadence probe routine
1141  * @cdns: Cadence instance
1142  */
1143 int sdw_cdns_probe(struct sdw_cdns *cdns)
1144 {
1145         init_completion(&cdns->tx_complete);
1146         cdns->bus.port_ops = &cdns_port_ops;
1147 
1148         return 0;
1149 }
1150 EXPORT_SYMBOL(sdw_cdns_probe);
1151 
1152 int cdns_set_sdw_stream(struct snd_soc_dai *dai,
1153                         void *stream, bool pcm, int direction)
1154 {
1155         struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
1156         struct sdw_cdns_dma_data *dma;
1157 
1158         dma = kzalloc(sizeof(*dma), GFP_KERNEL);
1159         if (!dma)
1160                 return -ENOMEM;
1161 
1162         if (pcm)
1163                 dma->stream_type = SDW_STREAM_PCM;
1164         else
1165                 dma->stream_type = SDW_STREAM_PDM;
1166 
1167         dma->bus = &cdns->bus;
1168         dma->link_id = cdns->instance;
1169 
1170         dma->stream = stream;
1171 
1172         if (direction == SNDRV_PCM_STREAM_PLAYBACK)
1173                 dai->playback_dma_data = dma;
1174         else
1175                 dai->capture_dma_data = dma;
1176 
1177         return 0;
1178 }
1179 EXPORT_SYMBOL(cdns_set_sdw_stream);
1180 
1181 /**
1182  * cdns_find_pdi() - Find a free PDI
1183  *
1184  * @cdns: Cadence instance
1185  * @num: Number of PDIs
1186  * @pdi: PDI instances
1187  *
1188  * Find and return a free PDI for a given PDI array
1189  */
1190 static struct sdw_cdns_pdi *cdns_find_pdi(struct sdw_cdns *cdns,
1191                                           unsigned int num,
1192                                           struct sdw_cdns_pdi *pdi)
1193 {
1194         int i;
1195 
1196         for (i = 0; i < num; i++) {
1197                 if (pdi[i].assigned)
1198                         continue;
1199                 pdi[i].assigned = true;
1200                 return &pdi[i];
1201         }
1202 
1203         return NULL;
1204 }
1205 
1206 /**
1207  * sdw_cdns_config_stream: Configure a stream
1208  *
1209  * @cdns: Cadence instance
1210  * @port: Cadence data port
1211  * @ch: Channel count
1212  * @dir: Data direction
1213  * @pdi: PDI to be used
1214  */
1215 void sdw_cdns_config_stream(struct sdw_cdns *cdns,
1216                             struct sdw_cdns_port *port,
1217                             u32 ch, u32 dir, struct sdw_cdns_pdi *pdi)
1218 {
1219         u32 offset, val = 0;
1220 
1221         if (dir == SDW_DATA_DIR_RX)
1222                 val = CDNS_PORTCTRL_DIRN;
1223 
1224         offset = CDNS_PORTCTRL + port->num * CDNS_PORT_OFFSET;
1225         cdns_updatel(cdns, offset, CDNS_PORTCTRL_DIRN, val);
1226 
1227         val = port->num;
1228         val |= ((1 << ch) - 1) << SDW_REG_SHIFT(CDNS_PDI_CONFIG_CHANNEL);
1229         cdns_writel(cdns, CDNS_PDI_CONFIG(pdi->num), val);
1230 }
1231 EXPORT_SYMBOL(sdw_cdns_config_stream);
1232 
1233 /**
1234  * cdns_get_num_pdi() - Get number of PDIs required
1235  *
1236  * @cdns: Cadence instance
1237  * @pdi: PDI to be used
1238  * @num: Number of PDIs
1239  * @ch_count: Channel count
1240  */
1241 static int cdns_get_num_pdi(struct sdw_cdns *cdns,
1242                             struct sdw_cdns_pdi *pdi,
1243                             unsigned int num, u32 ch_count)
1244 {
1245         int i, pdis = 0;
1246 
1247         for (i = 0; i < num; i++) {
1248                 if (pdi[i].assigned)
1249                         continue;
1250 
1251                 if (pdi[i].ch_count < ch_count)
1252                         ch_count -= pdi[i].ch_count;
1253                 else
1254                         ch_count = 0;
1255 
1256                 pdis++;
1257 
1258                 if (!ch_count)
1259                         break;
1260         }
1261 
1262         if (ch_count)
1263                 return 0;
1264 
1265         return pdis;
1266 }
1267 
1268 /**
1269  * sdw_cdns_get_stream() - Get stream information
1270  *
1271  * @cdns: Cadence instance
1272  * @stream: Stream to be allocated
1273  * @ch: Channel count
1274  * @dir: Data direction
1275  */
1276 int sdw_cdns_get_stream(struct sdw_cdns *cdns,
1277                         struct sdw_cdns_streams *stream,
1278                         u32 ch, u32 dir)
1279 {
1280         int pdis = 0;
1281 
1282         if (dir == SDW_DATA_DIR_RX)
1283                 pdis = cdns_get_num_pdi(cdns, stream->in, stream->num_in, ch);
1284         else
1285                 pdis = cdns_get_num_pdi(cdns, stream->out, stream->num_out, ch);
1286 
1287         /* check if we found PDI, else find in bi-directional */
1288         if (!pdis)
1289                 pdis = cdns_get_num_pdi(cdns, stream->bd, stream->num_bd, ch);
1290 
1291         return pdis;
1292 }
1293 EXPORT_SYMBOL(sdw_cdns_get_stream);
1294 
1295 /**
1296  * sdw_cdns_alloc_stream() - Allocate a stream
1297  *
1298  * @cdns: Cadence instance
1299  * @stream: Stream to be allocated
1300  * @port: Cadence data port
1301  * @ch: Channel count
1302  * @dir: Data direction
1303  */
1304 int sdw_cdns_alloc_stream(struct sdw_cdns *cdns,
1305                           struct sdw_cdns_streams *stream,
1306                           struct sdw_cdns_port *port, u32 ch, u32 dir)
1307 {
1308         struct sdw_cdns_pdi *pdi = NULL;
1309 
1310         if (dir == SDW_DATA_DIR_RX)
1311                 pdi = cdns_find_pdi(cdns, stream->num_in, stream->in);
1312         else
1313                 pdi = cdns_find_pdi(cdns, stream->num_out, stream->out);
1314 
1315         /* check if we found a PDI, else find in bi-directional */
1316         if (!pdi)
1317                 pdi = cdns_find_pdi(cdns, stream->num_bd, stream->bd);
1318 
1319         if (!pdi)
1320                 return -EIO;
1321 
1322         port->pdi = pdi;
1323         pdi->l_ch_num = 0;
1324         pdi->h_ch_num = ch - 1;
1325         pdi->dir = dir;
1326         pdi->ch_count = ch;
1327 
1328         return 0;
1329 }
1330 EXPORT_SYMBOL(sdw_cdns_alloc_stream);
1331 
1332 MODULE_LICENSE("Dual BSD/GPL");
1333 MODULE_DESCRIPTION("Cadence Soundwire Library");

/* [<][>][^][v][top][bottom][index][help] */