| 1 |
|
| 2 |
|
| 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;
|
| 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;
|
| 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;
|
| 257 | }
|
| 258 |
|
| 259 |
|
| 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 |
|
| 267 | int intel_pre_bank_switch(struct sdw_intel *sdw);
|
| 268 | int intel_post_bank_switch(struct sdw_intel *sdw);
|
| 269 |
|
| 270 | #endif
|