1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ |
2 | /* |
3 | * This file is provided under a dual BSD/GPLv2 license. When using or |
4 | * redistributing this file, you may do so under either license. |
5 | * |
6 | * Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved. |
7 | * |
8 | * Author: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> |
9 | */ |
10 | |
11 | #ifndef __AMD_ACP_H |
12 | #define __AMD_ACP_H |
13 | |
14 | #include <sound/pcm.h> |
15 | #include <sound/soc.h> |
16 | #include <sound/soc-acpi.h> |
17 | #include <sound/soc-dai.h> |
18 | |
19 | #include "chip_offset_byte.h" |
20 | |
21 | #define ACP3X_DEV 3 |
22 | #define ACP6X_DEV 6 |
23 | #define ACP63_DEV 0x63 |
24 | #define ACP70_DEV 0x70 |
25 | |
26 | #define DMIC_INSTANCE 0x00 |
27 | #define I2S_SP_INSTANCE 0x01 |
28 | #define I2S_BT_INSTANCE 0x02 |
29 | #define I2S_HS_INSTANCE 0x03 |
30 | |
31 | #define MEM_WINDOW_START 0x4080000 |
32 | |
33 | #define ACP_I2S_REG_START 0x1242400 |
34 | #define ACP_I2S_REG_END 0x1242810 |
35 | #define ACP3x_I2STDM_REG_START 0x1242400 |
36 | #define ACP3x_I2STDM_REG_END 0x1242410 |
37 | #define ACP3x_BT_TDM_REG_START 0x1242800 |
38 | #define ACP3x_BT_TDM_REG_END 0x1242810 |
39 | |
40 | #define THRESHOLD(bit, base) ((bit) + (base)) |
41 | #define I2S_RX_THRESHOLD(base) THRESHOLD(7, base) |
42 | #define I2S_TX_THRESHOLD(base) THRESHOLD(8, base) |
43 | #define BT_TX_THRESHOLD(base) THRESHOLD(6, base) |
44 | #define BT_RX_THRESHOLD(base) THRESHOLD(5, base) |
45 | #define HS_TX_THRESHOLD(base) THRESHOLD(4, base) |
46 | #define HS_RX_THRESHOLD(base) THRESHOLD(3, base) |
47 | |
48 | #define ACP_SRAM_SP_PB_PTE_OFFSET 0x0 |
49 | #define ACP_SRAM_SP_CP_PTE_OFFSET 0x100 |
50 | #define ACP_SRAM_BT_PB_PTE_OFFSET 0x200 |
51 | #define ACP_SRAM_BT_CP_PTE_OFFSET 0x300 |
52 | #define ACP_SRAM_PDM_PTE_OFFSET 0x400 |
53 | #define ACP_SRAM_HS_PB_PTE_OFFSET 0x500 |
54 | #define ACP_SRAM_HS_CP_PTE_OFFSET 0x600 |
55 | #define PAGE_SIZE_4K_ENABLE 0x2 |
56 | |
57 | #define I2S_SP_TX_MEM_WINDOW_START 0x4000000 |
58 | #define I2S_SP_RX_MEM_WINDOW_START 0x4020000 |
59 | #define I2S_BT_TX_MEM_WINDOW_START 0x4040000 |
60 | #define I2S_BT_RX_MEM_WINDOW_START 0x4060000 |
61 | #define I2S_HS_TX_MEM_WINDOW_START 0x40A0000 |
62 | #define I2S_HS_RX_MEM_WINDOW_START 0x40C0000 |
63 | |
64 | #define SP_PB_FIFO_ADDR_OFFSET 0x500 |
65 | #define SP_CAPT_FIFO_ADDR_OFFSET 0x700 |
66 | #define BT_PB_FIFO_ADDR_OFFSET 0x900 |
67 | #define BT_CAPT_FIFO_ADDR_OFFSET 0xB00 |
68 | #define HS_PB_FIFO_ADDR_OFFSET 0xD00 |
69 | #define HS_CAPT_FIFO_ADDR_OFFSET 0xF00 |
70 | #define PLAYBACK_MIN_NUM_PERIODS 2 |
71 | #define PLAYBACK_MAX_NUM_PERIODS 8 |
72 | #define PLAYBACK_MAX_PERIOD_SIZE 8192 |
73 | #define PLAYBACK_MIN_PERIOD_SIZE 1024 |
74 | #define CAPTURE_MIN_NUM_PERIODS 2 |
75 | #define CAPTURE_MAX_NUM_PERIODS 8 |
76 | #define CAPTURE_MAX_PERIOD_SIZE 8192 |
77 | #define CAPTURE_MIN_PERIOD_SIZE 1024 |
78 | |
79 | #define MAX_BUFFER 65536 |
80 | #define MIN_BUFFER MAX_BUFFER |
81 | #define FIFO_SIZE 0x100 |
82 | #define DMA_SIZE 0x40 |
83 | #define FRM_LEN 0x100 |
84 | |
85 | #define ACP3x_ITER_IRER_SAMP_LEN_MASK 0x38 |
86 | |
87 | #define ACP_MAX_STREAM 8 |
88 | |
89 | #define TDM_ENABLE 1 |
90 | #define TDM_DISABLE 0 |
91 | |
92 | #define SLOT_WIDTH_8 0x8 |
93 | #define SLOT_WIDTH_16 0x10 |
94 | #define SLOT_WIDTH_24 0x18 |
95 | #define SLOT_WIDTH_32 0x20 |
96 | |
97 | #define ACP6X_PGFSM_CONTROL 0x1024 |
98 | #define ACP6X_PGFSM_STATUS 0x1028 |
99 | |
100 | #define ACP63_PGFSM_CONTROL ACP6X_PGFSM_CONTROL |
101 | #define ACP63_PGFSM_STATUS ACP6X_PGFSM_STATUS |
102 | |
103 | #define ACP70_PGFSM_CONTROL ACP6X_PGFSM_CONTROL |
104 | #define ACP70_PGFSM_STATUS ACP6X_PGFSM_STATUS |
105 | |
106 | #define ACP_SOFT_RST_DONE_MASK 0x00010001 |
107 | |
108 | #define ACP_PGFSM_CNTL_POWER_ON_MASK 0xffffffff |
109 | #define ACP_PGFSM_CNTL_POWER_OFF_MASK 0x00 |
110 | #define ACP_PGFSM_STATUS_MASK 0x03 |
111 | #define ACP_POWERED_ON 0x00 |
112 | #define ACP_POWER_ON_IN_PROGRESS 0x01 |
113 | #define ACP_POWERED_OFF 0x02 |
114 | #define ACP_POWER_OFF_IN_PROGRESS 0x03 |
115 | |
116 | #define ACP_ERROR_MASK 0x20000000 |
117 | #define ACP_EXT_INTR_STAT_CLEAR_MASK 0xffffffff |
118 | |
119 | #define ACP_TIMEOUT 500 |
120 | #define DELAY_US 5 |
121 | #define ACP_SUSPEND_DELAY_MS 2000 |
122 | |
123 | #define PDM_DMA_STAT 0x10 |
124 | #define PDM_DMA_INTR_MASK 0x10000 |
125 | #define PDM_DEC_64 0x2 |
126 | #define PDM_CLK_FREQ_MASK 0x07 |
127 | #define PDM_MISC_CTRL_MASK 0x10 |
128 | #define PDM_ENABLE 0x01 |
129 | #define PDM_DISABLE 0x00 |
130 | #define DMA_EN_MASK 0x02 |
131 | #define DELAY_US 5 |
132 | #define PDM_TIMEOUT 1000 |
133 | #define ACP_REGION2_OFFSET 0x02000000 |
134 | |
135 | struct acp_chip_info { |
136 | char *name; /* Platform name */ |
137 | unsigned int acp_rev; /* ACP Revision id */ |
138 | void __iomem *base; /* ACP memory PCI base */ |
139 | struct platform_device *chip_pdev; |
140 | unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ |
141 | }; |
142 | |
143 | struct acp_stream { |
144 | struct list_head list; |
145 | struct snd_pcm_substream *substream; |
146 | int irq_bit; |
147 | int dai_id; |
148 | int id; |
149 | int dir; |
150 | u64 bytescount; |
151 | u32 reg_offset; |
152 | u32 pte_offset; |
153 | u32 fifo_offset; |
154 | }; |
155 | |
156 | struct acp_resource { |
157 | int offset; |
158 | int no_of_ctrls; |
159 | int irqp_used; |
160 | bool soc_mclk; |
161 | u32 irq_reg_offset; |
162 | u32 i2s_pin_cfg_offset; |
163 | int i2s_mode; |
164 | u64 scratch_reg_offset; |
165 | u64 sram_pte_offset; |
166 | }; |
167 | |
168 | struct acp_dev_data { |
169 | char *name; |
170 | struct device *dev; |
171 | void __iomem *acp_base; |
172 | unsigned int i2s_irq; |
173 | |
174 | bool tdm_mode; |
175 | /* SOC specific dais */ |
176 | struct snd_soc_dai_driver *dai_driver; |
177 | int num_dai; |
178 | |
179 | struct list_head stream_list; |
180 | spinlock_t acp_lock; |
181 | |
182 | struct snd_soc_acpi_mach *machines; |
183 | struct platform_device *mach_dev; |
184 | |
185 | u32 bclk_div; |
186 | u32 lrclk_div; |
187 | |
188 | struct acp_resource *rsrc; |
189 | u32 ch_mask; |
190 | u32 tdm_tx_fmt[3]; |
191 | u32 tdm_rx_fmt[3]; |
192 | u32 xfer_tx_resolution[3]; |
193 | u32 xfer_rx_resolution[3]; |
194 | unsigned int flag; |
195 | unsigned int platform; |
196 | }; |
197 | |
198 | enum acp_config { |
199 | ACP_CONFIG_0 = 0, |
200 | ACP_CONFIG_1, |
201 | ACP_CONFIG_2, |
202 | ACP_CONFIG_3, |
203 | ACP_CONFIG_4, |
204 | ACP_CONFIG_5, |
205 | ACP_CONFIG_6, |
206 | ACP_CONFIG_7, |
207 | ACP_CONFIG_8, |
208 | ACP_CONFIG_9, |
209 | ACP_CONFIG_10, |
210 | ACP_CONFIG_11, |
211 | ACP_CONFIG_12, |
212 | ACP_CONFIG_13, |
213 | ACP_CONFIG_14, |
214 | ACP_CONFIG_15, |
215 | }; |
216 | |
217 | extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops; |
218 | extern const struct snd_soc_dai_ops acp_dmic_dai_ops; |
219 | |
220 | int acp_platform_register(struct device *dev); |
221 | int acp_platform_unregister(struct device *dev); |
222 | |
223 | int acp_machine_select(struct acp_dev_data *adata); |
224 | |
225 | int smn_read(struct pci_dev *dev, u32 smn_addr); |
226 | int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data); |
227 | |
228 | int acp_init(struct acp_chip_info *chip); |
229 | int acp_deinit(struct acp_chip_info *chip); |
230 | void acp_enable_interrupts(struct acp_dev_data *adata); |
231 | void acp_disable_interrupts(struct acp_dev_data *adata); |
232 | /* Machine configuration */ |
233 | int snd_amd_acp_find_config(struct pci_dev *pci); |
234 | |
235 | void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream); |
236 | void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size); |
237 | void restore_acp_pdm_params(struct snd_pcm_substream *substream, |
238 | struct acp_dev_data *adata); |
239 | |
240 | int restore_acp_i2s_params(struct snd_pcm_substream *substream, |
241 | struct acp_dev_data *adata, struct acp_stream *stream); |
242 | |
243 | int check_acp_pdm(struct pci_dev *pci, struct acp_chip_info *chip); |
244 | |
245 | static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction) |
246 | { |
247 | u64 byte_count = 0, low = 0, high = 0; |
248 | |
249 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) { |
250 | switch (dai_id) { |
251 | case I2S_BT_INSTANCE: |
252 | high = readl(addr: adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH); |
253 | low = readl(addr: adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW); |
254 | break; |
255 | case I2S_SP_INSTANCE: |
256 | high = readl(addr: adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH); |
257 | low = readl(addr: adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW); |
258 | break; |
259 | case I2S_HS_INSTANCE: |
260 | high = readl(addr: adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH); |
261 | low = readl(addr: adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_LOW); |
262 | break; |
263 | default: |
264 | dev_err(adata->dev, "Invalid dai id %x\n" , dai_id); |
265 | goto POINTER_RETURN_BYTES; |
266 | } |
267 | } else { |
268 | switch (dai_id) { |
269 | case I2S_BT_INSTANCE: |
270 | high = readl(addr: adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH); |
271 | low = readl(addr: adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW); |
272 | break; |
273 | case I2S_SP_INSTANCE: |
274 | high = readl(addr: adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH); |
275 | low = readl(addr: adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW); |
276 | break; |
277 | case I2S_HS_INSTANCE: |
278 | high = readl(addr: adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH); |
279 | low = readl(addr: adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_LOW); |
280 | break; |
281 | case DMIC_INSTANCE: |
282 | high = readl(addr: adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH); |
283 | low = readl(addr: adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW); |
284 | break; |
285 | default: |
286 | dev_err(adata->dev, "Invalid dai id %x\n" , dai_id); |
287 | goto POINTER_RETURN_BYTES; |
288 | } |
289 | } |
290 | /* Get 64 bit value from two 32 bit registers */ |
291 | byte_count = (high << 32) | low; |
292 | |
293 | POINTER_RETURN_BYTES: |
294 | return byte_count; |
295 | } |
296 | #endif |
297 | |