aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/801-audio-0027-MLK-15140-1-ASoC-fsl_sai-support-latest-sai-module.patch
diff options
context:
space:
mode:
authorYangbo Lu <yangbo.lu@nxp.com>2020-04-10 10:47:05 +0800
committerPetr Štetiar <ynezz@true.cz>2020-05-07 12:53:06 +0200
commitcddd4591404fb4c53dc0b3c0b15b942cdbed4356 (patch)
tree392c1179de46b0f804e3789edca19069b64e6b44 /target/linux/layerscape/patches-5.4/801-audio-0027-MLK-15140-1-ASoC-fsl_sai-support-latest-sai-module.patch
parentd1d2c0b5579ea4f69a42246c9318539d61ba1999 (diff)
downloadupstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.tar.gz
upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.tar.bz2
upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.zip
layerscape: add patches-5.4
Add patches for linux-5.4. The patches are from NXP LSDK-20.04 release which was tagged LSDK-20.04-V5.4. https://source.codeaurora.org/external/qoriq/qoriq-components/linux/ For boards LS1021A-IOT, and Traverse-LS1043 which are not involved in LSDK, port the dts patches from 4.14. The patches are sorted into the following categories: 301-arch-xxxx 302-dts-xxxx 303-core-xxxx 701-net-xxxx 801-audio-xxxx 802-can-xxxx 803-clock-xxxx 804-crypto-xxxx 805-display-xxxx 806-dma-xxxx 807-gpio-xxxx 808-i2c-xxxx 809-jailhouse-xxxx 810-keys-xxxx 811-kvm-xxxx 812-pcie-xxxx 813-pm-xxxx 814-qe-xxxx 815-sata-xxxx 816-sdhc-xxxx 817-spi-xxxx 818-thermal-xxxx 819-uart-xxxx 820-usb-xxxx 821-vfio-xxxx Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Diffstat (limited to 'target/linux/layerscape/patches-5.4/801-audio-0027-MLK-15140-1-ASoC-fsl_sai-support-latest-sai-module.patch')
-rw-r--r--target/linux/layerscape/patches-5.4/801-audio-0027-MLK-15140-1-ASoC-fsl_sai-support-latest-sai-module.patch701
1 files changed, 701 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/801-audio-0027-MLK-15140-1-ASoC-fsl_sai-support-latest-sai-module.patch b/target/linux/layerscape/patches-5.4/801-audio-0027-MLK-15140-1-ASoC-fsl_sai-support-latest-sai-module.patch
new file mode 100644
index 0000000000..38d3041bae
--- /dev/null
+++ b/target/linux/layerscape/patches-5.4/801-audio-0027-MLK-15140-1-ASoC-fsl_sai-support-latest-sai-module.patch
@@ -0,0 +1,701 @@
+From 21cf15cd000ba45bc02b8bfcf59df1e13bfdb803 Mon Sep 17 00:00:00 2001
+From: Shengjiu Wang <shengjiu.wang@freescale.com>
+Date: Thu, 22 Jun 2017 15:39:24 +0800
+Subject: [PATCH] MLK-15140-1: ASoC: fsl_sai: support latest sai module
+
+The version of sai is upgrate in imx8mq, which add two register
+in beginning, there is VERID and PARAM. the driver need to be
+update
+
+Signed-off-by: Mihai Serban <mihai.serban@nxp.com>
+Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
+---
+ sound/soc/fsl/fsl_sai.c | 273 ++++++++++++++++++++++++++++--------------------
+ sound/soc/fsl/fsl_sai.h | 43 ++++----
+ 2 files changed, 180 insertions(+), 136 deletions(-)
+
+--- a/sound/soc/fsl/fsl_sai.c
++++ b/sound/soc/fsl/fsl_sai.c
+@@ -43,6 +43,7 @@ static struct fsl_sai_soc_data fsl_sai_i
+ .fifos = 1,
+ .fifo_depth = 32,
+ .flags = 0,
++ .reg_offset = 0,
+ };
+
+ static struct fsl_sai_soc_data fsl_sai_imx6ul = {
+@@ -51,6 +52,7 @@ static struct fsl_sai_soc_data fsl_sai_i
+ .fifos = 1,
+ .fifo_depth = 32,
+ .flags = 0,
++ .reg_offset = 0,
+ };
+
+ static struct fsl_sai_soc_data fsl_sai_imx7ulp = {
+@@ -59,6 +61,16 @@ static struct fsl_sai_soc_data fsl_sai_i
+ .fifos = 2,
+ .fifo_depth = 16,
+ .flags = SAI_FLAG_PMQOS,
++ .reg_offset = 0,
++};
++
++static struct fsl_sai_soc_data fsl_sai_imx8mq = {
++ .imx = true,
++ .dataline = 0xff,
++ .fifos = 8,
++ .fifo_depth = 32,
++ .flags = 0,
++ .reg_offset = 8,
+ };
+
+ static const unsigned int fsl_sai_rates[] = {
+@@ -75,6 +87,7 @@ static const struct snd_pcm_hw_constrain
+ static irqreturn_t fsl_sai_isr(int irq, void *devid)
+ {
+ struct fsl_sai *sai = (struct fsl_sai *)devid;
++ unsigned char offset = sai->soc->reg_offset;
+ struct device *dev = &sai->pdev->dev;
+ u32 flags, xcsr, mask;
+ bool irq_none = true;
+@@ -87,7 +100,7 @@ static irqreturn_t fsl_sai_isr(int irq,
+ mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;
+
+ /* Tx IRQ */
+- regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr);
++ regmap_read(sai->regmap, FSL_SAI_TCSR(offset), &xcsr);
+ flags = xcsr & mask;
+
+ if (flags)
+@@ -117,11 +130,11 @@ static irqreturn_t fsl_sai_isr(int irq,
+ xcsr &= ~FSL_SAI_CSR_xF_MASK;
+
+ if (flags)
+- regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr);
++ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), flags | xcsr);
+
+ irq_rx:
+ /* Rx IRQ */
+- regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr);
++ regmap_read(sai->regmap, FSL_SAI_RCSR(offset), &xcsr);
+ flags = xcsr & mask;
+
+ if (flags)
+@@ -151,7 +164,7 @@ irq_rx:
+ xcsr &= ~FSL_SAI_CSR_xF_MASK;
+
+ if (flags)
+- regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr);
++ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), flags | xcsr);
+
+ out:
+ if (irq_none)
+@@ -175,6 +188,7 @@ static int fsl_sai_set_dai_sysclk_tr(str
+ int clk_id, unsigned int freq, int fsl_dir)
+ {
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
++ unsigned char offset = sai->soc->reg_offset;
+ bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
+ u32 val_cr2 = 0;
+
+@@ -195,7 +209,7 @@ static int fsl_sai_set_dai_sysclk_tr(str
+ return -EINVAL;
+ }
+
+- regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, offset),
+ FSL_SAI_CR2_MSEL_MASK, val_cr2);
+
+ return 0;
+@@ -228,6 +242,7 @@ static int fsl_sai_set_dai_fmt_tr(struct
+ unsigned int fmt, int fsl_dir)
+ {
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
++ unsigned char offset = sai->soc->reg_offset;
+ bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
+ u32 val_cr2 = 0, val_cr4 = 0;
+
+@@ -324,9 +339,9 @@ static int fsl_sai_set_dai_fmt_tr(struct
+ return -EINVAL;
+ }
+
+- regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, offset),
+ FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2);
+- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
+ FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE |
+ FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4);
+
+@@ -362,6 +377,7 @@ static int fsl_sai_set_dai_fmt(struct sn
+ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
+ {
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
++ unsigned char offset = sai->soc->reg_offset;
+ unsigned long clk_rate;
+ u32 savediv = 0, ratio, savesub = freq;
+ u32 id;
+@@ -424,17 +440,17 @@ static int fsl_sai_set_bclk(struct snd_s
+ */
+ if ((sai->synchronous[TX] && !sai->synchronous[RX]) ||
+ (!tx && !sai->synchronous[RX])) {
+- regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
++ regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset),
+ FSL_SAI_CR2_MSEL_MASK,
+ FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
+- regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
++ regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset),
+ FSL_SAI_CR2_DIV_MASK, savediv - 1);
+ } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) ||
+ (tx && !sai->synchronous[TX])) {
+- regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
++ regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset),
+ FSL_SAI_CR2_MSEL_MASK,
+ FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
+- regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
++ regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset),
+ FSL_SAI_CR2_DIV_MASK, savediv - 1);
+ }
+
+@@ -449,6 +465,7 @@ static int fsl_sai_hw_params(struct snd_
+ struct snd_soc_dai *cpu_dai)
+ {
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
++ unsigned char offset = sai->soc->reg_offset;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ unsigned int channels = params_channels(params);
+ u32 word_width = params_width(params);
+@@ -501,49 +518,35 @@ static int fsl_sai_hw_params(struct snd_
+
+ if (!sai->slave_mode[tx]) {
+ if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
+- regmap_update_bits(sai->regmap, FSL_SAI_TCR4,
++ regmap_update_bits(sai->regmap, FSL_SAI_TCR4(offset),
+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
+ val_cr4);
+- regmap_update_bits(sai->regmap, FSL_SAI_TCR5,
++ regmap_update_bits(sai->regmap, FSL_SAI_TCR5(offset),
+ FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
+ FSL_SAI_CR5_FBT_MASK, val_cr5);
+ } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
+- regmap_update_bits(sai->regmap, FSL_SAI_RCR4,
++ regmap_update_bits(sai->regmap, FSL_SAI_RCR4(offset),
+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
+ val_cr4);
+- regmap_update_bits(sai->regmap, FSL_SAI_RCR5,
++ regmap_update_bits(sai->regmap, FSL_SAI_RCR5(offset),
+ FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
+ FSL_SAI_CR5_FBT_MASK, val_cr5);
+ }
+ }
+
+ if (sai->soc->dataline != 0x1) {
+- switch (sai->dataline[tx]) {
+- case 0x0:
+- break;
+- case 0x1:
+- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
+- FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT, 0);
+- break;
+- case 0x2:
+- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
+- FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT,
+- FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT);
+- break;
+- case 0x3:
+- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
+- FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT,
+- FSL_SAI_CR4_FCOMB_SOFT);
+- break;
+- default:
+- break;
+- }
++ if (sai->dataline[tx] <= 1)
++ 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);
+ }
+
+- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
+ val_cr4);
+- regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, offset),
+ FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
+ FSL_SAI_CR5_FBT_MASK, val_cr5);
+ regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1));
+@@ -571,6 +574,7 @@ static int fsl_sai_trigger(struct snd_pc
+ struct snd_soc_dai *cpu_dai)
+ {
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
++ unsigned char offset = sai->soc->reg_offset;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ u8 channels = substream->runtime->channels;
+ u32 xcsr, count = 100;
+@@ -581,9 +585,9 @@ static int fsl_sai_trigger(struct snd_pc
+ * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx.
+ * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx.
+ */
+- regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC,
++ regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset), FSL_SAI_CR2_SYNC,
+ sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
+- regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
++ regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset), FSL_SAI_CR2_SYNC,
+ sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
+
+ /*
+@@ -599,49 +603,50 @@ static int fsl_sai_trigger(struct snd_pc
+ if (tx)
+ udelay(10);
+
+- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
+ FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
+- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
++
++ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
+ FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
+- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
+ FSL_SAI_CSR_SE, FSL_SAI_CSR_SE);
+ if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
+- regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx)),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), offset),
+ FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
+ } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
+- regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx)),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), offset),
+ FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
+ }
+
+- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
+ FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
+ FSL_SAI_CSR_FRDE, 0);
+- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
++ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
+ FSL_SAI_CSR_xIE_MASK, 0);
+
+ /* Check if the opposite FRDE is also disabled */
+- regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr);
++ regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, offset), &xcsr);
+ if (!(xcsr & FSL_SAI_CSR_FRDE)) {
+ /* Disable both directions and reset their FIFOs */
+- regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
++ regmap_update_bits(sai->regmap, FSL_SAI_TCSR(offset),
+ FSL_SAI_CSR_TERE, 0);
+- regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
++ regmap_update_bits(sai->regmap, FSL_SAI_RCSR(offset),
+ FSL_SAI_CSR_TERE, 0);
+
+ /* TERE will remain set till the end of current frame */
+ do {
+ udelay(10);
+- regmap_read(sai->regmap, FSL_SAI_xCSR(tx), &xcsr);
++ regmap_read(sai->regmap, FSL_SAI_xCSR(tx, offset), &xcsr);
+ } while (--count && xcsr & FSL_SAI_CSR_TERE);
+
+- regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
++ regmap_update_bits(sai->regmap, FSL_SAI_TCSR(offset),
+ FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
+- regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
++ regmap_update_bits(sai->regmap, FSL_SAI_RCSR(offset),
+ FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
+
+ /*
+@@ -654,12 +659,12 @@ static int fsl_sai_trigger(struct snd_pc
+ if (!sai->slave_mode[tx]) {
+ /* Software Reset for both Tx and Rx */
+ regmap_write(sai->regmap,
+- FSL_SAI_TCSR, FSL_SAI_CSR_SR);
++ FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR);
+ regmap_write(sai->regmap,
+- FSL_SAI_RCSR, FSL_SAI_CSR_SR);
++ FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR);
+ /* Clear SR bit to finish the reset */
+- regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
+- regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
++ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0);
++ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0);
+ }
+ }
+ break;
+@@ -674,6 +679,7 @@ static int fsl_sai_startup(struct snd_pc
+ struct snd_soc_dai *cpu_dai)
+ {
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
++ unsigned char offset = sai->soc->reg_offset;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ int ret;
+
+@@ -682,7 +688,8 @@ static int fsl_sai_startup(struct snd_pc
+ else
+ sai->is_stream_opened[tx] = true;
+
+- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE0|FSL_SAI_CR3_TRCE1,
++ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset),
++ FSL_SAI_CR3_TRCE_MASK,
+ FSL_SAI_CR3_TRCE(sai->dataline[tx]));
+
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+@@ -695,12 +702,14 @@ static void fsl_sai_shutdown(struct snd_
+ struct snd_soc_dai *cpu_dai)
+ {
+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
++ unsigned char offset = sai->soc->reg_offset;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
+
+ if (sai->is_stream_opened[tx]) {
+- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE0 | FSL_SAI_CR3_TRCE1, 0);
++ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset),
++ FSL_SAI_CR3_TRCE_MASK, 0);
+ sai->is_stream_opened[tx] = false;
+ }
+ }
+@@ -719,17 +728,18 @@ static const struct snd_soc_dai_ops fsl_
+ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
+ {
+ struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
++ unsigned char offset = sai->soc->reg_offset;
+
+ /* Software Reset for both Tx and Rx */
+- regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
+- regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
++ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR);
++ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR);
+ /* Clear SR bit to finish the reset */
+- regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
+- regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
++ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0);
++ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0);
+
+- regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
++ regmap_update_bits(sai->regmap, FSL_SAI_TCR1(offset), FSL_SAI_CR1_RFW_MASK,
+ sai->soc->fifo_depth - FSL_SAI_MAXBURST_TX);
+- regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
++ regmap_update_bits(sai->regmap, FSL_SAI_RCR1(offset), FSL_SAI_CR1_RFW_MASK,
+ FSL_SAI_MAXBURST_RX - 1);
+
+ snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
+@@ -767,41 +777,55 @@ static const struct snd_soc_component_dr
+ .name = "fsl-sai",
+ };
+
+-static struct reg_default fsl_sai_reg_defaults[] = {
+- {FSL_SAI_TCR1, 0},
+- {FSL_SAI_TCR2, 0},
+- {FSL_SAI_TCR3, 0},
+- {FSL_SAI_TCR4, 0},
+- {FSL_SAI_TCR5, 0},
++static struct reg_default fsl_sai_v2_reg_defaults[] = {
++ {FSL_SAI_TCR1(0), 0},
++ {FSL_SAI_TCR2(0), 0},
++ {FSL_SAI_TCR3(0), 0},
++ {FSL_SAI_TCR4(0), 0},
++ {FSL_SAI_TCR5(0), 0},
++ {FSL_SAI_TDR0, 0},
++ {FSL_SAI_TDR1, 0},
++ {FSL_SAI_TMR, 0},
++ {FSL_SAI_RCR1(0), 0},
++ {FSL_SAI_RCR2(0), 0},
++ {FSL_SAI_RCR3(0), 0},
++ {FSL_SAI_RCR4(0), 0},
++ {FSL_SAI_RCR5(0), 0},
++ {FSL_SAI_RMR, 0},
++};
++
++static struct reg_default fsl_sai_v3_reg_defaults[] = {
++ {FSL_SAI_TCR1(8), 0},
++ {FSL_SAI_TCR2(8), 0},
++ {FSL_SAI_TCR3(8), 0},
++ {FSL_SAI_TCR4(8), 0},
++ {FSL_SAI_TCR5(8), 0},
+ {FSL_SAI_TDR0, 0},
+ {FSL_SAI_TDR1, 0},
+ {FSL_SAI_TMR, 0},
+- {FSL_SAI_RCR1, 0},
+- {FSL_SAI_RCR2, 0},
+- {FSL_SAI_RCR3, 0},
+- {FSL_SAI_RCR4, 0},
+- {FSL_SAI_RCR5, 0},
++ {FSL_SAI_RCR1(8), 0},
++ {FSL_SAI_RCR2(8), 0},
++ {FSL_SAI_RCR3(8), 0},
++ {FSL_SAI_RCR4(8), 0},
++ {FSL_SAI_RCR5(8), 0},
+ {FSL_SAI_RMR, 0},
+ };
+
+ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
+ {
++ struct fsl_sai *sai = dev_get_drvdata(dev);
++ unsigned char offset = sai->soc->reg_offset;
++
++ if (reg >= FSL_SAI_TCSR(offset) && reg <= FSL_SAI_TCR5(offset))
++ return true;
++
++ if (reg >= FSL_SAI_RCSR(offset) && reg <= FSL_SAI_RCR5(offset))
++ return true;
++
+ switch (reg) {
+- case FSL_SAI_TCSR:
+- case FSL_SAI_TCR1:
+- case FSL_SAI_TCR2:
+- case FSL_SAI_TCR3:
+- case FSL_SAI_TCR4:
+- case FSL_SAI_TCR5:
+ case FSL_SAI_TFR0:
+ case FSL_SAI_TFR1:
+ case FSL_SAI_TMR:
+- case FSL_SAI_RCSR:
+- case FSL_SAI_RCR1:
+- case FSL_SAI_RCR2:
+- case FSL_SAI_RCR3:
+- case FSL_SAI_RCR4:
+- case FSL_SAI_RCR5:
+ case FSL_SAI_RDR0:
+ case FSL_SAI_RDR1:
+ case FSL_SAI_RFR0:
+@@ -815,9 +839,13 @@ static bool fsl_sai_readable_reg(struct
+
+ static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
+ {
++ struct fsl_sai *sai = dev_get_drvdata(dev);
++ unsigned char offset = sai->soc->reg_offset;
++
++ if (reg == FSL_SAI_TCSR(offset) || reg == FSL_SAI_RCSR(offset))
++ return true;
++
+ switch (reg) {
+- case FSL_SAI_TCSR:
+- case FSL_SAI_RCSR:
+ case FSL_SAI_TFR0:
+ case FSL_SAI_TFR1:
+ case FSL_SAI_RFR0:
+@@ -832,22 +860,19 @@ static bool fsl_sai_volatile_reg(struct
+
+ static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
+ {
++ struct fsl_sai *sai = dev_get_drvdata(dev);
++ unsigned char offset = sai->soc->reg_offset;
++
++ if (reg >= FSL_SAI_TCSR(offset) && reg <= FSL_SAI_TCR5(offset))
++ return true;
++
++ if (reg >= FSL_SAI_RCSR(offset) && reg <= FSL_SAI_RCR5(offset))
++ return true;
++
+ switch (reg) {
+- case FSL_SAI_TCSR:
+- case FSL_SAI_TCR1:
+- case FSL_SAI_TCR2:
+- case FSL_SAI_TCR3:
+- case FSL_SAI_TCR4:
+- case FSL_SAI_TCR5:
+ case FSL_SAI_TDR0:
+ case FSL_SAI_TDR1:
+ case FSL_SAI_TMR:
+- case FSL_SAI_RCSR:
+- case FSL_SAI_RCR1:
+- case FSL_SAI_RCR2:
+- case FSL_SAI_RCR3:
+- case FSL_SAI_RCR4:
+- case FSL_SAI_RCR5:
+ case FSL_SAI_RMR:
+ return true;
+ default:
+@@ -855,14 +880,28 @@ static bool fsl_sai_writeable_reg(struct
+ }
+ }
+
+-static const struct regmap_config fsl_sai_regmap_config = {
++static const struct regmap_config fsl_sai_v2_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+
+ .max_register = FSL_SAI_RMR,
+- .reg_defaults = fsl_sai_reg_defaults,
+- .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults),
++ .reg_defaults = fsl_sai_v2_reg_defaults,
++ .num_reg_defaults = ARRAY_SIZE(fsl_sai_v2_reg_defaults),
++ .readable_reg = fsl_sai_readable_reg,
++ .volatile_reg = fsl_sai_volatile_reg,
++ .writeable_reg = fsl_sai_writeable_reg,
++ .cache_type = REGCACHE_FLAT,
++};
++
++static const struct regmap_config fsl_sai_v3_regmap_config = {
++ .reg_bits = 32,
++ .reg_stride = 4,
++ .val_bits = 32,
++
++ .max_register = FSL_SAI_RMR,
++ .reg_defaults = fsl_sai_v3_reg_defaults,
++ .num_reg_defaults = ARRAY_SIZE(fsl_sai_v3_reg_defaults),
+ .readable_reg = fsl_sai_readable_reg,
+ .volatile_reg = fsl_sai_volatile_reg,
+ .writeable_reg = fsl_sai_writeable_reg,
+@@ -874,6 +913,7 @@ static const struct of_device_id fsl_sai
+ { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx },
+ { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6ul },
+ { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp },
++ { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, fsl_sai_ids);
+@@ -889,7 +929,8 @@ static int fsl_sai_probe(struct platform
+ char tmp[8];
+ int irq, ret, i;
+ int index;
+- unsigned long irqflag = 0;
++ struct regmap_config fsl_sai_regmap_config = fsl_sai_v2_regmap_config;
++ unsigned long irqflags = 0;
+
+ sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
+ if (!sai)
+@@ -909,6 +950,9 @@ static int fsl_sai_probe(struct platform
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
++ if (sai->soc->reg_offset == 8)
++ fsl_sai_regmap_config = fsl_sai_v3_regmap_config;
++
+ sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+ "bus", base, &fsl_sai_regmap_config);
+
+@@ -963,11 +1007,11 @@ static int fsl_sai_probe(struct platform
+ }
+
+ /* SAI shared interrupt */
+- if (of_property_read_bool(np, "shared-interrupt"))
+- irqflag = IRQF_SHARED;
++ if (of_property_read_bool(np, "fsl,shared-interrupt"))
++ irqflags = IRQF_SHARED;
+
+- ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, irqflag,
+- np->name, sai);
++ ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, irqflags, np->name,
++ sai);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
+ return ret;
+@@ -1090,6 +1134,7 @@ static int fsl_sai_runtime_suspend(struc
+ static int fsl_sai_runtime_resume(struct device *dev)
+ {
+ struct fsl_sai *sai = dev_get_drvdata(dev);
++ unsigned char offset = sai->soc->reg_offset;
+ int ret;
+
+ ret = clk_prepare_enable(sai->bus_clk);
+@@ -1115,11 +1160,11 @@ static int fsl_sai_runtime_resume(struct
+ PM_QOS_CPU_DMA_LATENCY, 0);
+
+ regcache_cache_only(sai->regmap, false);
+- regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
+- regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
++ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR);
++ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR);
+ usleep_range(1000, 2000);
+- regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
+- regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
++ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0);
++ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0);
+
+ ret = regcache_sync(sai->regmap);
+ if (ret)
+--- a/sound/soc/fsl/fsl_sai.h
++++ b/sound/soc/fsl/fsl_sai.h
+@@ -14,38 +14,36 @@
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+ /* SAI Register Map Register */
+-#define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */
+-#define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */
+-#define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */
+-#define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */
+-#define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */
+-#define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */
++#define FSL_SAI_TCSR(offset) (0x00 + offset) /* SAI Transmit Control */
++#define FSL_SAI_TCR1(offset) (0x04 + offset) /* SAI Transmit Configuration 1 */
++#define FSL_SAI_TCR2(offset) (0x08 + offset) /* SAI Transmit Configuration 2 */
++#define FSL_SAI_TCR3(offset) (0x0c + offset) /* SAI Transmit Configuration 3 */
++#define FSL_SAI_TCR4(offset) (0x10 + offset) /* SAI Transmit Configuration 4 */
++#define FSL_SAI_TCR5(offset) (0x14 + offset) /* SAI Transmit Configuration 5 */
+ #define FSL_SAI_TDR0 0x20 /* SAI Transmit Data */
+ #define FSL_SAI_TDR1 0x24 /* SAI Transmit Data */
+ #define FSL_SAI_TFR0 0x40 /* SAI Transmit FIFO */
+ #define FSL_SAI_TFR1 0x44 /* SAI Transmit FIFO */
+ #define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */
+ #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */
+-#define FSL_SAI_RCSR 0x80 /* SAI Receive Control */
+-#define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */
+-#define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */
+-#define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */
+-#define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */
+-#define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */
++#define FSL_SAI_RCSR(offset) (0x80 + offset) /* SAI Receive Control */
++#define FSL_SAI_RCR1(offset) (0x84 + offset) /* SAI Receive Configuration 1 */
++#define FSL_SAI_RCR2(offset) (0x88 + offset) /* SAI Receive Configuration 2 */
++#define FSL_SAI_RCR3(offset) (0x8c + offset) /* SAI Receive Configuration 3 */
++#define FSL_SAI_RCR4(offset) (0x90 + offset) /* SAI Receive Configuration 4 */
++#define FSL_SAI_RCR5(offset) (0x94 + offset) /* SAI Receive Configuration 5 */
+ #define FSL_SAI_RDR0 0xa0 /* SAI Receive Data */
+ #define FSL_SAI_RDR1 0xa4 /* SAI Receive Data */
+ #define FSL_SAI_RFR0 0xc0 /* SAI Receive FIFO */
+ #define FSL_SAI_RFR1 0xc4 /* SAI Receive FIFO */
+ #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */
+
+-#define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR)
+-#define FSL_SAI_xCR1(tx) (tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1)
+-#define FSL_SAI_xCR2(tx) (tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2)
+-#define FSL_SAI_xCR3(tx) (tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3)
+-#define FSL_SAI_xCR4(tx) (tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4)
+-#define FSL_SAI_xCR5(tx) (tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5)
+-#define FSL_SAI_xDR(tx) (tx ? FSL_SAI_TDR : FSL_SAI_RDR)
+-#define FSL_SAI_xFR(tx) (tx ? FSL_SAI_TFR : FSL_SAI_RFR)
++#define FSL_SAI_xCSR(tx, off) (tx ? FSL_SAI_TCSR(off) : FSL_SAI_RCSR(off))
++#define FSL_SAI_xCR1(tx, off) (tx ? FSL_SAI_TCR1(off) : FSL_SAI_RCR1(off))
++#define FSL_SAI_xCR2(tx, off) (tx ? FSL_SAI_TCR2(off) : FSL_SAI_RCR2(off))
++#define FSL_SAI_xCR3(tx, off) (tx ? FSL_SAI_TCR3(off) : FSL_SAI_RCR3(off))
++#define FSL_SAI_xCR4(tx, off) (tx ? FSL_SAI_TCR4(off) : FSL_SAI_RCR4(off))
++#define FSL_SAI_xCR5(tx, off) (tx ? FSL_SAI_TCR5(off) : FSL_SAI_RCR5(off))
+ #define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR)
+
+ /* SAI Transmit/Receive Control Register */
+@@ -87,8 +85,7 @@
+ #define FSL_SAI_CR2_DIV_MASK 0xff
+
+ /* SAI Transmit and Receive Configuration 3 Register */
+-#define FSL_SAI_CR3_TRCE0 BIT(16)
+-#define FSL_SAI_CR3_TRCE1 BIT(17)
++#define FSL_SAI_CR3_TRCE_MASK (0xff << 16)
+ #define FSL_SAI_CR3_TRCE(x) (x << 16)
+ #define FSL_SAI_CR3_WDFL(x) (x)
+ #define FSL_SAI_CR3_WDFL_MASK 0x1f
+@@ -98,6 +95,7 @@
+ #define FSL_SAI_CR4_FCONT BIT(28)
+ #define FSL_SAI_CR4_FCOMB_SHIFT BIT(26)
+ #define FSL_SAI_CR4_FCOMB_SOFT BIT(27)
++#define FSL_SAI_CR4_FCOMB_MASK (0x3 << 26)
+ #define FSL_SAI_CR4_FPACK_8 (0x2 << 24)
+ #define FSL_SAI_CR4_FPACK_16 (0x3 << 24)
+ #define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16)
+@@ -147,6 +145,7 @@ struct fsl_sai_soc_data {
+ unsigned int fifos;
+ unsigned int dataline;
+ unsigned int flags;
++ unsigned char reg_offset;
+ bool imx;
+ };
+