1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3 * Copyright(c) 2023 MediaTek. All rights reserved.
4 *
5 * Author: Bo Pan <bo.pan@mediatek.com>
6 * YC Hung <yc.hung@mediatek.com>
7 * Chunxu Li <chunxu.li@mediatek.com>
8 * Trevor Wu <trevor.wu@mediatek.com>
9 */
10
11 #include <sof/common.h>
12 #include <sof/lib/io.h>
13 #include <rtos/alloc.h>
14 #include <ipc/stream.h>
15 #include <ipc/topology.h>
16 #include <sof/lib/uuid.h>
17 #include <errno.h>
18 #include <sof/drivers/afe-drv.h>
19 #include <sof/drivers/afe-memif.h>
20
21 /*#define AFE_DRV_LOG*/
22 static struct mtk_base_afe mtk_afe;
23
24 #ifndef AFE_DRV_LOG
25 #undef printf
26 #define printf(format, ...)
27 #endif
28
29 DECLARE_SOF_UUID("afedrv", afedrv_uuid, 0x4e8f16d1, 0xe935, 0x41f4,
30 0xb9, 0x9e, 0x42, 0xc5, 0x7e, 0x74, 0x57, 0x84);
31
32 DECLARE_TR_CTX(afedrv_tr, SOF_UUID(afedrv_uuid), LOG_LEVEL_INFO);
33
afe_reg_read(struct mtk_base_afe * afe,uint32_t reg,uint32_t * value)34 static inline void afe_reg_read(struct mtk_base_afe *afe, uint32_t reg, uint32_t *value)
35 {
36 *value = io_reg_read((uint32_t)((char *)afe->base + reg));
37 tr_dbg(&afedrv_tr, "r_reg:0x%x, value:0x%x\n", reg, *value);
38 }
39
afe_reg_write(struct mtk_base_afe * afe,uint32_t reg,uint32_t value)40 static inline void afe_reg_write(struct mtk_base_afe *afe, uint32_t reg, uint32_t value)
41 {
42 io_reg_write((uint32_t)((char *)afe->base + reg), value);
43 tr_dbg(&afedrv_tr, "w_reg:0x%x, value:0x%x\n", reg, value);
44 }
45
afe_reg_update_bits(struct mtk_base_afe * afe,uint32_t reg,uint32_t mask,uint32_t value)46 static inline void afe_reg_update_bits(struct mtk_base_afe *afe, uint32_t reg, uint32_t mask,
47 uint32_t value)
48 {
49 io_reg_update_bits((uint32_t)((char *)afe->base + reg), mask, value);
50 tr_dbg(&afedrv_tr, "u_reg:0x%x, value:0x%x\n", reg, value);
51 }
52
afe_memif_set_channel(struct mtk_base_afe * afe,int id,unsigned int channel)53 static int afe_memif_set_channel(struct mtk_base_afe *afe, int id, unsigned int channel)
54 {
55 struct mtk_base_afe_memif *memif = &afe->memif[id];
56 unsigned int mono;
57
58 if (memif->data->ch_num_reg >= 0) {
59 afe_reg_update_bits(afe, memif->data->ch_num_reg,
60 memif->data->ch_num_maskbit << memif->data->ch_num_shift,
61 channel << memif->data->ch_num_shift);
62 }
63
64 if (memif->data->quad_ch_mask) {
65 unsigned int quad_ch = (channel == 4);
66
67 afe_reg_update_bits(afe, memif->data->quad_ch_reg,
68 memif->data->quad_ch_mask << memif->data->quad_ch_shift,
69 quad_ch << memif->data->quad_ch_shift);
70 }
71
72 mono = (bool)memif->data->mono_invert ^ (channel == 1);
73
74 if (memif->data->int_odd_flag_reg > 0)
75 afe_reg_update_bits(afe, memif->data->int_odd_flag_reg,
76 1 << memif->data->int_odd_flag_shift,
77 mono << memif->data->int_odd_flag_shift);
78
79 if (memif->data->mono_reg > 0 && memif->data->mono_shift >= 0)
80 afe_reg_update_bits(afe, memif->data->mono_reg,
81 1 << memif->data->mono_shift,
82 mono << memif->data->mono_shift);
83 return 0;
84 }
85
afe_memif_set_rate(struct mtk_base_afe * afe,int id,unsigned int rate)86 static int afe_memif_set_rate(struct mtk_base_afe *afe, int id, unsigned int rate)
87 {
88 struct mtk_base_afe_memif *memif = &afe->memif[id];
89 int fs;
90
91 fs = afe->afe_fs(rate, memif->data->id);
92 if (fs < 0) {
93 tr_err(&afedrv_tr, "invalid fs:%d\n", fs);
94 return -EINVAL;
95 }
96
97 afe_reg_update_bits(afe, memif->data->fs_reg,
98 memif->data->fs_maskbit << memif->data->fs_shift,
99 fs << memif->data->fs_shift);
100
101 return 0;
102 }
103
afe_memif_set_format(struct mtk_base_afe * afe,int id,unsigned int format)104 static int afe_memif_set_format(struct mtk_base_afe *afe, int id, unsigned int format)
105 {
106 struct mtk_base_afe_memif *memif = &afe->memif[id];
107 int hd_audio;
108 int memif_32bit_supported = afe->memif_32bit_supported;
109
110 /* set hd mode */
111 switch (format) {
112 case SOF_IPC_FRAME_S16_LE:
113 hd_audio = 0;
114 break;
115 case SOF_IPC_FRAME_S32_LE:
116 case SOF_IPC_FRAME_S24_4LE:
117 if (memif_32bit_supported)
118 hd_audio = 2;
119 else
120 hd_audio = 1;
121 break;
122 default:
123 tr_err(&afedrv_tr, "not support format:%u\n", format);
124 return -EINVAL;
125 }
126
127 afe_reg_update_bits(afe, memif->data->hd_reg, 0x3 << memif->data->hd_shift,
128 hd_audio << memif->data->hd_shift);
129 return 0;
130 }
131
afe_memif_set_params(struct mtk_base_afe * afe,int id,unsigned int channel,unsigned int rate,unsigned int format)132 int afe_memif_set_params(struct mtk_base_afe *afe, int id, unsigned int channel, unsigned int rate,
133 unsigned int format)
134 {
135 int ret;
136
137 ret = afe_memif_set_channel(afe, id, channel);
138 if (ret < 0)
139 return ret;
140 ret = afe_memif_set_rate(afe, id, rate);
141 if (ret < 0)
142 return ret;
143 ret = afe_memif_set_format(afe, id, format);
144 if (ret < 0)
145 return ret;
146 /* TODO IRQ direction, irq format setting ? */
147
148 return ret;
149 }
150
afe_memif_set_addr(struct mtk_base_afe * afe,int id,unsigned int dma_addr,unsigned int dma_bytes)151 int afe_memif_set_addr(struct mtk_base_afe *afe, int id, unsigned int dma_addr,
152 unsigned int dma_bytes)
153 {
154 struct mtk_base_afe_memif *memif = &afe->memif[id];
155 int msb_at_bit33 = 0; /* for dsp side only support 32bit address */
156 unsigned int phys_buf_addr;
157 unsigned int phys_buf_addr_upper_32 = 0; /* for dsp side only support 32bit address */
158
159 memif->dma_addr = dma_addr;
160
161 /* convert adsp address to afe address */
162 if (afe->adsp2afe_addr)
163 dma_addr = afe->adsp2afe_addr(dma_addr);
164
165 phys_buf_addr = dma_addr;
166
167 memif->afe_addr = phys_buf_addr;
168 memif->buffer_size = dma_bytes;
169 tr_dbg(&afedrv_tr, "dma_addr:0x%x, size:%u\n", dma_addr, dma_bytes);
170 /* start */
171 afe_reg_write(afe, memif->data->reg_ofs_base, phys_buf_addr);
172 /* end */
173 if (memif->data->reg_ofs_end)
174 afe_reg_write(afe, memif->data->reg_ofs_end, phys_buf_addr + dma_bytes - 1);
175 else
176 afe_reg_write(afe, memif->data->reg_ofs_base + afe->base_end_offset,
177 phys_buf_addr + dma_bytes - 1);
178
179 /* set start, end, upper 32 bits */
180 if (memif->data->reg_ofs_base_msb) {
181 afe_reg_write(afe, memif->data->reg_ofs_base_msb, phys_buf_addr_upper_32);
182 afe_reg_write(afe, memif->data->reg_ofs_end_msb, phys_buf_addr_upper_32);
183 }
184
185 /* set MSB to 33-bit */
186 if (memif->data->msb_reg > 0)
187 afe_reg_update_bits(afe, memif->data->msb_reg, 1 << memif->data->msb_shift,
188 msb_at_bit33 << memif->data->msb_shift);
189
190 /* set MSB to 33-bit, for memif end address */
191 if (memif->data->msb2_reg > 0)
192 afe_reg_update_bits(afe, memif->data->msb2_reg, 1 << memif->data->msb2_shift,
193 msb_at_bit33 << memif->data->msb2_shift);
194
195 return 0;
196 }
197
afe_memif_set_enable(struct mtk_base_afe * afe,int id,int enable)198 int afe_memif_set_enable(struct mtk_base_afe *afe, int id, int enable)
199 {
200 const struct mtk_base_memif_data *memif_data = afe->memif[id].data;
201
202 if (memif_data->enable_shift < 0)
203 return 0;
204
205 /* enable agent */
206 /* TODO: enable/disable should in different sequence? */
207 if (memif_data->agent_disable_reg > 0) {
208 afe_reg_update_bits(afe, memif_data->agent_disable_reg,
209 1 << memif_data->agent_disable_shift,
210 (!enable) << memif_data->agent_disable_shift);
211 }
212
213 afe_reg_update_bits(afe, memif_data->enable_reg, 1 << memif_data->enable_shift,
214 enable << memif_data->enable_shift);
215
216 return 0;
217 }
218
afe_memif_get_direction(struct mtk_base_afe * afe,int id)219 int afe_memif_get_direction(struct mtk_base_afe *afe, int id)
220 {
221 const struct mtk_base_memif_data *memif_data = afe->memif[id].data;
222
223 if (memif_data->id >= 0 && memif_data->id < afe->memif_dl_num)
224 return MEM_DIR_PLAYBACK;
225 return MEM_DIR_CAPTURE;
226 }
227
afe_memif_get_cur_position(struct mtk_base_afe * afe,int id)228 unsigned int afe_memif_get_cur_position(struct mtk_base_afe *afe, int id)
229 {
230 const struct mtk_base_memif_data *memif_data = afe->memif[id].data;
231 unsigned int hw_ptr;
232
233 if (memif_data->reg_ofs_cur < 0)
234 return 0;
235 afe_reg_read(afe, memif_data->reg_ofs_cur, &hw_ptr);
236
237 /* convert afe address to adsp address */
238 if (afe->afe2adsp_addr)
239 hw_ptr = afe->afe2adsp_addr(hw_ptr);
240 return hw_ptr;
241 }
242
afe_dai_set_config(struct mtk_base_afe * afe,int id,unsigned int channel,unsigned int rate,unsigned int format)243 int afe_dai_set_config(struct mtk_base_afe *afe, int id, unsigned int channel, unsigned int rate,
244 unsigned int format)
245 {
246 struct mtk_base_afe_dai *dai;
247
248 /* TODO 1. if need use dai->id to search target dai */
249 /* TODO 1. if need a status to control the dai status */
250
251 if (id >= afe->dais_size)
252 return -EINVAL;
253
254 tr_info(&afedrv_tr, "afe_dai_set_config, id:%d\n", id);
255
256 dai = &afe->dais[id];
257 dai->channel = channel;
258 dai->format = format;
259 dai->rate = rate;
260
261 tr_info(&afedrv_tr, "dai:%d set: format:%d, rate:%d, channel:%d\n", id, format, rate,
262 channel);
263
264 return 0;
265 }
266
afe_dai_get_config(struct mtk_base_afe * afe,int id,unsigned int * channel,unsigned int * rate,unsigned int * format)267 int afe_dai_get_config(struct mtk_base_afe *afe, int id, unsigned int *channel, unsigned int *rate,
268 unsigned int *format)
269 {
270 struct mtk_base_afe_dai *dai;
271
272 /* TODO 1. if need use dai->id to search target dai */
273 /* TODO 1. if need a status to control the dai status */
274 tr_info(&afedrv_tr, "afe_dai_get_config, id:%d\n", id);
275
276 if (id >= afe->dais_size || id < 0) {
277 tr_err(&afedrv_tr, "afe_dai_get_config , invalid id:%d\n", id);
278 return -EINVAL;
279 }
280 dai = &afe->dais[id];
281
282 *channel = dai->channel;
283 *rate = dai->rate;
284 *format = dai->format;
285
286 tr_info(&afedrv_tr, "dai:%d get: format:%d, rate:%d, channel:%d\n", id, *format, *rate,
287 *channel);
288
289 return 0;
290 }
291
292 /* TODO, IRQ common register name need use config? */
afe_irq_get_status(struct mtk_base_afe * afe,int id)293 int afe_irq_get_status(struct mtk_base_afe *afe, int id)
294 {
295 return 0;
296 }
297
afe_irq_clear(struct mtk_base_afe * afe,int id)298 int afe_irq_clear(struct mtk_base_afe *afe, int id)
299 {
300 return 0;
301 }
302
afe_irq_config(struct mtk_base_afe * afe,int id,unsigned int rate,unsigned int period)303 int afe_irq_config(struct mtk_base_afe *afe, int id, unsigned int rate, unsigned int period)
304 {
305 struct mtk_base_afe_irq *irq = &afe->irqs[id];
306 int fs;
307
308 afe_reg_update_bits(afe, irq->irq_data->irq_cnt_reg,
309 irq->irq_data->irq_cnt_maskbit << irq->irq_data->irq_cnt_shift,
310 period << irq->irq_data->irq_cnt_shift);
311
312 /* set irq fs */
313 fs = afe->irq_fs(rate);
314 if (fs < 0)
315 return -EINVAL;
316
317 afe_reg_update_bits(afe, irq->irq_data->irq_fs_reg,
318 irq->irq_data->irq_fs_maskbit << irq->irq_data->irq_fs_shift,
319 fs << irq->irq_data->irq_fs_shift);
320 return 0;
321 }
322
323 /* TODO, for dma based scheduler*/
afe_irq_enable(struct mtk_base_afe * afe,int id)324 int afe_irq_enable(struct mtk_base_afe *afe, int id)
325 {
326 return 0;
327 }
328
afe_irq_disable(struct mtk_base_afe * afe,int id)329 int afe_irq_disable(struct mtk_base_afe *afe, int id)
330 {
331 return 0;
332 }
333
afe_get(void)334 struct mtk_base_afe *afe_get(void)
335 {
336 return &mtk_afe;
337 }
338
afe_probe(struct mtk_base_afe * afe)339 int afe_probe(struct mtk_base_afe *afe)
340 {
341 int i;
342 struct mtk_base_afe_platform *platform = &mtk_afe_platform;
343
344 /* mtk afe already init done */
345 if (afe->ref_count > 0) {
346 afe->ref_count++;
347 return 0;
348 }
349
350 afe->platform_priv = platform;
351 afe->base = platform->base_addr;
352 afe->memif_32bit_supported = platform->memif_32bit_supported;
353 afe->memif_dl_num = platform->memif_dl_num;
354
355 afe->base_end_offset = platform->base_end_offset;
356 afe->adsp2afe_addr = platform->adsp2afe_addr;
357 afe->afe2adsp_addr = platform->afe2adsp_addr;
358 afe->afe_fs = platform->afe_fs; /* must be */
359 afe->irq_fs = platform->irq_fs;
360 if (!afe->afe_fs)
361 return -EINVAL;
362 tr_dbg(&afedrv_tr, "afe_base:0x%x\n", afe->base);
363 /* TODO how to get the memif number, how to sync with dmac lib */
364 afe->memifs_size = platform->memif_size;
365 afe->memif = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM,
366 sizeof(struct mtk_base_afe_memif) * afe->memifs_size);
367 if (!afe->memif)
368 return -ENOMEM;
369
370 for (i = 0; i < afe->memifs_size; i++)
371 afe->memif[i].data = &platform->memif_datas[i];
372
373 /* TODO how to get the dai number, how to sync with dai lib*/
374 afe->dais_size = platform->dais_size;
375 afe->dais = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM,
376 sizeof(struct mtk_base_afe_dai) * afe->dais_size);
377 if (!afe->dais)
378 goto err_alloc_memif;
379
380 /* TODO how to get the irq number */
381 afe->irqs_size = platform->irqs_size;
382 afe->irqs = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM,
383 sizeof(struct mtk_base_afe_irq) * afe->irqs_size);
384 if (!afe->irqs)
385 goto err_alloc_dais;
386
387 for (i = 0; i < afe->irqs_size; i++)
388 afe->irqs[i].irq_data = &platform->irq_datas[i];
389
390 afe->ref_count++;
391
392 return 0;
393 err_alloc_dais:
394 rfree(afe->dais);
395 err_alloc_memif:
396 rfree(afe->memif);
397
398 return -ENOMEM;
399 }
400
afe_remove(struct mtk_base_afe * afe)401 void afe_remove(struct mtk_base_afe *afe)
402 {
403 afe->ref_count--;
404
405 if (afe->ref_count > 0)
406 return;
407
408 if (afe->ref_count < 0) {
409 afe->ref_count = 0;
410 tr_dbg(&afedrv_tr, "afe ref_count < 0, :%d\n", afe->ref_count);
411 return;
412 }
413
414 rfree(afe->memif);
415 afe->memif = NULL;
416
417 rfree(afe->dais);
418 afe->dais = NULL;
419
420 rfree(afe->irqs);
421 afe->irqs = NULL;
422 }
423
424