diff mbox

[V3,1/3] ASoC: fsl_esai: spba clock is needed by esai device

Message ID 37808c01df126622c41c2d413fddf838dc2aa71d.1448348336.git.shengjiu.wang@freescale.com (mailing list archive)
State Superseded
Delegated to: Scott Wood
Headers show

Commit Message

Shengjiu Wang Nov. 24, 2015, 7:03 a.m. UTC
ESAI need to enable the spba clock, when sdma is using share peripheral
script. In this case, there is two spba master port is used, if don't
enable the clock, the spba bus will have arbitration issue, which may
cause read/write wrong data from/to ESAI registers.

Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
---
 Documentation/devicetree/bindings/sound/fsl,esai.txt |  5 +++++
 sound/soc/fsl/fsl_esai.c                             | 13 +++++++++++++
 2 files changed, 18 insertions(+)

Comments

Nicolin Chen Nov. 24, 2015, 8:33 a.m. UTC | #1
On Tue, Nov 24, 2015 at 03:03:28PM +0800, Shengjiu Wang wrote:

> @@ -469,6 +471,9 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
>  	ret = clk_prepare_enable(esai_priv->coreclk);
>  	if (ret)
>  		return ret;
> +	ret = clk_prepare_enable(esai_priv->spbaclk);
> +	if (ret)
> +		goto err_spbaclk;
>  	if (!IS_ERR(esai_priv->extalclk)) {
>  		ret = clk_prepare_enable(esai_priv->extalclk);
>  		if (ret)

Just like for extalclk there is a IS_ERR check out there, there
should be one for spbaclk as well. Otherwise....

root@imx6qdlsolo:~# aplay /unit_tests/audio8k16S.wav 
[   29.956250] Unable to handle kernel paging request at virtual address fffffffe
[   29.963491] pgd = edd98000
[   29.966278] [fffffffe] *pgd=afffd861, *pte=00000000, *ppte=00000000
[   29.972615] Internal error: Oops: 37 [#1] SMP ARM
[   29.977327] Modules linked in:
[   29.980410] CPU: 0 PID: 755 Comm: aplay Not tainted 4.4.0-rc1-12414-gcc8db17 #250
[   29.987899] Hardware name: Freescale i.MX6 SoloX (Device Tree)
[   29.993738] task: edece780 ti: ed26a000 task.ti: ed26a000
[   29.999156] PC is at clk_prepare+0x18/0x38
[   30.003268] LR is at mark_held_locks+0x70/0x98
[   30.007720] pc : [<c0568714>]    lr : [<c006f42c>]    psr: 600f0013
[   30.007720] sp : ed26bc60  ip : 00000003  fp : ed26bc74
[   30.019204] r10: eebe4d9c  r9 : eeb2e00c  r8 : eeb2e00c
[   30.024435] r7 : fffffffe  r6 : eeb2c500  r5 : eeb2d0c0  r4 : fffffffe
[   30.030966] r3 : edece780  r2 : 00000001  r1 : 00000001  r0 : 00000001
[   30.037502] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   30.044643] Control: 10c5387d  Table: add9804a  DAC: 00000051
[   30.050395] Process aplay (pid: 755, stack limit = 0xed26a210)
Shengjiu Wang Nov. 24, 2015, 9:02 a.m. UTC | #2
On Tue, Nov 24, 2015 at 12:33:45AM -0800, Nicolin Chen wrote:
> On Tue, Nov 24, 2015 at 03:03:28PM +0800, Shengjiu Wang wrote:
> 
> > @@ -469,6 +471,9 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
> >  	ret = clk_prepare_enable(esai_priv->coreclk);
> >  	if (ret)
> >  		return ret;
> > +	ret = clk_prepare_enable(esai_priv->spbaclk);
> > +	if (ret)
> > +		goto err_spbaclk;
> >  	if (!IS_ERR(esai_priv->extalclk)) {
> >  		ret = clk_prepare_enable(esai_priv->extalclk);
> >  		if (ret)
> 
> Just like for extalclk there is a IS_ERR check out there, there
> should be one for spbaclk as well. Otherwise....
> 
> root@imx6qdlsolo:~# aplay /unit_tests/audio8k16S.wav 
> [   29.956250] Unable to handle kernel paging request at virtual address fffffffe
> [   29.963491] pgd = edd98000
> [   29.966278] [fffffffe] *pgd=afffd861, *pte=00000000, *ppte=00000000
> [   29.972615] Internal error: Oops: 37 [#1] SMP ARM
> [   29.977327] Modules linked in:
> [   29.980410] CPU: 0 PID: 755 Comm: aplay Not tainted 4.4.0-rc1-12414-gcc8db17 #250
> [   29.987899] Hardware name: Freescale i.MX6 SoloX (Device Tree)
> [   29.993738] task: edece780 ti: ed26a000 task.ti: ed26a000
> [   29.999156] PC is at clk_prepare+0x18/0x38
> [   30.003268] LR is at mark_held_locks+0x70/0x98
> [   30.007720] pc : [<c0568714>]    lr : [<c006f42c>]    psr: 600f0013
> [   30.007720] sp : ed26bc60  ip : 00000003  fp : ed26bc74
> [   30.019204] r10: eebe4d9c  r9 : eeb2e00c  r8 : eeb2e00c
> [   30.024435] r7 : fffffffe  r6 : eeb2c500  r5 : eeb2d0c0  r4 : fffffffe
> [   30.030966] r3 : edece780  r2 : 00000001  r1 : 00000001  r0 : 00000001
> [   30.037502] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
> [   30.044643] Control: 10c5387d  Table: add9804a  DAC: 00000051
> [   30.050395] Process aplay (pid: 755, stack limit = 0xed26a210)
>

Will fix it in next version, and send it out later.

best regards
wang shengjiu
Rob Herring (Arm) Nov. 24, 2015, 11:21 p.m. UTC | #3
On Tue, Nov 24, 2015 at 03:03:28PM +0800, Shengjiu Wang wrote:
> ESAI need to enable the spba clock, when sdma is using share peripheral
> script. In this case, there is two spba master port is used, if don't
> enable the clock, the spba bus will have arbitration issue, which may
> cause read/write wrong data from/to ESAI registers.
> 
> Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
> ---
>  Documentation/devicetree/bindings/sound/fsl,esai.txt |  5 +++++

Acked-by: Rob Herring <robh@kernel.org>

>  sound/soc/fsl/fsl_esai.c                             | 13 +++++++++++++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt
> index d3b6b5f..cd3ee5d 100644
> --- a/Documentation/devicetree/bindings/sound/fsl,esai.txt
> +++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt
> @@ -27,6 +27,11 @@ Required properties:
>  			  derive HCK, SCK and FS.
>  	"fsys"		  The system clock derived from ahb clock used to
>  			  derive HCK, SCK and FS.
> +	"spba"		  The spba clock is required when ESAI is placed as a
> +			  bus slave of the Shared Peripheral Bus and when two
> +			  or more bus masters (CPU, DMA or DSP) try to access
> +			  it. This property is optional depending on the SoC
> +			  design.
>  
>    - fsl,fifo-depth	: The number of elements in the transmit and receive
>  			  FIFOs. This number is the maximum allowed value for
> diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
> index 504e731..4d7589c 100644
> --- a/sound/soc/fsl/fsl_esai.c
> +++ b/sound/soc/fsl/fsl_esai.c
> @@ -35,6 +35,7 @@
>   * @coreclk: clock source to access register
>   * @extalclk: esai clock source to derive HCK, SCK and FS
>   * @fsysclk: system clock source to derive HCK, SCK and FS
> + * @spbaclk: SPBA clock (optional, depending on SoC design)
>   * @fifo_depth: depth of tx/rx FIFO
>   * @slot_width: width of each DAI slot
>   * @slots: number of slots
> @@ -54,6 +55,7 @@ struct fsl_esai {
>  	struct clk *coreclk;
>  	struct clk *extalclk;
>  	struct clk *fsysclk;
> +	struct clk *spbaclk;
>  	u32 fifo_depth;
>  	u32 slot_width;
>  	u32 slots;
> @@ -469,6 +471,9 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
>  	ret = clk_prepare_enable(esai_priv->coreclk);
>  	if (ret)
>  		return ret;
> +	ret = clk_prepare_enable(esai_priv->spbaclk);
> +	if (ret)
> +		goto err_spbaclk;
>  	if (!IS_ERR(esai_priv->extalclk)) {
>  		ret = clk_prepare_enable(esai_priv->extalclk);
>  		if (ret)
> @@ -499,6 +504,8 @@ err_fsysclk:
>  	if (!IS_ERR(esai_priv->extalclk))
>  		clk_disable_unprepare(esai_priv->extalclk);
>  err_extalck:
> +	clk_disable_unprepare(esai_priv->spbaclk);
> +err_spbaclk:
>  	clk_disable_unprepare(esai_priv->coreclk);
>  
>  	return ret;
> @@ -564,6 +571,7 @@ static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
>  		clk_disable_unprepare(esai_priv->fsysclk);
>  	if (!IS_ERR(esai_priv->extalclk))
>  		clk_disable_unprepare(esai_priv->extalclk);
> +	clk_disable_unprepare(esai_priv->spbaclk);
>  	clk_disable_unprepare(esai_priv->coreclk);
>  }
>  
> @@ -819,6 +827,11 @@ static int fsl_esai_probe(struct platform_device *pdev)
>  		dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
>  				PTR_ERR(esai_priv->fsysclk));
>  
> +	esai_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
> +	if (IS_ERR(esai_priv->spbaclk))
> +		dev_warn(&pdev->dev, "failed to get spba clock: %ld\n",
> +				PTR_ERR(esai_priv->spbaclk));
> +
>  	irq = platform_get_irq(pdev, 0);
>  	if (irq < 0) {
>  		dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
> -- 
> 1.9.1
>
Shengjiu Wang Nov. 25, 2015, 2:02 a.m. UTC | #4
On Tue, Nov 24, 2015 at 05:21:30PM -0600, Rob Herring wrote:
> On Tue, Nov 24, 2015 at 03:03:28PM +0800, Shengjiu Wang wrote:
> > ESAI need to enable the spba clock, when sdma is using share peripheral
> > script. In this case, there is two spba master port is used, if don't
> > enable the clock, the spba bus will have arbitration issue, which may
> > cause read/write wrong data from/to ESAI registers.
> > 
> > Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
> > ---
> >  Documentation/devicetree/bindings/sound/fsl,esai.txt |  5 +++++
> 
> Acked-by: Rob Herring <robh@kernel.org>

Hi Mark, Rob

   Just a reminder. There is V4 for this patch set. I think the "Acked-by:" is
for the V4. Thanks.

best regards
wang shengjiu

> 
> >  sound/soc/fsl/fsl_esai.c                             | 13 +++++++++++++
> >  2 files changed, 18 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt
> > index d3b6b5f..cd3ee5d 100644
> > --- a/Documentation/devicetree/bindings/sound/fsl,esai.txt
> > +++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt
> > @@ -27,6 +27,11 @@ Required properties:
> >  			  derive HCK, SCK and FS.
> >  	"fsys"		  The system clock derived from ahb clock used to
> >  			  derive HCK, SCK and FS.
> > +	"spba"		  The spba clock is required when ESAI is placed as a
> > +			  bus slave of the Shared Peripheral Bus and when two
> > +			  or more bus masters (CPU, DMA or DSP) try to access
> > +			  it. This property is optional depending on the SoC
> > +			  design.
> >  
> >    - fsl,fifo-depth	: The number of elements in the transmit and receive
> >  			  FIFOs. This number is the maximum allowed value for
> > diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
> > index 504e731..4d7589c 100644
> > --- a/sound/soc/fsl/fsl_esai.c
> > +++ b/sound/soc/fsl/fsl_esai.c
> > @@ -35,6 +35,7 @@
> >   * @coreclk: clock source to access register
> >   * @extalclk: esai clock source to derive HCK, SCK and FS
> >   * @fsysclk: system clock source to derive HCK, SCK and FS
> > + * @spbaclk: SPBA clock (optional, depending on SoC design)
> >   * @fifo_depth: depth of tx/rx FIFO
> >   * @slot_width: width of each DAI slot
> >   * @slots: number of slots
> > @@ -54,6 +55,7 @@ struct fsl_esai {
> >  	struct clk *coreclk;
> >  	struct clk *extalclk;
> >  	struct clk *fsysclk;
> > +	struct clk *spbaclk;
> >  	u32 fifo_depth;
> >  	u32 slot_width;
> >  	u32 slots;
> > @@ -469,6 +471,9 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
> >  	ret = clk_prepare_enable(esai_priv->coreclk);
> >  	if (ret)
> >  		return ret;
> > +	ret = clk_prepare_enable(esai_priv->spbaclk);
> > +	if (ret)
> > +		goto err_spbaclk;
> >  	if (!IS_ERR(esai_priv->extalclk)) {
> >  		ret = clk_prepare_enable(esai_priv->extalclk);
> >  		if (ret)
> > @@ -499,6 +504,8 @@ err_fsysclk:
> >  	if (!IS_ERR(esai_priv->extalclk))
> >  		clk_disable_unprepare(esai_priv->extalclk);
> >  err_extalck:
> > +	clk_disable_unprepare(esai_priv->spbaclk);
> > +err_spbaclk:
> >  	clk_disable_unprepare(esai_priv->coreclk);
> >  
> >  	return ret;
> > @@ -564,6 +571,7 @@ static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
> >  		clk_disable_unprepare(esai_priv->fsysclk);
> >  	if (!IS_ERR(esai_priv->extalclk))
> >  		clk_disable_unprepare(esai_priv->extalclk);
> > +	clk_disable_unprepare(esai_priv->spbaclk);
> >  	clk_disable_unprepare(esai_priv->coreclk);
> >  }
> >  
> > @@ -819,6 +827,11 @@ static int fsl_esai_probe(struct platform_device *pdev)
> >  		dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
> >  				PTR_ERR(esai_priv->fsysclk));
> >  
> > +	esai_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
> > +	if (IS_ERR(esai_priv->spbaclk))
> > +		dev_warn(&pdev->dev, "failed to get spba clock: %ld\n",
> > +				PTR_ERR(esai_priv->spbaclk));
> > +
> >  	irq = platform_get_irq(pdev, 0);
> >  	if (irq < 0) {
> >  		dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
> > -- 
> > 1.9.1
> >
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt
index d3b6b5f..cd3ee5d 100644
--- a/Documentation/devicetree/bindings/sound/fsl,esai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt
@@ -27,6 +27,11 @@  Required properties:
 			  derive HCK, SCK and FS.
 	"fsys"		  The system clock derived from ahb clock used to
 			  derive HCK, SCK and FS.
+	"spba"		  The spba clock is required when ESAI is placed as a
+			  bus slave of the Shared Peripheral Bus and when two
+			  or more bus masters (CPU, DMA or DSP) try to access
+			  it. This property is optional depending on the SoC
+			  design.
 
   - fsl,fifo-depth	: The number of elements in the transmit and receive
 			  FIFOs. This number is the maximum allowed value for
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 504e731..4d7589c 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -35,6 +35,7 @@ 
  * @coreclk: clock source to access register
  * @extalclk: esai clock source to derive HCK, SCK and FS
  * @fsysclk: system clock source to derive HCK, SCK and FS
+ * @spbaclk: SPBA clock (optional, depending on SoC design)
  * @fifo_depth: depth of tx/rx FIFO
  * @slot_width: width of each DAI slot
  * @slots: number of slots
@@ -54,6 +55,7 @@  struct fsl_esai {
 	struct clk *coreclk;
 	struct clk *extalclk;
 	struct clk *fsysclk;
+	struct clk *spbaclk;
 	u32 fifo_depth;
 	u32 slot_width;
 	u32 slots;
@@ -469,6 +471,9 @@  static int fsl_esai_startup(struct snd_pcm_substream *substream,
 	ret = clk_prepare_enable(esai_priv->coreclk);
 	if (ret)
 		return ret;
+	ret = clk_prepare_enable(esai_priv->spbaclk);
+	if (ret)
+		goto err_spbaclk;
 	if (!IS_ERR(esai_priv->extalclk)) {
 		ret = clk_prepare_enable(esai_priv->extalclk);
 		if (ret)
@@ -499,6 +504,8 @@  err_fsysclk:
 	if (!IS_ERR(esai_priv->extalclk))
 		clk_disable_unprepare(esai_priv->extalclk);
 err_extalck:
+	clk_disable_unprepare(esai_priv->spbaclk);
+err_spbaclk:
 	clk_disable_unprepare(esai_priv->coreclk);
 
 	return ret;
@@ -564,6 +571,7 @@  static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
 		clk_disable_unprepare(esai_priv->fsysclk);
 	if (!IS_ERR(esai_priv->extalclk))
 		clk_disable_unprepare(esai_priv->extalclk);
+	clk_disable_unprepare(esai_priv->spbaclk);
 	clk_disable_unprepare(esai_priv->coreclk);
 }
 
@@ -819,6 +827,11 @@  static int fsl_esai_probe(struct platform_device *pdev)
 		dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
 				PTR_ERR(esai_priv->fsysclk));
 
+	esai_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
+	if (IS_ERR(esai_priv->spbaclk))
+		dev_warn(&pdev->dev, "failed to get spba clock: %ld\n",
+				PTR_ERR(esai_priv->spbaclk));
+
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);