From bab10ec9fd9dc1537b705d0dd3862dd5982b921f Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Wed, 17 Aug 2022 11:05:26 +0300 Subject: [PATCH 1/4] ASoC: SOF: compress: Remove byte offset computation Byte offset is the offset in the ring buffer to the DSP while posn_offset is an offset inside the stream_box where we keep position information. Reviewed-by: Paul Olaru Reviewed-by: Pierre-Louis Bossart Signed-off-by: Daniel Baluta Link: https://lore.kernel.org/r/20220817080529.10864-2-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown --- sound/soc/sof/compress.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index 67139e15f862..760d6a4a5253 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -237,7 +237,6 @@ static int sof_compr_set_params(struct snd_soc_component *component, goto out; } - tstamp->byte_offset = sdev->stream_box.offset + ipc_params_reply.posn_offset; tstamp->sampling_rate = params->codec.sample_rate; spcm->prepared[cstream->direction] = true; From e3091f0a3f563ad1c9b60c290752e1190b67ea97 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Wed, 17 Aug 2022 11:05:27 +0300 Subject: [PATCH 2/4] ASoC: SOF: compress: Introduce sof_compr_stream This will keep SOF compress stream private data. So far we used snd_compr_tstamp to hold the private data but this is no longer enough as we need to hold other info like number of channels or sample bytes. Reviewed-by: Paul Olaru Reviewed-by: Pierre-Louis Bossart Signed-off-by: Daniel Baluta Link: https://lore.kernel.org/r/20220817080529.10864-3-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown --- sound/soc/sof/compress.c | 40 ++++++++++++++++++++-------------------- sound/soc/sof/sof-priv.h | 5 +++++ 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index 760d6a4a5253..e990fa093bb5 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -11,20 +11,20 @@ #include "sof-priv.h" #include "sof-utils.h" -static void sof_set_transferred_bytes(struct snd_compr_tstamp *tstamp, +static void sof_set_transferred_bytes(struct sof_compr_stream *sstream, u64 host_pos, u64 buffer_size) { u64 prev_pos; unsigned int copied; - div64_u64_rem(tstamp->copied_total, buffer_size, &prev_pos); + div64_u64_rem(sstream->copied_total, buffer_size, &prev_pos); if (host_pos < prev_pos) copied = (buffer_size - prev_pos) + host_pos; else copied = host_pos - prev_pos; - tstamp->copied_total += copied; + sstream->copied_total += copied; } static void snd_sof_compr_fragment_elapsed_work(struct work_struct *work) @@ -49,7 +49,7 @@ void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream) struct snd_soc_pcm_runtime *rtd; struct snd_compr_runtime *crtd; struct snd_soc_component *component; - struct snd_compr_tstamp *tstamp; + struct sof_compr_stream *sstream; struct snd_sof_pcm *spcm; if (!cstream) @@ -57,7 +57,7 @@ void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream) rtd = cstream->private_data; crtd = cstream->runtime; - tstamp = crtd->private_data; + sstream = crtd->private_data; component = snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME); spcm = snd_sof_find_spcm_dai(component, rtd); @@ -67,7 +67,7 @@ void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream) return; } - sof_set_transferred_bytes(tstamp, spcm->stream[cstream->direction].posn.host_posn, + sof_set_transferred_bytes(sstream, spcm->stream[cstream->direction].posn.host_posn, crtd->buffer_size); /* use the same workqueue-based solution as for PCM, cf. snd_sof_pcm_elapsed */ @@ -96,24 +96,24 @@ static int sof_compr_open(struct snd_soc_component *component, { struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct snd_compr_runtime *crtd = cstream->runtime; - struct snd_compr_tstamp *tstamp; + struct sof_compr_stream *sstream; struct snd_sof_pcm *spcm; int dir; - tstamp = kzalloc(sizeof(*tstamp), GFP_KERNEL); - if (!tstamp) + sstream = kzalloc(sizeof(*sstream), GFP_KERNEL); + if (!sstream) return -ENOMEM; spcm = snd_sof_find_spcm_dai(component, rtd); if (!spcm) { - kfree(tstamp); + kfree(sstream); return -EINVAL; } dir = cstream->direction; if (spcm->stream[dir].cstream) { - kfree(tstamp); + kfree(sstream); return -EBUSY; } @@ -122,7 +122,7 @@ static int sof_compr_open(struct snd_soc_component *component, spcm->stream[dir].posn.dai_posn = 0; spcm->prepared[dir] = false; - crtd->private_data = tstamp; + crtd->private_data = sstream; return 0; } @@ -131,7 +131,7 @@ static int sof_compr_free(struct snd_soc_component *component, struct snd_compr_stream *cstream) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); - struct snd_compr_tstamp *tstamp = cstream->runtime->private_data; + struct sof_compr_stream *sstream = cstream->runtime->private_data; struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct sof_ipc_stream stream; struct sof_ipc_reply reply; @@ -155,7 +155,7 @@ static int sof_compr_free(struct snd_soc_component *component, cancel_work_sync(&spcm->stream[cstream->direction].period_elapsed_work); spcm->stream[cstream->direction].cstream = NULL; - kfree(tstamp); + kfree(sstream); return ret; } @@ -169,7 +169,7 @@ static int sof_compr_set_params(struct snd_soc_component *component, struct sof_ipc_pcm_params_reply ipc_params_reply; struct sof_ipc_fw_ready *ready = &sdev->fw_ready; struct sof_ipc_fw_version *v = &ready->version; - struct snd_compr_tstamp *tstamp; + struct sof_compr_stream *sstream; struct sof_ipc_pcm_params *pcm; struct snd_sof_pcm *spcm; size_t ext_data_size; @@ -184,7 +184,7 @@ static int sof_compr_set_params(struct snd_soc_component *component, return -EINVAL; } - tstamp = crtd->private_data; + sstream = crtd->private_data; spcm = snd_sof_find_spcm_dai(component, rtd); @@ -237,7 +237,7 @@ static int sof_compr_set_params(struct snd_soc_component *component, goto out; } - tstamp->sampling_rate = params->codec.sample_rate; + sstream->sampling_rate = params->codec.sample_rate; spcm->prepared[cstream->direction] = true; @@ -325,10 +325,10 @@ static int sof_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *cstream, struct snd_compr_tstamp *tstamp) { - struct snd_compr_tstamp *pstamp = cstream->runtime->private_data; + struct sof_compr_stream *sstream = cstream->runtime->private_data; - tstamp->sampling_rate = pstamp->sampling_rate; - tstamp->copied_total = pstamp->copied_total; + tstamp->sampling_rate = sstream->sampling_rate; + tstamp->copied_total = sstream->copied_total; return 0; } diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 823583086279..42f112030fb8 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -105,6 +105,11 @@ enum sof_debugfs_access_type { SOF_DEBUGFS_ACCESS_D0_ONLY, }; +struct sof_compr_stream { + u64 copied_total; + u32 sampling_rate; +}; + struct snd_sof_dev; struct snd_sof_ipc_msg; struct snd_sof_ipc; From 3ccbe6887747679d15e5c9524b23754281a24d9e Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Wed, 17 Aug 2022 11:05:28 +0300 Subject: [PATCH 3/4] ASoC: SOF: compress: Save channel count and sample bytes The purpose of this change is to enable the saving of the channel count and sample container bytes format parameters for later use to compute the timestamps. This is done when setting the compress stream parameters (in sof_compr_set_params). Reviewed-by: Paul Olaru Reviewed-by: Pierre-Louis Bossart Signed-off-by: Laurentiu Mihalcea Signed-off-by: Daniel Baluta Link: https://lore.kernel.org/r/20220817080529.10864-4-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown --- sound/soc/sof/compress.c | 2 ++ sound/soc/sof/sof-priv.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index e990fa093bb5..ac79b46ce3b9 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -238,6 +238,8 @@ static int sof_compr_set_params(struct snd_soc_component *component, } sstream->sampling_rate = params->codec.sample_rate; + sstream->channels = params->codec.ch_out; + sstream->sample_container_bytes = pcm->params.sample_container_bytes; spcm->prepared[cstream->direction] = true; diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 42f112030fb8..33165299a20f 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -108,6 +108,8 @@ enum sof_debugfs_access_type { struct sof_compr_stream { u64 copied_total; u32 sampling_rate; + u16 channels; + u16 sample_container_bytes; }; struct snd_sof_dev; From c1a731c71359407eae4fd0a5fd675ef25a582764 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Wed, 17 Aug 2022 11:05:29 +0300 Subject: [PATCH 4/4] ASoC: SOF: compress: Add support for computing timestamps We compute the number of pcm_io_frames by dividing the dai position to size of a frame (channels * sample size). Reviewed-by: Paul Olaru Reviewed-by: Pierre-Louis Bossart Signed-off-by: Laurentiu Mihalcea Signed-off-by: Daniel Baluta Link: https://lore.kernel.org/r/20220817080529.10864-5-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown --- sound/soc/sof/compress.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index ac79b46ce3b9..174b3d8e67dd 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -327,10 +327,21 @@ static int sof_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *cstream, struct snd_compr_tstamp *tstamp) { + u64 dai_posn; + struct snd_sof_pcm *spcm; + struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct sof_compr_stream *sstream = cstream->runtime->private_data; + spcm = snd_sof_find_spcm_dai(component, rtd); + if (!spcm) + return -EINVAL; + + dai_posn = spcm->stream[cstream->direction].posn.dai_posn; + tstamp->sampling_rate = sstream->sampling_rate; tstamp->copied_total = sstream->copied_total; + tstamp->pcm_io_frames = div_u64(spcm->stream[cstream->direction].posn.dai_posn, + sstream->channels * sstream->sample_container_bytes); return 0; }