|
Jiri Slaby |
eeab2a |
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
|
|
Jiri Slaby |
eeab2a |
Date: Fri, 24 Feb 2023 16:33:01 +0100
|
|
Jiri Slaby |
eeab2a |
Subject: [PATCH] ASoC: apple: mca: Fix SERDES reset sequence
|
|
Jiri Slaby |
eeab2a |
MIME-Version: 1.0
|
|
Jiri Slaby |
eeab2a |
Content-Type: text/plain; charset=UTF-8
|
|
Jiri Slaby |
eeab2a |
Content-Transfer-Encoding: 8bit
|
|
Jiri Slaby |
eeab2a |
References: bsc#1012628
|
|
Jiri Slaby |
eeab2a |
Patch-mainline: 6.2.5
|
|
Jiri Slaby |
eeab2a |
Git-commit: d8b3e396088d787771f19fd3b7949e080dc31d6f
|
|
Jiri Slaby |
eeab2a |
|
|
Jiri Slaby |
eeab2a |
[ Upstream commit d8b3e396088d787771f19fd3b7949e080dc31d6f ]
|
|
Jiri Slaby |
eeab2a |
|
|
Jiri Slaby |
eeab2a |
Fix the reset sequence of reads and writes that we invoke from within
|
|
Jiri Slaby |
eeab2a |
the early trigger. It looks like there never was a SERDES_CONF_SOME_RST
|
|
Jiri Slaby |
eeab2a |
bit that should be involved in the reset sequence, and its presence in
|
|
Jiri Slaby |
eeab2a |
the driver code is a mistake from earlier.
|
|
Jiri Slaby |
eeab2a |
|
|
Jiri Slaby |
eeab2a |
Instead, the reset sequence should go as follows: We should switch the
|
|
Jiri Slaby |
eeab2a |
the SERDES unit's SYNC_SEL mux to the value of 7 (so outside the range
|
|
Jiri Slaby |
eeab2a |
of 1...6 representing cluster's SYNCGEN units), then raise the RST bit
|
|
Jiri Slaby |
eeab2a |
in SERDES_STATUS and wait for it to clear.
|
|
Jiri Slaby |
eeab2a |
|
|
Jiri Slaby |
eeab2a |
Properly resetting the SERDES unit fixes frame desynchronization hazard
|
|
Jiri Slaby |
eeab2a |
in case of long frames (longer than 4 used slots). The desynchronization
|
|
Jiri Slaby |
eeab2a |
manifests itself by rotating the PCM channels.
|
|
Jiri Slaby |
eeab2a |
|
|
Jiri Slaby |
eeab2a |
Fixes: 3df5d0d97289 ("ASoC: apple: mca: Start new platform driver")
|
|
Jiri Slaby |
eeab2a |
Signed-off-by: Martin PoviĊĦer <povik+lin@cutebit.org>
|
|
Jiri Slaby |
eeab2a |
Link: https://lore.kernel.org/r/20230224153302.45365-2-povik+lin@cutebit.org
|
|
Jiri Slaby |
eeab2a |
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Jiri Slaby |
eeab2a |
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
|
Jiri Slaby |
eeab2a |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Jiri Slaby |
eeab2a |
---
|
|
Jiri Slaby |
eeab2a |
sound/soc/apple/mca.c | 18 +++++++++++++-----
|
|
Jiri Slaby |
eeab2a |
1 file changed, 13 insertions(+), 5 deletions(-)
|
|
Jiri Slaby |
eeab2a |
|
|
Jiri Slaby |
eeab2a |
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
|
|
Jiri Slaby |
eeab2a |
index 9cceeb25..aea08c7b 100644
|
|
Jiri Slaby |
eeab2a |
--- a/sound/soc/apple/mca.c
|
|
Jiri Slaby |
eeab2a |
+++ b/sound/soc/apple/mca.c
|
|
Jiri Slaby |
eeab2a |
@@ -101,7 +101,6 @@
|
|
Jiri Slaby |
eeab2a |
#define SERDES_CONF_UNK3 BIT(14)
|
|
Jiri Slaby |
eeab2a |
#define SERDES_CONF_NO_DATA_FEEDBACK BIT(15)
|
|
Jiri Slaby |
eeab2a |
#define SERDES_CONF_SYNC_SEL GENMASK(18, 16)
|
|
Jiri Slaby |
eeab2a |
-#define SERDES_CONF_SOME_RST BIT(19)
|
|
Jiri Slaby |
eeab2a |
#define REG_TX_SERDES_BITSTART 0x08
|
|
Jiri Slaby |
eeab2a |
#define REG_RX_SERDES_BITSTART 0x0c
|
|
Jiri Slaby |
eeab2a |
#define REG_TX_SERDES_SLOTMASK 0x0c
|
|
Jiri Slaby |
eeab2a |
@@ -203,15 +202,24 @@ static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
|
|
Jiri Slaby |
eeab2a |
case SNDRV_PCM_TRIGGER_START:
|
|
Jiri Slaby |
eeab2a |
case SNDRV_PCM_TRIGGER_RESUME:
|
|
Jiri Slaby |
eeab2a |
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
|
Jiri Slaby |
eeab2a |
+ mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
|
|
Jiri Slaby |
eeab2a |
+ FIELD_PREP(SERDES_CONF_SYNC_SEL, 0));
|
|
Jiri Slaby |
eeab2a |
+ mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
|
|
Jiri Slaby |
eeab2a |
+ FIELD_PREP(SERDES_CONF_SYNC_SEL, 7));
|
|
Jiri Slaby |
eeab2a |
mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
|
|
Jiri Slaby |
eeab2a |
SERDES_STATUS_EN | SERDES_STATUS_RST,
|
|
Jiri Slaby |
eeab2a |
SERDES_STATUS_RST);
|
|
Jiri Slaby |
eeab2a |
- mca_modify(cl, serdes_conf, SERDES_CONF_SOME_RST,
|
|
Jiri Slaby |
eeab2a |
- SERDES_CONF_SOME_RST);
|
|
Jiri Slaby |
eeab2a |
- readl_relaxed(cl->base + serdes_conf);
|
|
Jiri Slaby |
eeab2a |
- mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
|
|
Jiri Slaby |
eeab2a |
+ /*
|
|
Jiri Slaby |
eeab2a |
+ * Experiments suggest that it takes at most ~1 us
|
|
Jiri Slaby |
eeab2a |
+ * for the bit to clear, so wait 2 us for good measure.
|
|
Jiri Slaby |
eeab2a |
+ */
|
|
Jiri Slaby |
eeab2a |
+ udelay(2);
|
|
Jiri Slaby |
eeab2a |
WARN_ON(readl_relaxed(cl->base + serdes_unit + REG_SERDES_STATUS) &
|
|
Jiri Slaby |
eeab2a |
SERDES_STATUS_RST);
|
|
Jiri Slaby |
eeab2a |
+ mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
|
|
Jiri Slaby |
eeab2a |
+ FIELD_PREP(SERDES_CONF_SYNC_SEL, 0));
|
|
Jiri Slaby |
eeab2a |
+ mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
|
|
Jiri Slaby |
eeab2a |
+ FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1));
|
|
Jiri Slaby |
eeab2a |
break;
|
|
Jiri Slaby |
eeab2a |
default:
|
|
Jiri Slaby |
eeab2a |
break;
|
|
Jiri Slaby |
eeab2a |
--
|
|
Jiri Slaby |
eeab2a |
2.35.3
|
|
Jiri Slaby |
eeab2a |
|