diff options
Diffstat (limited to 'target/linux/layerscape/patches-5.4/801-audio-0037-MLK-16224-4-ASoC-fsl_sai-support-multi-fifo-and-DSD.patch')
-rw-r--r-- | target/linux/layerscape/patches-5.4/801-audio-0037-MLK-16224-4-ASoC-fsl_sai-support-multi-fifo-and-DSD.patch | 326 |
1 files changed, 0 insertions, 326 deletions
diff --git a/target/linux/layerscape/patches-5.4/801-audio-0037-MLK-16224-4-ASoC-fsl_sai-support-multi-fifo-and-DSD.patch b/target/linux/layerscape/patches-5.4/801-audio-0037-MLK-16224-4-ASoC-fsl_sai-support-multi-fifo-and-DSD.patch deleted file mode 100644 index c2952deaab..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0037-MLK-16224-4-ASoC-fsl_sai-support-multi-fifo-and-DSD.patch +++ /dev/null @@ -1,326 +0,0 @@ -From 87f734fa8214b4ddbfdac9b7ac5dc75a3d86badb Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang <shengjiu.wang@nxp.com> -Date: Tue, 23 Jan 2018 13:26:37 +0800 -Subject: [PATCH] MLK-16224-4: ASoC: fsl_sai: support multi fifo and DSD - -The codec always mux the LRCLK pin to DSD data line, so when -we want to support DSD, the pinmux is different. For two channel -DSD, the DSDL is mapped to TX0, but the DSDR is mapped to TX4, -there is address offset for the fifo address of TX0 and TX4, TX4's -fifo is not adjacent to TX0's. - -Usually, if mapping is TX0 and TX1, that will be easy for SAI -and SDMA to handle, that SAI can use the FIFO combine mode, SDMA -can use the normal script. - -so for DSD: -1. The SDMA should use the multi-fifo script, and SAI can't -use the FIFO combine mode. -2. driver should to check the dts configuration(fsl,dataline) for -which dataline is used corrently -3. maxburst is the multiply of datalines -4. each channel of DSD occupy one data lane -5. according to data lane, set TRCE bits - -Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> -Reviewed-by: Viorel Suman <viorel.suman@nxp.com> ---- - sound/soc/fsl/fsl_sai.c | 162 +++++++++++++++++++++++++++++++++++++++++++++--- - sound/soc/fsl/fsl_sai.h | 12 +++- - 2 files changed, 164 insertions(+), 10 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -267,6 +267,7 @@ static int fsl_sai_set_dai_fmt_tr(struct - if (!sai->is_lsb_first) - val_cr4 |= FSL_SAI_CR4_MF; - -+ sai->is_dsp_mode = false; - /* DAI mode */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: -@@ -305,6 +306,11 @@ static int fsl_sai_set_dai_fmt_tr(struct - val_cr2 |= FSL_SAI_CR2_BCP; - sai->is_dsp_mode = true; - break; -+ case SND_SOC_DAIFMT_PDM: -+ val_cr2 |= FSL_SAI_CR2_BCP; -+ val_cr4 &= ~FSL_SAI_CR4_MF; -+ sai->is_dsp_mode = true; -+ break; - case SND_SOC_DAIFMT_RIGHT_J: - /* To be done */ - default: -@@ -492,12 +498,38 @@ static int fsl_sai_hw_params(struct snd_ - u32 slot_width = word_width; - u32 pins; - int ret; -+ int i; -+ int trce_mask = 0; -+ snd_pcm_format_t format = params_format(params); - - if (sai->slots) - slots = sai->slots; - - pins = DIV_ROUND_UP(channels, slots); - -+ if (format == SNDRV_PCM_FORMAT_DSD_U8 || -+ format == SNDRV_PCM_FORMAT_DSD_U16_LE || -+ format == SNDRV_PCM_FORMAT_DSD_U16_BE || -+ format == SNDRV_PCM_FORMAT_DSD_U32_LE || -+ format == SNDRV_PCM_FORMAT_DSD_U32_BE) { -+ sai->is_dsd = true; -+ -+ if (!IS_ERR_OR_NULL(sai->pins_dsd)) { -+ ret = pinctrl_select_state(sai->pinctrl, sai->pins_dsd); -+ if (ret) { -+ dev_err(cpu_dai->dev, -+ "failed to set proper pins state: %d\n", ret); -+ return ret; -+ } -+ } -+ } else { -+ pinctrl_pm_select_default_state(cpu_dai->dev); -+ sai->is_dsd = false; -+ } -+ -+ if (sai->is_dsd) -+ pins = channels; -+ - if (sai->slot_width) - slot_width = sai->slot_width; - -@@ -527,7 +559,7 @@ static int fsl_sai_hw_params(struct snd_ - val_cr5 |= FSL_SAI_CR5_WNW(slot_width); - val_cr5 |= FSL_SAI_CR5_W0W(slot_width); - -- if (sai->is_lsb_first) -+ if (sai->is_lsb_first || sai->is_dsd) - val_cr5 |= FSL_SAI_CR5_FBT(0); - else - val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); -@@ -560,17 +592,71 @@ static int fsl_sai_hw_params(struct snd_ - } - - if (sai->soc->dataline != 0x1) { -- if (sai->dataline[tx] <= 1) -+ -+ if (sai->dataline[tx] <= 1 || sai->is_multi_lane) - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_FCOMB_MASK, 0); - else - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT); -+ -+ if (sai->is_multi_lane) { -+ if (tx) { -+ sai->dma_params_tx.maxburst = -+ FSL_SAI_MAXBURST_TX * pins; -+ if (sai->is_dsd) -+ sai->dma_params_tx.fifo_num = pins + -+ (sai->dataline_off_dsd[tx] << 8); -+ else -+ sai->dma_params_tx.fifo_num = pins + -+ (sai->dataline_off[tx] << 8); -+ } else { -+ sai->dma_params_rx.maxburst = -+ FSL_SAI_MAXBURST_RX * pins; -+ if (sai->is_dsd) -+ sai->dma_params_rx.fifo_num = pins + -+ (sai->dataline_off_dsd[tx] << 8); -+ else -+ sai->dma_params_rx.fifo_num = pins + -+ (sai->dataline_off[tx] << 8); -+ } -+ } -+ -+ snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, -+ &sai->dma_params_rx); - } - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -+ if (sai->is_dsd) { -+ if (__sw_hweight8(sai->dataline_dsd[tx] & 0xFF) < pins) { -+ dev_err(cpu_dai->dev, "channel not supported\n"); -+ return -EINVAL; -+ } -+ /*find a proper tcre setting*/ -+ for (i = 0; i < 8; i++) { -+ trce_mask = (1 << (i + 1)) - 1; -+ if (__sw_hweight8(sai->dataline_dsd[tx] & trce_mask) == pins) -+ break; -+ } -+ -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), - FSL_SAI_CR3_TRCE_MASK, -- FSL_SAI_CR3_TRCE((sai->dataline[tx] & ((1 << pins) - 1)))); -+ FSL_SAI_CR3_TRCE((sai->dataline_dsd[tx] & trce_mask))); -+ } else { -+ if (__sw_hweight8(sai->dataline[tx] & 0xFF) < pins) { -+ dev_err(cpu_dai->dev, "channel not supported\n"); -+ return -EINVAL; -+ } -+ /*find a proper tcre setting*/ -+ for (i = 0; i < 8; i++) { -+ trce_mask = (1 << (i + 1)) - 1; -+ if (__sw_hweight8(sai->dataline[tx] & trce_mask) == pins) -+ break; -+ } -+ -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -+ FSL_SAI_CR3_TRCE_MASK, -+ FSL_SAI_CR3_TRCE((sai->dataline[tx] & trce_mask))); -+ } - - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -@@ -610,9 +696,18 @@ static int fsl_sai_trigger(struct snd_pc - unsigned char offset = sai->soc->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - u8 channels = substream->runtime->channels; -+ u32 slots = (channels == 1) ? 2 : channels; - u32 xcsr, count = 100; -- int i; -+ u32 pins; -+ int i = 0, j = 0, k = 0; -+ -+ if (sai->slots) -+ slots = sai->slots; -+ -+ pins = DIV_ROUND_UP(channels, slots); - -+ if (sai->is_dsd) -+ pins = channels; - /* - * Asynchronous mode: Clear SYNC for both Tx and Rx. - * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. -@@ -631,10 +726,19 @@ static int fsl_sai_trigger(struct snd_pc - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -- for (i = 0; tx && i < channels; i++) -- regmap_write(sai->regmap, FSL_SAI_TDR0, 0x0); -- if (tx) -- udelay(10); -+ -+ for (i = 0; tx && i < channels; i++) { -+ while (tx && i < channels) -+ if (sai->dataline[tx] & (1 << j)) { -+ regmap_write(sai->regmap, FSL_SAI_TDR0 + j * 0x4, 0x0); -+ i++; -+ k++; -+ } -+ j++; -+ -+ if (k%pins == 0) -+ j = 0; -+ } - - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset), - FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); -@@ -994,6 +1098,7 @@ static int fsl_sai_probe(struct platform - char tmp[8]; - int irq, ret, i; - int index; -+ int firstbitidx, nextbitidx; - struct regmap_config fsl_sai_regmap_config = fsl_sai_v2_regmap_config; - unsigned long irqflags = 0; - -@@ -1048,6 +1153,9 @@ static int fsl_sai_probe(struct platform - } - } - -+ if (of_find_property(np, "fsl,sai-multi-lane", NULL)) -+ sai->is_multi_lane = true; -+ - /*dataline mask for rx and tx*/ - ret = of_property_read_u32_index(np, "fsl,dataline", 0, &sai->dataline[0]); - if (ret) -@@ -1062,6 +1170,37 @@ static int fsl_sai_probe(struct platform - return -EINVAL; - } - -+ for (i = 0; i < 2; i++) { -+ firstbitidx = find_first_bit((const unsigned long *)&sai->dataline[i], 8); -+ nextbitidx = find_next_bit((const unsigned long *)&sai->dataline[i], 8, firstbitidx+1); -+ sai->dataline_off[i] = nextbitidx - firstbitidx - 1; -+ -+ if (sai->dataline_off[i] < 0 || sai->dataline_off[i] >= 7) -+ sai->dataline_off[i] = 0; -+ } -+ -+ ret = of_property_read_u32_index(np, "fsl,dataline,dsd", 0, &sai->dataline_dsd[0]); -+ if (ret) -+ sai->dataline_dsd[0] = 1; -+ -+ ret = of_property_read_u32_index(np, "fsl,dataline,dsd", 1, &sai->dataline_dsd[1]); -+ if (ret) -+ sai->dataline_dsd[1] = 1; -+ -+ if ((sai->dataline_dsd[0] & (~sai->soc->dataline)) || sai->dataline_dsd[1] & (~sai->soc->dataline)) { -+ dev_err(&pdev->dev, "dataline setting error, Mask is 0x%x\n", sai->soc->dataline); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < 2; i++) { -+ firstbitidx = find_first_bit((const unsigned long *)&sai->dataline_dsd[i], 8); -+ nextbitidx = find_next_bit((const unsigned long *)&sai->dataline_dsd[i], 8, firstbitidx+1); -+ sai->dataline_off_dsd[i] = nextbitidx - firstbitidx - 1; -+ -+ if (sai->dataline_off_dsd[i] < 0 || sai->dataline_off_dsd[i] >= 7) -+ sai->dataline_off_dsd[i] = 0; -+ } -+ - if ((of_find_property(np, "fsl,i2s-xtor", NULL) != NULL) || - (of_find_property(np, "fsl,txm-rxs", NULL) != NULL)) - { -@@ -1144,6 +1283,11 @@ static int fsl_sai_probe(struct platform - sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; - sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; - -+ sai->pinctrl = devm_pinctrl_get(&pdev->dev); -+ -+ if (!IS_ERR_OR_NULL(sai->pinctrl)) -+ sai->pins_dsd = pinctrl_lookup_state(sai->pinctrl, "dsd"); -+ - platform_set_drvdata(pdev, sai); - - pm_runtime_enable(&pdev->dev); ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -11,7 +11,10 @@ - - #define FSL_SAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S24_LE |\ -- SNDRV_PCM_FMTBIT_S32_LE) -+ SNDRV_PCM_FMTBIT_S32_LE |\ -+ SNDRV_PCM_FMTBIT_DSD_U8 |\ -+ SNDRV_PCM_FMTBIT_DSD_U16_LE |\ -+ SNDRV_PCM_FMTBIT_DSD_U32_LE) - - /* SAI Register Map Register */ - #define FSL_SAI_TCSR(offset) (0x00 + offset) /* SAI Transmit Control */ -@@ -172,9 +175,14 @@ struct fsl_sai { - bool slave_mode[2]; - bool is_lsb_first; - bool is_dsp_mode; -+ bool is_multi_lane; - bool synchronous[2]; - bool is_stream_opened[2]; -+ bool is_dsd; - unsigned int dataline[2]; -+ unsigned int dataline_dsd[2]; -+ unsigned int dataline_off[2]; -+ unsigned int dataline_off_dsd[2]; - unsigned int masterflag[2]; - - unsigned int mclk_id[2]; -@@ -188,6 +196,8 @@ struct fsl_sai { - struct snd_dmaengine_dai_dma_data dma_params_tx; - const struct fsl_sai_soc_data *soc; - struct pm_qos_request pm_qos_req; -+ struct pinctrl *pinctrl; -+ struct pinctrl_state *pins_dsd; - }; - - #define TX 1 |