Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.17 751 lines 19 kB view raw
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/interrupt.h> 12#include <linux/module.h> 13#include <linux/mod_devicetable.h> 14#include <linux/soundwire/sdw_registers.h> 15#include <linux/soundwire/sdw.h> 16#include "bus.h" 17#include "cadence_master.h" 18 19#define CDNS_MCP_CONFIG 0x0 20 21#define CDNS_MCP_CONFIG_MCMD_RETRY GENMASK(27, 24) 22#define CDNS_MCP_CONFIG_MPREQ_DELAY GENMASK(20, 16) 23#define CDNS_MCP_CONFIG_MMASTER BIT(7) 24#define CDNS_MCP_CONFIG_BUS_REL BIT(6) 25#define CDNS_MCP_CONFIG_SNIFFER BIT(5) 26#define CDNS_MCP_CONFIG_SSPMOD BIT(4) 27#define CDNS_MCP_CONFIG_CMD BIT(3) 28#define CDNS_MCP_CONFIG_OP GENMASK(2, 0) 29#define CDNS_MCP_CONFIG_OP_NORMAL 0 30 31#define CDNS_MCP_CONTROL 0x4 32 33#define CDNS_MCP_CONTROL_RST_DELAY GENMASK(10, 8) 34#define CDNS_MCP_CONTROL_CMD_RST BIT(7) 35#define CDNS_MCP_CONTROL_SOFT_RST BIT(6) 36#define CDNS_MCP_CONTROL_SW_RST BIT(5) 37#define CDNS_MCP_CONTROL_HW_RST BIT(4) 38#define CDNS_MCP_CONTROL_CLK_PAUSE BIT(3) 39#define CDNS_MCP_CONTROL_CLK_STOP_CLR BIT(2) 40#define CDNS_MCP_CONTROL_CMD_ACCEPT BIT(1) 41#define CDNS_MCP_CONTROL_BLOCK_WAKEUP BIT(0) 42 43 44#define CDNS_MCP_CMDCTRL 0x8 45#define CDNS_MCP_SSPSTAT 0xC 46#define CDNS_MCP_FRAME_SHAPE 0x10 47#define CDNS_MCP_FRAME_SHAPE_INIT 0x14 48 49#define CDNS_MCP_CONFIG_UPDATE 0x18 50#define CDNS_MCP_CONFIG_UPDATE_BIT BIT(0) 51 52#define CDNS_MCP_PHYCTRL 0x1C 53#define CDNS_MCP_SSP_CTRL0 0x20 54#define CDNS_MCP_SSP_CTRL1 0x28 55#define CDNS_MCP_CLK_CTRL0 0x30 56#define CDNS_MCP_CLK_CTRL1 0x38 57 58#define CDNS_MCP_STAT 0x40 59 60#define CDNS_MCP_STAT_ACTIVE_BANK BIT(20) 61#define CDNS_MCP_STAT_CLK_STOP BIT(16) 62 63#define CDNS_MCP_INTSTAT 0x44 64#define CDNS_MCP_INTMASK 0x48 65 66#define CDNS_MCP_INT_IRQ BIT(31) 67#define CDNS_MCP_INT_WAKEUP BIT(16) 68#define CDNS_MCP_INT_SLAVE_RSVD BIT(15) 69#define CDNS_MCP_INT_SLAVE_ALERT BIT(14) 70#define CDNS_MCP_INT_SLAVE_ATTACH BIT(13) 71#define CDNS_MCP_INT_SLAVE_NATTACH BIT(12) 72#define CDNS_MCP_INT_SLAVE_MASK GENMASK(15, 12) 73#define CDNS_MCP_INT_DPINT BIT(11) 74#define CDNS_MCP_INT_CTRL_CLASH BIT(10) 75#define CDNS_MCP_INT_DATA_CLASH BIT(9) 76#define CDNS_MCP_INT_CMD_ERR BIT(7) 77#define CDNS_MCP_INT_RX_WL BIT(2) 78#define CDNS_MCP_INT_TXE BIT(1) 79 80#define CDNS_MCP_INTSET 0x4C 81 82#define CDNS_SDW_SLAVE_STAT 0x50 83#define CDNS_MCP_SLAVE_STAT_MASK BIT(1, 0) 84 85#define CDNS_MCP_SLAVE_INTSTAT0 0x54 86#define CDNS_MCP_SLAVE_INTSTAT1 0x58 87#define CDNS_MCP_SLAVE_INTSTAT_NPRESENT BIT(0) 88#define CDNS_MCP_SLAVE_INTSTAT_ATTACHED BIT(1) 89#define CDNS_MCP_SLAVE_INTSTAT_ALERT BIT(2) 90#define CDNS_MCP_SLAVE_INTSTAT_RESERVED BIT(3) 91#define CDNS_MCP_SLAVE_STATUS_BITS GENMASK(3, 0) 92#define CDNS_MCP_SLAVE_STATUS_NUM 4 93 94#define CDNS_MCP_SLAVE_INTMASK0 0x5C 95#define CDNS_MCP_SLAVE_INTMASK1 0x60 96 97#define CDNS_MCP_SLAVE_INTMASK0_MASK GENMASK(30, 0) 98#define CDNS_MCP_SLAVE_INTMASK1_MASK GENMASK(16, 0) 99 100#define CDNS_MCP_PORT_INTSTAT 0x64 101#define CDNS_MCP_PDI_STAT 0x6C 102 103#define CDNS_MCP_FIFOLEVEL 0x78 104#define CDNS_MCP_FIFOSTAT 0x7C 105#define CDNS_MCP_RX_FIFO_AVAIL GENMASK(5, 0) 106 107#define CDNS_MCP_CMD_BASE 0x80 108#define CDNS_MCP_RESP_BASE 0x80 109#define CDNS_MCP_CMD_LEN 0x20 110#define CDNS_MCP_CMD_WORD_LEN 0x4 111 112#define CDNS_MCP_CMD_SSP_TAG BIT(31) 113#define CDNS_MCP_CMD_COMMAND GENMASK(30, 28) 114#define CDNS_MCP_CMD_DEV_ADDR GENMASK(27, 24) 115#define CDNS_MCP_CMD_REG_ADDR_H GENMASK(23, 16) 116#define CDNS_MCP_CMD_REG_ADDR_L GENMASK(15, 8) 117#define CDNS_MCP_CMD_REG_DATA GENMASK(7, 0) 118 119#define CDNS_MCP_CMD_READ 2 120#define CDNS_MCP_CMD_WRITE 3 121 122#define CDNS_MCP_RESP_RDATA GENMASK(15, 8) 123#define CDNS_MCP_RESP_ACK BIT(0) 124#define CDNS_MCP_RESP_NACK BIT(1) 125 126#define CDNS_DP_SIZE 128 127 128#define CDNS_DPN_B0_CONFIG(n) (0x100 + CDNS_DP_SIZE * (n)) 129#define CDNS_DPN_B0_CH_EN(n) (0x104 + CDNS_DP_SIZE * (n)) 130#define CDNS_DPN_B0_SAMPLE_CTRL(n) (0x108 + CDNS_DP_SIZE * (n)) 131#define CDNS_DPN_B0_OFFSET_CTRL(n) (0x10C + CDNS_DP_SIZE * (n)) 132#define CDNS_DPN_B0_HCTRL(n) (0x110 + CDNS_DP_SIZE * (n)) 133#define CDNS_DPN_B0_ASYNC_CTRL(n) (0x114 + CDNS_DP_SIZE * (n)) 134 135#define CDNS_DPN_B1_CONFIG(n) (0x118 + CDNS_DP_SIZE * (n)) 136#define CDNS_DPN_B1_CH_EN(n) (0x11C + CDNS_DP_SIZE * (n)) 137#define CDNS_DPN_B1_SAMPLE_CTRL(n) (0x120 + CDNS_DP_SIZE * (n)) 138#define CDNS_DPN_B1_OFFSET_CTRL(n) (0x124 + CDNS_DP_SIZE * (n)) 139#define CDNS_DPN_B1_HCTRL(n) (0x128 + CDNS_DP_SIZE * (n)) 140#define CDNS_DPN_B1_ASYNC_CTRL(n) (0x12C + CDNS_DP_SIZE * (n)) 141 142#define CDNS_DPN_CONFIG_BPM BIT(18) 143#define CDNS_DPN_CONFIG_BGC GENMASK(17, 16) 144#define CDNS_DPN_CONFIG_WL GENMASK(12, 8) 145#define CDNS_DPN_CONFIG_PORT_DAT GENMASK(3, 2) 146#define CDNS_DPN_CONFIG_PORT_FLOW GENMASK(1, 0) 147 148#define CDNS_DPN_SAMPLE_CTRL_SI GENMASK(15, 0) 149 150#define CDNS_DPN_OFFSET_CTRL_1 GENMASK(7, 0) 151#define CDNS_DPN_OFFSET_CTRL_2 GENMASK(15, 8) 152 153#define CDNS_DPN_HCTRL_HSTOP GENMASK(3, 0) 154#define CDNS_DPN_HCTRL_HSTART GENMASK(7, 4) 155#define CDNS_DPN_HCTRL_LCTRL GENMASK(10, 8) 156 157#define CDNS_PORTCTRL 0x130 158#define CDNS_PORTCTRL_DIRN BIT(7) 159#define CDNS_PORTCTRL_BANK_INVERT BIT(8) 160 161#define CDNS_PORT_OFFSET 0x80 162 163#define CDNS_PDI_CONFIG(n) (0x1100 + (n) * 16) 164 165#define CDNS_PDI_CONFIG_SOFT_RESET BIT(24) 166#define CDNS_PDI_CONFIG_CHANNEL GENMASK(15, 8) 167#define CDNS_PDI_CONFIG_PORT GENMASK(4, 0) 168 169/* Driver defaults */ 170 171#define CDNS_DEFAULT_CLK_DIVIDER 0 172#define CDNS_DEFAULT_FRAME_SHAPE 0x30 173#define CDNS_DEFAULT_SSP_INTERVAL 0x18 174#define CDNS_TX_TIMEOUT 2000 175 176#define CDNS_PCM_PDI_OFFSET 0x2 177#define CDNS_PDM_PDI_OFFSET 0x6 178 179#define CDNS_SCP_RX_FIFOLEVEL 0x2 180 181/* 182 * register accessor helpers 183 */ 184static inline u32 cdns_readl(struct sdw_cdns *cdns, int offset) 185{ 186 return readl(cdns->registers + offset); 187} 188 189static inline void cdns_writel(struct sdw_cdns *cdns, int offset, u32 value) 190{ 191 writel(value, cdns->registers + offset); 192} 193 194static inline void cdns_updatel(struct sdw_cdns *cdns, 195 int offset, u32 mask, u32 val) 196{ 197 u32 tmp; 198 199 tmp = cdns_readl(cdns, offset); 200 tmp = (tmp & ~mask) | val; 201 cdns_writel(cdns, offset, tmp); 202} 203 204static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value) 205{ 206 int timeout = 10; 207 u32 reg_read; 208 209 writel(value, cdns->registers + offset); 210 211 /* Wait for bit to be self cleared */ 212 do { 213 reg_read = readl(cdns->registers + offset); 214 if ((reg_read & value) == 0) 215 return 0; 216 217 timeout--; 218 udelay(50); 219 } while (timeout != 0); 220 221 return -EAGAIN; 222} 223 224/* 225 * IO Calls 226 */ 227static enum sdw_command_response cdns_fill_msg_resp( 228 struct sdw_cdns *cdns, 229 struct sdw_msg *msg, int count, int offset) 230{ 231 int nack = 0, no_ack = 0; 232 int i; 233 234 /* check message response */ 235 for (i = 0; i < count; i++) { 236 if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) { 237 no_ack = 1; 238 dev_dbg(cdns->dev, "Msg Ack not received\n"); 239 if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) { 240 nack = 1; 241 dev_err(cdns->dev, "Msg NACK received\n"); 242 } 243 } 244 } 245 246 if (nack) { 247 dev_err(cdns->dev, "Msg NACKed for Slave %d\n", msg->dev_num); 248 return SDW_CMD_FAIL; 249 } else if (no_ack) { 250 dev_dbg(cdns->dev, "Msg ignored for Slave %d\n", msg->dev_num); 251 return SDW_CMD_IGNORED; 252 } 253 254 /* fill response */ 255 for (i = 0; i < count; i++) 256 msg->buf[i + offset] = cdns->response_buf[i] >> 257 SDW_REG_SHIFT(CDNS_MCP_RESP_RDATA); 258 259 return SDW_CMD_OK; 260} 261 262static enum sdw_command_response 263_cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd, 264 int offset, int count, bool defer) 265{ 266 unsigned long time; 267 u32 base, i, data; 268 u16 addr; 269 270 /* Program the watermark level for RX FIFO */ 271 if (cdns->msg_count != count) { 272 cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, count); 273 cdns->msg_count = count; 274 } 275 276 base = CDNS_MCP_CMD_BASE; 277 addr = msg->addr; 278 279 for (i = 0; i < count; i++) { 280 data = msg->dev_num << SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR); 281 data |= cmd << SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND); 282 data |= addr++ << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L); 283 284 if (msg->flags == SDW_MSG_FLAG_WRITE) 285 data |= msg->buf[i + offset]; 286 287 data |= msg->ssp_sync << SDW_REG_SHIFT(CDNS_MCP_CMD_SSP_TAG); 288 cdns_writel(cdns, base, data); 289 base += CDNS_MCP_CMD_WORD_LEN; 290 } 291 292 if (defer) 293 return SDW_CMD_OK; 294 295 /* wait for timeout or response */ 296 time = wait_for_completion_timeout(&cdns->tx_complete, 297 msecs_to_jiffies(CDNS_TX_TIMEOUT)); 298 if (!time) { 299 dev_err(cdns->dev, "IO transfer timed out\n"); 300 msg->len = 0; 301 return SDW_CMD_TIMEOUT; 302 } 303 304 return cdns_fill_msg_resp(cdns, msg, count, offset); 305} 306 307static enum sdw_command_response cdns_program_scp_addr( 308 struct sdw_cdns *cdns, struct sdw_msg *msg) 309{ 310 int nack = 0, no_ack = 0; 311 unsigned long time; 312 u32 data[2], base; 313 int i; 314 315 /* Program the watermark level for RX FIFO */ 316 if (cdns->msg_count != CDNS_SCP_RX_FIFOLEVEL) { 317 cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, CDNS_SCP_RX_FIFOLEVEL); 318 cdns->msg_count = CDNS_SCP_RX_FIFOLEVEL; 319 } 320 321 data[0] = msg->dev_num << SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR); 322 data[0] |= 0x3 << SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND); 323 data[1] = data[0]; 324 325 data[0] |= SDW_SCP_ADDRPAGE1 << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L); 326 data[1] |= SDW_SCP_ADDRPAGE2 << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L); 327 328 data[0] |= msg->addr_page1; 329 data[1] |= msg->addr_page2; 330 331 base = CDNS_MCP_CMD_BASE; 332 cdns_writel(cdns, base, data[0]); 333 base += CDNS_MCP_CMD_WORD_LEN; 334 cdns_writel(cdns, base, data[1]); 335 336 time = wait_for_completion_timeout(&cdns->tx_complete, 337 msecs_to_jiffies(CDNS_TX_TIMEOUT)); 338 if (!time) { 339 dev_err(cdns->dev, "SCP Msg trf timed out\n"); 340 msg->len = 0; 341 return SDW_CMD_TIMEOUT; 342 } 343 344 /* check response the writes */ 345 for (i = 0; i < 2; i++) { 346 if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) { 347 no_ack = 1; 348 dev_err(cdns->dev, "Program SCP Ack not received"); 349 if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) { 350 nack = 1; 351 dev_err(cdns->dev, "Program SCP NACK received"); 352 } 353 } 354 } 355 356 /* For NACK, NO ack, don't return err if we are in Broadcast mode */ 357 if (nack) { 358 dev_err(cdns->dev, 359 "SCP_addrpage NACKed for Slave %d", msg->dev_num); 360 return SDW_CMD_FAIL; 361 } else if (no_ack) { 362 dev_dbg(cdns->dev, 363 "SCP_addrpage ignored for Slave %d", msg->dev_num); 364 return SDW_CMD_IGNORED; 365 } 366 367 return SDW_CMD_OK; 368} 369 370static int cdns_prep_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int *cmd) 371{ 372 int ret; 373 374 if (msg->page) { 375 ret = cdns_program_scp_addr(cdns, msg); 376 if (ret) { 377 msg->len = 0; 378 return ret; 379 } 380 } 381 382 switch (msg->flags) { 383 case SDW_MSG_FLAG_READ: 384 *cmd = CDNS_MCP_CMD_READ; 385 break; 386 387 case SDW_MSG_FLAG_WRITE: 388 *cmd = CDNS_MCP_CMD_WRITE; 389 break; 390 391 default: 392 dev_err(cdns->dev, "Invalid msg cmd: %d\n", msg->flags); 393 return -EINVAL; 394 } 395 396 return 0; 397} 398 399static enum sdw_command_response 400cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg) 401{ 402 struct sdw_cdns *cdns = bus_to_cdns(bus); 403 int cmd = 0, ret, i; 404 405 ret = cdns_prep_msg(cdns, msg, &cmd); 406 if (ret) 407 return SDW_CMD_FAIL_OTHER; 408 409 for (i = 0; i < msg->len / CDNS_MCP_CMD_LEN; i++) { 410 ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN, 411 CDNS_MCP_CMD_LEN, false); 412 if (ret < 0) 413 goto exit; 414 } 415 416 if (!(msg->len % CDNS_MCP_CMD_LEN)) 417 goto exit; 418 419 ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN, 420 msg->len % CDNS_MCP_CMD_LEN, false); 421 422exit: 423 return ret; 424} 425 426static enum sdw_command_response 427cdns_xfer_msg_defer(struct sdw_bus *bus, 428 struct sdw_msg *msg, struct sdw_defer *defer) 429{ 430 struct sdw_cdns *cdns = bus_to_cdns(bus); 431 int cmd = 0, ret; 432 433 /* for defer only 1 message is supported */ 434 if (msg->len > 1) 435 return -ENOTSUPP; 436 437 ret = cdns_prep_msg(cdns, msg, &cmd); 438 if (ret) 439 return SDW_CMD_FAIL_OTHER; 440 441 cdns->defer = defer; 442 cdns->defer->length = msg->len; 443 444 return _cdns_xfer_msg(cdns, msg, cmd, 0, msg->len, true); 445} 446 447static enum sdw_command_response 448cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num) 449{ 450 struct sdw_cdns *cdns = bus_to_cdns(bus); 451 struct sdw_msg msg; 452 453 /* Create dummy message with valid device number */ 454 memset(&msg, 0, sizeof(msg)); 455 msg.dev_num = dev_num; 456 457 return cdns_program_scp_addr(cdns, &msg); 458} 459 460/* 461 * IRQ handling 462 */ 463 464static void cdns_read_response(struct sdw_cdns *cdns) 465{ 466 u32 num_resp, cmd_base; 467 int i; 468 469 num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT); 470 num_resp &= CDNS_MCP_RX_FIFO_AVAIL; 471 472 cmd_base = CDNS_MCP_CMD_BASE; 473 474 for (i = 0; i < num_resp; i++) { 475 cdns->response_buf[i] = cdns_readl(cdns, cmd_base); 476 cmd_base += CDNS_MCP_CMD_WORD_LEN; 477 } 478} 479 480static int cdns_update_slave_status(struct sdw_cdns *cdns, 481 u32 slave0, u32 slave1) 482{ 483 enum sdw_slave_status status[SDW_MAX_DEVICES + 1]; 484 bool is_slave = false; 485 u64 slave, mask; 486 int i, set_status; 487 488 /* combine the two status */ 489 slave = ((u64)slave1 << 32) | slave0; 490 memset(status, 0, sizeof(status)); 491 492 for (i = 0; i <= SDW_MAX_DEVICES; i++) { 493 mask = (slave >> (i * CDNS_MCP_SLAVE_STATUS_NUM)) & 494 CDNS_MCP_SLAVE_STATUS_BITS; 495 if (!mask) 496 continue; 497 498 is_slave = true; 499 set_status = 0; 500 501 if (mask & CDNS_MCP_SLAVE_INTSTAT_RESERVED) { 502 status[i] = SDW_SLAVE_RESERVED; 503 set_status++; 504 } 505 506 if (mask & CDNS_MCP_SLAVE_INTSTAT_ATTACHED) { 507 status[i] = SDW_SLAVE_ATTACHED; 508 set_status++; 509 } 510 511 if (mask & CDNS_MCP_SLAVE_INTSTAT_ALERT) { 512 status[i] = SDW_SLAVE_ALERT; 513 set_status++; 514 } 515 516 if (mask & CDNS_MCP_SLAVE_INTSTAT_NPRESENT) { 517 status[i] = SDW_SLAVE_UNATTACHED; 518 set_status++; 519 } 520 521 /* first check if Slave reported multiple status */ 522 if (set_status > 1) { 523 dev_warn(cdns->dev, 524 "Slave reported multiple Status: %d\n", 525 status[i]); 526 /* 527 * TODO: we need to reread the status here by 528 * issuing a PING cmd 529 */ 530 } 531 } 532 533 if (is_slave) 534 return sdw_handle_slave_status(&cdns->bus, status); 535 536 return 0; 537} 538 539/** 540 * sdw_cdns_irq() - Cadence interrupt handler 541 * @irq: irq number 542 * @dev_id: irq context 543 */ 544irqreturn_t sdw_cdns_irq(int irq, void *dev_id) 545{ 546 struct sdw_cdns *cdns = dev_id; 547 u32 int_status; 548 int ret = IRQ_HANDLED; 549 550 /* Check if the link is up */ 551 if (!cdns->link_up) 552 return IRQ_NONE; 553 554 int_status = cdns_readl(cdns, CDNS_MCP_INTSTAT); 555 556 if (!(int_status & CDNS_MCP_INT_IRQ)) 557 return IRQ_NONE; 558 559 if (int_status & CDNS_MCP_INT_RX_WL) { 560 cdns_read_response(cdns); 561 562 if (cdns->defer) { 563 cdns_fill_msg_resp(cdns, cdns->defer->msg, 564 cdns->defer->length, 0); 565 complete(&cdns->defer->complete); 566 cdns->defer = NULL; 567 } else 568 complete(&cdns->tx_complete); 569 } 570 571 if (int_status & CDNS_MCP_INT_CTRL_CLASH) { 572 573 /* Slave is driving bit slot during control word */ 574 dev_err_ratelimited(cdns->dev, "Bus clash for control word\n"); 575 int_status |= CDNS_MCP_INT_CTRL_CLASH; 576 } 577 578 if (int_status & CDNS_MCP_INT_DATA_CLASH) { 579 /* 580 * Multiple slaves trying to drive bit slot, or issue with 581 * ownership of data bits or Slave gone bonkers 582 */ 583 dev_err_ratelimited(cdns->dev, "Bus clash for data word\n"); 584 int_status |= CDNS_MCP_INT_DATA_CLASH; 585 } 586 587 if (int_status & CDNS_MCP_INT_SLAVE_MASK) { 588 /* Mask the Slave interrupt and wake thread */ 589 cdns_updatel(cdns, CDNS_MCP_INTMASK, 590 CDNS_MCP_INT_SLAVE_MASK, 0); 591 592 int_status &= ~CDNS_MCP_INT_SLAVE_MASK; 593 ret = IRQ_WAKE_THREAD; 594 } 595 596 cdns_writel(cdns, CDNS_MCP_INTSTAT, int_status); 597 return ret; 598} 599EXPORT_SYMBOL(sdw_cdns_irq); 600 601/** 602 * sdw_cdns_thread() - Cadence irq thread handler 603 * @irq: irq number 604 * @dev_id: irq context 605 */ 606irqreturn_t sdw_cdns_thread(int irq, void *dev_id) 607{ 608 struct sdw_cdns *cdns = dev_id; 609 u32 slave0, slave1; 610 611 dev_dbg(cdns->dev, "Slave status change\n"); 612 613 slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0); 614 slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1); 615 616 cdns_update_slave_status(cdns, slave0, slave1); 617 cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0); 618 cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1); 619 620 /* clear and unmask Slave interrupt now */ 621 cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK); 622 cdns_updatel(cdns, CDNS_MCP_INTMASK, 623 CDNS_MCP_INT_SLAVE_MASK, CDNS_MCP_INT_SLAVE_MASK); 624 625 return IRQ_HANDLED; 626} 627EXPORT_SYMBOL(sdw_cdns_thread); 628 629/* 630 * init routines 631 */ 632static int _cdns_enable_interrupt(struct sdw_cdns *cdns) 633{ 634 u32 mask; 635 636 cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0, 637 CDNS_MCP_SLAVE_INTMASK0_MASK); 638 cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1, 639 CDNS_MCP_SLAVE_INTMASK1_MASK); 640 641 mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT | 642 CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH | 643 CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH | 644 CDNS_MCP_INT_RX_WL | CDNS_MCP_INT_IRQ | CDNS_MCP_INT_DPINT; 645 646 cdns_writel(cdns, CDNS_MCP_INTMASK, mask); 647 648 return 0; 649} 650 651/** 652 * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config 653 * @cdns: Cadence instance 654 */ 655int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns) 656{ 657 int ret; 658 659 _cdns_enable_interrupt(cdns); 660 ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE, 661 CDNS_MCP_CONFIG_UPDATE_BIT); 662 if (ret < 0) 663 dev_err(cdns->dev, "Config update timedout"); 664 665 return ret; 666} 667EXPORT_SYMBOL(sdw_cdns_enable_interrupt); 668 669/** 670 * sdw_cdns_init() - Cadence initialization 671 * @cdns: Cadence instance 672 */ 673int sdw_cdns_init(struct sdw_cdns *cdns) 674{ 675 u32 val; 676 int ret; 677 678 /* Exit clock stop */ 679 ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL, 680 CDNS_MCP_CONTROL_CLK_STOP_CLR); 681 if (ret < 0) { 682 dev_err(cdns->dev, "Couldn't exit from clock stop\n"); 683 return ret; 684 } 685 686 /* Set clock divider */ 687 val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0); 688 val |= CDNS_DEFAULT_CLK_DIVIDER; 689 cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val); 690 691 /* Set the default frame shape */ 692 cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, CDNS_DEFAULT_FRAME_SHAPE); 693 694 /* Set SSP interval to default value */ 695 cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL); 696 cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL); 697 698 /* Set cmd accept mode */ 699 cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT, 700 CDNS_MCP_CONTROL_CMD_ACCEPT); 701 702 /* Configure mcp config */ 703 val = cdns_readl(cdns, CDNS_MCP_CONFIG); 704 705 /* Set Max cmd retry to 15 */ 706 val |= CDNS_MCP_CONFIG_MCMD_RETRY; 707 708 /* Set frame delay between PREQ and ping frame to 15 frames */ 709 val |= 0xF << SDW_REG_SHIFT(CDNS_MCP_CONFIG_MPREQ_DELAY); 710 711 /* Disable auto bus release */ 712 val &= ~CDNS_MCP_CONFIG_BUS_REL; 713 714 /* Disable sniffer mode */ 715 val &= ~CDNS_MCP_CONFIG_SNIFFER; 716 717 /* Set cmd mode for Tx and Rx cmds */ 718 val &= ~CDNS_MCP_CONFIG_CMD; 719 720 /* Set operation to normal */ 721 val &= ~CDNS_MCP_CONFIG_OP; 722 val |= CDNS_MCP_CONFIG_OP_NORMAL; 723 724 cdns_writel(cdns, CDNS_MCP_CONFIG, val); 725 726 return 0; 727} 728EXPORT_SYMBOL(sdw_cdns_init); 729 730struct sdw_master_ops sdw_cdns_master_ops = { 731 .read_prop = sdw_master_read_prop, 732 .xfer_msg = cdns_xfer_msg, 733 .xfer_msg_defer = cdns_xfer_msg_defer, 734 .reset_page_addr = cdns_reset_page_addr, 735}; 736EXPORT_SYMBOL(sdw_cdns_master_ops); 737 738/** 739 * sdw_cdns_probe() - Cadence probe routine 740 * @cdns: Cadence instance 741 */ 742int sdw_cdns_probe(struct sdw_cdns *cdns) 743{ 744 init_completion(&cdns->tx_complete); 745 746 return 0; 747} 748EXPORT_SYMBOL(sdw_cdns_probe); 749 750MODULE_LICENSE("Dual BSD/GPL"); 751MODULE_DESCRIPTION("Cadence Soundwire Library");