GNU Linux-libre 6.1.91-gnu
[releases.git] / sound / soc / qcom / lpass-sc7280.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
4  *
5  * lpass-sc7180.c -- ALSA SoC platform-machine driver for QTi LPASS
6  */
7
8 #include <linux/module.h>
9 #include <sound/pcm.h>
10 #include <sound/soc.h>
11 #include <linux/pm_runtime.h>
12
13 #include <dt-bindings/sound/sc7180-lpass.h>
14
15 #include "lpass-lpaif-reg.h"
16 #include "lpass.h"
17
18 static struct snd_soc_dai_driver sc7280_lpass_cpu_dai_driver[] = {
19         {
20                 .id = MI2S_PRIMARY,
21                 .name = "Primary MI2S",
22                 .playback = {
23                         .stream_name = "Primary Playback",
24                         .formats        = SNDRV_PCM_FMTBIT_S16,
25                         .rates = SNDRV_PCM_RATE_48000,
26                         .rate_min       = 48000,
27                         .rate_max       = 48000,
28                         .channels_min   = 2,
29                         .channels_max   = 2,
30                 },
31                 .capture = {
32                         .stream_name = "Primary Capture",
33                         .formats = SNDRV_PCM_FMTBIT_S16 |
34                                 SNDRV_PCM_FMTBIT_S32,
35                         .rates = SNDRV_PCM_RATE_48000,
36                         .rate_min       = 48000,
37                         .rate_max       = 48000,
38                         .channels_min   = 2,
39                         .channels_max   = 2,
40                 },
41                 .probe  = &asoc_qcom_lpass_cpu_dai_probe,
42                 .ops    = &asoc_qcom_lpass_cpu_dai_ops,
43         }, {
44                 .id = MI2S_SECONDARY,
45                 .name = "Secondary MI2S",
46                 .playback = {
47                         .stream_name = "Secondary MI2S Playback",
48                         .formats = SNDRV_PCM_FMTBIT_S16,
49                         .rates = SNDRV_PCM_RATE_48000,
50                         .rate_min       = 48000,
51                         .rate_max       = 48000,
52                         .channels_min   = 2,
53                         .channels_max   = 2,
54                 },
55                 .probe  = &asoc_qcom_lpass_cpu_dai_probe,
56                 .ops    = &asoc_qcom_lpass_cpu_dai_ops,
57         }, {
58                 .id = LPASS_DP_RX,
59                 .name = "Hdmi",
60                 .playback = {
61                         .stream_name = "DP Playback",
62                         .formats = SNDRV_PCM_FMTBIT_S24,
63                         .rates = SNDRV_PCM_RATE_48000,
64                         .rate_min       = 48000,
65                         .rate_max       = 48000,
66                         .channels_min   = 2,
67                         .channels_max   = 2,
68                 },
69                 .ops    = &asoc_qcom_lpass_hdmi_dai_ops,
70         }, {
71                 .id = LPASS_CDC_DMA_RX0,
72                 .name = "CDC DMA RX",
73                 .playback = {
74                         .stream_name = "WCD Playback",
75                         .formats = SNDRV_PCM_FMTBIT_S16,
76                         .rates = SNDRV_PCM_RATE_48000,
77                         .rate_min       = 48000,
78                         .rate_max       = 48000,
79                         .channels_min   = 2,
80                         .channels_max   = 2,
81                 },
82                 .ops    = &asoc_qcom_lpass_cdc_dma_dai_ops,
83         }, {
84                 .id = LPASS_CDC_DMA_TX3,
85                 .name = "CDC DMA TX",
86                 .capture = {
87                         .stream_name = "WCD Capture",
88                         .formats = SNDRV_PCM_FMTBIT_S16,
89                         .rates = SNDRV_PCM_RATE_48000,
90                         .rate_min       = 48000,
91                         .rate_max       = 48000,
92                         .channels_min   = 1,
93                         .channels_max   = 1,
94                 },
95                 .ops    = &asoc_qcom_lpass_cdc_dma_dai_ops,
96         }, {
97                 .id = LPASS_CDC_DMA_VA_TX0,
98                 .name = "CDC DMA VA",
99                 .capture = {
100                         .stream_name = "DMIC Capture",
101                         .formats = SNDRV_PCM_FMTBIT_S16,
102                         .rates = SNDRV_PCM_RATE_48000,
103                         .rate_min       = 48000,
104                         .rate_max       = 48000,
105                         .channels_min   = 2,
106                         .channels_max   = 4,
107                 },
108                 .ops    = &asoc_qcom_lpass_cdc_dma_dai_ops,
109         },
110 };
111
112 static int sc7280_lpass_alloc_dma_channel(struct lpass_data *drvdata,
113                                           int direction, unsigned int dai_id)
114 {
115         struct lpass_variant *v = drvdata->variant;
116         int chan = 0;
117
118         switch (dai_id) {
119         case MI2S_PRIMARY ... MI2S_QUINARY:
120                 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
121                         chan = find_first_zero_bit(&drvdata->dma_ch_bit_map,
122                                                    v->rdma_channels);
123
124                         if (chan >= v->rdma_channels)
125                                 return -EBUSY;
126                 } else {
127                         chan = find_next_zero_bit(&drvdata->dma_ch_bit_map,
128                                                   v->wrdma_channel_start +
129                                                   v->wrdma_channels,
130                                                   v->wrdma_channel_start);
131
132                         if (chan >= v->wrdma_channel_start + v->wrdma_channels)
133                                 return -EBUSY;
134                 }
135                 set_bit(chan, &drvdata->dma_ch_bit_map);
136                 break;
137         case LPASS_DP_RX:
138                 chan = find_first_zero_bit(&drvdata->hdmi_dma_ch_bit_map,
139                                            v->hdmi_rdma_channels);
140                 if (chan >= v->hdmi_rdma_channels)
141                         return -EBUSY;
142                 set_bit(chan, &drvdata->hdmi_dma_ch_bit_map);
143                 break;
144         case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9:
145                 chan = find_first_zero_bit(&drvdata->rxtx_dma_ch_bit_map,
146                                            v->rxtx_rdma_channels);
147                 if (chan >= v->rxtx_rdma_channels)
148                         return -EBUSY;
149                 break;
150         case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8:
151                 chan = find_next_zero_bit(&drvdata->rxtx_dma_ch_bit_map,
152                                           v->rxtx_wrdma_channel_start +
153                                           v->rxtx_wrdma_channels,
154                                           v->rxtx_wrdma_channel_start);
155                 if (chan >= v->rxtx_wrdma_channel_start + v->rxtx_wrdma_channels)
156                         return -EBUSY;
157                 set_bit(chan, &drvdata->rxtx_dma_ch_bit_map);
158                 break;
159         case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8:
160                 chan = find_next_zero_bit(&drvdata->va_dma_ch_bit_map,
161                                           v->va_wrdma_channel_start +
162                                           v->va_wrdma_channels,
163                                           v->va_wrdma_channel_start);
164                 if (chan >= v->va_wrdma_channel_start + v->va_wrdma_channels)
165                         return -EBUSY;
166                 set_bit(chan, &drvdata->va_dma_ch_bit_map);
167                 break;
168         default:
169                 break;
170         }
171
172         return chan;
173 }
174
175 static int sc7280_lpass_free_dma_channel(struct lpass_data *drvdata, int chan, unsigned int dai_id)
176 {
177         switch (dai_id) {
178         case MI2S_PRIMARY ... MI2S_QUINARY:
179                 clear_bit(chan, &drvdata->dma_ch_bit_map);
180                 break;
181         case LPASS_DP_RX:
182                 clear_bit(chan, &drvdata->hdmi_dma_ch_bit_map);
183                 break;
184         case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9:
185         case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8:
186                 clear_bit(chan, &drvdata->rxtx_dma_ch_bit_map);
187                 break;
188         case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8:
189                 clear_bit(chan, &drvdata->va_dma_ch_bit_map);
190                 break;
191         default:
192                 break;
193         }
194
195         return 0;
196 }
197
198 static int sc7280_lpass_init(struct platform_device *pdev)
199 {
200         struct lpass_data *drvdata = platform_get_drvdata(pdev);
201         struct lpass_variant *variant = drvdata->variant;
202         struct device *dev = &pdev->dev;
203         int ret, i;
204
205         drvdata->clks = devm_kcalloc(dev, variant->num_clks,
206                                      sizeof(*drvdata->clks), GFP_KERNEL);
207         if (!drvdata->clks)
208                 return -ENOMEM;
209
210         drvdata->num_clks = variant->num_clks;
211
212         for (i = 0; i < drvdata->num_clks; i++)
213                 drvdata->clks[i].id = variant->clk_name[i];
214
215         ret = devm_clk_bulk_get(dev, drvdata->num_clks, drvdata->clks);
216         if (ret) {
217                 dev_err(dev, "Failed to get clocks %d\n", ret);
218                 return ret;
219         }
220
221         ret = clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks);
222         if (ret) {
223                 dev_err(dev, "sc7280 clk_enable failed\n");
224                 return ret;
225         }
226
227         return 0;
228 }
229
230 static int sc7280_lpass_exit(struct platform_device *pdev)
231 {
232         struct lpass_data *drvdata = platform_get_drvdata(pdev);
233
234         clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
235
236         return 0;
237 }
238
239 static struct lpass_variant sc7280_data = {
240         .i2sctrl_reg_base               = 0x1000,
241         .i2sctrl_reg_stride             = 0x1000,
242         .i2s_ports                      = 3,
243         .irq_reg_base                   = 0x9000,
244         .irq_reg_stride                 = 0x1000,
245         .irq_ports                      = 3,
246         .rdma_reg_base                  = 0xC000,
247         .rdma_reg_stride                = 0x1000,
248         .rdma_channels                  = 5,
249         .rxtx_rdma_reg_base             = 0xC000,
250         .rxtx_rdma_reg_stride           = 0x1000,
251         .rxtx_rdma_channels             = 8,
252         .hdmi_rdma_reg_base             = 0x64000,
253         .hdmi_rdma_reg_stride           = 0x1000,
254         .hdmi_rdma_channels             = 4,
255         .dmactl_audif_start             = 1,
256         .wrdma_reg_base                 = 0x18000,
257         .wrdma_reg_stride               = 0x1000,
258         .wrdma_channel_start            = 5,
259         .wrdma_channels                 = 4,
260         .rxtx_irq_reg_base              = 0x9000,
261         .rxtx_irq_reg_stride            = 0x1000,
262         .rxtx_irq_ports                 = 3,
263         .rxtx_wrdma_reg_base            = 0x18000,
264         .rxtx_wrdma_reg_stride          = 0x1000,
265         .rxtx_wrdma_channel_start       = 5,
266         .rxtx_wrdma_channels            = 6,
267         .va_wrdma_reg_base              = 0x18000,
268         .va_wrdma_reg_stride            = 0x1000,
269         .va_wrdma_channel_start         = 5,
270         .va_wrdma_channels              = 3,
271         .va_irq_reg_base                = 0x9000,
272         .va_irq_reg_stride              = 0x1000,
273         .va_irq_ports                   = 3,
274
275         .loopback                       = REG_FIELD_ID(0x1000, 17, 17, 3, 0x1000),
276         .spken                          = REG_FIELD_ID(0x1000, 16, 16, 3, 0x1000),
277         .spkmode                        = REG_FIELD_ID(0x1000, 11, 15, 3, 0x1000),
278         .spkmono                        = REG_FIELD_ID(0x1000, 10, 10, 3, 0x1000),
279         .micen                          = REG_FIELD_ID(0x1000, 9, 9, 3, 0x1000),
280         .micmode                        = REG_FIELD_ID(0x1000, 4, 8, 3, 0x1000),
281         .micmono                        = REG_FIELD_ID(0x1000, 3, 3, 3, 0x1000),
282         .wssrc                          = REG_FIELD_ID(0x1000, 2, 2, 3, 0x1000),
283         .bitwidth                       = REG_FIELD_ID(0x1000, 0, 1, 3, 0x1000),
284
285         .rdma_dyncclk                   = REG_FIELD_ID(0xC000, 21, 21, 5, 0x1000),
286         .rdma_bursten                   = REG_FIELD_ID(0xC000, 20, 20, 5, 0x1000),
287         .rdma_wpscnt                    = REG_FIELD_ID(0xC000, 16, 19, 5, 0x1000),
288         .rdma_intf                      = REG_FIELD_ID(0xC000, 12, 15, 5, 0x1000),
289         .rdma_fifowm                    = REG_FIELD_ID(0xC000, 1, 5, 5, 0x1000),
290         .rdma_enable                    = REG_FIELD_ID(0xC000, 0, 0, 5, 0x1000),
291
292         .wrdma_dyncclk                  = REG_FIELD_ID(0x18000, 22, 22, 4, 0x1000),
293         .wrdma_bursten                  = REG_FIELD_ID(0x18000, 21, 21, 4, 0x1000),
294         .wrdma_wpscnt                   = REG_FIELD_ID(0x18000, 17, 20, 4, 0x1000),
295         .wrdma_intf                     = REG_FIELD_ID(0x18000, 12, 16, 4, 0x1000),
296         .wrdma_fifowm                   = REG_FIELD_ID(0x18000, 1, 5, 4, 0x1000),
297         .wrdma_enable                   = REG_FIELD_ID(0x18000, 0, 0, 4, 0x1000),
298
299         .rxtx_rdma_enable               = REG_FIELD_ID(0xC000, 0, 0, 7, 0x1000),
300         .rxtx_rdma_fifowm               = REG_FIELD_ID(0xC000, 1, 11, 7, 0x1000),
301         .rxtx_rdma_intf                 = REG_FIELD_ID(0xC000, 12, 15, 7, 0x1000),
302         .rxtx_rdma_wpscnt               = REG_FIELD_ID(0xC000, 16, 19, 7, 0x1000),
303         .rxtx_rdma_bursten              = REG_FIELD_ID(0xC000, 20, 20, 7, 0x1000),
304         .rxtx_rdma_dyncclk              = REG_FIELD_ID(0xC000, 21, 21, 7, 0x1000),
305
306         .rxtx_rdma_codec_ch             = REG_FIELD_ID(0xC050, 0, 7, 7, 0x1000),
307         .rxtx_rdma_codec_intf           = REG_FIELD_ID(0xC050, 16, 19, 7, 0x1000),
308         .rxtx_rdma_codec_fs_delay       = REG_FIELD_ID(0xC050, 21, 24, 7, 0x1000),
309         .rxtx_rdma_codec_fs_sel         = REG_FIELD_ID(0xC050, 25, 27, 7, 0x1000),
310         .rxtx_rdma_codec_pack           = REG_FIELD_ID(0xC050, 29, 29, 5, 0x1000),
311         .rxtx_rdma_codec_enable         = REG_FIELD_ID(0xC050, 30, 30, 7, 0x1000),
312
313         .rxtx_wrdma_enable              = REG_FIELD_ID(0x18000, 0, 0, 5, 0x1000),
314         .rxtx_wrdma_fifowm              = REG_FIELD_ID(0x18000, 1, 11, 5, 0x1000),
315         .rxtx_wrdma_intf                = REG_FIELD_ID(0x18000, 12, 16, 5, 0x1000),
316         .rxtx_wrdma_wpscnt              = REG_FIELD_ID(0x18000, 17, 20, 5, 0x1000),
317         .rxtx_wrdma_bursten             = REG_FIELD_ID(0x18000, 21, 21, 5, 0x1000),
318         .rxtx_wrdma_dyncclk             = REG_FIELD_ID(0x18000, 22, 22, 5, 0x1000),
319
320         .rxtx_wrdma_codec_ch            = REG_FIELD_ID(0x18050, 0, 7, 5, 0x1000),
321         .rxtx_wrdma_codec_intf          = REG_FIELD_ID(0x18050, 16, 19, 5, 0x1000),
322         .rxtx_wrdma_codec_fs_delay      = REG_FIELD_ID(0x18050, 21, 24, 5, 0x1000),
323         .rxtx_wrdma_codec_fs_sel        = REG_FIELD_ID(0x18050, 25, 27, 5, 0x1000),
324         .rxtx_wrdma_codec_pack          = REG_FIELD_ID(0x18050, 29, 29, 5, 0x1000),
325         .rxtx_wrdma_codec_enable        = REG_FIELD_ID(0x18050, 30, 30, 5, 0x1000),
326
327         .va_wrdma_enable                = REG_FIELD_ID(0x18000, 0, 0, 5, 0x1000),
328         .va_wrdma_fifowm                = REG_FIELD_ID(0x18000, 1, 11, 5, 0x1000),
329         .va_wrdma_intf                  = REG_FIELD_ID(0x18000, 12, 16, 5, 0x1000),
330         .va_wrdma_wpscnt                = REG_FIELD_ID(0x18000, 17, 20, 5, 0x1000),
331         .va_wrdma_bursten               = REG_FIELD_ID(0x18000, 21, 21, 5, 0x1000),
332         .va_wrdma_dyncclk               = REG_FIELD_ID(0x18000, 22, 22, 5, 0x1000),
333
334         .va_wrdma_codec_ch              = REG_FIELD_ID(0x18050, 0, 7, 5, 0x1000),
335         .va_wrdma_codec_intf            = REG_FIELD_ID(0x18050, 16, 19, 5, 0x1000),
336         .va_wrdma_codec_fs_delay        = REG_FIELD_ID(0x18050, 21, 24, 5, 0x1000),
337         .va_wrdma_codec_fs_sel          = REG_FIELD_ID(0x18050, 25, 27, 5, 0x1000),
338         .va_wrdma_codec_pack            = REG_FIELD_ID(0x18050, 29, 29, 5, 0x1000),
339         .va_wrdma_codec_enable          = REG_FIELD_ID(0x18050, 30, 30, 5, 0x1000),
340
341         .hdmi_tx_ctl_addr               = 0x1000,
342         .hdmi_legacy_addr               = 0x1008,
343         .hdmi_vbit_addr                 = 0x610c0,
344         .hdmi_ch_lsb_addr               = 0x61048,
345         .hdmi_ch_msb_addr               = 0x6104c,
346         .ch_stride                      = 0x8,
347         .hdmi_parity_addr               = 0x61034,
348         .hdmi_dmactl_addr               = 0x61038,
349         .hdmi_dma_stride                = 0x4,
350         .hdmi_DP_addr                   = 0x610c8,
351         .hdmi_sstream_addr              = 0x6101c,
352         .hdmi_irq_reg_base              = 0x63000,
353         .hdmi_irq_ports                 = 1,
354
355         .hdmi_rdma_dyncclk              = REG_FIELD_ID(0x64000, 14, 14, 4, 0x1000),
356         .hdmi_rdma_bursten              = REG_FIELD_ID(0x64000, 13, 13, 4, 0x1000),
357         .hdmi_rdma_burst8               = REG_FIELD_ID(0x64000, 15, 15, 4, 0x1000),
358         .hdmi_rdma_burst16              = REG_FIELD_ID(0x64000, 16, 16, 4, 0x1000),
359         .hdmi_rdma_dynburst             = REG_FIELD_ID(0x64000, 18, 18, 4, 0x1000),
360         .hdmi_rdma_wpscnt               = REG_FIELD_ID(0x64000, 10, 12, 4, 0x1000),
361         .hdmi_rdma_fifowm               = REG_FIELD_ID(0x64000, 1, 5, 4, 0x1000),
362         .hdmi_rdma_enable               = REG_FIELD_ID(0x64000, 0, 0, 4, 0x1000),
363
364         .sstream_en                     = REG_FIELD(0x6101c, 0, 0),
365         .dma_sel                        = REG_FIELD(0x6101c, 1, 2),
366         .auto_bbit_en                   = REG_FIELD(0x6101c, 3, 3),
367         .layout                         = REG_FIELD(0x6101c, 4, 4),
368         .layout_sp                      = REG_FIELD(0x6101c, 5, 8),
369         .set_sp_on_en                   = REG_FIELD(0x6101c, 10, 10),
370         .dp_audio                       = REG_FIELD(0x6101c, 11, 11),
371         .dp_staffing_en                 = REG_FIELD(0x6101c, 12, 12),
372         .dp_sp_b_hw_en                  = REG_FIELD(0x6101c, 13, 13),
373
374         .mute                           = REG_FIELD(0x610c8, 0, 0),
375         .as_sdp_cc                      = REG_FIELD(0x610c8, 1, 3),
376         .as_sdp_ct                      = REG_FIELD(0x610c8, 4, 7),
377         .aif_db4                        = REG_FIELD(0x610c8, 8, 15),
378         .frequency                      = REG_FIELD(0x610c8, 16, 21),
379         .mst_index                      = REG_FIELD(0x610c8, 28, 29),
380         .dptx_index                     = REG_FIELD(0x610c8, 30, 31),
381
382         .soft_reset                     = REG_FIELD(0x1000, 31, 31),
383         .force_reset                    = REG_FIELD(0x1000, 30, 30),
384
385         .use_hw_chs                     = REG_FIELD(0x61038, 0, 0),
386         .use_hw_usr                     = REG_FIELD(0x61038, 1, 1),
387         .hw_chs_sel                     = REG_FIELD(0x61038, 2, 4),
388         .hw_usr_sel                     = REG_FIELD(0x61038, 5, 6),
389
390         .replace_vbit                   = REG_FIELD(0x610c0, 0, 0),
391         .vbit_stream                    = REG_FIELD(0x610c0, 1, 1),
392
393         .legacy_en                      =  REG_FIELD(0x1008, 0, 0),
394         .calc_en                        =  REG_FIELD(0x61034, 0, 0),
395         .lsb_bits                       =  REG_FIELD(0x61048, 0, 31),
396         .msb_bits                       =  REG_FIELD(0x6104c, 0, 31),
397
398         .clk_name                       = (const char*[]) {
399                                                         "core_cc_sysnoc_mport_core"
400                                                 },
401         .num_clks                       = 1,
402
403         .dai_driver                     = sc7280_lpass_cpu_dai_driver,
404         .num_dai                        = ARRAY_SIZE(sc7280_lpass_cpu_dai_driver),
405         .dai_osr_clk_names              = (const char *[]) {
406                                                         "audio_cc_ext_mclk0",
407                                                         "null"
408                                                         },
409         .dai_bit_clk_names              = (const char *[]) {
410                                                         "core_cc_ext_if0_ibit",
411                                                         "core_cc_ext_if1_ibit"
412                                                         },
413         .init                           = sc7280_lpass_init,
414         .exit                           = sc7280_lpass_exit,
415         .alloc_dma_channel              = sc7280_lpass_alloc_dma_channel,
416         .free_dma_channel               = sc7280_lpass_free_dma_channel,
417 };
418
419 static const struct of_device_id sc7280_lpass_cpu_device_id[] = {
420         {.compatible = "qcom,sc7280-lpass-cpu", .data = &sc7280_data},
421         {}
422 };
423 MODULE_DEVICE_TABLE(of, sc7280_lpass_cpu_device_id);
424
425 static struct platform_driver sc7280_lpass_cpu_platform_driver = {
426         .driver = {
427                 .name = "sc7280-lpass-cpu",
428                 .of_match_table = of_match_ptr(sc7280_lpass_cpu_device_id),
429         },
430         .probe = asoc_qcom_lpass_cpu_platform_probe,
431         .remove = asoc_qcom_lpass_cpu_platform_remove,
432         .shutdown = asoc_qcom_lpass_cpu_platform_shutdown,
433 };
434
435 module_platform_driver(sc7280_lpass_cpu_platform_driver);
436
437 MODULE_DESCRIPTION("SC7280 LPASS CPU DRIVER");
438 MODULE_LICENSE("GPL");