summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Krummenacher <max.krummenacher@toradex.com>2021-03-22 15:19:20 +0100
committerMax Krummenacher <max.krummenacher@toradex.com>2021-04-21 14:49:21 +0200
commit82e97870feb6303ecc71371abc76a606e724b065 (patch)
tree8ea64ef5c8671b0cbe349d782a2d9eba9faff073
parent8c05b31a44c32557db8bd9c151b2d057b2e7c5af (diff)
fsl_sai: work around missing MCLK on i.mx 8m plus
Some audio codecs need the MCLK during setup of the codec, however for the i.MX 8M Plus it is gated with the bce bit. So enable the bit already in fsl_sai_hw_params() which is an early state when initalizing sai and codec. Notably the WM8904 codec on the Dahlia carrier board is affected. Fixes a timeout on audio start: root@verdin-imx8mp:~# aplay sound/Gong.wav [ 1356.402716] wm8904 3-001a: DC servo timed out [ 1362.410401] wm8904 3-001a: DC servo timed out Playing WAVE 'sound/Gong.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo Related-to: ELB-3554 Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com>
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp.dtsi12
-rw-r--r--sound/soc/fsl/fsl_sai.c24
-rw-r--r--sound/soc/fsl/fsl_sai.h3
3 files changed, 33 insertions, 6 deletions
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index a0867c9feeb8..3a16d9d80a56 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1167,7 +1167,7 @@
ranges;
sai1: sai@30c10000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c10000 0x10000>;
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI1_IPG>, <&clk IMX8MP_CLK_DUMMY>,
@@ -1183,7 +1183,7 @@
};
sai2: sai@30c20000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c20000 0x10000>;
interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI2_IPG>, <&clk IMX8MP_CLK_DUMMY>,
@@ -1199,7 +1199,7 @@
};
sai3: sai@30c30000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c30000 0x10000>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI3_IPG>, <&clk IMX8MP_CLK_DUMMY>,
@@ -1215,7 +1215,7 @@
};
sai5: sai@30c50000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c50000 0x10000>;
interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI5_IPG>, <&clk IMX8MP_CLK_DUMMY>,
@@ -1231,7 +1231,7 @@
};
sai6: sai@30c60000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c60000 0x10000>;
interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI6_IPG>,
@@ -1248,7 +1248,7 @@
};
sai7: sai@30c80000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c80000 0x10000>;
interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI7_IPG>, <&clk IMX8MP_CLK_DUMMY>,
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index d9958a52e871..ec572612bb50 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -73,6 +73,17 @@ static struct fsl_sai_soc_data fsl_sai_imx7ulp = {
.constrain_period_size = false,
};
+static struct fsl_sai_soc_data fsl_sai_imx8mp = {
+ .imx = true,
+ .dataline = 0xff,
+ .fifos = 8,
+ .fifo_depth = 128,
+ .flags = 0,
+ .reg_offset = 8,
+ .constrain_period_size = false,
+ .mclk_gated_by_bce = true,
+};
+
static struct fsl_sai_soc_data fsl_sai_imx8mq = {
.imx = true,
.dataline = 0xff,
@@ -782,6 +793,18 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
FSL_SAI_CR5_FBT_MASK, val_cr5);
regmap_write(sai->regmap, FSL_SAI_xMR(tx),
~0UL - ((1 << min(channels, slots)) - 1));
+
+ /*
+ * Some audio codecs need the MCLK during setup of the codec, however
+ * for the i.MX 8M Plus it is gated with the receiver/transmiter BCE
+ * bit. So enable the bit already here.
+ */
+ if (sai->soc->mclk_gated_by_bce) {
+ /* Switch on MCLK early */
+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
+ FSL_SAI_CSR_BCE, FSL_SAI_CSR_BCE);
+ }
+
return 0;
}
@@ -1270,6 +1293,7 @@ static const struct of_device_id fsl_sai_ids[] = {
{ .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,imx8mp-sai", .data = &fsl_sai_imx8mp },
{ .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq },
{ .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm },
{ /* sentinel */ }
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index 8476cfffaa25..54e491182db8 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -89,6 +89,7 @@
/* SAI Transmit/Receive Control Register */
#define FSL_SAI_CSR_TERE BIT(31)
#define FSL_SAI_CSR_SE BIT(30)
+#define FSL_SAI_CSR_BCE BIT(28)
#define FSL_SAI_CSR_FR BIT(25)
#define FSL_SAI_CSR_SR BIT(24)
#define FSL_SAI_CSR_xF_SHIFT 16
@@ -225,6 +226,8 @@ struct fsl_sai_soc_data {
bool imx;
/* True for EDMA because it needs period size multiple of maxburst */
bool constrain_period_size;
+ /* Set to true if the MCLK to the output pin is gated with bce */
+ bool mclk_gated_by_bce;
};
struct fsl_sai_verid {