Message ID | 20241113133540.2005850-19-claudiu.beznea.uj@bp.renesas.com |
---|---|
State | New |
Headers | show |
Series | Add audio support for the Renesas RZ/G3S SoC | expand |
On Wed, Nov 13, 2024 at 2:36 PM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > The code initially issued software reset on SNDRV_PCM_TRIGGER_START > action only before starting the first stream. This can be easily moved to > hw_params() as the action is similar to setting the clocks. Moreover, > according to the hardware manual (Table 35.7 Bits Initialized by Software > Reset of the SSIFCR.SSIRST Bit) the software reset action acts also on the > clock dividers bits. Due to this issue the software reset in hw_params() > before configuring the clock dividers. This also simplifies the code in > trigger API. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > --- a/sound/soc/renesas/rz-ssi.c > +++ b/sound/soc/renesas/rz-ssi.c > @@ -388,6 +388,15 @@ static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) > return 0; > } > > +static int rz_ssi_swreset(struct rz_ssi_priv *ssi) > +{ > + u32 tmp; > + > + rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, SSIFCR_SSIRST); Nit: no need to clear SSIFCR_SSIRST first: rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_SSIRST); cfr. what the original code did below. > + rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0); > + return readl_poll_timeout_atomic(ssi->base + SSIFCR, tmp, !(tmp & SSIFCR_SSIRST), 1, 5); > +} > + > static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) > { > strm->running = 0; > @@ -782,14 +791,6 @@ static int rz_ssi_dai_trigger(struct snd_pcm_substream *substream, int cmd, > > switch (cmd) { > case SNDRV_PCM_TRIGGER_START: > - /* Soft Reset */ > - if (!rz_ssi_is_stream_running(&ssi->playback) && > - !rz_ssi_is_stream_running(&ssi->capture)) { > - rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_SSIRST); > - rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0); > - udelay(5); > - } > - > rz_ssi_stream_init(strm, substream); > > if (ssi->dma_rt) { Gr{oetje,eeting}s, Geert
diff --git a/sound/soc/renesas/rz-ssi.c b/sound/soc/renesas/rz-ssi.c index d0e2665ec830..10dd973a1c85 100644 --- a/sound/soc/renesas/rz-ssi.c +++ b/sound/soc/renesas/rz-ssi.c @@ -388,6 +388,15 @@ static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) return 0; } +static int rz_ssi_swreset(struct rz_ssi_priv *ssi) +{ + u32 tmp; + + rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, SSIFCR_SSIRST); + rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0); + return readl_poll_timeout_atomic(ssi->base + SSIFCR, tmp, !(tmp & SSIFCR_SSIRST), 1, 5); +} + static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) { strm->running = 0; @@ -782,14 +791,6 @@ static int rz_ssi_dai_trigger(struct snd_pcm_substream *substream, int cmd, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - /* Soft Reset */ - if (!rz_ssi_is_stream_running(&ssi->playback) && - !rz_ssi_is_stream_running(&ssi->capture)) { - rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_SSIRST); - rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0); - udelay(5); - } - rz_ssi_stream_init(strm, substream); if (ssi->dma_rt) { @@ -914,6 +915,7 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min; unsigned int channels = params_channels(params); unsigned int rate = params_rate(params); + int ret; if (sample_bits != 16) { dev_err(ssi->dev, "Unsupported sample width: %d\n", @@ -940,6 +942,10 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream, rz_ssi_cache_hw_params(ssi, rate, channels, strm->sample_width, sample_bits); + ret = rz_ssi_swreset(ssi); + if (ret) + return ret; + return rz_ssi_clk_setup(ssi, rate, channels); }