ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 801-audio-0018-MLK-13574-2-ASoC-fsl_sai-refine-driver-for-ip-upgrad.patch
1 From c516c261c49d0ce9509d6b9623dec6a4e9f919c3 Mon Sep 17 00:00:00 2001
2 From: Shengjiu Wang <shengjiu.wang@freescale.com>
3 Date: Mon, 30 Mar 2020 16:21:00 +0800
4 Subject: [PATCH] MLK-13574-2: ASoC: fsl_sai: refine driver for ip upgrade
5
6 In imx7ulp1, the sai can support two TX channel and two RX
7 channels, So the usage need to be updated.
8
9 Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
10 [rebase]
11 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
12 ---
13  sound/soc/fsl/fsl_sai.c | 145 ++++++++++++++++++++++++++++++++++++++++--------
14  sound/soc/fsl/fsl_sai.h |  37 ++++++++++--
15  2 files changed, 156 insertions(+), 26 deletions(-)
16
17 --- a/sound/soc/fsl/fsl_sai.c
18 +++ b/sound/soc/fsl/fsl_sai.c
19 @@ -8,16 +8,19 @@
20  #include <linux/delay.h>
21  #include <linux/dmaengine.h>
22  #include <linux/module.h>
23 +#include <linux/of_device.h>
24  #include <linux/of_address.h>
25  #include <linux/pm_runtime.h>
26  #include <linux/regmap.h>
27  #include <linux/slab.h>
28  #include <linux/time.h>
29 +#include <linux/pm_qos.h>
30  #include <sound/core.h>
31  #include <sound/dmaengine_pcm.h>
32  #include <sound/pcm_params.h>
33  #include <linux/mfd/syscon.h>
34  #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
35 +#include <linux/pm_runtime.h>
36  
37  #include "fsl_sai.h"
38  #include "imx-pcm.h"
39 @@ -25,6 +28,39 @@
40  #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
41                        FSL_SAI_CSR_FEIE)
42  
43 +static struct fsl_sai_soc_data fsl_sai_vf610 = {
44 +       .imx = false,
45 +       /*dataline is mask, not index*/
46 +       .dataline = 0x1,
47 +       .fifos = 1,
48 +       .fifo_depth = 32,
49 +       .flags = 0,
50 +};
51 +
52 +static struct fsl_sai_soc_data fsl_sai_imx6sx = {
53 +       .imx = true,
54 +       .dataline = 0x1,
55 +       .fifos = 1,
56 +       .fifo_depth = 32,
57 +       .flags = 0,
58 +};
59 +
60 +static struct fsl_sai_soc_data fsl_sai_imx6ul = {
61 +       .imx = true,
62 +       .dataline = 0x1,
63 +       .fifos = 1,
64 +       .fifo_depth = 32,
65 +       .flags = 0,
66 +};
67 +
68 +static struct fsl_sai_soc_data fsl_sai_imx7ulp = {
69 +       .imx = true,
70 +       .dataline = 0x3,
71 +       .fifos = 2,
72 +       .fifo_depth = 16,
73 +       .flags = SAI_FLAG_PMQOS,
74 +};
75 +
76  static const unsigned int fsl_sai_rates[] = {
77         8000, 11025, 12000, 16000, 22050,
78         24000, 32000, 44100, 48000, 64000,
79 @@ -505,6 +541,29 @@ static int fsl_sai_hw_params(struct snd_
80                 }
81         }
82  
83 +       if (sai->soc->dataline != 0x1) {
84 +               switch (sai->dataline[tx]) {
85 +               case 0x0:
86 +                       break;
87 +               case 0x1:
88 +                       regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
89 +                               FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT, 0);
90 +                       break;
91 +               case 0x2:
92 +                       regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
93 +                               FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT,
94 +                               FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT);
95 +                       break;
96 +               case 0x3:
97 +                       regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
98 +                               FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT,
99 +                               FSL_SAI_CR4_FCOMB_SOFT);
100 +                       break;
101 +               default:
102 +                       break;
103 +               }
104 +       }
105 +
106         regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
107                            FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
108                            val_cr4);
109 @@ -563,14 +622,16 @@ static int fsl_sai_trigger(struct snd_pc
110                                    FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
111  
112                 for (i = 0; tx && i < channels; i++)
113 -                       regmap_write(sai->regmap, FSL_SAI_TDR, 0x0);
114 +                       regmap_write(sai->regmap, FSL_SAI_TDR0, 0x0);
115                 if (tx)
116                         udelay(10);
117  
118 -               regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
119 -                                  FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
120                 regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
121                                    FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
122 +               regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
123 +                                  FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
124 +               regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
125 +                                  FSL_SAI_CSR_SE, FSL_SAI_CSR_SE);
126  
127                 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
128                                    FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
129 @@ -641,8 +702,8 @@ static int fsl_sai_startup(struct snd_pc
130         else
131                 sai->is_stream_opened[tx] = true;
132  
133 -       regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE,
134 -                          FSL_SAI_CR3_TRCE);
135 +       regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE0|FSL_SAI_CR3_TRCE1,
136 +                          FSL_SAI_CR3_TRCE(sai->dataline[tx]));
137  
138         ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
139                         SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints);
140 @@ -659,7 +720,7 @@ static void fsl_sai_shutdown(struct snd_
141         regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
142  
143         if (sai->is_stream_opened[tx]) {
144 -               regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
145 +               regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE0 | FSL_SAI_CR3_TRCE1, 0);
146                 sai->is_stream_opened[tx] = false;
147         }
148  }
149 @@ -687,7 +748,7 @@ static int fsl_sai_dai_probe(struct snd_
150         regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
151  
152         regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
153 -                          FSL_SAI_MAXBURST_TX * 2);
154 +                          sai->soc->fifo_depth - FSL_SAI_MAXBURST_TX);
155         regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
156                            FSL_SAI_MAXBURST_RX - 1);
157  
158 @@ -732,7 +793,8 @@ static struct reg_default fsl_sai_reg_de
159         {FSL_SAI_TCR3, 0},
160         {FSL_SAI_TCR4, 0},
161         {FSL_SAI_TCR5, 0},
162 -       {FSL_SAI_TDR,  0},
163 +       {FSL_SAI_TDR0, 0},
164 +       {FSL_SAI_TDR1, 0},
165         {FSL_SAI_TMR,  0},
166         {FSL_SAI_RCR1, 0},
167         {FSL_SAI_RCR2, 0},
168 @@ -751,7 +813,8 @@ static bool fsl_sai_readable_reg(struct
169         case FSL_SAI_TCR3:
170         case FSL_SAI_TCR4:
171         case FSL_SAI_TCR5:
172 -       case FSL_SAI_TFR:
173 +       case FSL_SAI_TFR0:
174 +       case FSL_SAI_TFR1:
175         case FSL_SAI_TMR:
176         case FSL_SAI_RCSR:
177         case FSL_SAI_RCR1:
178 @@ -759,8 +822,10 @@ static bool fsl_sai_readable_reg(struct
179         case FSL_SAI_RCR3:
180         case FSL_SAI_RCR4:
181         case FSL_SAI_RCR5:
182 -       case FSL_SAI_RDR:
183 -       case FSL_SAI_RFR:
184 +       case FSL_SAI_RDR0:
185 +       case FSL_SAI_RDR1:
186 +       case FSL_SAI_RFR0:
187 +       case FSL_SAI_RFR1:
188         case FSL_SAI_RMR:
189                 return true;
190         default:
191 @@ -773,9 +838,12 @@ static bool fsl_sai_volatile_reg(struct
192         switch (reg) {
193         case FSL_SAI_TCSR:
194         case FSL_SAI_RCSR:
195 -       case FSL_SAI_TFR:
196 -       case FSL_SAI_RFR:
197 -       case FSL_SAI_RDR:
198 +       case FSL_SAI_TFR0:
199 +       case FSL_SAI_TFR1:
200 +       case FSL_SAI_RFR0:
201 +       case FSL_SAI_RFR1:
202 +       case FSL_SAI_RDR0:
203 +       case FSL_SAI_RDR1:
204                 return true;
205         default:
206                 return false;
207 @@ -791,7 +859,8 @@ static bool fsl_sai_writeable_reg(struct
208         case FSL_SAI_TCR3:
209         case FSL_SAI_TCR4:
210         case FSL_SAI_TCR5:
211 -       case FSL_SAI_TDR:
212 +       case FSL_SAI_TDR0:
213 +       case FSL_SAI_TDR1:
214         case FSL_SAI_TMR:
215         case FSL_SAI_RCSR:
216         case FSL_SAI_RCR1:
217 @@ -820,9 +889,19 @@ static const struct regmap_config fsl_sa
218         .cache_type = REGCACHE_FLAT,
219  };
220  
221 +static const struct of_device_id fsl_sai_ids[] = {
222 +       { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610 },
223 +       { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx },
224 +       { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6ul },
225 +       { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp },
226 +       { /* sentinel */ }
227 +};
228 +MODULE_DEVICE_TABLE(of, fsl_sai_ids);
229 +
230  static int fsl_sai_probe(struct platform_device *pdev)
231  {
232         struct device_node *np = pdev->dev.of_node;
233 +       const struct of_device_id *of_id;
234         struct fsl_sai *sai;
235         struct regmap *gpr;
236         struct resource *res;
237 @@ -837,11 +916,12 @@ static int fsl_sai_probe(struct platform
238  
239         sai->pdev = pdev;
240  
241 -       if (of_device_is_compatible(np, "fsl,imx6sx-sai") ||
242 -           of_device_is_compatible(np, "fsl,imx6ul-sai"))
243 -               sai->sai_on_imx = true;
244 +       of_id = of_match_device(fsl_sai_ids, &pdev->dev);
245 +       if (!of_id || !of_id->data)
246 +               return -EINVAL;
247  
248         sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
249 +       sai->soc = of_id->data;
250  
251         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
252         base = devm_ioremap_resource(&pdev->dev, res);
253 @@ -873,11 +953,25 @@ static int fsl_sai_probe(struct platform
254                 sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp);
255                 if (IS_ERR(sai->mclk_clk[i])) {
256                         dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n",
257 -                                       i + 1, PTR_ERR(sai->mclk_clk[i]));
258 +                                       i, PTR_ERR(sai->mclk_clk[i]));
259                         sai->mclk_clk[i] = NULL;
260                 }
261         }
262  
263 +       /*dataline mask for rx and tx*/
264 +       ret = of_property_read_u32_index(np, "fsl,dataline", 0, &sai->dataline[0]);
265 +       if (ret)
266 +               sai->dataline[0] = 1;
267 +
268 +       ret = of_property_read_u32_index(np, "fsl,dataline", 1, &sai->dataline[1]);
269 +       if (ret)
270 +               sai->dataline[1] = 1;
271 +
272 +       if ((sai->dataline[0] & (~sai->soc->dataline)) || sai->dataline[1] & (~sai->soc->dataline)) {
273 +               dev_err(&pdev->dev, "dataline setting error, Mask is 0x%x\n", sai->soc->dataline);
274 +               return -EINVAL;
275 +       }
276 +
277         irq = platform_get_irq(pdev, 0);
278         if (irq < 0) {
279                 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
280 @@ -933,8 +1027,8 @@ static int fsl_sai_probe(struct platform
281                                    MCLK_DIR(index));
282         }
283  
284 -       sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
285 -       sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
286 +       sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0;
287 +       sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0;
288         sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
289         sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;
290  
291 @@ -947,7 +1041,7 @@ static int fsl_sai_probe(struct platform
292         if (ret)
293                 goto err_pm_disable;
294  
295 -       if (sai->sai_on_imx)
296 +       if (sai->soc->imx)
297                 ret = imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE);
298                 if (ret)
299                         goto err_pm_disable;
300 @@ -993,6 +1087,9 @@ static int fsl_sai_runtime_suspend(struc
301  
302         clk_disable_unprepare(sai->bus_clk);
303  
304 +       if (sai->soc->flags & SAI_FLAG_PMQOS)
305 +               pm_qos_remove_request(&sai->pm_qos_req);
306 +
307         regcache_cache_only(sai->regmap, true);
308         regcache_mark_dirty(sai->regmap);
309  
310 @@ -1022,6 +1119,10 @@ static int fsl_sai_runtime_resume(struct
311                         goto disable_tx_clk;
312         }
313  
314 +       if (sai->soc->flags & SAI_FLAG_PMQOS)
315 +               pm_qos_add_request(&sai->pm_qos_req,
316 +                               PM_QOS_CPU_DMA_LATENCY, 0);
317 +
318         regcache_cache_only(sai->regmap, false);
319         regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
320         regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
321 --- a/sound/soc/fsl/fsl_sai.h
322 +++ b/sound/soc/fsl/fsl_sai.h
323 @@ -1,11 +1,12 @@
324  /* SPDX-License-Identifier: GPL-2.0 */
325  /*
326 - * Copyright 2012-2013 Freescale Semiconductor, Inc.
327 + * Copyright 2012-2016 Freescale Semiconductor, Inc.
328   */
329  
330  #ifndef __FSL_SAI_H
331  #define __FSL_SAI_H
332  
333 +#include <linux/pm_qos.h>
334  #include <sound/dmaengine_pcm.h>
335  
336  #define FSL_SAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
337 @@ -20,7 +21,10 @@
338  #define FSL_SAI_TCR3   0x0c /* SAI Transmit Configuration 3 */
339  #define FSL_SAI_TCR4   0x10 /* SAI Transmit Configuration 4 */
340  #define FSL_SAI_TCR5   0x14 /* SAI Transmit Configuration 5 */
341 -#define FSL_SAI_TDR    0x20 /* SAI Transmit Data */
342 +#define FSL_SAI_TDR0    0x20 /* SAI Transmit Data */
343 +#define FSL_SAI_TDR1    0x24 /* SAI Transmit Data */
344 +#define FSL_SAI_TFR0    0x40 /* SAI Transmit FIFO */
345 +#define FSL_SAI_TFR1    0x44 /* SAI Transmit FIFO */
346  #define FSL_SAI_TFR    0x40 /* SAI Transmit FIFO */
347  #define FSL_SAI_TMR    0x60 /* SAI Transmit Mask */
348  #define FSL_SAI_RCSR   0x80 /* SAI Receive Control */
349 @@ -29,7 +33,10 @@
350  #define FSL_SAI_RCR3   0x8c /* SAI Receive Configuration 3 */
351  #define FSL_SAI_RCR4   0x90 /* SAI Receive Configuration 4 */
352  #define FSL_SAI_RCR5   0x94 /* SAI Receive Configuration 5 */
353 -#define FSL_SAI_RDR    0xa0 /* SAI Receive Data */
354 +#define FSL_SAI_RDR0    0xa0 /* SAI Receive Data */
355 +#define FSL_SAI_RDR1    0xa4 /* SAI Receive Data */
356 +#define FSL_SAI_RFR0    0xc0 /* SAI Receive FIFO */
357 +#define FSL_SAI_RFR1    0xc4 /* SAI Receive FIFO */
358  #define FSL_SAI_RFR    0xc0 /* SAI Receive FIFO */
359  #define FSL_SAI_RMR    0xe0 /* SAI Receive Mask */
360  
361 @@ -45,6 +52,7 @@
362  
363  /* SAI Transmit/Receive Control Register */
364  #define FSL_SAI_CSR_TERE       BIT(31)
365 +#define FSL_SAI_CSR_SE         BIT(30)
366  #define FSL_SAI_CSR_FR         BIT(25)
367  #define FSL_SAI_CSR_SR         BIT(24)
368  #define FSL_SAI_CSR_xF_SHIFT   16
369 @@ -81,11 +89,19 @@
370  #define FSL_SAI_CR2_DIV_MASK   0xff
371  
372  /* SAI Transmit and Receive Configuration 3 Register */
373 -#define FSL_SAI_CR3_TRCE       BIT(16)
374 +#define FSL_SAI_CR3_TRCE0      BIT(16)
375 +#define FSL_SAI_CR3_TRCE1      BIT(17)
376 +#define FSL_SAI_CR3_TRCE(x)    (x << 16)
377  #define FSL_SAI_CR3_WDFL(x)    (x)
378  #define FSL_SAI_CR3_WDFL_MASK  0x1f
379  
380  /* SAI Transmit and Receive Configuration 4 Register */
381 +
382 +#define FSL_SAI_CR4_FCONT      BIT(28)
383 +#define FSL_SAI_CR4_FCOMB_SHIFT BIT(26)
384 +#define FSL_SAI_CR4_FCOMB_SOFT  BIT(27)
385 +#define FSL_SAI_CR4_FPACK_8     (0x2 << 24)
386 +#define FSL_SAI_CR4_FPACK_16    (0x3 << 24)
387  #define FSL_SAI_CR4_FRSZ(x)    (((x) - 1) << 16)
388  #define FSL_SAI_CR4_FRSZ_MASK  (0x1f << 16)
389  #define FSL_SAI_CR4_SYWD(x)    (((x) - 1) << 8)
390 @@ -126,6 +142,16 @@
391  #define FSL_SAI_MAXBURST_TX 6
392  #define FSL_SAI_MAXBURST_RX 6
393  
394 +#define SAI_FLAG_PMQOS   BIT(0)
395 +
396 +struct fsl_sai_soc_data {
397 +       unsigned int fifo_depth;
398 +       unsigned int fifos;
399 +       unsigned int dataline;
400 +       unsigned int flags;
401 +       bool imx;
402 +};
403 +
404  struct fsl_sai {
405         struct platform_device *pdev;
406         struct regmap *regmap;
407 @@ -138,6 +164,7 @@ struct fsl_sai {
408         bool sai_on_imx;
409         bool synchronous[2];
410         bool is_stream_opened[2];
411 +       unsigned int dataline[2];
412  
413         unsigned int mclk_id[2];
414         unsigned int mclk_streams;
415 @@ -146,6 +173,8 @@ struct fsl_sai {
416  
417         struct snd_dmaengine_dai_dma_data dma_params_rx;
418         struct snd_dmaengine_dai_dma_data dma_params_tx;
419 +       const struct fsl_sai_soc_data *soc;
420 +       struct pm_qos_request pm_qos_req;
421  };
422  
423  #define TX 1