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");