From fa86218f9faee82bdc6771162ffe321259ef3e35 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Fri, 16 Jun 2023 11:01:55 +0800 Subject: [PATCH] ASoC: rockchip: i2s-tdm: Optimize TRCM-resume for QUIRKS_ALWAYS_ON On the QUIRKS_ALWAYS_ON path, we bring up the clk path on probe to achieve the clk always on function. for this situation, the refcount always true, so, we should save the stream dma state on pause and then do restore on resume. Signed-off-by: Sugar Zhang Change-Id: I8e45b78a475a468880ef2fb0b358dbdd1169ff08 --- sound/soc/rockchip/rockchip_i2s_tdm.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index ab3441d01205..9b9a34c6b312 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -101,6 +101,7 @@ struct rk_i2s_tdm_dev { bool mclk_calibrate; bool tdm_mode; bool tdm_fsync_half_frame; + bool is_dma_active[SNDRV_PCM_STREAM_LAST + 1]; unsigned int mclk_rx_freq; unsigned int mclk_tx_freq; unsigned int mclk_root0_freq; @@ -299,6 +300,18 @@ static inline bool is_stream_active(struct rk_i2s_tdm_dev *i2s_tdm, int stream) return (val & I2S_XFER_RXS_START); } +static inline bool is_dma_active(struct rk_i2s_tdm_dev *i2s_tdm, int stream) +{ + unsigned int val; + + regmap_read(i2s_tdm->regmap, I2S_DMACR, &val); + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + return (val & I2S_DMACR_TDE_MASK); + else + return (val & I2S_DMACR_RDE_MASK); +} + #ifdef HAVE_SYNC_RESET #if defined(CONFIG_ARM) && !defined(writeq) static inline void __raw_writeq(u64 val, volatile void __iomem *addr) @@ -683,6 +696,9 @@ static void rockchip_i2s_tdm_trcm_pause(struct snd_pcm_substream *substream, int stream = substream->stream; int bstream = SNDRV_PCM_STREAM_LAST - stream; + /* store the current state, prepare for resume if necessary */ + i2s_tdm->is_dma_active[bstream] = is_dma_active(i2s_tdm, bstream); + /* disable dma for both tx and rx */ rockchip_i2s_tdm_dma_ctrl(i2s_tdm, stream, 0); rockchip_i2s_tdm_dma_ctrl(i2s_tdm, bstream, 0); @@ -698,7 +714,8 @@ static void rockchip_i2s_tdm_trcm_resume(struct snd_pcm_substream *substream, * just resume bstream, because current stream will be * startup in the trigger-cmd-START */ - rockchip_i2s_tdm_dma_ctrl(i2s_tdm, bstream, 1); + if (i2s_tdm->is_dma_active[bstream]) + rockchip_i2s_tdm_dma_ctrl(i2s_tdm, bstream, 1); rockchip_i2s_tdm_xfer_start(i2s_tdm, bstream); }