cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cadence_master.c (48480B)


      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/pm_runtime.h>
     17#include <linux/soundwire/sdw_registers.h>
     18#include <linux/soundwire/sdw.h>
     19#include <sound/pcm_params.h>
     20#include <sound/soc.h>
     21#include <linux/workqueue.h>
     22#include "bus.h"
     23#include "cadence_master.h"
     24
     25static int interrupt_mask;
     26module_param_named(cnds_mcp_int_mask, interrupt_mask, int, 0444);
     27MODULE_PARM_DESC(cdns_mcp_int_mask, "Cadence MCP IntMask");
     28
     29#define CDNS_MCP_CONFIG				0x0
     30
     31#define CDNS_MCP_CONFIG_MCMD_RETRY		GENMASK(27, 24)
     32#define CDNS_MCP_CONFIG_MPREQ_DELAY		GENMASK(20, 16)
     33#define CDNS_MCP_CONFIG_MMASTER			BIT(7)
     34#define CDNS_MCP_CONFIG_BUS_REL			BIT(6)
     35#define CDNS_MCP_CONFIG_SNIFFER			BIT(5)
     36#define CDNS_MCP_CONFIG_SSPMOD			BIT(4)
     37#define CDNS_MCP_CONFIG_CMD			BIT(3)
     38#define CDNS_MCP_CONFIG_OP			GENMASK(2, 0)
     39#define CDNS_MCP_CONFIG_OP_NORMAL		0
     40
     41#define CDNS_MCP_CONTROL			0x4
     42
     43#define CDNS_MCP_CONTROL_RST_DELAY		GENMASK(10, 8)
     44#define CDNS_MCP_CONTROL_CMD_RST		BIT(7)
     45#define CDNS_MCP_CONTROL_SOFT_RST		BIT(6)
     46#define CDNS_MCP_CONTROL_SW_RST			BIT(5)
     47#define CDNS_MCP_CONTROL_HW_RST			BIT(4)
     48#define CDNS_MCP_CONTROL_CLK_PAUSE		BIT(3)
     49#define CDNS_MCP_CONTROL_CLK_STOP_CLR		BIT(2)
     50#define CDNS_MCP_CONTROL_CMD_ACCEPT		BIT(1)
     51#define CDNS_MCP_CONTROL_BLOCK_WAKEUP		BIT(0)
     52
     53#define CDNS_MCP_CMDCTRL			0x8
     54
     55#define CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR	BIT(2)
     56
     57#define CDNS_MCP_SSPSTAT			0xC
     58#define CDNS_MCP_FRAME_SHAPE			0x10
     59#define CDNS_MCP_FRAME_SHAPE_INIT		0x14
     60#define CDNS_MCP_FRAME_SHAPE_COL_MASK		GENMASK(2, 0)
     61#define CDNS_MCP_FRAME_SHAPE_ROW_MASK		GENMASK(7, 3)
     62
     63#define CDNS_MCP_CONFIG_UPDATE			0x18
     64#define CDNS_MCP_CONFIG_UPDATE_BIT		BIT(0)
     65
     66#define CDNS_MCP_PHYCTRL			0x1C
     67#define CDNS_MCP_SSP_CTRL0			0x20
     68#define CDNS_MCP_SSP_CTRL1			0x28
     69#define CDNS_MCP_CLK_CTRL0			0x30
     70#define CDNS_MCP_CLK_CTRL1			0x38
     71#define CDNS_MCP_CLK_MCLKD_MASK		GENMASK(7, 0)
     72
     73#define CDNS_MCP_STAT				0x40
     74
     75#define CDNS_MCP_STAT_ACTIVE_BANK		BIT(20)
     76#define CDNS_MCP_STAT_CLK_STOP			BIT(16)
     77
     78#define CDNS_MCP_INTSTAT			0x44
     79#define CDNS_MCP_INTMASK			0x48
     80
     81#define CDNS_MCP_INT_IRQ			BIT(31)
     82#define CDNS_MCP_INT_RESERVED1			GENMASK(30, 17)
     83#define CDNS_MCP_INT_WAKEUP			BIT(16)
     84#define CDNS_MCP_INT_SLAVE_RSVD			BIT(15)
     85#define CDNS_MCP_INT_SLAVE_ALERT		BIT(14)
     86#define CDNS_MCP_INT_SLAVE_ATTACH		BIT(13)
     87#define CDNS_MCP_INT_SLAVE_NATTACH		BIT(12)
     88#define CDNS_MCP_INT_SLAVE_MASK			GENMASK(15, 12)
     89#define CDNS_MCP_INT_DPINT			BIT(11)
     90#define CDNS_MCP_INT_CTRL_CLASH			BIT(10)
     91#define CDNS_MCP_INT_DATA_CLASH			BIT(9)
     92#define CDNS_MCP_INT_PARITY			BIT(8)
     93#define CDNS_MCP_INT_CMD_ERR			BIT(7)
     94#define CDNS_MCP_INT_RESERVED2			GENMASK(6, 4)
     95#define CDNS_MCP_INT_RX_NE			BIT(3)
     96#define CDNS_MCP_INT_RX_WL			BIT(2)
     97#define CDNS_MCP_INT_TXE			BIT(1)
     98#define CDNS_MCP_INT_TXF			BIT(0)
     99#define CDNS_MCP_INT_RESERVED (CDNS_MCP_INT_RESERVED1 | CDNS_MCP_INT_RESERVED2)
    100
    101#define CDNS_MCP_INTSET				0x4C
    102
    103#define CDNS_MCP_SLAVE_STAT			0x50
    104#define CDNS_MCP_SLAVE_STAT_MASK		GENMASK(1, 0)
    105
    106#define CDNS_MCP_SLAVE_INTSTAT0			0x54
    107#define CDNS_MCP_SLAVE_INTSTAT1			0x58
    108#define CDNS_MCP_SLAVE_INTSTAT_NPRESENT		BIT(0)
    109#define CDNS_MCP_SLAVE_INTSTAT_ATTACHED		BIT(1)
    110#define CDNS_MCP_SLAVE_INTSTAT_ALERT		BIT(2)
    111#define CDNS_MCP_SLAVE_INTSTAT_RESERVED		BIT(3)
    112#define CDNS_MCP_SLAVE_STATUS_BITS		GENMASK(3, 0)
    113#define CDNS_MCP_SLAVE_STATUS_NUM		4
    114
    115#define CDNS_MCP_SLAVE_INTMASK0			0x5C
    116#define CDNS_MCP_SLAVE_INTMASK1			0x60
    117
    118#define CDNS_MCP_SLAVE_INTMASK0_MASK		GENMASK(31, 0)
    119#define CDNS_MCP_SLAVE_INTMASK1_MASK		GENMASK(15, 0)
    120
    121#define CDNS_MCP_PORT_INTSTAT			0x64
    122#define CDNS_MCP_PDI_STAT			0x6C
    123
    124#define CDNS_MCP_FIFOLEVEL			0x78
    125#define CDNS_MCP_FIFOSTAT			0x7C
    126#define CDNS_MCP_RX_FIFO_AVAIL			GENMASK(5, 0)
    127
    128#define CDNS_MCP_CMD_BASE			0x80
    129#define CDNS_MCP_RESP_BASE			0x80
    130#define CDNS_MCP_CMD_LEN			0x20
    131#define CDNS_MCP_CMD_WORD_LEN			0x4
    132
    133#define CDNS_MCP_CMD_SSP_TAG			BIT(31)
    134#define CDNS_MCP_CMD_COMMAND			GENMASK(30, 28)
    135#define CDNS_MCP_CMD_DEV_ADDR			GENMASK(27, 24)
    136#define CDNS_MCP_CMD_REG_ADDR			GENMASK(23, 8)
    137#define CDNS_MCP_CMD_REG_DATA			GENMASK(7, 0)
    138
    139#define CDNS_MCP_CMD_READ			2
    140#define CDNS_MCP_CMD_WRITE			3
    141
    142#define CDNS_MCP_RESP_RDATA			GENMASK(15, 8)
    143#define CDNS_MCP_RESP_ACK			BIT(0)
    144#define CDNS_MCP_RESP_NACK			BIT(1)
    145
    146#define CDNS_DP_SIZE				128
    147
    148#define CDNS_DPN_B0_CONFIG(n)			(0x100 + CDNS_DP_SIZE * (n))
    149#define CDNS_DPN_B0_CH_EN(n)			(0x104 + CDNS_DP_SIZE * (n))
    150#define CDNS_DPN_B0_SAMPLE_CTRL(n)		(0x108 + CDNS_DP_SIZE * (n))
    151#define CDNS_DPN_B0_OFFSET_CTRL(n)		(0x10C + CDNS_DP_SIZE * (n))
    152#define CDNS_DPN_B0_HCTRL(n)			(0x110 + CDNS_DP_SIZE * (n))
    153#define CDNS_DPN_B0_ASYNC_CTRL(n)		(0x114 + CDNS_DP_SIZE * (n))
    154
    155#define CDNS_DPN_B1_CONFIG(n)			(0x118 + CDNS_DP_SIZE * (n))
    156#define CDNS_DPN_B1_CH_EN(n)			(0x11C + CDNS_DP_SIZE * (n))
    157#define CDNS_DPN_B1_SAMPLE_CTRL(n)		(0x120 + CDNS_DP_SIZE * (n))
    158#define CDNS_DPN_B1_OFFSET_CTRL(n)		(0x124 + CDNS_DP_SIZE * (n))
    159#define CDNS_DPN_B1_HCTRL(n)			(0x128 + CDNS_DP_SIZE * (n))
    160#define CDNS_DPN_B1_ASYNC_CTRL(n)		(0x12C + CDNS_DP_SIZE * (n))
    161
    162#define CDNS_DPN_CONFIG_BPM			BIT(18)
    163#define CDNS_DPN_CONFIG_BGC			GENMASK(17, 16)
    164#define CDNS_DPN_CONFIG_WL			GENMASK(12, 8)
    165#define CDNS_DPN_CONFIG_PORT_DAT		GENMASK(3, 2)
    166#define CDNS_DPN_CONFIG_PORT_FLOW		GENMASK(1, 0)
    167
    168#define CDNS_DPN_SAMPLE_CTRL_SI			GENMASK(15, 0)
    169
    170#define CDNS_DPN_OFFSET_CTRL_1			GENMASK(7, 0)
    171#define CDNS_DPN_OFFSET_CTRL_2			GENMASK(15, 8)
    172
    173#define CDNS_DPN_HCTRL_HSTOP			GENMASK(3, 0)
    174#define CDNS_DPN_HCTRL_HSTART			GENMASK(7, 4)
    175#define CDNS_DPN_HCTRL_LCTRL			GENMASK(10, 8)
    176
    177#define CDNS_PORTCTRL				0x130
    178#define CDNS_PORTCTRL_TEST_FAILED		BIT(1)
    179#define CDNS_PORTCTRL_DIRN			BIT(7)
    180#define CDNS_PORTCTRL_BANK_INVERT		BIT(8)
    181
    182#define CDNS_PORT_OFFSET			0x80
    183
    184#define CDNS_PDI_CONFIG(n)			(0x1100 + (n) * 16)
    185
    186#define CDNS_PDI_CONFIG_SOFT_RESET		BIT(24)
    187#define CDNS_PDI_CONFIG_CHANNEL			GENMASK(15, 8)
    188#define CDNS_PDI_CONFIG_PORT			GENMASK(4, 0)
    189
    190/* Driver defaults */
    191#define CDNS_TX_TIMEOUT				500
    192
    193#define CDNS_SCP_RX_FIFOLEVEL			0x2
    194
    195/*
    196 * register accessor helpers
    197 */
    198static inline u32 cdns_readl(struct sdw_cdns *cdns, int offset)
    199{
    200	return readl(cdns->registers + offset);
    201}
    202
    203static inline void cdns_writel(struct sdw_cdns *cdns, int offset, u32 value)
    204{
    205	writel(value, cdns->registers + offset);
    206}
    207
    208static inline void cdns_updatel(struct sdw_cdns *cdns,
    209				int offset, u32 mask, u32 val)
    210{
    211	u32 tmp;
    212
    213	tmp = cdns_readl(cdns, offset);
    214	tmp = (tmp & ~mask) | val;
    215	cdns_writel(cdns, offset, tmp);
    216}
    217
    218static int cdns_set_wait(struct sdw_cdns *cdns, int offset, u32 mask, u32 value)
    219{
    220	int timeout = 10;
    221	u32 reg_read;
    222
    223	/* Wait for bit to be set */
    224	do {
    225		reg_read = readl(cdns->registers + offset);
    226		if ((reg_read & mask) == value)
    227			return 0;
    228
    229		timeout--;
    230		usleep_range(50, 100);
    231	} while (timeout != 0);
    232
    233	return -ETIMEDOUT;
    234}
    235
    236static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
    237{
    238	writel(value, cdns->registers + offset);
    239
    240	/* Wait for bit to be self cleared */
    241	return cdns_set_wait(cdns, offset, value, 0);
    242}
    243
    244/*
    245 * all changes to the MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL
    246 * need to be confirmed with a write to MCP_CONFIG_UPDATE
    247 */
    248static int cdns_config_update(struct sdw_cdns *cdns)
    249{
    250	int ret;
    251
    252	if (sdw_cdns_is_clock_stop(cdns)) {
    253		dev_err(cdns->dev, "Cannot program MCP_CONFIG_UPDATE in ClockStopMode\n");
    254		return -EINVAL;
    255	}
    256
    257	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
    258			     CDNS_MCP_CONFIG_UPDATE_BIT);
    259	if (ret < 0)
    260		dev_err(cdns->dev, "Config update timedout\n");
    261
    262	return ret;
    263}
    264
    265/*
    266 * debugfs
    267 */
    268#ifdef CONFIG_DEBUG_FS
    269
    270#define RD_BUF (2 * PAGE_SIZE)
    271
    272static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
    273			    char *buf, size_t pos, unsigned int reg)
    274{
    275	return scnprintf(buf + pos, RD_BUF - pos,
    276			 "%4x\t%8x\n", reg, cdns_readl(cdns, reg));
    277}
    278
    279static int cdns_reg_show(struct seq_file *s, void *data)
    280{
    281	struct sdw_cdns *cdns = s->private;
    282	char *buf;
    283	ssize_t ret;
    284	int num_ports;
    285	int i, j;
    286
    287	buf = kzalloc(RD_BUF, GFP_KERNEL);
    288	if (!buf)
    289		return -ENOMEM;
    290
    291	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
    292	ret += scnprintf(buf + ret, RD_BUF - ret, "\nMCP Registers\n");
    293	/* 8 MCP registers */
    294	for (i = CDNS_MCP_CONFIG; i <= CDNS_MCP_PHYCTRL; i += sizeof(u32))
    295		ret += cdns_sprintf(cdns, buf, ret, i);
    296
    297	ret += scnprintf(buf + ret, RD_BUF - ret,
    298			 "\nStatus & Intr Registers\n");
    299	/* 13 Status & Intr registers (offsets 0x70 and 0x74 not defined) */
    300	for (i = CDNS_MCP_STAT; i <=  CDNS_MCP_FIFOSTAT; i += sizeof(u32))
    301		ret += cdns_sprintf(cdns, buf, ret, i);
    302
    303	ret += scnprintf(buf + ret, RD_BUF - ret,
    304			 "\nSSP & Clk ctrl Registers\n");
    305	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL0);
    306	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL1);
    307	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL0);
    308	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL1);
    309
    310	ret += scnprintf(buf + ret, RD_BUF - ret,
    311			 "\nDPn B0 Registers\n");
    312
    313	num_ports = cdns->num_ports;
    314
    315	for (i = 0; i < num_ports; i++) {
    316		ret += scnprintf(buf + ret, RD_BUF - ret,
    317				 "\nDP-%d\n", i);
    318		for (j = CDNS_DPN_B0_CONFIG(i);
    319		     j < CDNS_DPN_B0_ASYNC_CTRL(i); j += sizeof(u32))
    320			ret += cdns_sprintf(cdns, buf, ret, j);
    321	}
    322
    323	ret += scnprintf(buf + ret, RD_BUF - ret,
    324			 "\nDPn B1 Registers\n");
    325	for (i = 0; i < num_ports; i++) {
    326		ret += scnprintf(buf + ret, RD_BUF - ret,
    327				 "\nDP-%d\n", i);
    328
    329		for (j = CDNS_DPN_B1_CONFIG(i);
    330		     j < CDNS_DPN_B1_ASYNC_CTRL(i); j += sizeof(u32))
    331			ret += cdns_sprintf(cdns, buf, ret, j);
    332	}
    333
    334	ret += scnprintf(buf + ret, RD_BUF - ret,
    335			 "\nDPn Control Registers\n");
    336	for (i = 0; i < num_ports; i++)
    337		ret += cdns_sprintf(cdns, buf, ret,
    338				CDNS_PORTCTRL + i * CDNS_PORT_OFFSET);
    339
    340	ret += scnprintf(buf + ret, RD_BUF - ret,
    341			 "\nPDIn Config Registers\n");
    342
    343	/* number of PDI and ports is interchangeable */
    344	for (i = 0; i < num_ports; i++)
    345		ret += cdns_sprintf(cdns, buf, ret, CDNS_PDI_CONFIG(i));
    346
    347	seq_printf(s, "%s", buf);
    348	kfree(buf);
    349
    350	return 0;
    351}
    352DEFINE_SHOW_ATTRIBUTE(cdns_reg);
    353
    354static int cdns_hw_reset(void *data, u64 value)
    355{
    356	struct sdw_cdns *cdns = data;
    357	int ret;
    358
    359	if (value != 1)
    360		return -EINVAL;
    361
    362	/* Userspace changed the hardware state behind the kernel's back */
    363	add_taint(TAINT_USER, LOCKDEP_STILL_OK);
    364
    365	ret = sdw_cdns_exit_reset(cdns);
    366
    367	dev_dbg(cdns->dev, "link hw_reset done: %d\n", ret);
    368
    369	return ret;
    370}
    371
    372DEFINE_DEBUGFS_ATTRIBUTE(cdns_hw_reset_fops, NULL, cdns_hw_reset, "%llu\n");
    373
    374static int cdns_parity_error_injection(void *data, u64 value)
    375{
    376	struct sdw_cdns *cdns = data;
    377	struct sdw_bus *bus;
    378	int ret;
    379
    380	if (value != 1)
    381		return -EINVAL;
    382
    383	bus = &cdns->bus;
    384
    385	/*
    386	 * Resume Master device. If this results in a bus reset, the
    387	 * Slave devices will re-attach and be re-enumerated.
    388	 */
    389	ret = pm_runtime_resume_and_get(bus->dev);
    390	if (ret < 0 && ret != -EACCES) {
    391		dev_err_ratelimited(cdns->dev,
    392				    "pm_runtime_resume_and_get failed in %s, ret %d\n",
    393				    __func__, ret);
    394		return ret;
    395	}
    396
    397	/*
    398	 * wait long enough for Slave(s) to be in steady state. This
    399	 * does not need to be super precise.
    400	 */
    401	msleep(200);
    402
    403	/*
    404	 * Take the bus lock here to make sure that any bus transactions
    405	 * will be queued while we inject a parity error on a dummy read
    406	 */
    407	mutex_lock(&bus->bus_lock);
    408
    409	/* program hardware to inject parity error */
    410	cdns_updatel(cdns, CDNS_MCP_CMDCTRL,
    411		     CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR,
    412		     CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR);
    413
    414	/* commit changes */
    415	cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
    416		     CDNS_MCP_CONFIG_UPDATE_BIT,
    417		     CDNS_MCP_CONFIG_UPDATE_BIT);
    418
    419	/* do a broadcast dummy read to avoid bus clashes */
    420	ret = sdw_bread_no_pm_unlocked(&cdns->bus, 0xf, SDW_SCP_DEVID_0);
    421	dev_info(cdns->dev, "parity error injection, read: %d\n", ret);
    422
    423	/* program hardware to disable parity error */
    424	cdns_updatel(cdns, CDNS_MCP_CMDCTRL,
    425		     CDNS_MCP_CMDCTRL_INSERT_PARITY_ERR,
    426		     0);
    427
    428	/* commit changes */
    429	cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
    430		     CDNS_MCP_CONFIG_UPDATE_BIT,
    431		     CDNS_MCP_CONFIG_UPDATE_BIT);
    432
    433	/* Continue bus operation with parity error injection disabled */
    434	mutex_unlock(&bus->bus_lock);
    435
    436	/* Userspace changed the hardware state behind the kernel's back */
    437	add_taint(TAINT_USER, LOCKDEP_STILL_OK);
    438
    439	/*
    440	 * allow Master device to enter pm_runtime suspend. This may
    441	 * also result in Slave devices suspending.
    442	 */
    443	pm_runtime_mark_last_busy(bus->dev);
    444	pm_runtime_put_autosuspend(bus->dev);
    445
    446	return 0;
    447}
    448
    449DEFINE_DEBUGFS_ATTRIBUTE(cdns_parity_error_fops, NULL,
    450			 cdns_parity_error_injection, "%llu\n");
    451
    452static int cdns_set_pdi_loopback_source(void *data, u64 value)
    453{
    454	struct sdw_cdns *cdns = data;
    455	unsigned int pdi_out_num = cdns->pcm.num_bd + cdns->pcm.num_out;
    456
    457	if (value > pdi_out_num)
    458		return -EINVAL;
    459
    460	/* Userspace changed the hardware state behind the kernel's back */
    461	add_taint(TAINT_USER, LOCKDEP_STILL_OK);
    462
    463	cdns->pdi_loopback_source = value;
    464
    465	return 0;
    466}
    467DEFINE_DEBUGFS_ATTRIBUTE(cdns_pdi_loopback_source_fops, NULL, cdns_set_pdi_loopback_source, "%llu\n");
    468
    469static int cdns_set_pdi_loopback_target(void *data, u64 value)
    470{
    471	struct sdw_cdns *cdns = data;
    472	unsigned int pdi_in_num = cdns->pcm.num_bd + cdns->pcm.num_in;
    473
    474	if (value > pdi_in_num)
    475		return -EINVAL;
    476
    477	/* Userspace changed the hardware state behind the kernel's back */
    478	add_taint(TAINT_USER, LOCKDEP_STILL_OK);
    479
    480	cdns->pdi_loopback_target = value;
    481
    482	return 0;
    483}
    484DEFINE_DEBUGFS_ATTRIBUTE(cdns_pdi_loopback_target_fops, NULL, cdns_set_pdi_loopback_target, "%llu\n");
    485
    486/**
    487 * sdw_cdns_debugfs_init() - Cadence debugfs init
    488 * @cdns: Cadence instance
    489 * @root: debugfs root
    490 */
    491void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root)
    492{
    493	debugfs_create_file("cdns-registers", 0400, root, cdns, &cdns_reg_fops);
    494
    495	debugfs_create_file("cdns-hw-reset", 0200, root, cdns,
    496			    &cdns_hw_reset_fops);
    497
    498	debugfs_create_file("cdns-parity-error-injection", 0200, root, cdns,
    499			    &cdns_parity_error_fops);
    500
    501	cdns->pdi_loopback_source = -1;
    502	cdns->pdi_loopback_target = -1;
    503
    504	debugfs_create_file("cdns-pdi-loopback-source", 0200, root, cdns,
    505			    &cdns_pdi_loopback_source_fops);
    506
    507	debugfs_create_file("cdns-pdi-loopback-target", 0200, root, cdns,
    508			    &cdns_pdi_loopback_target_fops);
    509
    510}
    511EXPORT_SYMBOL_GPL(sdw_cdns_debugfs_init);
    512
    513#endif /* CONFIG_DEBUG_FS */
    514
    515/*
    516 * IO Calls
    517 */
    518static enum sdw_command_response
    519cdns_fill_msg_resp(struct sdw_cdns *cdns,
    520		   struct sdw_msg *msg, int count, int offset)
    521{
    522	int nack = 0, no_ack = 0;
    523	int i;
    524
    525	/* check message response */
    526	for (i = 0; i < count; i++) {
    527		if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
    528			no_ack = 1;
    529			dev_vdbg(cdns->dev, "Msg Ack not received, cmd %d\n", i);
    530		}
    531		if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
    532			nack = 1;
    533			dev_err_ratelimited(cdns->dev, "Msg NACK received, cmd %d\n", i);
    534		}
    535	}
    536
    537	if (nack) {
    538		dev_err_ratelimited(cdns->dev, "Msg NACKed for Slave %d\n", msg->dev_num);
    539		return SDW_CMD_FAIL;
    540	}
    541
    542	if (no_ack) {
    543		dev_dbg_ratelimited(cdns->dev, "Msg ignored for Slave %d\n", msg->dev_num);
    544		return SDW_CMD_IGNORED;
    545	}
    546
    547	/* fill response */
    548	for (i = 0; i < count; i++)
    549		msg->buf[i + offset] = FIELD_GET(CDNS_MCP_RESP_RDATA, cdns->response_buf[i]);
    550
    551	return SDW_CMD_OK;
    552}
    553
    554static enum sdw_command_response
    555_cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
    556	       int offset, int count, bool defer)
    557{
    558	unsigned long time;
    559	u32 base, i, data;
    560	u16 addr;
    561
    562	/* Program the watermark level for RX FIFO */
    563	if (cdns->msg_count != count) {
    564		cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, count);
    565		cdns->msg_count = count;
    566	}
    567
    568	base = CDNS_MCP_CMD_BASE;
    569	addr = msg->addr;
    570
    571	for (i = 0; i < count; i++) {
    572		data = FIELD_PREP(CDNS_MCP_CMD_DEV_ADDR, msg->dev_num);
    573		data |= FIELD_PREP(CDNS_MCP_CMD_COMMAND, cmd);
    574		data |= FIELD_PREP(CDNS_MCP_CMD_REG_ADDR, addr);
    575		addr++;
    576
    577		if (msg->flags == SDW_MSG_FLAG_WRITE)
    578			data |= msg->buf[i + offset];
    579
    580		data |= FIELD_PREP(CDNS_MCP_CMD_SSP_TAG, msg->ssp_sync);
    581		cdns_writel(cdns, base, data);
    582		base += CDNS_MCP_CMD_WORD_LEN;
    583	}
    584
    585	if (defer)
    586		return SDW_CMD_OK;
    587
    588	/* wait for timeout or response */
    589	time = wait_for_completion_timeout(&cdns->tx_complete,
    590					   msecs_to_jiffies(CDNS_TX_TIMEOUT));
    591	if (!time) {
    592		dev_err(cdns->dev, "IO transfer timed out, cmd %d device %d addr %x len %d\n",
    593			cmd, msg->dev_num, msg->addr, msg->len);
    594		msg->len = 0;
    595		return SDW_CMD_TIMEOUT;
    596	}
    597
    598	return cdns_fill_msg_resp(cdns, msg, count, offset);
    599}
    600
    601static enum sdw_command_response
    602cdns_program_scp_addr(struct sdw_cdns *cdns, struct sdw_msg *msg)
    603{
    604	int nack = 0, no_ack = 0;
    605	unsigned long time;
    606	u32 data[2], base;
    607	int i;
    608
    609	/* Program the watermark level for RX FIFO */
    610	if (cdns->msg_count != CDNS_SCP_RX_FIFOLEVEL) {
    611		cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, CDNS_SCP_RX_FIFOLEVEL);
    612		cdns->msg_count = CDNS_SCP_RX_FIFOLEVEL;
    613	}
    614
    615	data[0] = FIELD_PREP(CDNS_MCP_CMD_DEV_ADDR, msg->dev_num);
    616	data[0] |= FIELD_PREP(CDNS_MCP_CMD_COMMAND, 0x3);
    617	data[1] = data[0];
    618
    619	data[0] |= FIELD_PREP(CDNS_MCP_CMD_REG_ADDR, SDW_SCP_ADDRPAGE1);
    620	data[1] |= FIELD_PREP(CDNS_MCP_CMD_REG_ADDR, SDW_SCP_ADDRPAGE2);
    621
    622	data[0] |= msg->addr_page1;
    623	data[1] |= msg->addr_page2;
    624
    625	base = CDNS_MCP_CMD_BASE;
    626	cdns_writel(cdns, base, data[0]);
    627	base += CDNS_MCP_CMD_WORD_LEN;
    628	cdns_writel(cdns, base, data[1]);
    629
    630	time = wait_for_completion_timeout(&cdns->tx_complete,
    631					   msecs_to_jiffies(CDNS_TX_TIMEOUT));
    632	if (!time) {
    633		dev_err(cdns->dev, "SCP Msg trf timed out\n");
    634		msg->len = 0;
    635		return SDW_CMD_TIMEOUT;
    636	}
    637
    638	/* check response the writes */
    639	for (i = 0; i < 2; i++) {
    640		if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
    641			no_ack = 1;
    642			dev_err(cdns->dev, "Program SCP Ack not received\n");
    643			if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
    644				nack = 1;
    645				dev_err(cdns->dev, "Program SCP NACK received\n");
    646			}
    647		}
    648	}
    649
    650	/* For NACK, NO ack, don't return err if we are in Broadcast mode */
    651	if (nack) {
    652		dev_err_ratelimited(cdns->dev,
    653				    "SCP_addrpage NACKed for Slave %d\n", msg->dev_num);
    654		return SDW_CMD_FAIL;
    655	}
    656
    657	if (no_ack) {
    658		dev_dbg_ratelimited(cdns->dev,
    659				    "SCP_addrpage ignored for Slave %d\n", msg->dev_num);
    660		return SDW_CMD_IGNORED;
    661	}
    662
    663	return SDW_CMD_OK;
    664}
    665
    666static int cdns_prep_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int *cmd)
    667{
    668	int ret;
    669
    670	if (msg->page) {
    671		ret = cdns_program_scp_addr(cdns, msg);
    672		if (ret) {
    673			msg->len = 0;
    674			return ret;
    675		}
    676	}
    677
    678	switch (msg->flags) {
    679	case SDW_MSG_FLAG_READ:
    680		*cmd = CDNS_MCP_CMD_READ;
    681		break;
    682
    683	case SDW_MSG_FLAG_WRITE:
    684		*cmd = CDNS_MCP_CMD_WRITE;
    685		break;
    686
    687	default:
    688		dev_err(cdns->dev, "Invalid msg cmd: %d\n", msg->flags);
    689		return -EINVAL;
    690	}
    691
    692	return 0;
    693}
    694
    695enum sdw_command_response
    696cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg)
    697{
    698	struct sdw_cdns *cdns = bus_to_cdns(bus);
    699	int cmd = 0, ret, i;
    700
    701	ret = cdns_prep_msg(cdns, msg, &cmd);
    702	if (ret)
    703		return SDW_CMD_FAIL_OTHER;
    704
    705	for (i = 0; i < msg->len / CDNS_MCP_CMD_LEN; i++) {
    706		ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
    707				     CDNS_MCP_CMD_LEN, false);
    708		if (ret < 0)
    709			goto exit;
    710	}
    711
    712	if (!(msg->len % CDNS_MCP_CMD_LEN))
    713		goto exit;
    714
    715	ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
    716			     msg->len % CDNS_MCP_CMD_LEN, false);
    717
    718exit:
    719	return ret;
    720}
    721EXPORT_SYMBOL(cdns_xfer_msg);
    722
    723enum sdw_command_response
    724cdns_xfer_msg_defer(struct sdw_bus *bus,
    725		    struct sdw_msg *msg, struct sdw_defer *defer)
    726{
    727	struct sdw_cdns *cdns = bus_to_cdns(bus);
    728	int cmd = 0, ret;
    729
    730	/* for defer only 1 message is supported */
    731	if (msg->len > 1)
    732		return -ENOTSUPP;
    733
    734	ret = cdns_prep_msg(cdns, msg, &cmd);
    735	if (ret)
    736		return SDW_CMD_FAIL_OTHER;
    737
    738	cdns->defer = defer;
    739	cdns->defer->length = msg->len;
    740
    741	return _cdns_xfer_msg(cdns, msg, cmd, 0, msg->len, true);
    742}
    743EXPORT_SYMBOL(cdns_xfer_msg_defer);
    744
    745enum sdw_command_response
    746cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num)
    747{
    748	struct sdw_cdns *cdns = bus_to_cdns(bus);
    749	struct sdw_msg msg;
    750
    751	/* Create dummy message with valid device number */
    752	memset(&msg, 0, sizeof(msg));
    753	msg.dev_num = dev_num;
    754
    755	return cdns_program_scp_addr(cdns, &msg);
    756}
    757EXPORT_SYMBOL(cdns_reset_page_addr);
    758
    759/*
    760 * IRQ handling
    761 */
    762
    763static void cdns_read_response(struct sdw_cdns *cdns)
    764{
    765	u32 num_resp, cmd_base;
    766	int i;
    767
    768	num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
    769	num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
    770
    771	cmd_base = CDNS_MCP_CMD_BASE;
    772
    773	for (i = 0; i < num_resp; i++) {
    774		cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
    775		cmd_base += CDNS_MCP_CMD_WORD_LEN;
    776	}
    777}
    778
    779static int cdns_update_slave_status(struct sdw_cdns *cdns,
    780				    u64 slave_intstat)
    781{
    782	enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
    783	bool is_slave = false;
    784	u32 mask;
    785	int i, set_status;
    786
    787	memset(status, 0, sizeof(status));
    788
    789	for (i = 0; i <= SDW_MAX_DEVICES; i++) {
    790		mask = (slave_intstat >> (i * CDNS_MCP_SLAVE_STATUS_NUM)) &
    791			CDNS_MCP_SLAVE_STATUS_BITS;
    792		if (!mask)
    793			continue;
    794
    795		is_slave = true;
    796		set_status = 0;
    797
    798		if (mask & CDNS_MCP_SLAVE_INTSTAT_RESERVED) {
    799			status[i] = SDW_SLAVE_RESERVED;
    800			set_status++;
    801		}
    802
    803		if (mask & CDNS_MCP_SLAVE_INTSTAT_ATTACHED) {
    804			status[i] = SDW_SLAVE_ATTACHED;
    805			set_status++;
    806		}
    807
    808		if (mask & CDNS_MCP_SLAVE_INTSTAT_ALERT) {
    809			status[i] = SDW_SLAVE_ALERT;
    810			set_status++;
    811		}
    812
    813		if (mask & CDNS_MCP_SLAVE_INTSTAT_NPRESENT) {
    814			status[i] = SDW_SLAVE_UNATTACHED;
    815			set_status++;
    816		}
    817
    818		/* first check if Slave reported multiple status */
    819		if (set_status > 1) {
    820			u32 val;
    821
    822			dev_warn_ratelimited(cdns->dev,
    823					     "Slave %d reported multiple Status: %d\n",
    824					     i, mask);
    825
    826			/* check latest status extracted from PING commands */
    827			val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
    828			val >>= (i * 2);
    829
    830			switch (val & 0x3) {
    831			case 0:
    832				status[i] = SDW_SLAVE_UNATTACHED;
    833				break;
    834			case 1:
    835				status[i] = SDW_SLAVE_ATTACHED;
    836				break;
    837			case 2:
    838				status[i] = SDW_SLAVE_ALERT;
    839				break;
    840			case 3:
    841			default:
    842				status[i] = SDW_SLAVE_RESERVED;
    843				break;
    844			}
    845
    846			dev_warn_ratelimited(cdns->dev,
    847					     "Slave %d status updated to %d\n",
    848					     i, status[i]);
    849
    850		}
    851	}
    852
    853	if (is_slave)
    854		return sdw_handle_slave_status(&cdns->bus, status);
    855
    856	return 0;
    857}
    858
    859/**
    860 * sdw_cdns_irq() - Cadence interrupt handler
    861 * @irq: irq number
    862 * @dev_id: irq context
    863 */
    864irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
    865{
    866	struct sdw_cdns *cdns = dev_id;
    867	u32 int_status;
    868
    869	/* Check if the link is up */
    870	if (!cdns->link_up)
    871		return IRQ_NONE;
    872
    873	int_status = cdns_readl(cdns, CDNS_MCP_INTSTAT);
    874
    875	/* check for reserved values read as zero */
    876	if (int_status & CDNS_MCP_INT_RESERVED)
    877		return IRQ_NONE;
    878
    879	if (!(int_status & CDNS_MCP_INT_IRQ))
    880		return IRQ_NONE;
    881
    882	if (int_status & CDNS_MCP_INT_RX_WL) {
    883		cdns_read_response(cdns);
    884
    885		if (cdns->defer) {
    886			cdns_fill_msg_resp(cdns, cdns->defer->msg,
    887					   cdns->defer->length, 0);
    888			complete(&cdns->defer->complete);
    889			cdns->defer = NULL;
    890		} else {
    891			complete(&cdns->tx_complete);
    892		}
    893	}
    894
    895	if (int_status & CDNS_MCP_INT_PARITY) {
    896		/* Parity error detected by Master */
    897		dev_err_ratelimited(cdns->dev, "Parity error\n");
    898	}
    899
    900	if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
    901		/* Slave is driving bit slot during control word */
    902		dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
    903	}
    904
    905	if (int_status & CDNS_MCP_INT_DATA_CLASH) {
    906		/*
    907		 * Multiple slaves trying to drive bit slot, or issue with
    908		 * ownership of data bits or Slave gone bonkers
    909		 */
    910		dev_err_ratelimited(cdns->dev, "Bus clash for data word\n");
    911	}
    912
    913	if (cdns->bus.params.m_data_mode != SDW_PORT_DATA_MODE_NORMAL &&
    914	    int_status & CDNS_MCP_INT_DPINT) {
    915		u32 port_intstat;
    916
    917		/* just log which ports report an error */
    918		port_intstat = cdns_readl(cdns, CDNS_MCP_PORT_INTSTAT);
    919		dev_err_ratelimited(cdns->dev, "DP interrupt: PortIntStat %8x\n",
    920				    port_intstat);
    921
    922		/* clear status w/ write1 */
    923		cdns_writel(cdns, CDNS_MCP_PORT_INTSTAT, port_intstat);
    924	}
    925
    926	if (int_status & CDNS_MCP_INT_SLAVE_MASK) {
    927		/* Mask the Slave interrupt and wake thread */
    928		cdns_updatel(cdns, CDNS_MCP_INTMASK,
    929			     CDNS_MCP_INT_SLAVE_MASK, 0);
    930
    931		int_status &= ~CDNS_MCP_INT_SLAVE_MASK;
    932
    933		/*
    934		 * Deal with possible race condition between interrupt
    935		 * handling and disabling interrupts on suspend.
    936		 *
    937		 * If the master is in the process of disabling
    938		 * interrupts, don't schedule a workqueue
    939		 */
    940		if (cdns->interrupt_enabled)
    941			schedule_work(&cdns->work);
    942	}
    943
    944	cdns_writel(cdns, CDNS_MCP_INTSTAT, int_status);
    945	return IRQ_HANDLED;
    946}
    947EXPORT_SYMBOL(sdw_cdns_irq);
    948
    949/**
    950 * cdns_update_slave_status_work - update slave status in a work since we will need to handle
    951 * other interrupts eg. CDNS_MCP_INT_RX_WL during the update slave
    952 * process.
    953 * @work: cdns worker thread
    954 */
    955static void cdns_update_slave_status_work(struct work_struct *work)
    956{
    957	struct sdw_cdns *cdns =
    958		container_of(work, struct sdw_cdns, work);
    959	u32 slave0, slave1;
    960	u64 slave_intstat;
    961	u32 device0_status;
    962	int retry_count = 0;
    963
    964	slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
    965	slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
    966
    967	/* combine the two status */
    968	slave_intstat = ((u64)slave1 << 32) | slave0;
    969
    970	dev_dbg_ratelimited(cdns->dev, "Slave status change: 0x%llx\n", slave_intstat);
    971
    972update_status:
    973	cdns_update_slave_status(cdns, slave_intstat);
    974	cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0);
    975	cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1);
    976
    977	/*
    978	 * When there is more than one peripheral per link, it's
    979	 * possible that a deviceB becomes attached after we deal with
    980	 * the attachment of deviceA. Since the hardware does a
    981	 * logical AND, the attachment of the second device does not
    982	 * change the status seen by the driver.
    983	 *
    984	 * In that case, clearing the registers above would result in
    985	 * the deviceB never being detected - until a change of status
    986	 * is observed on the bus.
    987	 *
    988	 * To avoid this race condition, re-check if any device0 needs
    989	 * attention with PING commands. There is no need to check for
    990	 * ALERTS since they are not allowed until a non-zero
    991	 * device_number is assigned.
    992	 */
    993
    994	device0_status = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
    995	device0_status &= 3;
    996
    997	if (device0_status == SDW_SLAVE_ATTACHED) {
    998		if (retry_count++ < SDW_MAX_DEVICES) {
    999			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 */
   1019void 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}
   1059EXPORT_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 */
   1069int 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}
   1087EXPORT_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 */
   1094static 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 */
   1112int 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
   1147update_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}
   1177EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
   1178
   1179static 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 */
   1207int 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}
   1249EXPORT_SYMBOL(sdw_cdns_pdi_init);
   1250
   1251static 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
   1266static 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 */
   1300int 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}
   1348EXPORT_SYMBOL(sdw_cdns_init);
   1349
   1350int 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}
   1375EXPORT_SYMBOL(cdns_bus_conf);
   1376
   1377static 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
   1416static 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
   1506static 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
   1523static 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 */
   1534bool sdw_cdns_is_clock_stop(struct sdw_cdns *cdns)
   1535{
   1536	return !!(cdns_readl(cdns, CDNS_MCP_STAT) & CDNS_MCP_STAT_CLK_STOP);
   1537}
   1538EXPORT_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 */
   1546int 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}
   1619EXPORT_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 */
   1628int 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}
   1674EXPORT_SYMBOL(sdw_cdns_clock_restart);
   1675
   1676/**
   1677 * sdw_cdns_probe() - Cadence probe routine
   1678 * @cdns: Cadence instance
   1679 */
   1680int 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}
   1688EXPORT_SYMBOL(sdw_cdns_probe);
   1689
   1690int 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}
   1738EXPORT_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 */
   1752static 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 */
   1775void 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}
   1796EXPORT_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 */
   1807struct 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}
   1834EXPORT_SYMBOL(sdw_cdns_alloc_pdi);
   1835
   1836MODULE_LICENSE("Dual BSD/GPL");
   1837MODULE_DESCRIPTION("Cadence Soundwire Library");