| From 2ccf181ab1dd4af6cffd9f7b1509b181e5aa3c73 Mon Sep 17 00:00:00 2001 |
| From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Date: Tue, 14 Mar 2017 09:34:49 +0900 |
| Subject: [PATCH 118/255] ASoC: rcar: clear DE bit only in PDMACHCR when it |
| stops |
| |
| R-Car datasheet indicates "Clear DE in PDMACHCR" for transfer stop, |
| but current code clears all bits in PDMACHCR. |
| Because of this, DE bit might never been cleared, |
| and it causes CMD overflow. This patch fixes this issue. |
| |
| Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com> |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| (cherry picked from commit 62a10498afb27370ec6018e9d802b74850fd8d9a) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| sound/soc/sh/rcar/dma.c | 18 ++++++++++++++++-- |
| 1 file changed, 16 insertions(+), 2 deletions(-) |
| |
| --- a/sound/soc/sh/rcar/dma.c |
| +++ b/sound/soc/sh/rcar/dma.c |
| @@ -454,6 +454,20 @@ static u32 rsnd_dmapp_read(struct rsnd_d |
| return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); |
| } |
| |
| +static void rsnd_dmapp_bset(struct rsnd_dma *dma, u32 data, u32 mask, u32 reg) |
| +{ |
| + struct rsnd_mod *mod = rsnd_mod_get(dma); |
| + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
| + struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); |
| + volatile void __iomem *addr = rsnd_dmapp_addr(dmac, dma, reg); |
| + u32 val = ioread32(addr); |
| + |
| + val &= ~mask; |
| + val |= (data & mask); |
| + |
| + iowrite32(val, addr); |
| +} |
| + |
| static int rsnd_dmapp_stop(struct rsnd_mod *mod, |
| struct rsnd_dai_stream *io, |
| struct rsnd_priv *priv) |
| @@ -461,10 +475,10 @@ static int rsnd_dmapp_stop(struct rsnd_m |
| struct rsnd_dma *dma = rsnd_mod_to_dma(mod); |
| int i; |
| |
| - rsnd_dmapp_write(dma, 0, PDMACHCR); |
| + rsnd_dmapp_bset(dma, 0, PDMACHCR_DE, PDMACHCR); |
| |
| for (i = 0; i < 1024; i++) { |
| - if (0 == rsnd_dmapp_read(dma, PDMACHCR)) |
| + if (0 == (rsnd_dmapp_read(dma, PDMACHCR) & PDMACHCR_DE)) |
| return 0; |
| udelay(1); |
| } |