soundwire: intel: don't save hw_params for use in prepare
[linux-block.git] / drivers / soundwire / cadence_master.c
index e835dabb516c48e9684b93aa4f31585b614caf5f..39502bc75712c975cb9de6da501131f59cd9482d 100644 (file)
@@ -27,32 +27,36 @@ module_param_named(cnds_mcp_int_mask, interrupt_mask, int, 0444);
 MODULE_PARM_DESC(cdns_mcp_int_mask, "Cadence MCP IntMask");
 
 #define CDNS_MCP_CONFIG                                0x0
-
-#define CDNS_MCP_CONFIG_MCMD_RETRY             GENMASK(27, 24)
-#define CDNS_MCP_CONFIG_MPREQ_DELAY            GENMASK(20, 16)
-#define CDNS_MCP_CONFIG_MMASTER                        BIT(7)
 #define CDNS_MCP_CONFIG_BUS_REL                        BIT(6)
-#define CDNS_MCP_CONFIG_SNIFFER                        BIT(5)
-#define CDNS_MCP_CONFIG_SSPMOD                 BIT(4)
-#define CDNS_MCP_CONFIG_CMD                    BIT(3)
-#define CDNS_MCP_CONFIG_OP                     GENMASK(2, 0)
-#define CDNS_MCP_CONFIG_OP_NORMAL              0
+
+#define CDNS_IP_MCP_CONFIG                     0x0 /* IP offset added at run-time */
+
+#define CDNS_IP_MCP_CONFIG_MCMD_RETRY          GENMASK(27, 24)
+#define CDNS_IP_MCP_CONFIG_MPREQ_DELAY         GENMASK(20, 16)
+#define CDNS_IP_MCP_CONFIG_MMASTER             BIT(7)
+#define CDNS_IP_MCP_CONFIG_SNIFFER             BIT(5)
+#define CDNS_IP_MCP_CONFIG_CMD                 BIT(3)
+#define CDNS_IP_MCP_CONFIG_OP                  GENMASK(2, 0)
+#define CDNS_IP_MCP_CONFIG_OP_NORMAL           0
 
 #define CDNS_MCP_CONTROL                       0x4
 
-#define CDNS_MCP_CONTROL_RST_DELAY             GENMASK(10, 8)
 #define CDNS_MCP_CONTROL_CMD_RST               BIT(7)
 #define CDNS_MCP_CONTROL_SOFT_RST              BIT(6)
-#define CDNS_MCP_CONTROL_SW_RST                        BIT(5)
 #define CDNS_MCP_CONTROL_HW_RST                        BIT(4)
-#define CDNS_MCP_CONTROL_CLK_PAUSE             BIT(3)
 #define CDNS_MCP_CONTROL_CLK_STOP_CLR          BIT(2)
-#define CDNS_MCP_CONTROL_CMD_ACCEPT            BIT(1)
-#define CDNS_MCP_CONTROL_BLOCK_WAKEUP          BIT(0)
 
-#define CDNS_MCP_CMDCTRL                       0x8
+#define CDNS_IP_MCP_CONTROL                    0x4  /* IP offset added at run-time */
+
+#define CDNS_IP_MCP_CONTROL_RST_DELAY          GENMASK(10, 8)
+#define CDNS_IP_MCP_CONTROL_SW_RST             BIT(5)
+#define CDNS_IP_MCP_CONTROL_CLK_PAUSE          BIT(3)
+#define CDNS_IP_MCP_CONTROL_CMD_ACCEPT         BIT(1)
+#define CDNS_IP_MCP_CONTROL_BLOCK_WAKEUP       BIT(0)
 
-#define CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR     BIT(2)
+#define CDNS_IP_MCP_CMDCTRL                    0x8 /* IP offset added at run-time */
+
+#define CDNS_IP_MCP_CMDCTRL_INSERT_PARITY_ERR  BIT(2)
 
 #define CDNS_MCP_SSPSTAT                       0xC
 #define CDNS_MCP_FRAME_SHAPE                   0x10
