| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From 3b671c297cff1ba5f5c3e089ffa82523eca3c598 Mon Sep 17 00:00:00 2001 |
| 2 | From: Mihai Serban <mihai.serban@nxp.com> |
| 3 | Date: Fri, 7 Jul 2017 15:09:51 +0300 |
| 4 | Subject: [PATCH] MLK-15927-1: ASoC: fsl_sai: Fix noise when using EDMA |
| 5 | |
| 6 | EDMA requires the period size to be multiple of maxburst. Otherwise the |
| 7 | remaining bytes are not transferred and thus noise is produced. |
| 8 | |
| 9 | We can handle this issue by adding a constraint on |
| 10 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE to be multiple of tx/rx maxburst value. |
| 11 | |
| 12 | This is based on a similar patch we have for ESAI: |
| 13 | commit bd3f3eb2a37c |
| 14 | ("MLK-15109-2: ASoC: fsl_esai: add constrain_period_size") |
| 15 | |
| 16 | Signed-off-by: Mihai Serban <mihai.serban@nxp.com> |
| 17 | Reviewed-by: Shengjiu Wang <shengjiu.wang@nxp.com> |
| 18 | --- |
| 19 | sound/soc/fsl/fsl_sai.c | 23 +++++++++++++++++++++++ |
| 20 | sound/soc/fsl/fsl_sai.h | 2 ++ |
| 21 | 2 files changed, 25 insertions(+) |
| 22 | |
| 23 | --- a/sound/soc/fsl/fsl_sai.c |
| 24 | +++ b/sound/soc/fsl/fsl_sai.c |
| 25 | @@ -35,6 +35,7 @@ static struct fsl_sai_soc_data fsl_sai_v |
| 26 | .fifos = 1, |
| 27 | .fifo_depth = 32, |
| 28 | .flags = 0, |
| 29 | + .constrain_period_size = false, |
| 30 | }; |
| 31 | |
| 32 | static struct fsl_sai_soc_data fsl_sai_imx6sx = { |
| 33 | @@ -44,6 +45,7 @@ static struct fsl_sai_soc_data fsl_sai_i |
| 34 | .fifo_depth = 32, |
| 35 | .flags = 0, |
| 36 | .reg_offset = 0, |
| 37 | + .constrain_period_size = false, |
| 38 | }; |
| 39 | |
| 40 | static struct fsl_sai_soc_data fsl_sai_imx6ul = { |
| 41 | @@ -53,6 +55,7 @@ static struct fsl_sai_soc_data fsl_sai_i |
| 42 | .fifo_depth = 32, |
| 43 | .flags = 0, |
| 44 | .reg_offset = 0, |
| 45 | + .constrain_period_size = false, |
| 46 | }; |
| 47 | |
| 48 | static struct fsl_sai_soc_data fsl_sai_imx7ulp = { |
| 49 | @@ -62,6 +65,7 @@ static struct fsl_sai_soc_data fsl_sai_i |
| 50 | .fifo_depth = 16, |
| 51 | .flags = SAI_FLAG_PMQOS, |
| 52 | .reg_offset = 0, |
| 53 | + .constrain_period_size = false, |
| 54 | }; |
| 55 | |
| 56 | static struct fsl_sai_soc_data fsl_sai_imx8mq = { |
| 57 | @@ -71,6 +75,17 @@ static struct fsl_sai_soc_data fsl_sai_i |
| 58 | .fifo_depth = 32, |
| 59 | .flags = 0, |
| 60 | .reg_offset = 8, |
| 61 | + .constrain_period_size = false, |
| 62 | +}; |
| 63 | + |
| 64 | +static struct fsl_sai_soc_data fsl_sai_imx8qm = { |
| 65 | + .imx = true, |
| 66 | + .dataline = 0x3, |
| 67 | + .fifos = 1, |
| 68 | + .fifo_depth = 32, |
| 69 | + .flags = 0, |
| 70 | + .reg_offset = 0, |
| 71 | + .constrain_period_size = true, |
| 72 | }; |
| 73 | |
| 74 | static const unsigned int fsl_sai_rates[] = { |
| 75 | @@ -693,6 +708,13 @@ static int fsl_sai_startup(struct snd_pc |
| 76 | FSL_SAI_CR3_TRCE_MASK, |
| 77 | FSL_SAI_CR3_TRCE(sai->dataline[tx])); |
| 78 | |
| 79 | + /* EDMA engine needs periods of size multiple of tx/rx maxburst */ |
| 80 | + if (sai->soc->constrain_period_size) |
| 81 | + snd_pcm_hw_constraint_step(substream->runtime, 0, |
| 82 | + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
| 83 | + tx ? sai->dma_params_tx.maxburst : |
| 84 | + sai->dma_params_rx.maxburst); |
| 85 | + |
| 86 | ret = snd_pcm_hw_constraint_list(substream->runtime, 0, |
| 87 | SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints); |
| 88 | |
| 89 | @@ -915,6 +937,7 @@ static const struct of_device_id fsl_sai |
| 90 | { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6ul }, |
| 91 | { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp }, |
| 92 | { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq }, |
| 93 | + { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm }, |
| 94 | { /* sentinel */ } |
| 95 | }; |
| 96 | MODULE_DEVICE_TABLE(of, fsl_sai_ids); |
| 97 | --- a/sound/soc/fsl/fsl_sai.h |
| 98 | +++ b/sound/soc/fsl/fsl_sai.h |
| 99 | @@ -147,6 +147,8 @@ struct fsl_sai_soc_data { |
| 100 | unsigned int flags; |
| 101 | unsigned char reg_offset; |
| 102 | bool imx; |
| 103 | + /* True for EDMA because it needs period size multiple of maxburst */ |
| 104 | + bool constrain_period_size; |
| 105 | }; |
| 106 | |
| 107 | struct fsl_sai { |