Linux Audio

Check our new training course

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