@@ -125,8 +129,8 @@ MODULE_PARM_DESC(cdns_mcp_int_mask, "Cadence MCP IntMask");
 #define CDNS_MCP_FIFOSTAT                      0x7C
 #define CDNS_MCP_RX_FIFO_AVAIL                 GENMASK(5, 0)
 
-#define CDNS_MCP_CMD_BASE                      0x80
-#define CDNS_MCP_RESP_BASE                     0x80
+#define CDNS_IP_MCP_CMD_BASE                   0x80 /* IP offset added at run-time */
+#define CDNS_IP_MCP_RESP_BASE                  0x80 /* IP offset added at run-time */
 /* FIFO can hold 8 commands */
 #define CDNS_MCP_CMD_LEN                       8
 #define CDNS_MCP_CMD_WORD_LEN                  0x4
@@ -206,6 +210,16 @@ static inline void cdns_writel(struct sdw_cdns *cdns, int offset, u32 value)
        writel(value, cdns->registers + offset);
 }
 
+static inline u32 cdns_ip_readl(struct sdw_cdns *cdns, int offset)
+{
+       return cdns_readl(cdns, cdns->ip_offset + offset);
+}
+
+static inline void cdns_ip_writel(struct sdw_cdns *cdns, int offset, u32 value)
+{
+       return cdns_writel(cdns, cdns->ip_offset + offset, value);
+}
+
 static inline void cdns_updatel(struct sdw_cdns *cdns,
                                int offset, u32 mask, u32 val)
 {
@@ -216,6 +230,12 @@ static inline void cdns_updatel(struct sdw_cdns *cdns,
        cdns_writel(cdns, offset, tmp);
 }
 
+static inline void cdns_ip_updatel(struct sdw_cdns *cdns,
+                                  int offset, u32 mask, u32 val)
+{
+       cdns_updatel(cdns, cdns->ip_offset + offset, mask, val);
+}
+
 static int cdns_set_wait(struct sdw_cdns *cdns, int offset, u32 mask, u32 value)
 {
        int timeout = 10;
@@ -408,9 +428,9 @@ static int cdns_parity_error_injection(void *data, u64 value)
        mutex_lock(&bus->bus_lock);
 
        /* program hardware to inject parity error */
-       cdns_updatel(cdns, CDNS_MCP_CMDCTRL,
-                    CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR,
-                    CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR);
+       cdns_ip_updatel(cdns, CDNS_IP_MCP_CMDCTRL,
+                       CDNS_IP_MCP_CMDCTRL_INSERT_PARITY_ERR,
+                       CDNS_IP_MCP_CMDCTRL_INSERT_PARITY_ERR);
 
        /* commit changes */
        cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
@@ -422,9 +442,9 @@ static int cdns_parity_error_injection(void *data, u64 value)
        dev_info(cdns->dev, "parity error injection, read: %d\n", ret);
 
        /* program hardware to disable parity error */
-       cdns_updatel(cdns, CDNS_MCP_CMDCTRL,
-                    CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR,
-                    0);
+       cdns_ip_updatel(cdns, CDNS_IP_MCP_CMDCTRL,
+                       CDNS_IP_MCP_CMDCTRL_INSERT_PARITY_ERR,
+                       0);
 
        /* commit changes */
        cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
@@ -570,10 +590,10 @@ static void cdns_read_response(struct sdw_cdns *cdns)
                num_resp = ARRAY_SIZE(cdns->response_buf);
        }
 
-       cmd_base = CDNS_MCP_CMD_BASE;
+       cmd_base = CDNS_IP_MCP_CMD_BASE;
 
        for (i = 0; i < num_resp; i++) {
-               cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
+               cdns->response_buf[i] = cdns_ip_readl(cdns, cmd_base);
                cmd_base += CDNS_MCP_CMD_WORD_LEN;
        }
 }
@@ -592,7 +612,7 @@ _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
                cdns->msg_count = count;
        }
 
