linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] ASoC: fsl_sai: Fix some issues in fsl_sai_trigger()
@ 2014-07-23 11:23 Nicolin Chen
  2014-07-23 11:23 ` [PATCH 1/3] ASoC: fsl_sai: Reduce race condition during TE/RE enabling Nicolin Chen
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Nicolin Chen @ 2014-07-23 11:23 UTC (permalink / raw)
  To: broonie
  Cc: linux-kernel, linuxppc-dev, alsa-devel, timur, Li.Xiubo, b42378, b02247

The series of patches focus on issue fix inside fsl_sai_trigger().

Nicolin Chen (3):
  ASoC: fsl_sai: Reduce race condition during TE/RE enabling
  ASoC: fsl_sai: Don't reset FIFO until TE/RE bit is unset
  ASoC: fsl_sai: Improve enable flow in fsl_sai_trigger()

 sound/soc/fsl/fsl_sai.c | 40 +++++++++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 17 deletions(-)

-- 
1.8.4


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] ASoC: fsl_sai: Reduce race condition during TE/RE enabling
  2014-07-23 11:23 [PATCH 0/3] ASoC: fsl_sai: Fix some issues in fsl_sai_trigger() Nicolin Chen
@ 2014-07-23 11:23 ` Nicolin Chen
  2014-07-23 11:23 ` [PATCH 2/3] ASoC: fsl_sai: Don't reset FIFO until TE/RE bit is unset Nicolin Chen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Nicolin Chen @ 2014-07-23 11:23 UTC (permalink / raw)
  To: broonie
  Cc: linux-kernel, linuxppc-dev, alsa-devel, timur, Li.Xiubo, b42378, b02247

From: Nicolin Chen <Guangyu.Chen@freescale.com>

For trigger start, we don't need to check if it's the first time to
enable TE/RE or second time. It doesn't hurt to enable them any way,
which in the meantime can reduce race condition for TE/RE enabling.

For trigger stop, we will definitely clear FRDE of current direction.
Thus the driver only needs to read the opposite one's.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
 sound/soc/fsl/fsl_sai.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 1b6ee2c..a437899 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -327,7 +327,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 {
 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
 	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-	u32 tcsr, rcsr;
+	u32 xcsr;
 
 	/*
 	 * The transmitter bit clock and frame sync are to be
@@ -338,9 +338,6 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 	regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
 			   FSL_SAI_CR2_SYNC);
 
-	regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr);
-	regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr);
-
 	/*
 	 * It is recommended that the transmitter is the last enabled
 	 * and the first disabled.
@@ -349,12 +346,10 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) {
-			regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
-					   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
-			regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
-					   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
-		}
+		regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
+				   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
+		regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
+				   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
 
 		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
 				   FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
@@ -370,7 +365,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 				   FSL_SAI_CSR_xIE_MASK, 0);
 
 		/* Check if the opposite FRDE is also disabled */
-		if (!(tx ? rcsr & FSL_SAI_CSR_FRDE : tcsr & FSL_SAI_CSR_FRDE)) {
+		regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr);
+		if (!(xcsr & FSL_SAI_CSR_FRDE)) {
 			/* Disable both directions and reset their FIFOs */
 			regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
 					   FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR,
-- 
1.8.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] ASoC: fsl_sai: Don't reset FIFO until TE/RE bit is unset
  2014-07-23 11:23 [PATCH 0/3] ASoC: fsl_sai: Fix some issues in fsl_sai_trigger() Nicolin Chen
  2014-07-23 11:23 ` [PATCH 1/3] ASoC: fsl_sai: Reduce race condition during TE/RE enabling Nicolin Chen
