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