-       base = CDNS_MCP_CMD_BASE;
+       base = CDNS_IP_MCP_CMD_BASE;
        addr = msg->addr + offset;
 
        for (i = 0; i < count; i++) {
@@ -605,7 +625,7 @@ _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
                        data |= msg->buf[i + offset];
 
                data |= FIELD_PREP(CDNS_MCP_CMD_SSP_TAG, msg->ssp_sync);
-               cdns_writel(cdns, base, data);
+               cdns_ip_writel(cdns, base, data);
                base += CDNS_MCP_CMD_WORD_LEN;
        }
 
@@ -653,10 +673,10 @@ cdns_program_scp_addr(struct sdw_cdns *cdns, struct sdw_msg *msg)
        data[0] |= msg->addr_page1;
        data[1] |= msg->addr_page2;
 
-       base = CDNS_MCP_CMD_BASE;
-       cdns_writel(cdns, base, data[0]);
+       base = CDNS_IP_MCP_CMD_BASE;
+       cdns_ip_writel(cdns, base, data[0]);
        base += CDNS_MCP_CMD_WORD_LEN;
-       cdns_writel(cdns, base, data[1]);
+       cdns_ip_writel(cdns, base, data[1]);
 
        time = wait_for_completion_timeout(&cdns->tx_complete,
                                           msecs_to_jiffies(CDNS_TX_TIMEOUT));
@@ -1033,6 +1053,7 @@ update_status:
 void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string,
                                       bool initial_delay, int reset_iterations)
 {
+       u32 ip_mcp_control;
        u32 mcp_control;
        u32 mcp_config_update;
        int i;
@@ -1040,6 +1061,12 @@ void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string
        if (initial_delay)
                usleep_range(1000, 1500);
 
+       ip_mcp_control = cdns_ip_readl(cdns, CDNS_IP_MCP_CONTROL);
+
+       /* the following bits should be cleared immediately */
+       if (ip_mcp_control & CDNS_IP_MCP_CONTROL_SW_RST)
+               dev_err(cdns->dev, "%s failed: IP_MCP_CONTROL_SW_RST is not cleared\n", string);
+
        mcp_control = cdns_readl(cdns, CDNS_MCP_CONTROL);
 
        /* the following bits should be cleared immediately */
@@ -1047,10 +1074,9 @@ void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string
                dev_err(cdns->dev, "%s failed: MCP_CONTROL_CMD_RST is not cleared\n", string);
        if (mcp_control & CDNS_MCP_CONTROL_SOFT_RST)
                dev_err(cdns->dev, "%s failed: MCP_CONTROL_SOFT_RST is not cleared\n", string);
-       if (mcp_control & CDNS_MCP_CONTROL_SW_RST)
-               dev_err(cdns->dev, "%s failed: MCP_CONTROL_SW_RST is not cleared\n", string);
        if (mcp_control & CDNS_MCP_CONTROL_CLK_STOP_CLR)
                dev_err(cdns->dev, "%s failed: MCP_CONTROL_CLK_STOP_CLR is not cleared\n", string);
+
        mcp_config_update = cdns_readl(cdns, CDNS_MCP_CONFIG_UPDATE);
        if (mcp_config_update & CDNS_MCP_CONFIG_UPDATE_BIT)
                dev_err(cdns->dev, "%s failed: MCP_CONFIG_UPDATE_BIT is not cleared\n", string);
@@ -1327,34 +1353,39 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
                     CDNS_MCP_CONTROL_CMD_RST);
 
        /* Set cmd accept mode */
-       cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
-                    CDNS_MCP_CONTROL_CMD_ACCEPT);
+       cdns_ip_updatel(cdns, CDNS_IP_MCP_CONTROL, CDNS_IP_MCP_CONTROL_CMD_ACCEPT,
+                       CDNS_IP_MCP_CONTROL_CMD_ACCEPT);
 
        /* Configure mcp config */
        val = cdns_readl(cdns, CDNS_MCP_CONFIG);
 
