1 /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ 2 /* Copyright(c) 2015-17 Intel Corporation. */ 3 4 #ifndef __SDW_INTEL_LOCAL_H 5 #define __SDW_INTEL_LOCAL_H 6 7 struct hdac_bus; 8 9 /** 10 * struct sdw_intel_link_res - Soundwire Intel link resource structure, 11 * typically populated by the controller driver. 12 * @hw_ops: platform-specific ops 13 * @mmio_base: mmio base of SoundWire registers 14 * @registers: Link IO registers base 15 * @ip_offset: offset for MCP_IP registers 16 * @shim: Audio shim pointer 17 * @shim_vs: Audio vendor-specific shim pointer 18 * @alh: ALH (Audio Link Hub) pointer 19 * @irq: Interrupt line 20 * @ops: Shim callback ops 21 * @dev: device implementing hw_params and free callbacks 22 * @shim_lock: mutex to handle access to shared SHIM registers 23 * @shim_mask: global pointer to check SHIM register initialization 24 * @clock_stop_quirks: mask defining requested behavior on pm_suspend 25 * @mic_privacy: ACE version supports microphone privacy 26 * @link_mask: global mask needed for power-up/down sequences 27 * @cdns: Cadence master descriptor 28 * @list: used to walk-through all masters exposed by the same controller 29 * @hbus: hdac_bus pointer, needed for power management 30 */ 31 struct sdw_intel_link_res { 32 const struct sdw_intel_hw_ops *hw_ops; 33 34 void __iomem *mmio_base; /* not strictly needed, useful for debug */ 35 void __iomem *registers; 36 u32 ip_offset; 37 void __iomem *shim; 38 void __iomem *shim_vs; 39 void __iomem *alh; 40 int irq; 41 const struct sdw_intel_ops *ops; 42 struct device *dev; 43 struct mutex *shim_lock; /* protect shared registers */ 44 u32 *shim_mask; 45 u32 clock_stop_quirks; 46 bool mic_privacy; 47 u32 link_mask; 48 struct sdw_cdns *cdns; 49 struct list_head list; 50 struct hdac_bus *hbus; 51 }; 52 53 /** 54 * struct sdw_intel_bpt - SoundWire Intel BPT context 55 * @bpt_tx_stream: BPT TX stream 56 * @dmab_tx_bdl: BPT TX buffer descriptor list 57 * @bpt_rx_stream: BPT RX stream 58 * @dmab_rx_bdl: BPT RX buffer descriptor list 59 * @pdi0_buffer_size: PDI0 buffer size 60 * @pdi1_buffer_size: PDI1 buffer size 61 * @num_frames: number of frames 62 * @data_per_frame: data per frame 63 */ 64 struct sdw_intel_bpt { 65 struct hdac_ext_stream *bpt_tx_stream; 66 struct snd_dma_buffer dmab_tx_bdl; 67 struct hdac_ext_stream *bpt_rx_stream; 68 struct snd_dma_buffer dmab_rx_bdl; 69 unsigned int pdi0_buffer_size; 70 unsigned int pdi1_buffer_size; 71 unsigned int num_frames; 72 unsigned int data_per_frame; 73 }; 74 75 struct sdw_intel { 76 struct sdw_cdns cdns; 77 int instance; 78 struct sdw_intel_link_res *link_res; 79 bool startup_done; 80 struct sdw_intel_bpt bpt_ctx; 81 #ifdef CONFIG_DEBUG_FS 82 struct dentry *debugfs; 83 #endif 84 }; 85 86 struct sdw_intel_prop { 87 u16 clde; 88 u16 doaise2; 89 u16 dodse2; 90 u16 clds; 91 u16 clss; 92 u16 doaise; 93 u16 doais; 94 u16 dodse; 95 u16 dods; 96 }; 97 98 enum intel_pdi_type { 99 INTEL_PDI_IN = 0, 100 INTEL_PDI_OUT = 1, 101 INTEL_PDI_BD = 2, 102 }; 103 104 /* 105 * Read, write helpers for HW registers 106 */ 107 static inline int intel_readl(void __iomem *base, int offset) 108 { 109 return readl(base + offset); 110 } 111 112 static inline void intel_writel(void __iomem *base, int offset, int value) 113 { 114 writel(value, base + offset); 115 } 116 117 static inline u16 intel_readw(void __iomem *base, int offset) 118 { 119 return readw(base + offset); 120 } 121 122 static inline void intel_writew(void __iomem *base, int offset, u16 value) 123 { 124 writew(value, base + offset); 125 } 126 127 #define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns) 128 129 #define INTEL_MASTER_RESET_ITERATIONS 10 130 131 #define SDW_INTEL_DELAYED_ENUMERATION_MS 100 132 133 #define SDW_INTEL_CHECK_OPS(sdw, cb) ((sdw) && (sdw)->link_res && (sdw)->link_res->hw_ops && \ 134 (sdw)->link_res->hw_ops->cb) 135 #define SDW_INTEL_OPS(sdw, cb) ((sdw)->link_res->hw_ops->cb) 136 137 #ifdef CONFIG_DEBUG_FS 138 void intel_ace2x_debugfs_init(struct sdw_intel *sdw); 139 void intel_ace2x_debugfs_exit(struct sdw_intel *sdw); 140 #else 141 static inline void intel_ace2x_debugfs_init(struct sdw_intel *sdw) {} 142 static inline void intel_ace2x_debugfs_exit(struct sdw_intel *sdw) {} 143 #endif 144 145 static inline void sdw_intel_debugfs_init(struct sdw_intel *sdw) 146 { 147 if (SDW_INTEL_CHECK_OPS(sdw, debugfs_init)) 148 SDW_INTEL_OPS(sdw, debugfs_init)(sdw); 149 } 150 151 static inline void sdw_intel_debugfs_exit(struct sdw_intel *sdw) 152 { 153 if (SDW_INTEL_CHECK_OPS(sdw, debugfs_exit)) 154 SDW_INTEL_OPS(sdw, debugfs_exit)(sdw); 155 } 156 157 static inline int sdw_intel_register_dai(struct sdw_intel *sdw) 158 { 159 if (SDW_INTEL_CHECK_OPS(sdw, register_dai)) 160 return SDW_INTEL_OPS(sdw, register_dai)(sdw); 161 return -ENOTSUPP; 162 } 163 164 static inline void sdw_intel_check_clock_stop(struct sdw_intel *sdw) 165 { 166 if (SDW_INTEL_CHECK_OPS(sdw, check_clock_stop)) 167 SDW_INTEL_OPS(sdw, check_clock_stop)(sdw); 168 } 169 170 static inline int sdw_intel_start_bus(struct sdw_intel *sdw) 171 { 172 if (SDW_INTEL_CHECK_OPS(sdw, start_bus)) 173 return SDW_INTEL_OPS(sdw, start_bus)(sdw); 174 return -ENOTSUPP; 175 } 176 177 static inline int sdw_intel_start_bus_after_reset(struct sdw_intel *sdw) 178 { 179 if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_reset)) 180 return SDW_INTEL_OPS(sdw, start_bus_after_reset)(sdw); 181 return -ENOTSUPP; 182 } 183 184 static inline int sdw_intel_start_bus_after_clock_stop(struct sdw_intel *sdw) 185 { 186 if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_clock_stop)) 187 return SDW_INTEL_OPS(sdw, start_bus_after_clock_stop)(sdw); 188 return -ENOTSUPP; 189 } 190 191 static inline int sdw_intel_stop_bus(struct sdw_intel *sdw, bool clock_stop) 192 { 193 if (SDW_INTEL_CHECK_OPS(sdw, stop_bus)) 194 return SDW_INTEL_OPS(sdw, stop_bus)(sdw, clock_stop); 195 return -ENOTSUPP; 196 } 197 198 static inline int sdw_intel_link_power_up(struct sdw_intel *sdw) 199 { 200 if (SDW_INTEL_CHECK_OPS(sdw, link_power_up)) 201 return SDW_INTEL_OPS(sdw, link_power_up)(sdw); 202 return -ENOTSUPP; 203 } 204 205 static inline int sdw_intel_link_power_down(struct sdw_intel *sdw) 206 { 207 if (SDW_INTEL_CHECK_OPS(sdw, link_power_down)) 208 return SDW_INTEL_OPS(sdw, link_power_down)(sdw); 209 return -ENOTSUPP; 210 } 211 212 static inline int sdw_intel_shim_check_wake(struct sdw_intel *sdw) 213 { 214 if (SDW_INTEL_CHECK_OPS(sdw, shim_check_wake)) 215 return SDW_INTEL_OPS(sdw, shim_check_wake)(sdw); 216 return -ENOTSUPP; 217 } 218 219 static inline void sdw_intel_shim_wake(struct sdw_intel *sdw, bool wake_enable) 220 { 221 if (SDW_INTEL_CHECK_OPS(sdw, shim_wake)) 222 SDW_INTEL_OPS(sdw, shim_wake)(sdw, wake_enable); 223 } 224 225 static inline void sdw_intel_sync_arm(struct sdw_intel *sdw) 226 { 227 if (SDW_INTEL_CHECK_OPS(sdw, sync_arm)) 228 SDW_INTEL_OPS(sdw, sync_arm)(sdw); 229 } 230 231 static inline int sdw_intel_sync_go_unlocked(struct sdw_intel *sdw) 232 { 233 if (SDW_INTEL_CHECK_OPS(sdw, sync_go_unlocked)) 234 return SDW_INTEL_OPS(sdw, sync_go_unlocked)(sdw); 235 return -ENOTSUPP; 236 } 237 238 static inline int sdw_intel_sync_go(struct sdw_intel *sdw) 239 { 240 if (SDW_INTEL_CHECK_OPS(sdw, sync_go)) 241 return SDW_INTEL_OPS(sdw, sync_go)(sdw); 242 return -ENOTSUPP; 243 } 244 245 static inline bool sdw_intel_sync_check_cmdsync_unlocked(struct sdw_intel *sdw) 246 { 247 if (SDW_INTEL_CHECK_OPS(sdw, sync_check_cmdsync_unlocked)) 248 return SDW_INTEL_OPS(sdw, sync_check_cmdsync_unlocked)(sdw); 249 return false; 250 } 251 252 static inline int sdw_intel_get_link_count(struct sdw_intel *sdw) 253 { 254 if (SDW_INTEL_CHECK_OPS(sdw, get_link_count)) 255 return SDW_INTEL_OPS(sdw, get_link_count)(sdw); 256 return 4; /* default on older generations */ 257 } 258 259 /* common bus management */ 260 int intel_start_bus(struct sdw_intel *sdw); 261 int intel_start_bus_after_reset(struct sdw_intel *sdw); 262 void intel_check_clock_stop(struct sdw_intel *sdw); 263 int intel_start_bus_after_clock_stop(struct sdw_intel *sdw); 264 int intel_stop_bus(struct sdw_intel *sdw, bool clock_stop); 265 266 /* common bank switch routines */ 267 int intel_pre_bank_switch(struct sdw_intel *sdw); 268 int intel_post_bank_switch(struct sdw_intel *sdw); 269 270 #endif /* __SDW_INTEL_LOCAL_H */ 271