1 /*
2 * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
3 *
4 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
5 * the the people's Republic of China and other countries.
6 * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
7 *
8 * DISCLAIMER
9 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
10 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
11 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
12 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
13 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
14 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
15 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
19 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
21 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
22 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 #ifndef __SUNXI_MAD_H_
33 #define __SUNXI_MAD_H_
34 
35 #include <aw_common.h>
36 #include <hal_clk.h>
37 #include <hal_dma.h>
38 #include <snd_core.h>
39 #include <snd_pcm.h>
40 #include <snd_io.h>
41 
42 #include "sunxi-pcm.h"
43 
44 /* memory mapping */
45 #define MAD_BASE SUNXI_MAD_PBASE
46 #define MAD_SRAM_DMA_SRC_ADDR SUNXI_MAD_SRAM_PBASE
47 
48 #ifdef CONFIG_ARCH_SUN8IW18P1
49 /* SUN8IW18P1 should not be setup. */
50 #undef MAD_CLK_ALWAYS_ON
51 //#undef SUNXI_LPSD_CLK_ALWAYS_ON
52 #define SUNXI_LPSD_CLK_ALWAYS_ON
53 #undef SUNXI_MAD_DATA_INT_USE
54 //#define SUNXI_MAD_DATA_INT_USE
55 #define SUNXI_MAD_SRAM_SUSPEND_RESET
56 
57 /* 128k bytes */
58 #define MAD_SRAM_SIZE_VALUE 0x80
59 #endif
60 
61 /*memory mapping*/
62 #ifndef MAD_BASE
63 #define MAD_BASE (0x05400000)
64 #endif
65 #ifndef MAD_SRAM_DMA_SRC_ADDR
66 #define MAD_SRAM_DMA_SRC_ADDR (0x05480000)
67 #endif
68 /* 128k bytes */
69 #ifndef MAD_SRAM_SIZE_VALUE
70 #define MAD_SRAM_SIZE_VALUE 0x80
71 #endif
72 
73 enum mad_sram_bmode {
74         MAD_SRAM_BMODE_NORMAL = 0,
75         MAD_SRAM_BMODE_BOOT = 1,
76 };
77 
78 enum mad_path_sel {
79         MAD_PATH_NONE = 0,
80         MAD_PATH_I2S0 = 1,
81         MAD_PATH_CODEC = 2,
82         MAD_PATH_DMIC = 3,
83         MAD_PATH_I2S1 = 4,
84         MAD_PATH_I2S2 = 5,
85 };
86 
87 #ifdef CONFIG_ARCH_SUN8IW18P1
88 #undef SUNXI_MAD_DATA_INT_USE
89 #endif
90 
91 #define EVT_MAX_SIZE            256
92 #define SUNXI_NETLINK_MAD       30
93 
94 /*------------------MAD register definition--------------------*/
95 #define SUNXI_MAD_CTRL                  0x00
96 #define SUNXI_MAD_SRAM_POINT            0x04
97 #define SUNXI_MAD_SRAM_SIZE             0x08
98 #define SUNXI_MAD_SRAM_RD_POINT         0x0C
99 #define SUNXI_MAD_RD_SIZE               0x10
100 #define SUNXI_MAD_SRAM_STORE_TH         0x14
101 #define SUNXI_MAD_SRAM_AHB1_TX_TH       0x18
102 #define SUNXI_MAD_SRAM_AHB1_RX_TH       0x1C
103 #define SUNXI_MAD_SRAM_WAKE_BACK_DATA   0x20
104 #define SUNXI_MAD_AD_PATH_SEL           0x24
105 #define SUNXI_MAD_LPSD_AD_SYNC_FC       0x28
106 #define SUNXI_MAD_LPSD_TH               0x2C
107 #define SUNXI_MAD_LPSD_RRUN             0x30
108 #define SUNXI_MAD_LPSD_RSTOP            0x34
109 #define SUNXI_MAD_LPSD_ECNT             0x38
110 #define SUNXI_MAD_SRAM_CH_MASK          0x3C
111 #define SUNXI_MAD_LPSD_CH_MASK          0x40
112 #define SUNXI_MAD_SRAM_SEC_REGION_REG   0x44
113 #define SUNXI_MAD_SRAM_PRE_DSIZE        0x48
114 #define SUNXI_MAD_DMA_TF_SIZE           0x4C
115 #define SUNXI_MAD_DMA_TF_LAST_SIZE      0x50
116 #define SUNXI_MAD_INT_ST_CLR            0x60
117 #define SUNXI_MAD_INT_MASK              0x64
118 #define SUNXI_MAD_STA                   0x68
119 #define SUNXI_MAD_DEBUG                 0x6C
120 
121 /*SUNXI_MAD_CTRL: 0x00*/
122 #define AUDIO_DATA_SYNC_FRC             7
123 #define SRAM_RST                        6
124 #define DMA_TYPE                        5
125 #define DMA_EN                          4
126 #define CPUS_RD_DONE                    3
127 #define GO_ON_SLEEP                     2
128 #define KEY_WORD_OK                     1
129 #define MAD_EN                          0
130 /* DMA type*/
131 #define DMA_TYPE_MASK                   0x1
132 #define DMA_TYPE_IO                     0x1
133 #define DMA_TYPE_MEM                    0x0
134 
135 /*SUNXI_MAD_SRAM_POINT: 0x04*/
136 #define MAD_SRAM_PONT                   0
137 
138 /*SUNXI_MAD_SRAM_SIZE: 0x08*/
139 #define MAD_SRAM_SIZE                   0
140 
141 /*SUNXI_MAD_SRAM_RD_POINT: 0x0C*/
142 #define MAD_SRAM_RD_POINT               0
143 
144 /*SUNXI_MAD_SRAM_RD_SIZE(unit: half word): 0x10*/
145 #define MAD_SRAM_RD_SIZE                0
146 
147 /*SUNXI_MAD_SRAM_STORE_TH(unit: half word): 0x14*/
148 #define MAD_SRAM_STORE_TH               0
149 
150 /*SUNXI_MAD_SRAM_AHB1_TX_TH(unit: byte): 0x18*/
151 #define MAD_SRAM_AHB1_TX_TH             0
152 
153 /*SUNXI_MAD_SRAM_AHB1_RX_TH(unit: byte): 0x1C*/
154 #define MAD_SRAM_AHB1_RX_TH             0
155 
156 /*SUNXI_MAD_SRAM_WAKE_BACK_DATA(unit: frame): 0x20*/
157 #define MAD_SRAM_WAKE_BACK_DATA         0
158 
159 /*SUNXI_MAD_AD_PATH_SEL: 0x24*/
160 #define MAD_AD_PATH_SEL                 0
161 #define MAD_AD_PATH_SEL_MASK            0xF
162 /*MAD audio src sel*/
163 #define MAD_AD_PATH_NO_SRC              0x0
164 #define MAD_AD_PATH_I2S0_SRC            0x1
165 #define MAD_AD_PATH_CODEC_SRC           0x2
166 #define MAD_AD_PATH_DMIC_SRC            0x3
167 #define MAD_AD_PATH_I2S1_SRC            0x4
168 #define MAD_AD_PATH_I2S2_SRC            0x5
169 
170 /*SUNXI_MAD_LPSD_AD_SYNC_FC: 0x28*/
171 #define MAD_LPSD_AD_SYNC_FC             0
172 #define MAD_LPSD_AD_SYNC_FC_DEF         0X20
173 
174 /*SUNXI_MAD_LPSD_TH: 0x2C*/
175 #define MAD_LPSD_TH                     0
176 
177 /*SUNXI_MAD_LPSD_RRUN: 0x30*/
178 #define MAD_LPSD_RRUN                   0
179 
180 /*SUNXI_MAD_LPSD_RSTOP: 0x34*/
181 #define MAD_LPSD_RSTOP                  0
182 
183 /*SUNXI_MAD_LPSD_ECNT: 0x38*/
184 #define MAD_LPSD_ECNT                   0
185 
186 /*SUNXI_MAD_SRAM_CH_MASK: 0x3C*/
187 #define MAD_CH_CHANGE_EN                30
188 #define MAD_CH_COM_NUM                  26
189 #define MAD_AD_SRC_CH_NUM               21
190 #define MAD_SRAM_CH_NUM                 16
191 #define MAD_SRAM_CH_MASK                0
192 
193 #define MAD_SRAM_CH_NUM_MASK    0x1F
194 
195 /*MAD channel change sel*/
196 #define MAD_CH_COM_NUM_MASK             0xF
197 #define MAD_CH_COM_NON                  0x0
198 #define MAD_CH_COM_2CH_TO_4CH           0x1
199 #define MAD_CH_COM_2CH_TO_6CH           0x2
200 #define MAD_CH_COM_2CH_TO_8CH           0x3
201 #define MAD_CH_COM_4CH_TO_6CH           0x4
202 #define MAD_CH_COM_4CH_TO_8CH           0x5
203 
204 /*SUNXI_MAD_LPSD_CH_MASK: 0x40*/
205 #define MAD_LPSD_DCBLOCK_EN             20
206 #define MAD_LPSD_CH_NUM                 16
207 #define MAD_LPSD_CH_MASK                0
208 /*LPSD receive 0/1 audio channel mask*/
209 #define MAD_LPSD_CH_NUM_MASK            0xF
210 /*LPSD AUDIO channel num sel*/
211 #define MAD_LPSD_CH_NUM_NON             0x0
212 #define MAD_LPSD_CH_NUM_1CH             0x1
213 
214 /*SUNXI_MAD_SRAM_SEC_REGION: 0x44*/
215 #define MAD_SRAM_SEC_REGION             0
216 
217 /*SUNXI_MAD_SRAM_PRE_DATA_SIZE(unit: half word): 0x48*/
218 #define MAD_SRAM_PRE_DATA_SIZE          0
219 
220 /*SUNXI_MAD_DMA_TF_SIZE: 0x4C*/
221 #define MAD_DMA_TF_SIZE                 0
222 
223 /*SUNXI_MAD_DMA_TF_LAST_SIZE: 0x50*/
224 #define MAD_DMA_TF_LAST_SIZE            0
225 
226 /*SUNXI_MAD_INT_ST_CLR: 0x60*/
227 #define DATA_REQ_INT                    1
228 #define WAKE_INT                        0
229 
230 /*SUNXI_MAD_INT_MASK: 0x64*/
231 #define DATA_REQ_INT_MASK               1
232 #define MAD_REQ_INT_MASK                0
233 
234 /*SUNXI_MAD_STATE_REG: 0x68*/
235 #define MAD_LPSD_STAT                   8
236 #define MAD_STATE                       4
237 #define MAD_SRAM_FULL                   2
238 #define MAD_SRAM_EMPTY                  1
239 #define MAD_RUN                         0
240 /*MAD STATE(read only)*/
241 #define MAD_STATE_IDLE                  0x0
242 #define MAD_STATE_WAIT                  0x1
243 #define MAD_STATE_RUN                   0x2
244 #define MAD_STATE_NORMAL                0x4
245 
246 /*SUNXI_MAD_DEBUG: 0x6C*/
247 #define MAD_CFG_ERR                     4
248 #define MAD_SRAM_FULL_ERR               3
249 #define MAD_SRAM_EMPTY_ERR              2
250 #define DATA_SRAM_ADDR_ERR              1
251 #define MAD_SRAM_SEC_ERR                0
252 /*MAD_CFG_ERR mask*/
253 #define MAD_CFG_ERR_MASK                0x3
254 
255 /* for mad clk*/
256 #define MAD_SRAM_BMODE_CTRL 24
257 #define SRAM_BMODE_CTRL_REG 0x3000004
258 
259 enum sunxi_mad_standby_debug_flag {
260     SUNXI_MAD_DEBUG_STANDBY_NULL = 0,
261     SUNXI_MAD_DEBUG_STANDBY_SUSPEND = 1,
262     SUNXI_MAD_DEBUG_STANDBY_RESUME = 2,
263 };
264 
265 enum sunxi_mad_irq_work_flag {
266     SUNXI_MAD_NULL_IRQ_WORK = 0,
267     SUNXI_MAD_LPSD_IRQ_WORK = 1,
268     SUNXI_MAD_DATA_IRQ_WORK = 2,
269 };
270 
271 enum sunxi_mad_sram_reset_flag {
272     SUNXI_MAD_SRAM_RESET_IDLE = 0,
273     SUNXI_MAD_SRAM_RESET_START = 1,
274     SUNXI_MAD_SRAM_RESET_END = 2,
275 };
276 
277 enum sunxi_mad_status {
278     SUNXI_MAD_OPEN = 0,
279     SUNXI_MAD_PARAMS = 1,
280     SUNXI_MAD_SUSPEND = 2,
281     SUNXI_MAD_RESUME = 3,
282     SUNXI_MAD_CLOSE = 4,
283 };
284 
285 enum sunxi_mad_dma_type {
286     SUNXI_MAD_DMA_MEM = 0,
287     SUNXI_MAD_DMA_IO = 1,
288 };
289 
290 enum sunxi_mad_standby_flag {
291     /* bit0 for sram IO type when standby */
292     SUNXI_MAD_STANDBY_SRAM_MEM = 0x1,
293 };
294 
295 enum sunxi_mad_wakeup_flag {
296     /* bit0 for wakeup source */
297     SUNXI_MAD_WAKEUP_OFF = 0x0,
298     SUNXI_MAD_WAKEUP_ON = 0x1,
299     /* bit1 for wakeup use or no */
300     SUNXI_MAD_WAKEUP_USE = 0x2,
301 
302     /* bit2 for lpsd wakeup */
303     SUNXI_MAD_WAKEUP_LPSD_IRQ = 0x4,
304     /* bit3 for mad irq wakeup */
305     SUNXI_MAD_WAKEUP_MAD_IRQ = 0x8,
306     /* bit4 for other irq wakeup */
307     SUNXI_MAD_WAKEUP_OTHER = 0x10,
308 };
309 
310 struct sunxi_mad_priv {
311     struct sunxi_mad_info *sunxi_mad;
312     unsigned int mad_bind;
313     unsigned int mad_suspend;
314     /* mad params */
315     unsigned int sample_rate;
316     unsigned int lpsd_chan_sel;
317     unsigned int standby_chan_sel;
318     unsigned int audio_src_chan_num;
319 };
320 
321 struct sunxi_mad_info {
322     hal_clk_id_t mad_clk;
323     hal_clk_id_t mad_cfg_clk;
324     hal_clk_id_t mad_ad_clk;
325     hal_clk_id_t lpsd_clk;
326     hal_clk_id_t pll_clk;
327     hal_clk_id_t hosc_clk;
328 
329     freert_spinlock_t resume_spin;
330 
331     unsigned int pll_audio_src_used;
332     unsigned int hosc_src_used;
333 
334     void *mem_base;
335 
336     unsigned int mad_irq;
337     unsigned int lpsd_irq;
338     QueueHandle_t irq_queue;
339     TaskHandle_t pxMadIrqTask;
340 
341     unsigned int sram_rd_point;
342     unsigned int audio_src_path;
343 
344     unsigned int mad_bind;
345 
346     int status;
347     unsigned int wakeup_flag;
348     unsigned int suspend_flag;
349     unsigned int sram_reset_flag;
350     int standby_sram_type;
351     int wakeup_irq_en;
352     unsigned int ref_count;
353 
354     struct sunxi_mad_priv mad_priv;
355 
356     void *private_data;
357 };
358 
359 int sunxi_mad_sram_set_reset_flag(enum sunxi_mad_sram_reset_flag reset_flag);
360 enum sunxi_mad_sram_reset_flag sunxi_mad_sram_get_reset_flag(void);
361 int sunxi_mad_sram_wait_reset_flag(enum sunxi_mad_sram_reset_flag reset_flag,
362                         unsigned int time_out_msecond);
363 
364 void sunxi_mad_sram_chan_params(unsigned int mad_channels);
365 struct sunxi_mad_info *sunxi_mad_get_mad_info(void);
366 
367 void sunxi_mad_clk_enable(bool val);
368 void sunxi_mad_ad_clk_enable(bool val);
369 void sunxi_mad_cfg_clk_enable(bool val);
370 void sunxi_mad_module_clk_enable(bool val);
371 void sunxi_lpsd_clk_enable(bool val);
372 
373 /* for mad interrupt */
374 void sunxi_lpsd_int_stat_clr(void);
375 void sunxi_mad_set_lpsd_req(bool enable);
376 void sunxi_mad_set_data_req(bool enable);
377 
378 /* for mad init */
379 int sunxi_mad_open(void);
380 int sunxi_mad_close(void);
381 void sunxi_mad_sram_init(void);
382 void sunxi_mad_lpsd_init(void);
383 void sunxi_sram_ahb1_threshole_init(void);
384 void sunxi_mad_standby_chan_sel(unsigned int num);
385 void sunxi_lpsd_chan_sel(unsigned int num);
386 void sunxi_mad_audio_src_chan_num(unsigned int num);
387 void sunxi_sram_dma_config(struct sunxi_dma_params *capture_dma_param);
388 int sunxi_mad_hw_params(unsigned int mad_channels, unsigned int sample_rate);
389 int sunxi_mad_audio_source_sel(unsigned int path_sel, unsigned int enable);
390 int sunxi_mad_suspend_external(void);
391 int sunxi_mad_resume_external(void);
392 void sunxi_mad_dma_enable(bool enable);
393 void sunxi_mad_dma_type(enum sunxi_mad_dma_type dma_type);
394 int sunxi_mad_enable(bool enable);
395 void sunxi_mad_set_go_on_sleep(bool enable);
396 void sunxi_mad_sram_set_reset_bit(void);
397 
398 #ifdef CONFIG_SUNXI_MAD_DEBUG
399 int sunxi_mad_schd_timeout(SemaphoreHandle_t semaphore, long ms);
400 void sunxi_mad_schd_wakeup(SemaphoreHandle_t semaphore);
401 #endif
402 
403 /* for probe mad module */
404 int sunxi_mad_platform_probe(struct snd_platform *platform);
405 int sunxi_mad_platform_remove(struct snd_platform *platform);
406 #endif /* SUNXI_MAD_H */
407