+       /* Disable auto bus release */
+       val &= ~CDNS_MCP_CONFIG_BUS_REL;
+
+       cdns_writel(cdns, CDNS_MCP_CONFIG, val);
+
+       /* Configure IP mcp config */
+       val = cdns_ip_readl(cdns, CDNS_IP_MCP_CONFIG);
+
        /* enable bus operations with clock and data */
-       val &= ~CDNS_MCP_CONFIG_OP;
-       val |= CDNS_MCP_CONFIG_OP_NORMAL;
+       val &= ~CDNS_IP_MCP_CONFIG_OP;
+       val |= CDNS_IP_MCP_CONFIG_OP_NORMAL;
 
        /* Set cmd mode for Tx and Rx cmds */
-       val &= ~CDNS_MCP_CONFIG_CMD;
+       val &= ~CDNS_IP_MCP_CONFIG_CMD;
 
        /* Disable sniffer mode */
-       val &= ~CDNS_MCP_CONFIG_SNIFFER;
-
-       /* Disable auto bus release */
-       val &= ~CDNS_MCP_CONFIG_BUS_REL;
+       val &= ~CDNS_IP_MCP_CONFIG_SNIFFER;
 
        if (cdns->bus.multi_link)
                /* Set Multi-master mode to take gsync into account */
-               val |= CDNS_MCP_CONFIG_MMASTER;
+               val |= CDNS_IP_MCP_CONFIG_MMASTER;
 
        /* leave frame delay to hardware default of 0x1F */
 
        /* leave command retry to hardware default of 0 */
 
-       cdns_writel(cdns, CDNS_MCP_CONFIG, val);
+       cdns_ip_writel(cdns, CDNS_IP_MCP_CONFIG, val);
 
        /* changes will be committed later */
        return 0;
@@ -1584,9 +1615,9 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
         * in clock stop state
         */
        if (block_wake)
-               cdns_updatel(cdns, CDNS_MCP_CONTROL,
-                            CDNS_MCP_CONTROL_BLOCK_WAKEUP,
-                            CDNS_MCP_CONTROL_BLOCK_WAKEUP);
+               cdns_ip_updatel(cdns, CDNS_IP_MCP_CONTROL,
+                               CDNS_IP_MCP_CONTROL_BLOCK_WAKEUP,
+                               CDNS_IP_MCP_CONTROL_BLOCK_WAKEUP);
 
        list_for_each_entry(slave, &cdns->bus.slaves, node) {
                if (slave->status == SDW_SLAVE_ATTACHED ||
@@ -1659,18 +1690,18 @@ int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset)
                return ret;
        }
 
-       cdns_updatel(cdns, CDNS_MCP_CONTROL,
-                    CDNS_MCP_CONTROL_BLOCK_WAKEUP, 0);
+       cdns_ip_updatel(cdns, CDNS_IP_MCP_CONTROL,
+                       CDNS_IP_MCP_CONTROL_BLOCK_WAKEUP, 0);
 
-       cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
-                    CDNS_MCP_CONTROL_CMD_ACCEPT);
+       cdns_ip_updatel(cdns, CDNS_IP_MCP_CONTROL, CDNS_IP_MCP_CONTROL_CMD_ACCEPT,
+                       CDNS_IP_MCP_CONTROL_CMD_ACCEPT);
 
        if (!bus_reset) {
 
                /* enable bus operations with clock and data */
-               cdns_updatel(cdns, CDNS_MCP_CONFIG,
-                            CDNS_MCP_CONFIG_OP,
-                            CDNS_MCP_CONFIG_OP_NORMAL);
+               cdns_ip_updatel(cdns, CDNS_IP_MCP_CONFIG,
+                               CDNS_IP_MCP_CONFIG_OP,
+                               CDNS_IP_MCP_CONFIG_OP_NORMAL);
 
                ret = cdns_config_update(cdns);
                if (ret < 0) {