Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
0002 // Copyright(c) 2015-17 Intel Corporation.
0003 
0004 /*
0005  * Cadence SoundWire Master module
0006  * Used by Master driver
0007  */
0008 
0009 #include <linux/delay.h>
0010 #include <linux/device.h>
0011 #include <linux/debugfs.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/io.h>
0014 #include <linux/module.h>
0015 #include <linux/mod_devicetable.h>
0016 #include <linux/pm_runtime.h>
0017 #include <linux/soundwire/sdw_registers.h>
0018 #include <linux/soundwire/sdw.h>
0019 #include <sound/pcm_params.h>
0020 #include <sound/soc.h>
0021 #include <linux/workqueue.h>
0022 #include "bus.h"
0023 #include "cadence_master.h"
0024 
0025 static int interrupt_mask;
0026 module_param_named(cnds_mcp_int_mask, interrupt_mask, int, 0444);
0027 MODULE_PARM_DESC(cdns_mcp_int_mask, "Cadence MCP IntMask");
0028 
0029 #define CDNS_MCP_CONFIG             0x0
0030 
0031 #define CDNS_MCP_CONFIG_MCMD_RETRY      GENMASK(27, 24)
0032 #define CDNS_MCP_CONFIG_MPREQ_DELAY     GENMASK(20, 16)
0033 #define CDNS_MCP_CONFIG_MMASTER         BIT(7)
0034 #define CDNS_MCP_CONFIG_BUS_REL         BIT(6)
0035 #define CDNS_MCP_CONFIG_SNIFFER         BIT(5)
0036 #define CDNS_MCP_CONFIG_SSPMOD          BIT(4)
0037 #define CDNS_MCP_CONFIG_CMD         BIT(3)
0038 #define CDNS_MCP_CONFIG_OP          GENMASK(2, 0)
0039 #define CDNS_MCP_CONFIG_OP_NORMAL       0
0040 
0041 #define CDNS_MCP_CONTROL            0x4
0042 
0043 #define CDNS_MCP_CONTROL_RST_DELAY      GENMASK(10, 8)
0044 #define CDNS_MCP_CONTROL_CMD_RST        BIT(7)
0045 #define CDNS_MCP_CONTROL_SOFT_RST       BIT(6)
0046 #define CDNS_MCP_CONTROL_SW_RST         BIT(5)
0047 #define CDNS_MCP_CONTROL_HW_RST         BIT(4)
0048 #define CDNS_MCP_CONTROL_CLK_PAUSE      BIT(3)
0049 #define CDNS_MCP_CONTROL_CLK_STOP_CLR       BIT(2)
0050 #define CDNS_MCP_CONTROL_CMD_ACCEPT     BIT(1)
0051 #define CDNS_MCP_CONTROL_BLOCK_WAKEUP       BIT(0)
0052 
0053 #define CDNS_MCP_CMDCTRL            0x8
0054 
0055 #define CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR  BIT(2)
0056 
0057 #define CDNS_MCP_SSPSTAT            0xC
0058 #define CDNS_MCP_FRAME_SHAPE            0x10
0059 #define CDNS_MCP_FRAME_SHAPE_INIT       0x14
0060 #define CDNS_MCP_FRAME_SHAPE_COL_MASK       GENMASK(2, 0)
0061 #define CDNS_MCP_FRAME_SHAPE_ROW_MASK       GENMASK(7, 3)
0062 
0063 #define CDNS_MCP_CONFIG_UPDATE          0x18
0064 #define CDNS_MCP_CONFIG_UPDATE_BIT      BIT(0)
0065 
0066 #define CDNS_MCP_PHYCTRL            0x1C
0067 #define CDNS_MCP_SSP_CTRL0          0x20
0068 #define CDNS_MCP_SSP_CTRL1          0x28
0069 #define CDNS_MCP_CLK_CTRL0          0x30
0070 #define CDNS_MCP_CLK_CTRL1          0x38
0071 #define CDNS_MCP_CLK_MCLKD_MASK     GENMASK(7, 0)
0072 
0073 #define CDNS_MCP_STAT               0x40
0074 
0075 #define CDNS_MCP_STAT_ACTIVE_BANK       BIT(20)
0076 #define CDNS_MCP_STAT_CLK_STOP          BIT(16)
0077 
0078 #define CDNS_MCP_INTSTAT            0x44
0079 #define CDNS_MCP_INTMASK            0x48
0080 
0081 #define CDNS_MCP_INT_IRQ            BIT(31)
0082 #define CDNS_MCP_INT_RESERVED1          GENMASK(30, 17)
0083 #define CDNS_MCP_INT_WAKEUP         BIT(16)
0084 #define CDNS_MCP_INT_SLAVE_RSVD         BIT(15)
0085 #define CDNS_MCP_INT_SLAVE_ALERT        BIT(14)
0086 #define CDNS_MCP_INT_SLAVE_ATTACH       BIT(13)
0087 #define CDNS_MCP_INT_SLAVE_NATTACH      BIT(12)
0088 #define CDNS_MCP_INT_SLAVE_MASK         GENMASK(15, 12)
0089 #define CDNS_MCP_INT_DPINT          BIT(11)
0090 #define CDNS_MCP_INT_CTRL_CLASH         BIT(10)
0091 #define CDNS_MCP_INT_DATA_CLASH         BIT(9)
0092 #define CDNS_MCP_INT_PARITY         BIT(8)
0093 #define CDNS_MCP_INT_CMD_ERR            BIT(7)
0094 #define CDNS_MCP_INT_RESERVED2          GENMASK(6, 4)
0095 #define CDNS_MCP_INT_RX_NE          BIT(3)
0096 #define CDNS_MCP_INT_RX_WL          BIT(2)
0097 #define CDNS_MCP_INT_TXE            BIT(1)
0098 #define CDNS_MCP_INT_TXF            BIT(0)
0099 #define CDNS_MCP_INT_RESERVED (CDNS_MCP_INT_RESERVED1 | CDNS_MCP_INT_RESERVED2)
0100 
0101 #define CDNS_MCP_INTSET             0x4C
0102 
0103 #define CDNS_MCP_SLAVE_STAT         0x50
0104 #define CDNS_MCP_SLAVE_STAT_MASK        GENMASK(1, 0)
0105 
0106 #define CDNS_MCP_SLAVE_INTSTAT0         0x54
0107 #define CDNS_MCP_SLAVE_INTSTAT1         0x58
0108 #define CDNS_MCP_SLAVE_INTSTAT_NPRESENT     BIT(0)
0109 #define CDNS_MCP_SLAVE_INTSTAT_ATTACHED     BIT(1)
0110 #define CDNS_MCP_SLAVE_INTSTAT_ALERT        BIT(2)
0111 #define CDNS_MCP_SLAVE_INTSTAT_RESERVED     BIT(3)
0112 #define CDNS_MCP_SLAVE_STATUS_BITS      GENMASK(3, 0)
0113 #define CDNS_MCP_SLAVE_STATUS_NUM       4
0114 
0115 #define CDNS_MCP_SLAVE_INTMASK0         0x5C
0116 #define CDNS_MCP_SLAVE_INTMASK1         0x60
0117 
0118 #define CDNS_MCP_SLAVE_INTMASK0_MASK        GENMASK(31, 0)
0119 #define CDNS_MCP_SLAVE_INTMASK1_MASK        GENMASK(15, 0)
0120 
0121 #define CDNS_MCP_PORT_INTSTAT           0x64
0122 #define CDNS_MCP_PDI_STAT           0x6C
0123 
0124 #define CDNS_MCP_FIFOLEVEL          0x78
0125 #define CDNS_MCP_FIFOSTAT           0x7C
0126 #define CDNS_MCP_RX_FIFO_AVAIL          GENMASK(5, 0)
0127 
0128 #define CDNS_MCP_CMD_BASE           0x80
0129 #define CDNS_MCP_RESP_BASE          0x80
0130 #define CDNS_MCP_CMD_LEN            0x20
0131 #define CDNS_MCP_CMD_WORD_LEN           0x4
0132 
0133 #define CDNS_MCP_CMD_SSP_TAG            BIT(31)
0134 #define CDNS_MCP_CMD_COMMAND            GENMASK(30, 28)
0135 #define CDNS_MCP_CMD_DEV_ADDR           GENMASK(27, 24)
0136 #define CDNS_MCP_CMD_REG_ADDR           GENMASK(23, 8)
0137 #define CDNS_MCP_CMD_REG_DATA           GENMASK(7, 0)
0138 
0139 #define CDNS_MCP_CMD_READ           2
0140 #define CDNS_MCP_CMD_WRITE          3
0141 
0142 #define CDNS_MCP_RESP_RDATA         GENMASK(15, 8)
0143 #define CDNS_MCP_RESP_ACK           BIT(0)
0144 #define CDNS_MCP_RESP_NACK          BIT(1)
0145 
0146 #define CDNS_DP_SIZE                128
0147 
0148 #define CDNS_DPN_B0_CONFIG(n)           (0x100 + CDNS_DP_SIZE * (n))
0149 #define CDNS_DPN_B0_CH_EN(n)            (0x104 + CDNS_DP_SIZE * (n))
0150 #define CDNS_DPN_B0_SAMPLE_CTRL(n)      (0x108 + CDNS_DP_SIZE * (n))
0151 #define CDNS_DPN_B0_OFFSET_CTRL(n)      (0x10C + CDNS_DP_SIZE * (n))
0152 #define CDNS_DPN_B0_HCTRL(n)            (0x110 + CDNS_DP_SIZE * (n))
0153 #define CDNS_DPN_B0_ASYNC_CTRL(n)       (0x114 + CDNS_DP_SIZE * (n))
0154 
0155 #define CDNS_DPN_B1_CONFIG(n)           (0x118 + CDNS_DP_SIZE * (n))
0156 #define CDNS_DPN_B1_CH_EN(n)            (0x11C + CDNS_DP_SIZE * (n))
0157 #define CDNS_DPN_B1_SAMPLE_CTRL(n)      (0x120 + CDNS_DP_SIZE * (n))
0158 #define CDNS_DPN_B1_OFFSET_CTRL(n)      (0x124 + CDNS_DP_SIZE * (n))
0159 #define CDNS_DPN_B1_HCTRL(n)            (0x128 + CDNS_DP_SIZE * (n))
0160 #define CDNS_DPN_B1_ASYNC_CTRL(n)       (0x12C + CDNS_DP_SIZE * (n))
0161 
0162 #define CDNS_DPN_CONFIG_BPM         BIT(18)
0163 #define CDNS_DPN_CONFIG_BGC         GENMASK(17, 16)
0164 #define CDNS_DPN_CONFIG_WL          GENMASK(12, 8)
0165 #define CDNS_DPN_CONFIG_PORT_DAT        GENMASK(3, 2)
0166 #define CDNS_DPN_CONFIG_PORT_FLOW       GENMASK(1, 0)
0167 
0168 #define CDNS_DPN_SAMPLE_CTRL_SI         GENMASK(15, 0)
0169 
0170 #define CDNS_DPN_OFFSET_CTRL_1          GENMASK(7, 0)
0171 #define CDNS_DPN_OFFSET_CTRL_2          GENMASK(15, 8)
0172 
0173 #define CDNS_DPN_HCTRL_HSTOP            GENMASK(3, 0)
0174 #define CDNS_DPN_HCTRL_HSTART           GENMASK(7, 4)
0175 #define CDNS_DPN_HCTRL_LCTRL            GENMASK(10, 8)
0176 
0177 #define CDNS_PORTCTRL               0x130
0178 #define CDNS_PORTCTRL_TEST_FAILED       BIT(1)
0179 #define CDNS_PORTCTRL_DIRN          BIT(7)
0180 #define CDNS_PORTCTRL_BANK_INVERT       BIT(8)
0181 
0182 #define CDNS_PORT_OFFSET            0x80
0183 
0184 #define CDNS_PDI_CONFIG(n)          (0x1100 + (n) * 16)
0185 
0186 #define CDNS_PDI_CONFIG_SOFT_RESET      BIT(24)
0187 #define CDNS_PDI_CONFIG_CHANNEL         GENMASK(15, 8)
0188 #define CDNS_PDI_CONFIG_PORT            GENMASK(4, 0)
0189 
0190 /* Driver defaults */
0191 #define CDNS_TX_TIMEOUT             500
0192 
0193 #define CDNS_SCP_RX_FIFOLEVEL           0x2
0194 
0195 /*
0196  * register accessor helpers
0197  */
0198 static inline u32 cdns_readl(struct sdw_cdns *cdns, int offset)
0199 {
0200     return readl(cdns->registers + offset);
0201 }
0202 
0203 static inline void cdns_writel(struct sdw_cdns *cdns, int offset, u32 value)
0204 {
0205     writel(value, cdns->registers + offset);
0206 }
0207 
0208 static inline void cdns_updatel(struct sdw_cdns *cdns,
0209                 int offset, u32 mask, u32 val)
0210 {
0211     u32 tmp;
0212 
0213     tmp = cdns_readl(cdns, offset);
0214     tmp = (tmp & ~mask) | val;
0215     cdns_writel(cdns, offset, tmp);
0216 }
0217 
0218 static int cdns_set_wait(struct sdw_cdns *cdns, int offset, u32 mask, u32 value)
0219 {
0220     int timeout = 10;
0221     u32 reg_read;
0222 
0223     /* Wait for bit to be set */
0224     do {
0225         reg_read = readl(cdns->registers + offset);
0226         if ((reg_read & mask) == value)
0227             return 0;
0228 
0229         timeout--;
0230         usleep_range(50, 100);
0231     } while (timeout != 0);
0232 
0233     return -ETIMEDOUT;
0234 }
0235 
0236 static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
0237 {
0238     writel(value, cdns->registers + offset);
0239 
0240     /* Wait for bit to be self cleared */
0241     return cdns_set_wait(cdns, offset, value, 0);
0242 }
0243 
0244 /*
0245  * all changes to the MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL
0246  * need to be confirmed with a write to MCP_CONFIG_UPDATE
0247  */
0248 static int cdns_config_update(struct sdw_cdns *cdns)
0249 {
0250     int ret;
0251 
0252     if (sdw_cdns_is_clock_stop(cdns)) {
0253         dev_err(cdns->dev, "Cannot program MCP_CONFIG_UPDATE in ClockStopMode\n");
0254         return -EINVAL;
0255     }
0256 
0257     ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
0258                  CDNS_MCP_CONFIG_UPDATE_BIT);
0259     if (ret < 0)
0260         dev_err(cdns->dev, "Config update timedout\n");
0261 
0262     return ret;
0263 }
0264 
0265 /*
0266  * debugfs
0267  */
0268 #ifdef CONFIG_DEBUG_FS
0269 
0270 #define RD_BUF (2 * PAGE_SIZE)
0271 
0272 static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
0273                 char *buf, size_t pos, unsigned int reg)
0274 {
0275     return scnprintf(buf + pos, RD_BUF - pos,
0276              "%4x\t%8x\n", reg, cdns_readl(cdns, reg));
0277 }
0278 
0279 static int cdns_reg_show(struct seq_file *s, void *data)
0280 {
0281     struct sdw_cdns *cdns = s->private;
0282     char *buf;
0283     ssize_t ret;
0284     int num_ports;
0285     int i, j;
0286 
0287     buf = kzalloc(RD_BUF, GFP_KERNEL);
0288     if (!buf)
0289         return -ENOMEM;
0290 
0291     ret = scnprintf(buf, RD_BUF, "Register  Value\n");
0292     ret += scnprintf(buf + ret, RD_BUF - ret, "\nMCP Registers\n");
0293     /* 8 MCP registers */
0294     for (i = CDNS_MCP_CONFIG; i <= CDNS_MCP_PHYCTRL; i += sizeof(u32))
0295         ret += cdns_sprintf(cdns, buf, ret, i);
0296 
0297     ret += scnprintf(buf + ret, RD_BUF - ret,
0298              "\nStatus & Intr Registers\n");
0299     /* 13 Status & Intr registers (offsets 0x70 and 0x74 not defined) */
0300     for (i = CDNS_MCP_STAT; i <=  CDNS_MCP_FIFOSTAT; i += sizeof(u32))
0301         ret += cdns_sprintf(cdns, buf, ret, i);
0302 
0303     ret += scnprintf(buf + ret, RD_BUF - ret,
0304              "\nSSP & Clk ctrl Registers\n");
0305     ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL0);
0306     ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL1);
0307     ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL0);
0308     ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL1);
0309 
0310     ret += scnprintf(buf + ret, RD_BUF - ret,
0311              "\nDPn B0 Registers\n");
0312 
0313     num_ports = cdns->num_ports;
0314 
0315     for (i = 0; i < num_ports; i++) {
0316         ret += scnprintf(buf + ret, RD_BUF - ret,
0317                  "\nDP-%d\n", i);
0318         for (j = CDNS_DPN_B0_CONFIG(i);
0319              j < CDNS_DPN_B0_ASYNC_CTRL(i); j += sizeof(u32))
0320             ret += cdns_sprintf(cdns, buf, ret, j);
0321     }
0322 
0323     ret += scnprintf(buf + ret, RD_BUF - ret,
0324              "\nDPn B1 Registers\n");
0325     for (i = 0; i < num_ports; i++) {
0326         ret += scnprintf(buf + ret, RD_BUF - ret,
0327                  "\nDP-%d\n", i);
0328 
0329         for (j = CDNS_DPN_B1_CONFIG(i);
0330              j < CDNS_DPN_B1_ASYNC_CTRL(i); j += sizeof(u32))
0331             ret += cdns_sprintf(cdns, buf, ret, j);
0332     }
0333 
0334     ret += scnprintf(buf + ret, RD_BUF - ret,
0335              "\nDPn Control Registers\n");
0336     for (i = 0; i < num_ports; i++)
0337         ret += cdns_sprintf(cdns, buf, ret,
0338                 CDNS_PORTCTRL + i * CDNS_PORT_OFFSET);
0339 
0340     ret += scnprintf(buf + ret, RD_BUF - ret,
0341              "\nPDIn Config Registers\n");
0342 
0343     /* number of PDI and ports is interchangeable */
0344     for (i = 0; i < num_ports; i++)
0345         ret += cdns_sprintf(cdns, buf, ret, CDNS_PDI_CONFIG(i));
0346 
0347     seq_printf(s, "%s", buf);
0348     kfree(buf);
0349 
0350     return 0;
0351 }
0352 DEFINE_SHOW_ATTRIBUTE(cdns_reg);
0353 
0354 static int cdns_hw_reset(void *data, u64 value)
0355 {
0356     struct sdw_cdns *cdns = data;
0357     int ret;
0358 
0359     if (value != 1)
0360         return -EINVAL;
0361 
0362     /* Userspace changed the hardware state behind the kernel's back */
0363     add_taint(TAINT_USER, LOCKDEP_STILL_OK);
0364 
0365     ret = sdw_cdns_exit_reset(cdns);
0366 
0367     dev_dbg(cdns->dev, "link hw_reset done: %d\n", ret);
0368 
0369     return ret;
0370 }
0371 
0372 DEFINE_DEBUGFS_ATTRIBUTE(cdns_hw_reset_fops, NULL, cdns_hw_reset, "%llu\n");
0373 
0374 static int cdns_parity_error_injection(void *data, u64 value)
0375 {
0376     struct sdw_cdns *cdns = data;
0377     struct sdw_bus *bus;
0378     int ret;
0379 
0380     if (value != 1)
0381         return -EINVAL;
0382 
0383     bus = &cdns->bus;
0384 
0385     /*
0386      * Resume Master device. If this results in a bus reset, the
0387      * Slave devices will re-attach and be re-enumerated.
0388      */
0389     ret = pm_runtime_resume_and_get(bus->dev);
0390     if (ret < 0 && ret != -EACCES) {
0391         dev_err_ratelimited(cdns->dev,
0392                     "pm_runtime_resume_and_get failed in %s, ret %d\n",
0393                     __func__, ret);
0394         return ret;
0395     }
0396 
0397     /*
0398      * wait long enough for Slave(s) to be in steady state. This
0399      * does not need to be super precise.
0400      */
0401     msleep(200);
0402 
0403     /*
0404      * Take the bus lock here to make sure that any bus transactions
0405      * will be queued while we inject a parity error on a dummy read
0406      */
0407     mutex_lock(&bus->bus_lock);
0408 
0409     /* program hardware to inject parity error */
0410     cdns_updatel(cdns, CDNS_MCP_CMDCTRL,
0411              CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR,
0412              CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR);
0413 
0414     /* commit changes */
0415     cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
0416              CDNS_MCP_CONFIG_UPDATE_BIT,
0417              CDNS_MCP_CONFIG_UPDATE_BIT);
0418 
0419     /* do a broadcast dummy read to avoid bus clashes */
0420     ret = sdw_bread_no_pm_unlocked(&cdns->bus, 0xf, SDW_SCP_DEVID_0);
0421     dev_info(cdns->dev, "parity error injection, read: %d\n", ret);
0422 
0423     /* program hardware to disable parity error */
0424     cdns_updatel(cdns, CDNS_MCP_CMDCTRL,
0425              CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR,
0426              0);
0427 
0428     /* commit changes */
0429     cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
0430              CDNS_MCP_CONFIG_UPDATE_BIT,
0431              CDNS_MCP_CONFIG_UPDATE_BIT);
0432 
0433     /* Continue bus operation with parity error injection disabled */
0434     mutex_unlock(&bus->bus_lock);
0435 
0436     /* Userspace changed the hardware state behind the kernel's back */
0437     add_taint(TAINT_USER, LOCKDEP_STILL_OK);
0438 
0439     /*
0440      * allow Master device to enter pm_runtime suspend. This may
0441      * also result in Slave devices suspending.
0442      */
0443     pm_runtime_mark_last_busy(bus->dev);
0444     pm_runtime_put_autosuspend(bus->dev);
0445 
0446     return 0;
0447 }
0448 
0449 DEFINE_DEBUGFS_ATTRIBUTE(cdns_parity_error_fops, NULL,
0450              cdns_parity_error_injection, "%llu\n");
0451 
0452 static int cdns_set_pdi_loopback_source(void *data, u64 value)
0453 {
0454     struct sdw_cdns *cdns = data;
0455     unsigned int pdi_out_num = cdns->pcm.num_bd + cdns->pcm.num_out;
0456 
0457     if (value > pdi_out_num)
0458         return -EINVAL;
0459 
0460     /* Userspace changed the hardware state behind the kernel's back */
0461     add_taint(TAINT_USER, LOCKDEP_STILL_OK);
0462 
0463     cdns->pdi_loopback_source = value;
0464 
0465     return 0;
0466 }
0467 DEFINE_DEBUGFS_ATTRIBUTE(cdns_pdi_loopback_source_fops, NULL, cdns_set_pdi_loopback_source, "%llu\n");
0468 
0469 static int cdns_set_pdi_loopback_target(void *data, u64 value)
0470 {
0471     struct sdw_cdns *cdns = data;
0472     unsigned int pdi_in_num = cdns->pcm.num_bd + cdns->pcm.num_in;
0473 
0474     if (value > pdi_in_num)
0475         return -EINVAL;
0476 
0477     /* Userspace changed the hardware state behind the kernel's back */
0478     add_taint(TAINT_USER, LOCKDEP_STILL_OK);
0479 
0480     cdns->pdi_loopback_target = value;
0481 
0482     return 0;
0483 }
0484 DEFINE_DEBUGFS_ATTRIBUTE(cdns_pdi_loopback_target_fops, NULL, cdns_set_pdi_loopback_target, "%llu\n");
0485 
0486 /**
0487  * sdw_cdns_debugfs_init() - Cadence debugfs init
0488  * @cdns: Cadence instance
0489  * @root: debugfs root
0490  */
0491 void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root)
0492 {
0493     debugfs_create_file("cdns-registers", 0400, root, cdns, &cdns_reg_fops);
0494 
0495     debugfs_create_file("cdns-hw-reset", 0200, root, cdns,
0496                 &cdns_hw_reset_fops);
0497 
0498     debugfs_create_file("cdns-parity-error-injection", 0200, root, cdns,
0499                 &cdns_parity_error_fops);
0500 
0501     cdns->pdi_loopback_source = -1;
0502     cdns->pdi_loopback_target = -1;
0503 
0504     debugfs_create_file("cdns-pdi-loopback-source", 0200, root, cdns,
0505                 &cdns_pdi_loopback_source_fops);
0506 
0507     debugfs_create_file("cdns-pdi-loopback-target", 0200, root, cdns,
0508                 &cdns_pdi_loopback_target_fops);
0509 
0510 }
0511 EXPORT_SYMBOL_GPL(sdw_cdns_debugfs_init);
0512 
0513 #endif /* CONFIG_DEBUG_FS */
0514 
0515 /*
0516  * IO Calls
0517  */
0518 static enum sdw_command_response
0519 cdns_fill_msg_resp(struct sdw_cdns *cdns,
0520            struct sdw_msg *msg, int count, int offset)
0521 {
0522     int nack = 0, no_ack = 0;
0523     int i;
0524 
0525     /* check message response */
0526     for (i = 0; i < count; i++) {
0527         if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
0528             no_ack = 1;
0529             dev_vdbg(cdns->dev, "Msg Ack not received, cmd %d\n", i);
0530         }
0531         if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
0532             nack = 1;
0533             dev_err_ratelimited(cdns->dev, "Msg NACK received, cmd %d\n", i);
0534         }
0535     }
0536 
0537     if (nack) {
0538         dev_err_ratelimited(cdns->dev, "Msg NACKed for Slave %d\n", msg->dev_num);
0539         return SDW_CMD_FAIL;
0540     }
0541 
0542     if (no_ack) {
0543         dev_dbg_ratelimited(cdns->dev, "Msg ignored for Slave %d\n", msg->dev_num);
0544         return SDW_CMD_IGNORED;
0545     }
0546 
0547     /* fill response */
0548     for (i = 0; i < count; i++)
0549         msg->buf[i + offset] = FIELD_GET(CDNS_MCP_RESP_RDATA, cdns->response_buf[i]);
0550 
0551     return SDW_CMD_OK;
0552 }
0553 
0554 static enum sdw_command_response
0555 _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
0556            int offset, int count, bool defer)
0557 {
0558     unsigned long time;
0559     u32 base, i, data;
0560     u16 addr;
0561 
0562     /* Program the watermark level for RX FIFO */
0563     if (cdns->msg_count != count) {
0564         cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, count);
0565         cdns->msg_count = count;
0566     }
0567 
0568     base = CDNS_MCP_CMD_BASE;
0569     addr = msg->addr;
0570 
0571     for (i = 0; i < count; i++) {
0572         data = FIELD_PREP(CDNS_MCP_CMD_DEV_ADDR, msg->dev_num);
0573         data |= FIELD_PREP(CDNS_MCP_CMD_COMMAND, cmd);
0574         data |= FIELD_PREP(CDNS_MCP_CMD_REG_ADDR, addr);
0575         addr++;
0576 
0577         if (msg->flags == SDW_MSG_FLAG_WRITE)
0578             data |= msg->buf[i + offset];
0579 
0580         data |= FIELD_PREP(CDNS_MCP_CMD_SSP_TAG, msg->ssp_sync);
0581         cdns_writel(cdns, base, data);
0582         base += CDNS_MCP_CMD_WORD_LEN;
0583     }
0584 
0585     if (defer)
0586         return SDW_CMD_OK;
0587 
0588     /* wait for timeout or response */
0589     time = wait_for_completion_timeout(&cdns->tx_complete,
0590                        msecs_to_jiffies(CDNS_TX_TIMEOUT));
0591     if (!time) {
0592         dev_err(cdns->dev, "IO transfer timed out, cmd %d device %d addr %x len %d\n",
0593             cmd, msg->dev_num, msg->addr, msg->len);
0594         msg->len = 0;
0595         return SDW_CMD_TIMEOUT;
0596     }
0597 
0598     return cdns_fill_msg_resp(cdns, msg, count, offset);
0599 }
0600 
0601 static enum sdw_command_response
0602 cdns_program_scp_addr(struct sdw_cdns *cdns, struct sdw_msg *msg)
0603 {
0604     int nack = 0, no_ack = 0;
0605     unsigned long time;
0606     u32 data[2], base;
0607     int i;
0608 
0609     /* Program the watermark level for RX FIFO */
0610     if (cdns->msg_count != CDNS_SCP_RX_FIFOLEVEL) {
0611         cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, CDNS_SCP_RX_FIFOLEVEL);
0612         cdns->msg_count = CDNS_SCP_RX_FIFOLEVEL;
0613     }
0614 
0615     data[0] = FIELD_PREP(CDNS_MCP_CMD_DEV_ADDR, msg->dev_num);
0616     data[0] |= FIELD_PREP(CDNS_MCP_CMD_COMMAND, 0x3);
0617     data[1] = data[0];
0618 
0619     data[0] |= FIELD_PREP(CDNS_MCP_CMD_REG_ADDR, SDW_SCP_ADDRPAGE1);
0620     data[1] |= FIELD_PREP(CDNS_MCP_CMD_REG_ADDR, SDW_SCP_ADDRPAGE2);
0621 
0622     data[0] |= msg->addr_page1;
0623     data[1] |= msg->addr_page2;
0624 
0625     base = CDNS_MCP_CMD_BASE;
0626     cdns_writel(cdns, base, data[0]);
0627     base += CDNS_MCP_CMD_WORD_LEN;
0628     cdns_writel(cdns, base, data[1]);
0629 
0630     time = wait_for_completion_timeout(&cdns->tx_complete,
0631                        msecs_to_jiffies(CDNS_TX_TIMEOUT));
0632     if (!time) {
0633         dev_err(cdns->dev, "SCP Msg trf timed out\n");
0634         msg->len = 0;
0635         return SDW_CMD_TIMEOUT;
0636     }
0637 
0638     /* check response the writes */
0639     for (i = 0; i < 2; i++) {
0640         if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
0641             no_ack = 1;
0642             dev_err(cdns->dev, "Program SCP Ack not received\n");
0643             if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
0644                 nack = 1;
0645                 dev_err(cdns->dev, "Program SCP NACK received\n");
0646             }
0647         }
0648     }
0649 
0650     /* For NACK, NO ack, don't return err if we are in Broadcast mode */
0651     if (nack) {
0652         dev_err_ratelimited(cdns->dev,
0653                     "SCP_addrpage NACKed for Slave %d\n", msg->dev_num);
0654         return SDW_CMD_FAIL;
0655     }
0656 
0657     if (no_ack) {
0658         dev_dbg_ratelimited(cdns->dev,
0659                     "SCP_addrpage ignored for Slave %d\n", msg->dev_num);
0660         return SDW_CMD_IGNORED;
0661     }
0662 
0663     return SDW_CMD_OK;
0664 }
0665 
0666 static int cdns_prep_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int *cmd)
0667 {
0668     int ret;
0669 
0670     if (msg->page) {
0671         ret = cdns_program_scp_addr(cdns, msg);
0672         if (ret) {
0673             msg->len = 0;
0674             return ret;
0675         }
0676     }
0677 
0678     switch (msg->flags) {
0679     case SDW_MSG_FLAG_READ:
0680         *cmd = CDNS_MCP_CMD_READ;
0681         break;
0682 
0683     case SDW_MSG_FLAG_WRITE:
0684         *cmd = CDNS_MCP_CMD_WRITE;
0685         break;
0686 
0687     default:
0688         dev_err(cdns->dev, "Invalid msg cmd: %d\n", msg->flags);
0689         return -EINVAL;
0690     }
0691 
0692     return 0;
0693 }
0694 
0695 enum sdw_command_response
0696 cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg)
0697 {
0698     struct sdw_cdns *cdns = bus_to_cdns(bus);
0699     int cmd = 0, ret, i;
0700 
0701     ret = cdns_prep_msg(cdns, msg, &cmd);
0702     if (ret)
0703         return SDW_CMD_FAIL_OTHER;
0704 
0705     for (i = 0; i < msg->len / CDNS_MCP_CMD_LEN; i++) {
0706         ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
0707                      CDNS_MCP_CMD_LEN, false);
0708         if (ret < 0)
0709             goto exit;
0710     }
0711 
0712     if (!(msg->len % CDNS_MCP_CMD_LEN))
0713         goto exit;
0714 
0715     ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
0716                  msg->len % CDNS_MCP_CMD_LEN, false);
0717 
0718 exit:
0719     return ret;
0720 }
0721 EXPORT_SYMBOL(cdns_xfer_msg);
0722 
0723 enum sdw_command_response
0724 cdns_xfer_msg_defer(struct sdw_bus *bus,
0725             struct sdw_msg *msg, struct sdw_defer *defer)
0726 {
0727     struct sdw_cdns *cdns = bus_to_cdns(bus);
0728     int cmd = 0, ret;
0729 
0730     /* for defer only 1 message is supported */
0731     if (msg->len > 1)
0732         return -ENOTSUPP;
0733 
0734     ret = cdns_prep_msg(cdns, msg, &cmd);
0735     if (ret)
0736         return SDW_CMD_FAIL_OTHER;
0737 
0738     cdns->defer = defer;
0739     cdns->defer->length = msg->len;
0740 
0741     return _cdns_xfer_msg(cdns, msg, cmd, 0, msg->len, true);
0742 }
0743 EXPORT_SYMBOL(cdns_xfer_msg_defer);
0744 
0745 enum sdw_command_response
0746 cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num)
0747 {
0748     struct sdw_cdns *cdns = bus_to_cdns(bus);
0749     struct sdw_msg msg;
0750 
0751     /* Create dummy message with valid device number */
0752     memset(&msg, 0, sizeof(msg));
0753     msg.dev_num = dev_num;
0754 
0755     return cdns_program_scp_addr(cdns, &msg);
0756 }
0757 EXPORT_SYMBOL(cdns_reset_page_addr);
0758 
0759 /*
0760  * IRQ handling
0761  */
0762 
0763 static void cdns_read_response(struct sdw_cdns *cdns)
0764 {
0765     u32 num_resp, cmd_base;
0766     int i;
0767 
0768     num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
0769     num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
0770 
0771     cmd_base = CDNS_MCP_CMD_BASE;
0772 
0773     for (i = 0; i < num_resp; i++) {
0774         cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
0775         cmd_base += CDNS_MCP_CMD_WORD_LEN;
0776     }
0777 }
0778 
0779 static int cdns_update_slave_status(struct sdw_cdns *cdns,
0780                     u64 slave_intstat)
0781 {
0782     enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
0783     bool is_slave = false;
0784     u32 mask;
0785     int i, set_status;
0786 
0787     memset(status, 0, sizeof(status));
0788 
0789     for (i = 0; i <= SDW_MAX_DEVICES; i++) {
0790         mask = (slave_intstat >> (i * CDNS_MCP_SLAVE_STATUS_NUM)) &
0791             CDNS_MCP_SLAVE_STATUS_BITS;
0792         if (!mask)
0793             continue;
0794 
0795         is_slave = true;
0796         set_status = 0;
0797 
0798         if (mask & CDNS_MCP_SLAVE_INTSTAT_RESERVED) {
0799             status[i] = SDW_SLAVE_RESERVED;
0800             set_status++;
0801         }
0802 
0803         if (mask & CDNS_MCP_SLAVE_INTSTAT_ATTACHED) {
0804             status[i] = SDW_SLAVE_ATTACHED;
0805             set_status++;
0806         }
0807 
0808         if (mask & CDNS_MCP_SLAVE_INTSTAT_ALERT) {
0809             status[i] = SDW_SLAVE_ALERT;
0810             set_status++;
0811         }
0812 
0813         if (mask & CDNS_MCP_SLAVE_INTSTAT_NPRESENT) {
0814             status[i] = SDW_SLAVE_UNATTACHED;
0815             set_status++;
0816         }
0817 
0818         /* first check if Slave reported multiple status */
0819         if (set_status > 1) {
0820             u32 val;
0821 
0822             dev_warn_ratelimited(cdns->dev,
0823                          "Slave %d reported multiple Status: %d\n",
0824                          i, mask);
0825 
0826             /* check latest status extracted from PING commands */
0827             val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
0828             val >>= (i * 2);
0829 
0830             switch (val & 0x3) {
0831             case 0:
0832                 status[i] = SDW_SLAVE_UNATTACHED;
0833                 break;
0834             case 1:
0835                 status[i] = SDW_SLAVE_ATTACHED;
0836                 break;
0837             case 2:
0838                 status[i] = SDW_SLAVE_ALERT;
0839                 break;
0840             case 3:
0841             default:
0842                 status[i] = SDW_SLAVE_RESERVED;
0843                 break;
0844             }
0845 
0846             dev_warn_ratelimited(cdns->dev,
0847                          "Slave %d status updated to %d\n",
0848                          i, status[i]);
0849 
0850         }
0851     }
0852 
0853     if (is_slave)
0854         return sdw_handle_slave_status(&cdns->bus, status);
0855 
0856     return 0;
0857 }
0858 
0859 /**
0860  * sdw_cdns_irq() - Cadence interrupt handler
0861  * @irq: irq number
0862  * @dev_id: irq context
0863  */
0864 irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
0865 {
0866     struct sdw_cdns *cdns = dev_id;
0867     u32 int_status;
0868 
0869     /* Check if the link is up */
0870     if (!cdns->link_up)
0871         return IRQ_NONE;
0872 
0873     int_status = cdns_readl(cdns, CDNS_MCP_INTSTAT);
0874 
0875     /* check for reserved values read as zero */
0876     if (int_status & CDNS_MCP_INT_RESERVED)
0877         return IRQ_NONE;
0878 
0879     if (!(int_status & CDNS_MCP_INT_IRQ))
0880         return IRQ_NONE;
0881 
0882     if (int_status & CDNS_MCP_INT_RX_WL) {
0883         cdns_read_response(cdns);
0884 
0885         if (cdns->defer) {
0886             cdns_fill_msg_resp(cdns, cdns->defer->msg,
0887                        cdns->defer->length, 0);
0888             complete(&cdns->defer->complete);
0889             cdns->defer = NULL;
0890         } else {
0891             complete(&cdns->tx_complete);
0892         }
0893     }
0894 
0895     if (int_status & CDNS_MCP_INT_PARITY) {
0896         /* Parity error detected by Master */
0897         dev_err_ratelimited(cdns->dev, "Parity error\n");
0898     }
0899 
0900     if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
0901         /* Slave is driving bit slot during control word */
0902         dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
0903     }
0904 
0905     if (int_status & CDNS_MCP_INT_DATA_CLASH) {
0906         /*
0907          * Multiple slaves trying to drive bit slot, or issue with
0908          * ownership of data bits or Slave gone bonkers
0909          */
0910         dev_err_ratelimited(cdns->dev, "Bus clash for data word\n");
0911     }
0912 
0913     if (cdns->bus.params.m_data_mode != SDW_PORT_DATA_MODE_NORMAL &&
0914         int_status & CDNS_MCP_INT_DPINT) {
0915         u32 port_intstat;
0916 
0917         /* just log which ports report an error */
0918         port_intstat = cdns_readl(cdns, CDNS_MCP_PORT_INTSTAT);
0919         dev_err_ratelimited(cdns->dev, "DP interrupt: PortIntStat %8x\n",
0920                     port_intstat);
0921 
0922         /* clear status w/ write1 */
0923         cdns_writel(cdns, CDNS_MCP_PORT_INTSTAT, port_intstat);
0924     }
0925 
0926     if (int_status & CDNS_MCP_INT_SLAVE_MASK) {
0927         /* Mask the Slave interrupt and wake thread */
0928         cdns_updatel(cdns, CDNS_MCP_INTMASK,
0929                  CDNS_MCP_INT_SLAVE_MASK, 0);
0930 
0931         int_status &= ~CDNS_MCP_INT_SLAVE_MASK;
0932 
0933         /*
0934          * Deal with possible race condition between interrupt
0935          * handling and disabling interrupts on suspend.
0936          *
0937          * If the master is in the process of disabling
0938          * interrupts, don't schedule a workqueue
0939          */
0940         if (cdns->interrupt_enabled)
0941             schedule_work(&cdns->work);
0942     }
0943 
0944     cdns_writel(cdns, CDNS_MCP_INTSTAT, int_status);
0945     return IRQ_HANDLED;
0946 }
0947 EXPORT_SYMBOL(sdw_cdns_irq);
0948 
0949 /**
0950  * cdns_update_slave_status_work - update slave status in a work since we will need to handle
0951  * other interrupts eg. CDNS_MCP_INT_RX_WL during the update slave
0952  * process.
0953  * @work: cdns worker thread
0954  */
0955 static void cdns_update_slave_status_work(struct work_struct *work)
0956 {
0957     struct sdw_cdns *cdns =
0958         container_of(work, struct sdw_cdns, work);
0959     u32 slave0, slave1;
0960     u64 slave_intstat;
0961     u32 device0_status;
0962     int retry_count = 0;
0963 
0964     slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
0965     slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
0966 
0967     /* combine the two status */
0968     slave_intstat = ((u64)slave1 << 32) | slave0;
0969 
0970     dev_dbg_ratelimited(cdns->dev, "Slave status change: 0x%llx\n", slave_intstat);
0971 
0972 update_status:
0973     cdns_update_slave_status(cdns, slave_intstat);
0974     cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0);
0975     cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1);
0976 
0977     /*
0978      * When there is more than one peripheral per link, it's
0979      * possible that a deviceB becomes attached after we deal with
0980      * the attachment of deviceA. Since the hardware does a
0981      * logical AND, the attachment of the second device does not
0982      * change the status seen by the driver.
0983      *
0984      * In that case, clearing the registers above would result in
0985      * the deviceB never being detected - until a change of status
0986      * is observed on the bus.
0987      *
0988      * To avoid this race condition, re-check if any device0 needs
0989      * attention with PING commands. There is no need to check for
0990      * ALERTS since they are not allowed until a non-zero
0991      * device_number is assigned.
0992      */
0993 
0994     device0_status = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
0995     device0_status &= 3;
0996 
0997     if (device0_status == SDW_SLAVE_ATTACHED) {
0998         if (retry_count++ < SDW_MAX_DEVICES) {
0999             dev_dbg_ratelimited(cdns->dev,
1000                         "Device0 detected after clearing status, iteration %d\n",
1001                         retry_count);
1002             slave_intstat = CDNS_MCP_SLAVE_INTSTAT_ATTACHED;
1003             goto update_status;
1004         } else {
1005             dev_err_ratelimited(cdns->dev,
1006                         "Device0 detected after %d iterations\n",
1007                         retry_count);
1008         }
1009     }
1010 
1011     /* clear and unmask Slave interrupt now */
1012     cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK);
1013     cdns_updatel(cdns, CDNS_MCP_INTMASK,
1014              CDNS_MCP_INT_SLAVE_MASK, CDNS_MCP_INT_SLAVE_MASK);
1015 
1016 }
1017 
1018 /* paranoia check to make sure self-cleared bits are indeed cleared */
1019 void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string,
1020                        bool initial_delay, int reset_iterations)
1021 {
1022     u32 mcp_control;
1023     u32 mcp_config_update;
1024     int i;
1025 
1026     if (initial_delay)
1027         usleep_range(1000, 1500);
1028 
1029     mcp_control = cdns_readl(cdns, CDNS_MCP_CONTROL);
1030 
1031     /* the following bits should be cleared immediately */
1032     if (mcp_control & CDNS_MCP_CONTROL_CMD_RST)
1033         dev_err(cdns->dev, "%s failed: MCP_CONTROL_CMD_RST is not cleared\n", string);
1034     if (mcp_control & CDNS_MCP_CONTROL_SOFT_RST)
1035         dev_err(cdns->dev, "%s failed: MCP_CONTROL_SOFT_RST is not cleared\n", string);
1036     if (mcp_control & CDNS_MCP_CONTROL_SW_RST)
1037         dev_err(cdns->dev, "%s failed: MCP_CONTROL_SW_RST is not cleared\n", string);
1038     if (mcp_control & CDNS_MCP_CONTROL_CLK_STOP_CLR)
1039         dev_err(cdns->dev, "%s failed: MCP_CONTROL_CLK_STOP_CLR is not cleared\n", string);
1040     mcp_config_update = cdns_readl(cdns, CDNS_MCP_CONFIG_UPDATE);
1041     if (mcp_config_update & CDNS_MCP_CONFIG_UPDATE_BIT)
1042         dev_err(cdns->dev, "%s failed: MCP_CONFIG_UPDATE_BIT is not cleared\n", string);
1043 
1044     i = 0;
1045     while (mcp_control & CDNS_MCP_CONTROL_HW_RST) {
1046         if (i == reset_iterations) {
1047             dev_err(cdns->dev, "%s failed: MCP_CONTROL_HW_RST is not cleared\n", string);
1048             break;
1049         }
1050 
1051         dev_dbg(cdns->dev, "%s: MCP_CONTROL_HW_RST is not cleared at iteration %d\n", string, i);
1052         i++;
1053 
1054         usleep_range(1000, 1500);
1055         mcp_control = cdns_readl(cdns, CDNS_MCP_CONTROL);
1056     }
1057 
1058 }
1059 EXPORT_SYMBOL(sdw_cdns_check_self_clearing_bits);
1060 
1061 /*
1062  * init routines
1063  */
1064 
1065 /**
1066  * sdw_cdns_exit_reset() - Program reset parameters and start bus operations
1067  * @cdns: Cadence instance
1068  */
1069 int sdw_cdns_exit_reset(struct sdw_cdns *cdns)
1070 {
1071     /* keep reset delay unchanged to 4096 cycles */
1072 
1073     /* use hardware generated reset */
1074     cdns_updatel(cdns, CDNS_MCP_CONTROL,
1075              CDNS_MCP_CONTROL_HW_RST,
1076              CDNS_MCP_CONTROL_HW_RST);
1077 
1078     /* commit changes */
1079     cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
1080              CDNS_MCP_CONFIG_UPDATE_BIT,
1081              CDNS_MCP_CONFIG_UPDATE_BIT);
1082 
1083     /* don't wait here */
1084     return 0;
1085 
1086 }
1087 EXPORT_SYMBOL(sdw_cdns_exit_reset);
1088 
1089 /**
1090  * cdns_enable_slave_interrupts() - Enable SDW slave interrupts
1091  * @cdns: Cadence instance
1092  * @state: boolean for true/false
1093  */
1094 static void cdns_enable_slave_interrupts(struct sdw_cdns *cdns, bool state)
1095 {
1096     u32 mask;
1097 
1098     mask = cdns_readl(cdns, CDNS_MCP_INTMASK);
1099     if (state)
1100         mask |= CDNS_MCP_INT_SLAVE_MASK;
1101     else
1102         mask &= ~CDNS_MCP_INT_SLAVE_MASK;
1103 
1104     cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
1105 }
1106 
1107 /**
1108  * sdw_cdns_enable_interrupt() - Enable SDW interrupts
1109  * @cdns: Cadence instance
1110  * @state: True if we are trying to enable interrupt.
1111  */
1112 int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state)
1113 {
1114     u32 slave_intmask0 = 0;
1115     u32 slave_intmask1 = 0;
1116     u32 mask = 0;
1117 
1118     if (!state)
1119         goto update_masks;
1120 
1121     slave_intmask0 = CDNS_MCP_SLAVE_INTMASK0_MASK;
1122     slave_intmask1 = CDNS_MCP_SLAVE_INTMASK1_MASK;
1123 
1124     /* enable detection of all slave state changes */
1125     mask = CDNS_MCP_INT_SLAVE_MASK;
1126 
1127     /* enable detection of bus issues */
1128     mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
1129         CDNS_MCP_INT_PARITY;
1130 
1131     /* port interrupt limited to test modes for now */
1132     if (cdns->bus.params.m_data_mode != SDW_PORT_DATA_MODE_NORMAL)
1133         mask |= CDNS_MCP_INT_DPINT;
1134 
1135     /* enable detection of RX fifo level */
1136     mask |= CDNS_MCP_INT_RX_WL;
1137 
1138     /*
1139      * CDNS_MCP_INT_IRQ needs to be set otherwise all previous
1140      * settings are irrelevant
1141      */
1142     mask |= CDNS_MCP_INT_IRQ;
1143 
1144     if (interrupt_mask) /* parameter override */
1145         mask = interrupt_mask;
1146 
1147 update_masks:
1148     /* clear slave interrupt status before enabling interrupt */
1149     if (state) {
1150         u32 slave_state;
1151 
1152         slave_state = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
1153         cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave_state);
1154         slave_state = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
1155         cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave_state);
1156     }
1157     cdns->interrupt_enabled = state;
1158 
1159     /*
1160      * Complete any on-going status updates before updating masks,
1161      * and cancel queued status updates.
1162      *
1163      * There could be a race with a new interrupt thrown before
1164      * the 3 mask updates below are complete, so in the interrupt
1165      * we use the 'interrupt_enabled' status to prevent new work
1166      * from being queued.
1167      */
1168     if (!state)
1169         cancel_work_sync(&cdns->work);
1170 
1171     cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0, slave_intmask0);
1172     cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1, slave_intmask1);
1173     cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
1174 
1175     return 0;
1176 }
1177 EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
1178 
1179 static int cdns_allocate_pdi(struct sdw_cdns *cdns,
1180                  struct sdw_cdns_pdi **stream,
1181                  u32 num, u32 pdi_offset)
1182 {
1183     struct sdw_cdns_pdi *pdi;
1184     int i;
1185 
1186     if (!num)
1187         return 0;
1188 
1189     pdi = devm_kcalloc(cdns->dev, num, sizeof(*pdi), GFP_KERNEL);
1190     if (!pdi)
1191         return -ENOMEM;
1192 
1193     for (i = 0; i < num; i++) {
1194         pdi[i].num = i + pdi_offset;
1195     }
1196 
1197     *stream = pdi;
1198     return 0;
1199 }
1200 
1201 /**
1202  * sdw_cdns_pdi_init() - PDI initialization routine
1203  *
1204  * @cdns: Cadence instance
1205  * @config: Stream configurations
1206  */
1207 int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
1208               struct sdw_cdns_stream_config config)
1209 {
1210     struct sdw_cdns_streams *stream;
1211     int offset;
1212     int ret;
1213 
1214     cdns->pcm.num_bd = config.pcm_bd;
1215     cdns->pcm.num_in = config.pcm_in;
1216     cdns->pcm.num_out = config.pcm_out;
1217 
1218     /* Allocate PDIs for PCMs */
1219     stream = &cdns->pcm;
1220 
1221     /* we allocate PDI0 and PDI1 which are used for Bulk */
1222     offset = 0;
1223 
1224     ret = cdns_allocate_pdi(cdns, &stream->bd,
1225                 stream->num_bd, offset);
1226     if (ret)
1227         return ret;
1228 
1229     offset += stream->num_bd;
1230 
1231     ret = cdns_allocate_pdi(cdns, &stream->in,
1232                 stream->num_in, offset);
1233     if (ret)
1234         return ret;
1235 
1236     offset += stream->num_in;
1237 
1238     ret = cdns_allocate_pdi(cdns, &stream->out,
1239                 stream->num_out, offset);
1240     if (ret)
1241         return ret;
1242 
1243     /* Update total number of PCM PDIs */
1244     stream->num_pdi = stream->num_bd + stream->num_in + stream->num_out;
1245     cdns->num_ports = stream->num_pdi;
1246 
1247     return 0;
1248 }
1249 EXPORT_SYMBOL(sdw_cdns_pdi_init);
1250 
1251 static u32 cdns_set_initial_frame_shape(int n_rows, int n_cols)
1252 {
1253     u32 val;
1254     int c;
1255     int r;
1256 
1257     r = sdw_find_row_index(n_rows);
1258     c = sdw_find_col_index(n_cols);
1259 
1260     val = FIELD_PREP(CDNS_MCP_FRAME_SHAPE_ROW_MASK, r);
1261     val |= FIELD_PREP(CDNS_MCP_FRAME_SHAPE_COL_MASK, c);
1262 
1263     return val;
1264 }
1265 
1266 static void cdns_init_clock_ctrl(struct sdw_cdns *cdns)
1267 {
1268     struct sdw_bus *bus = &cdns->bus;
1269     struct sdw_master_prop *prop = &bus->prop;
1270     u32 val;
1271     u32 ssp_interval;
1272     int divider;
1273 
1274     /* Set clock divider */
1275     divider = (prop->mclk_freq / prop->max_clk_freq) - 1;
1276 
1277     cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0,
1278              CDNS_MCP_CLK_MCLKD_MASK, divider);
1279     cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1,
1280              CDNS_MCP_CLK_MCLKD_MASK, divider);
1281 
1282     /*
1283      * Frame shape changes after initialization have to be done
1284      * with the bank switch mechanism
1285      */
1286     val = cdns_set_initial_frame_shape(prop->default_row,
1287                        prop->default_col);
1288     cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, val);
1289 
1290     /* Set SSP interval to default value */
1291     ssp_interval = prop->default_frame_rate / SDW_CADENCE_GSYNC_HZ;
1292     cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, ssp_interval);
1293     cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, ssp_interval);
1294 }
1295 
1296 /**
1297  * sdw_cdns_init() - Cadence initialization
1298  * @cdns: Cadence instance
1299  */
1300 int sdw_cdns_init(struct sdw_cdns *cdns)
1301 {
1302     u32 val;
1303 
1304     cdns_init_clock_ctrl(cdns);
1305 
1306     sdw_cdns_check_self_clearing_bits(cdns, __func__, false, 0);
1307 
1308     /* reset msg_count to default value of FIFOLEVEL */
1309     cdns->msg_count = cdns_readl(cdns, CDNS_MCP_FIFOLEVEL);
1310 
1311     /* flush command FIFOs */
1312     cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_RST,
1313              CDNS_MCP_CONTROL_CMD_RST);
1314 
1315     /* Set cmd accept mode */
1316     cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
1317              CDNS_MCP_CONTROL_CMD_ACCEPT);
1318 
1319     /* Configure mcp config */
1320     val = cdns_readl(cdns, CDNS_MCP_CONFIG);
1321 
1322     /* enable bus operations with clock and data */
1323     val &= ~CDNS_MCP_CONFIG_OP;
1324     val |= CDNS_MCP_CONFIG_OP_NORMAL;
1325 
1326     /* Set cmd mode for Tx and Rx cmds */
1327     val &= ~CDNS_MCP_CONFIG_CMD;
1328 
1329     /* Disable sniffer mode */
1330     val &= ~CDNS_MCP_CONFIG_SNIFFER;
1331 
1332     /* Disable auto bus release */
1333     val &= ~CDNS_MCP_CONFIG_BUS_REL;
1334 
1335     if (cdns->bus.multi_link)
1336         /* Set Multi-master mode to take gsync into account */
1337         val |= CDNS_MCP_CONFIG_MMASTER;
1338 
1339     /* leave frame delay to hardware default of 0x1F */
1340 
1341     /* leave command retry to hardware default of 0 */
1342 
1343     cdns_writel(cdns, CDNS_MCP_CONFIG, val);
1344 
1345     /* changes will be committed later */
1346     return 0;
1347 }
1348 EXPORT_SYMBOL(sdw_cdns_init);
1349 
1350 int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
1351 {
1352     struct sdw_master_prop *prop = &bus->prop;
1353     struct sdw_cdns *cdns = bus_to_cdns(bus);
1354     int mcp_clkctrl_off;
1355     int divider;
1356 
1357     if (!params->curr_dr_freq) {
1358         dev_err(cdns->dev, "NULL curr_dr_freq\n");
1359         return -EINVAL;
1360     }
1361 
1362     divider = prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR /
1363         params->curr_dr_freq;
1364     divider--; /* divider is 1/(N+1) */
1365 
1366     if (params->next_bank)
1367         mcp_clkctrl_off = CDNS_MCP_CLK_CTRL1;
1368     else
1369         mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
1370 
1371     cdns_updatel(cdns, mcp_clkctrl_off, CDNS_MCP_CLK_MCLKD_MASK, divider);
1372 
1373     return 0;
1374 }
1375 EXPORT_SYMBOL(cdns_bus_conf);
1376 
1377 static int cdns_port_params(struct sdw_bus *bus,
1378                 struct sdw_port_params *p_params, unsigned int bank)
1379 {
1380     struct sdw_cdns *cdns = bus_to_cdns(bus);
1381     int dpn_config_off_source;
1382     int dpn_config_off_target;
1383     int target_num = p_params->num;
1384     int source_num = p_params->num;
1385     bool override = false;
1386     int dpn_config;
1387 
1388     if (target_num == cdns->pdi_loopback_target &&
1389         cdns->pdi_loopback_source != -1) {
1390         source_num = cdns->pdi_loopback_source;
1391         override = true;
1392     }
1393 
1394     if (bank) {
1395         dpn_config_off_source = CDNS_DPN_B1_CONFIG(source_num);
1396         dpn_config_off_target = CDNS_DPN_B1_CONFIG(target_num);
1397     } else {
1398         dpn_config_off_source = CDNS_DPN_B0_CONFIG(source_num);
1399         dpn_config_off_target = CDNS_DPN_B0_CONFIG(target_num);
1400     }
1401 
1402     dpn_config = cdns_readl(cdns, dpn_config_off_source);
1403 
1404     /* use port params if there is no loopback, otherwise use source as is */
1405     if (!override) {
1406         u32p_replace_bits(&dpn_config, p_params->bps - 1, CDNS_DPN_CONFIG_WL);
1407         u32p_replace_bits(&dpn_config, p_params->flow_mode, CDNS_DPN_CONFIG_PORT_FLOW);
1408         u32p_replace_bits(&dpn_config, p_params->data_mode, CDNS_DPN_CONFIG_PORT_DAT);
1409     }
1410 
1411     cdns_writel(cdns, dpn_config_off_target, dpn_config);
1412 
1413     return 0;
1414 }
1415 
1416 static int cdns_transport_params(struct sdw_bus *bus,
1417                  struct sdw_transport_params *t_params,
1418                  enum sdw_reg_bank bank)
1419 {
1420     struct sdw_cdns *cdns = bus_to_cdns(bus);
1421     int dpn_config;
1422     int dpn_config_off_source;
1423     int dpn_config_off_target;
1424     int dpn_hctrl;
1425     int dpn_hctrl_off_source;
1426     int dpn_hctrl_off_target;
1427     int dpn_offsetctrl;
1428     int dpn_offsetctrl_off_source;
1429     int dpn_offsetctrl_off_target;
1430     int dpn_samplectrl;
1431     int dpn_samplectrl_off_source;
1432     int dpn_samplectrl_off_target;
1433     int source_num = t_params->port_num;
1434     int target_num = t_params->port_num;
1435     bool override = false;
1436 
1437     if (target_num == cdns->pdi_loopback_target &&
1438         cdns->pdi_loopback_source != -1) {
1439         source_num = cdns->pdi_loopback_source;
1440         override = true;
1441     }
1442 
1443     /*
1444      * Note: Only full data port is supported on the Master side for
1445      * both PCM and PDM ports.
1446      */
1447 
1448     if (bank) {
1449         dpn_config_off_source = CDNS_DPN_B1_CONFIG(source_num);
1450         dpn_hctrl_off_source = CDNS_DPN_B1_HCTRL(source_num);
1451         dpn_offsetctrl_off_source = CDNS_DPN_B1_OFFSET_CTRL(source_num);
1452         dpn_samplectrl_off_source = CDNS_DPN_B1_SAMPLE_CTRL(source_num);
1453 
1454         dpn_config_off_target = CDNS_DPN_B1_CONFIG(target_num);
1455         dpn_hctrl_off_target = CDNS_DPN_B1_HCTRL(target_num);
1456         dpn_offsetctrl_off_target = CDNS_DPN_B1_OFFSET_CTRL(target_num);
1457         dpn_samplectrl_off_target = CDNS_DPN_B1_SAMPLE_CTRL(target_num);
1458 
1459     } else {
1460         dpn_config_off_source = CDNS_DPN_B0_CONFIG(source_num);
1461         dpn_hctrl_off_source = CDNS_DPN_B0_HCTRL(source_num);
1462         dpn_offsetctrl_off_source = CDNS_DPN_B0_OFFSET_CTRL(source_num);
1463         dpn_samplectrl_off_source = CDNS_DPN_B0_SAMPLE_CTRL(source_num);
1464 
1465         dpn_config_off_target = CDNS_DPN_B0_CONFIG(target_num);
1466         dpn_hctrl_off_target = CDNS_DPN_B0_HCTRL(target_num);
1467         dpn_offsetctrl_off_target = CDNS_DPN_B0_OFFSET_CTRL(target_num);
1468         dpn_samplectrl_off_target = CDNS_DPN_B0_SAMPLE_CTRL(target_num);
1469     }
1470 
1471     dpn_config = cdns_readl(cdns, dpn_config_off_source);
1472     if (!override) {
1473         u32p_replace_bits(&dpn_config, t_params->blk_grp_ctrl, CDNS_DPN_CONFIG_BGC);
1474         u32p_replace_bits(&dpn_config, t_params->blk_pkg_mode, CDNS_DPN_CONFIG_BPM);
1475     }
1476     cdns_writel(cdns, dpn_config_off_target, dpn_config);
1477 
1478     if (!override) {
1479         dpn_offsetctrl = 0;
1480         u32p_replace_bits(&dpn_offsetctrl, t_params->offset1, CDNS_DPN_OFFSET_CTRL_1);
1481         u32p_replace_bits(&dpn_offsetctrl, t_params->offset2, CDNS_DPN_OFFSET_CTRL_2);
1482     } else {
1483         dpn_offsetctrl = cdns_readl(cdns, dpn_offsetctrl_off_source);
1484     }
1485     cdns_writel(cdns, dpn_offsetctrl_off_target,  dpn_offsetctrl);
1486 
1487     if (!override) {
1488         dpn_hctrl = 0;
1489         u32p_replace_bits(&dpn_hctrl, t_params->hstart, CDNS_DPN_HCTRL_HSTART);
1490         u32p_replace_bits(&dpn_hctrl, t_params->hstop, CDNS_DPN_HCTRL_HSTOP);
1491         u32p_replace_bits(&dpn_hctrl, t_params->lane_ctrl, CDNS_DPN_HCTRL_LCTRL);
1492     } else {
1493         dpn_hctrl = cdns_readl(cdns, dpn_hctrl_off_source);
1494     }
1495     cdns_writel(cdns, dpn_hctrl_off_target, dpn_hctrl);
1496 
1497     if (!override)
1498         dpn_samplectrl = t_params->sample_interval - 1;
1499     else
1500         dpn_samplectrl = cdns_readl(cdns, dpn_samplectrl_off_source);
1501     cdns_writel(cdns, dpn_samplectrl_off_target, dpn_samplectrl);
1502 
1503     return 0;
1504 }
1505 
1506 static int cdns_port_enable(struct sdw_bus *bus,
1507                 struct sdw_enable_ch *enable_ch, unsigned int bank)
1508 {
1509     struct sdw_cdns *cdns = bus_to_cdns(bus);
1510     int dpn_chnen_off, ch_mask;
1511 
1512     if (bank)
1513         dpn_chnen_off = CDNS_DPN_B1_CH_EN(enable_ch->port_num);
1514     else
1515         dpn_chnen_off = CDNS_DPN_B0_CH_EN(enable_ch->port_num);
1516 
1517     ch_mask = enable_ch->ch_mask * enable_ch->enable;
1518     cdns_writel(cdns, dpn_chnen_off, ch_mask);
1519 
1520     return 0;
1521 }
1522 
1523 static const struct sdw_master_port_ops cdns_port_ops = {
1524     .dpn_set_port_params = cdns_port_params,
1525     .dpn_set_port_transport_params = cdns_transport_params,
1526     .dpn_port_enable_ch = cdns_port_enable,
1527 };
1528 
1529 /**
1530  * sdw_cdns_is_clock_stop: Check clock status
1531  *
1532  * @cdns: Cadence instance
1533  */
1534 bool sdw_cdns_is_clock_stop(struct sdw_cdns *cdns)
1535 {
1536     return !!(cdns_readl(cdns, CDNS_MCP_STAT) & CDNS_MCP_STAT_CLK_STOP);
1537 }
1538 EXPORT_SYMBOL(sdw_cdns_is_clock_stop);
1539 
1540 /**
1541  * sdw_cdns_clock_stop: Cadence clock stop configuration routine
1542  *
1543  * @cdns: Cadence instance
1544  * @block_wake: prevent wakes if required by the platform
1545  */
1546 int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
1547 {
1548     bool slave_present = false;
1549     struct sdw_slave *slave;
1550     int ret;
1551 
1552     sdw_cdns_check_self_clearing_bits(cdns, __func__, false, 0);
1553 
1554     /* Check suspend status */
1555     if (sdw_cdns_is_clock_stop(cdns)) {
1556         dev_dbg(cdns->dev, "Clock is already stopped\n");
1557         return 0;
1558     }
1559 
1560     /*
1561      * Before entering clock stop we mask the Slave
1562      * interrupts. This helps avoid having to deal with e.g. a
1563      * Slave becoming UNATTACHED while the clock is being stopped
1564      */
1565     cdns_enable_slave_interrupts(cdns, false);
1566 
1567     /*
1568      * For specific platforms, it is required to be able to put
1569      * master into a state in which it ignores wake-up trials
1570      * in clock stop state
1571      */
1572     if (block_wake)
1573         cdns_updatel(cdns, CDNS_MCP_CONTROL,
1574                  CDNS_MCP_CONTROL_BLOCK_WAKEUP,
1575                  CDNS_MCP_CONTROL_BLOCK_WAKEUP);
1576 
1577     list_for_each_entry(slave, &cdns->bus.slaves, node) {
1578         if (slave->status == SDW_SLAVE_ATTACHED ||
1579             slave->status == SDW_SLAVE_ALERT) {
1580             slave_present = true;
1581             break;
1582         }
1583     }
1584 
1585     /* commit changes */
1586     ret = cdns_config_update(cdns);
1587     if (ret < 0) {
1588         dev_err(cdns->dev, "%s: config_update failed\n", __func__);
1589         return ret;
1590     }
1591 
1592     /* Prepare slaves for clock stop */
1593     if (slave_present) {
1594         ret = sdw_bus_prep_clk_stop(&cdns->bus);
1595         if (ret < 0 && ret != -ENODATA) {
1596             dev_err(cdns->dev, "prepare clock stop failed %d\n", ret);
1597             return ret;
1598         }
1599     }
1600 
1601     /*
1602      * Enter clock stop mode and only report errors if there are
1603      * Slave devices present (ALERT or ATTACHED)
1604      */
1605     ret = sdw_bus_clk_stop(&cdns->bus);
1606     if (ret < 0 && slave_present && ret != -ENODATA) {
1607         dev_err(cdns->dev, "bus clock stop failed %d\n", ret);
1608         return ret;
1609     }
1610 
1611     ret = cdns_set_wait(cdns, CDNS_MCP_STAT,
1612                 CDNS_MCP_STAT_CLK_STOP,
1613                 CDNS_MCP_STAT_CLK_STOP);
1614     if (ret < 0)
1615         dev_err(cdns->dev, "Clock stop failed %d\n", ret);
1616 
1617     return ret;
1618 }
1619 EXPORT_SYMBOL(sdw_cdns_clock_stop);
1620 
1621 /**
1622  * sdw_cdns_clock_restart: Cadence PM clock restart configuration routine
1623  *
1624  * @cdns: Cadence instance
1625  * @bus_reset: context may be lost while in low power modes and the bus
1626  * may require a Severe Reset and re-enumeration after a wake.
1627  */
1628 int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset)
1629 {
1630     int ret;
1631 
1632     /* unmask Slave interrupts that were masked when stopping the clock */
1633     cdns_enable_slave_interrupts(cdns, true);
1634 
1635     ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
1636                  CDNS_MCP_CONTROL_CLK_STOP_CLR);
1637     if (ret < 0) {
1638         dev_err(cdns->dev, "Couldn't exit from clock stop\n");
1639         return ret;
1640     }
1641 
1642     ret = cdns_set_wait(cdns, CDNS_MCP_STAT, CDNS_MCP_STAT_CLK_STOP, 0);
1643     if (ret < 0) {
1644         dev_err(cdns->dev, "clock stop exit failed %d\n", ret);
1645         return ret;
1646     }
1647 
1648     cdns_updatel(cdns, CDNS_MCP_CONTROL,
1649              CDNS_MCP_CONTROL_BLOCK_WAKEUP, 0);
1650 
1651     cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
1652              CDNS_MCP_CONTROL_CMD_ACCEPT);
1653 
1654     if (!bus_reset) {
1655 
1656         /* enable bus operations with clock and data */
1657         cdns_updatel(cdns, CDNS_MCP_CONFIG,
1658                  CDNS_MCP_CONFIG_OP,
1659                  CDNS_MCP_CONFIG_OP_NORMAL);
1660 
1661         ret = cdns_config_update(cdns);
1662         if (ret < 0) {
1663             dev_err(cdns->dev, "%s: config_update failed\n", __func__);
1664             return ret;
1665         }
1666 
1667         ret = sdw_bus_exit_clk_stop(&cdns->bus);
1668         if (ret < 0)
1669             dev_err(cdns->dev, "bus failed to exit clock stop %d\n", ret);
1670     }
1671 
1672     return ret;
1673 }
1674 EXPORT_SYMBOL(sdw_cdns_clock_restart);
1675 
1676 /**
1677  * sdw_cdns_probe() - Cadence probe routine
1678  * @cdns: Cadence instance
1679  */
1680 int sdw_cdns_probe(struct sdw_cdns *cdns)
1681 {
1682     init_completion(&cdns->tx_complete);
1683     cdns->bus.port_ops = &cdns_port_ops;
1684 
1685     INIT_WORK(&cdns->work, cdns_update_slave_status_work);
1686     return 0;
1687 }
1688 EXPORT_SYMBOL(sdw_cdns_probe);
1689 
1690 int cdns_set_sdw_stream(struct snd_soc_dai *dai,
1691             void *stream, int direction)
1692 {
1693     struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
1694     struct sdw_cdns_dma_data *dma;
1695 
1696     if (stream) {
1697         /* first paranoia check */
1698         if (direction == SNDRV_PCM_STREAM_PLAYBACK)
1699             dma = dai->playback_dma_data;
1700         else
1701             dma = dai->capture_dma_data;
1702 
1703         if (dma) {
1704             dev_err(dai->dev,
1705                 "dma_data already allocated for dai %s\n",
1706                 dai->name);
1707             return -EINVAL;
1708         }
1709 
1710         /* allocate and set dma info */
1711         dma = kzalloc(sizeof(*dma), GFP_KERNEL);
1712         if (!dma)
1713             return -ENOMEM;
1714 
1715         dma->stream_type = SDW_STREAM_PCM;
1716 
1717         dma->bus = &cdns->bus;
1718         dma->link_id = cdns->instance;
1719 
1720         dma->stream = stream;
1721 
1722         if (direction == SNDRV_PCM_STREAM_PLAYBACK)
1723             dai->playback_dma_data = dma;
1724         else
1725             dai->capture_dma_data = dma;
1726     } else {
1727         /* for NULL stream we release allocated dma_data */
1728         if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
1729             kfree(dai->playback_dma_data);
1730             dai->playback_dma_data = NULL;
1731         } else {
1732             kfree(dai->capture_dma_data);
1733             dai->capture_dma_data = NULL;
1734         }
1735     }
1736     return 0;
1737 }
1738 EXPORT_SYMBOL(cdns_set_sdw_stream);
1739 
1740 /**
1741  * cdns_find_pdi() - Find a free PDI
1742  *
1743  * @cdns: Cadence instance
1744  * @offset: Starting offset
1745  * @num: Number of PDIs
1746  * @pdi: PDI instances
1747  * @dai_id: DAI id
1748  *
1749  * Find a PDI for a given PDI array. The PDI num and dai_id are
1750  * expected to match, return NULL otherwise.
1751  */
1752 static struct sdw_cdns_pdi *cdns_find_pdi(struct sdw_cdns *cdns,
1753                       unsigned int offset,
1754                       unsigned int num,
1755                       struct sdw_cdns_pdi *pdi,
1756                       int dai_id)
1757 {
1758     int i;
1759 
1760     for (i = offset; i < offset + num; i++)
1761         if (pdi[i].num == dai_id)
1762             return &pdi[i];
1763 
1764     return NULL;
1765 }
1766 
1767 /**
1768  * sdw_cdns_config_stream: Configure a stream
1769  *
1770  * @cdns: Cadence instance
1771  * @ch: Channel count
1772  * @dir: Data direction
1773  * @pdi: PDI to be used
1774  */
1775 void sdw_cdns_config_stream(struct sdw_cdns *cdns,
1776                 u32 ch, u32 dir, struct sdw_cdns_pdi *pdi)
1777 {
1778     u32 offset, val = 0;
1779 
1780     if (dir == SDW_DATA_DIR_RX) {
1781         val = CDNS_PORTCTRL_DIRN;
1782 
1783         if (cdns->bus.params.m_data_mode != SDW_PORT_DATA_MODE_NORMAL)
1784             val |= CDNS_PORTCTRL_TEST_FAILED;
1785     }
1786     offset = CDNS_PORTCTRL + pdi->num * CDNS_PORT_OFFSET;
1787     cdns_updatel(cdns, offset,
1788              CDNS_PORTCTRL_DIRN | CDNS_PORTCTRL_TEST_FAILED,
1789              val);
1790 
1791     val = pdi->num;
1792     val |= CDNS_PDI_CONFIG_SOFT_RESET;
1793     val |= FIELD_PREP(CDNS_PDI_CONFIG_CHANNEL, (1 << ch) - 1);
1794     cdns_writel(cdns, CDNS_PDI_CONFIG(pdi->num), val);
1795 }
1796 EXPORT_SYMBOL(sdw_cdns_config_stream);
1797 
1798 /**
1799  * sdw_cdns_alloc_pdi() - Allocate a PDI
1800  *
1801  * @cdns: Cadence instance
1802  * @stream: Stream to be allocated
1803  * @ch: Channel count
1804  * @dir: Data direction
1805  * @dai_id: DAI id
1806  */
1807 struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns,
1808                     struct sdw_cdns_streams *stream,
1809                     u32 ch, u32 dir, int dai_id)
1810 {
1811     struct sdw_cdns_pdi *pdi = NULL;
1812 
1813     if (dir == SDW_DATA_DIR_RX)
1814         pdi = cdns_find_pdi(cdns, 0, stream->num_in, stream->in,
1815                     dai_id);
1816     else
1817         pdi = cdns_find_pdi(cdns, 0, stream->num_out, stream->out,
1818                     dai_id);
1819 
1820     /* check if we found a PDI, else find in bi-directional */
1821     if (!pdi)
1822         pdi = cdns_find_pdi(cdns, 2, stream->num_bd, stream->bd,
1823                     dai_id);
1824 
1825     if (pdi) {
1826         pdi->l_ch_num = 0;
1827         pdi->h_ch_num = ch - 1;
1828         pdi->dir = dir;
1829         pdi->ch_count = ch;
1830     }
1831 
1832     return pdi;
1833 }
1834 EXPORT_SYMBOL(sdw_cdns_alloc_pdi);
1835 
1836 MODULE_LICENSE("Dual BSD/GPL");
1837 MODULE_DESCRIPTION("Cadence Soundwire Library");