diff mbox series

[7/7] ASoC: soc-pcm: Merge CPU/Codec at soc_pcm_pointer()

Message ID 87o8t3vgur.wl-kuninori.morimoto.gx@renesas.com (mailing list archive)
State New, archived
Headers show
Series ASoC: Merge CPU/Codec DAIs | expand

Commit Message

Kuninori Morimoto March 11, 2020, 1:07 a.m. UTC
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

soc_pcm_pointer() is getting eash DAI's delay via snd_soc_dai_delay(),
but, it is adding CPU delay and Codec delay.
We need is not "added delay", but "max delay" of CPU/Codec.
This patch finds maximum delay from CPU/Codec.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/soc-pcm.c | 27 +++++++--------------------
 1 file changed, 7 insertions(+), 20 deletions(-)

Comments

Pierre-Louis Bossart March 11, 2020, 2 a.m. UTC | #1
On 3/10/20 8:07 PM, Kuninori Morimoto wrote:
> 
> From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> 
> soc_pcm_pointer() is getting eash DAI's delay via snd_soc_dai_delay(),
> but, it is adding CPU delay and Codec delay.
> We need is not "added delay", but "max delay" of CPU/Codec.
> This patch finds maximum delay from CPU/Codec.

The max() used between all cpu or codec dais for the same dailink is 
largely defensive programming, in practice it's not clear to me if we 
have different delays reported by differents codec or cpu_dais. I would 
expect all cpu dais in the same dailink to report the same delay, and 
likewise all codecs dais in the same dailink should provide the same value.

Now doing a max between cpu and codec dais does not seem right to me. 
You may have a delay in a DSP and a delay in a codec, and worst case the 
delay is the total of the two. It wouldn't matter too much with a 
'simple' codec with limited buffering, but the moment the codec itself 
has a DSP and internal buffering this change in accounting would 
introduce a real offset.


> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> ---
>   sound/soc/soc-pcm.c | 27 +++++++--------------------
>   1 file changed, 7 insertions(+), 20 deletions(-)
> 
> diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
> index c0f318699fe4..675de7c0eaa4 100644
> --- a/sound/soc/soc-pcm.c
> +++ b/sound/soc/soc-pcm.c
> @@ -1274,13 +1274,10 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
>   static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
>   {
>   	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> -	struct snd_soc_dai *cpu_dai;
> -	struct snd_soc_dai *codec_dai;
> +	struct snd_soc_dai *dai;
>   	struct snd_pcm_runtime *runtime = substream->runtime;
>   	snd_pcm_uframes_t offset = 0;
> -	snd_pcm_sframes_t delay = 0;
> -	snd_pcm_sframes_t codec_delay = 0;
> -	snd_pcm_sframes_t cpu_delay = 0;
> +	snd_pcm_sframes_t add_delay = 0;
>   	int i;
>   
>   	/* clearing the previous total delay */
> @@ -1288,22 +1285,12 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
>   
>   	offset = snd_soc_pcm_component_pointer(substream);
>   
> -	/* base delay if assigned in pointer callback */
> -	delay = runtime->delay;
> -
> -	for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
> -		cpu_delay = max(cpu_delay,
> -				snd_soc_dai_delay(cpu_dai, substream));
> -	}
> -	delay += cpu_delay;
> -
> -	for_each_rtd_codec_dais(rtd, i, codec_dai) {
> -		codec_delay = max(codec_delay,
> -				  snd_soc_dai_delay(codec_dai, substream));
> -	}
> -	delay += codec_delay;
> +	for_each_rtd_dais(rtd, i, dai)
> +		add_delay = max(add_delay,
> +				snd_soc_dai_delay(dai, substream));
>   
> -	runtime->delay = delay;
> +	/* base delay if assigned in pointer callback */
> +	runtime->delay += add_delay;
>   
>   	return offset;
>   }
>
Kuninori Morimoto March 11, 2020, 2:39 a.m. UTC | #2
Hi Pierre-Louis

Thank you for your review

> The max() used between all cpu or codec dais for the same dailink is
> largely defensive programming, in practice it's not clear to me if we
> have different delays reported by differents codec or cpu_dais. I
> would expect all cpu dais in the same dailink to report the same
> delay, and likewise all codecs dais in the same dailink should provide
> the same value.
> 
> Now doing a max between cpu and codec dais does not seem right to
> me. You may have a delay in a DSP and a delay in a codec, and worst
> case the delay is the total of the two. It wouldn't matter too much
> with a 'simple' codec with limited buffering, but the moment the codec
> itself has a DSP and internal buffering this change in accounting
> would introduce a real offset.
(snip)
> > -	for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
> > -		cpu_delay = max(cpu_delay,
> > -				snd_soc_dai_delay(cpu_dai, substream));
> > -	}
> > -	delay += cpu_delay;
> > -
> > -	for_each_rtd_codec_dais(rtd, i, codec_dai) {
> > -		codec_delay = max(codec_delay,
> > -				  snd_soc_dai_delay(codec_dai, substream));
> > -	}
> > -	delay += codec_delay;
> > +	for_each_rtd_dais(rtd, i, dai)
> > +		add_delay = max(add_delay,
> > +				snd_soc_dai_delay(dai, substream));
> >   -	runtime->delay = delay;
> > +	/* base delay if assigned in pointer callback */
> > +	runtime->delay += add_delay;
> >     	return offset;

Hmm.. ? Indeed...
Why I merged these ??
Thank you for pointing it. This patch is indeed wrong.
Will remove it in v2.

Thank you for your help !!

Best regards
---
Kuninori Morimoto
diff mbox series

Patch

diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index c0f318699fe4..675de7c0eaa4 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1274,13 +1274,10 @@  static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
 static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai;
-	struct snd_soc_dai *codec_dai;
+	struct snd_soc_dai *dai;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t offset = 0;
-	snd_pcm_sframes_t delay = 0;
-	snd_pcm_sframes_t codec_delay = 0;
-	snd_pcm_sframes_t cpu_delay = 0;
+	snd_pcm_sframes_t add_delay = 0;
 	int i;
 
 	/* clearing the previous total delay */
@@ -1288,22 +1285,12 @@  static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
 
 	offset = snd_soc_pcm_component_pointer(substream);
 
-	/* base delay if assigned in pointer callback */
-	delay = runtime->delay;
-
-	for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
-		cpu_delay = max(cpu_delay,
-				snd_soc_dai_delay(cpu_dai, substream));
-	}
-	delay += cpu_delay;
-
-	for_each_rtd_codec_dais(rtd, i, codec_dai) {
-		codec_delay = max(codec_delay,
-				  snd_soc_dai_delay(codec_dai, substream));
-	}
-	delay += codec_delay;
+	for_each_rtd_dais(rtd, i, dai)
+		add_delay = max(add_delay,
+				snd_soc_dai_delay(dai, substream));
 
-	runtime->delay = delay;
+	/* base delay if assigned in pointer callback */
+	runtime->delay += add_delay;
 
 	return offset;
 }