@ 2014-07-23 11:23 ` Nicolin Chen
  2014-07-23 11:23 ` [PATCH 3/3] ASoC: fsl_sai: Improve enable flow in fsl_sai_trigger() Nicolin Chen
  2014-07-25 17:52 ` [PATCH 0/3] ASoC: fsl_sai: Fix some issues " Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: Nicolin Chen @ 2014-07-23 11:23 UTC (permalink / raw)
  To: broonie
  Cc: linux-kernel, linuxppc-dev, alsa-devel, timur, Li.Xiubo, b42378, b02247

From: Nicolin Chen <Guangyu.Chen@freescale.com>

TE/RE bit of T/RCSR will remain set untill the current frame is physically
finished. The FIFO reset operation should wait this bit's totally cleared
rather than ignoring its status which might cause TE/RE disabling failed.

This patch adds delay and timeout to wait for its completion before FIFO
reset.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
 sound/soc/fsl/fsl_sai.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index a437899..a79a9b0 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -327,7 +327,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 {
 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
 	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-	u32 xcsr;
+	u32 xcsr, count = 100;
 
 	/*
 	 * The transmitter bit clock and frame sync are to be
@@ -369,11 +369,20 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 		if (!(xcsr & FSL_SAI_CSR_FRDE)) {
 			/* Disable both directions and reset their FIFOs */
 			regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
-					   FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR,
-					   FSL_SAI_CSR_FR);
+					   FSL_SAI_CSR_TERE, 0);
 			regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
-					   FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR,
-					   FSL_SAI_CSR_FR);
+					   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);
+			} while (--count && xcsr & FSL_SAI_CSR_TERE);
+
+			regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
+					   FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
+			regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
+					   FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
 		}
 		break;
 	default:
-- 
1.8.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] ASoC: fsl_sai: Improve enable flow in fsl_sai_trigger()
  2014-07-23 11:23 [PATCH 0/3] ASoC: fsl_sai: Fix some issues in fsl_sai_trigger() Nicolin Chen
  2014-07-23 11:23 ` [PATCH 1/3] ASoC: fsl_sai: Reduce race condition during TE/RE enabling Nicolin Chen
  2014-07-23 11:23 ` [PATCH 2/3] ASoC: fsl_sai: Don't reset FIFO until TE/RE bit is unset Nicolin Chen
@ 2014-07-23 11:23 ` Nicolin Chen
  2014-07-25 17:52 ` [PATCH 0/3] ASoC: fsl_sai: Fix some issues " Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: Nicolin Chen @ 2014-07-23 11:23 UTC (permalink / raw)
  To: broonie
  Cc: linux-kernel, linuxppc-dev, alsa-devel, timur, Li.Xiubo, b42378, b02247

From: Nicolin Chen <Guangyu.Chen@freescale.com>

The previous enable flow:
1, Enable TE&RE (SAI starts to consume tx FIFO and feed rx FIFO)
2, Mask IRQ of Tx/Rx to enable its interrupt.
3, Enable DMA request of Tx/Rx.

As this flow would enable DMA request later than TERE, the Tx FIFO
would be easily emptied into underrun while Rx FIFO would be easily
stuffed into overrun due to the delayed DMA transfering.

This issue happened merely occational before the patch 'ASoC: fsl_sai:
Reset FIFOs after disabling TE/RE' because there were useless data
remaining in the FIFO for the gap. However, it manifested after FIFO
reset's implemented.

After this patch, the new flow:
1, Enable DMA request of Tx/Rx.
2, Enable TE&RE (SAI starts to consume tx FIFO and feed rx FIFO)
3, Mask IRQ of Tx/Rx to enable its interrupt.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
 sound/soc/fsl/fsl_sai.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index a79a9b0..364410b 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -346,6 +346,9 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
+				   FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
+
 		regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
 				   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
 		regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
@@ -353,8 +356,6 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 
 		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
 				   FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
-		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
-				   FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
-- 
1.8.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] ASoC: fsl_sai: Fix some issues in fsl_sai_trigger()
  2014-07-23 11:23 [PATCH 0/3] ASoC: fsl_sai: Fix some issues in fsl_sai_trigger() Nicolin Chen
                   ` (2 preceding siblings ...)
  2014-07-23 11:23 ` [PATCH 3/3] ASoC: fsl_sai: Improve enable flow in fsl_sai_trigger() Nicolin Chen
@ 2014-07-25 17:52 ` Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2014-07-25 17:52 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: linux-kernel, linuxppc-dev, alsa-devel, timur, Li.Xiubo, b42378, b02247

[-- Attachment #1: Type: text/plain, Size: 153 bytes --]

On Wed, Jul 23, 2014 at 07:23:37PM +0800, Nicolin Chen wrote:
> The series of patches focus on issue fix inside fsl_sai_trigger().

Applied all, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-07-25 17:53 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-23 11:23 [PATCH 0/3] ASoC: fsl_sai: Fix some issues in fsl_sai_trigger() Nicolin Chen
2014-07-23 11:23 ` [PATCH 1/3] ASoC: fsl_sai: Reduce race condition during TE/RE enabling Nicolin Chen
2014-07-23 11:23 ` [PATCH 2/3] ASoC: fsl_sai: Don't reset FIFO until TE/RE bit is unset Nicolin Chen
2014-07-23 11:23 ` [PATCH 3/3] ASoC: fsl_sai: Improve enable flow in fsl_sai_trigger() Nicolin Chen
2014-07-25 17:52 ` [PATCH 0/3] ASoC: fsl_sai: Fix some issues " Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).