From: Herve Codina <herve.codina@bootlin.com>
To: Herve Codina <herve.codina@bootlin.com>,
Liam Girdwood <lgirdwood@gmail.com>,
Mark Brown <broonie@kernel.org>, Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Qiang Zhao <qiang.zhao@nxp.com>,
Shengjiu Wang <shengjiu.wang@gmail.com>,
Xiubo Li <Xiubo.Lee@gmail.com>,
Fabio Estevam <festevam@gmail.com>,
Nicolin Chen <nicoleotsuka@gmail.com>,
Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: alsa-devel@alsa-project.org, linuxppc-dev@lists.ozlabs.org,
linux-sound@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Subject: [PATCH 03/10] ASoC: fsl: fsl_qmc_audio: Split channel buffer and PCM pointer handling
Date: Thu, 20 Jun 2024 10:42:50 +0200 [thread overview]
Message-ID: <20240620084300.397853-4-herve.codina@bootlin.com> (raw)
In-Reply-To: <20240620084300.397853-1-herve.codina@bootlin.com>
The driver mixes some internal values for channel DMA buffer handling
and PCM pointer handling. In the currently supported interleaved mode,
this mix does not lead to any issues but in order to prepare the
support for the non-interleaved mode, having them clearly separated will
ease the support and avoid additional computation to convert values used
in channel DMA buffer management in values usable for PCM pointer.
Use a specific set of variable for PCM pointer handling and an other set
for channel DMA buffer.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
sound/soc/fsl/fsl_qmc_audio.c | 84 +++++++++++++++++++----------------
1 file changed, 46 insertions(+), 38 deletions(-)
diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
index 917a32389f3d..e8281e548746 100644
--- a/sound/soc/fsl/fsl_qmc_audio.c
+++ b/sound/soc/fsl/fsl_qmc_audio.c
@@ -35,11 +35,16 @@ struct qmc_audio {
struct qmc_dai_prtd {
struct qmc_dai *qmc_dai;
- dma_addr_t dma_buffer_start;
- dma_addr_t period_ptr_submitted;
- dma_addr_t period_ptr_ended;
- dma_addr_t dma_buffer_end;
- size_t period_size;
+
+ snd_pcm_uframes_t buffer_ended;
+ snd_pcm_uframes_t buffer_size;
+ snd_pcm_uframes_t period_size;
+
+ dma_addr_t ch_dma_addr_start;
+ dma_addr_t ch_dma_addr_current;
+ dma_addr_t ch_dma_addr_end;
+ size_t ch_dma_size;
+
struct snd_pcm_substream *substream;
};
@@ -65,13 +70,17 @@ static int qmc_audio_pcm_hw_params(struct snd_soc_component *component,
struct snd_pcm_runtime *runtime = substream->runtime;
struct qmc_dai_prtd *prtd = substream->runtime->private_data;
- prtd->dma_buffer_start = runtime->dma_addr;
- prtd->dma_buffer_end = runtime->dma_addr + params_buffer_bytes(params);
- prtd->period_size = params_period_bytes(params);
- prtd->period_ptr_submitted = prtd->dma_buffer_start;
- prtd->period_ptr_ended = prtd->dma_buffer_start;
prtd->substream = substream;
+ prtd->buffer_ended = 0;
+ prtd->buffer_size = params_buffer_size(params);
+ prtd->period_size = params_period_size(params);
+
+ prtd->ch_dma_addr_start = runtime->dma_addr;
+ prtd->ch_dma_addr_end = runtime->dma_addr + params_buffer_bytes(params);
+ prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
+ prtd->ch_dma_size = params_period_bytes(params);
+
return 0;
}
@@ -80,16 +89,16 @@ static void qmc_audio_pcm_write_complete(void *context)
struct qmc_dai_prtd *prtd = context;
int ret;
- prtd->period_ptr_ended += prtd->period_size;
- if (prtd->period_ptr_ended >= prtd->dma_buffer_end)
- prtd->period_ptr_ended = prtd->dma_buffer_start;
+ prtd->buffer_ended += prtd->period_size;
+ if (prtd->buffer_ended >= prtd->buffer_size)
+ prtd->buffer_ended = 0;
- prtd->period_ptr_submitted += prtd->period_size;
- if (prtd->period_ptr_submitted >= prtd->dma_buffer_end)
- prtd->period_ptr_submitted = prtd->dma_buffer_start;
+ prtd->ch_dma_addr_current += prtd->ch_dma_size;
+ if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
+ prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
- prtd->period_ptr_submitted, prtd->period_size,
+ prtd->ch_dma_addr_current, prtd->ch_dma_size,
qmc_audio_pcm_write_complete, prtd);
if (ret) {
dev_err(prtd->qmc_dai->dev, "write_submit failed %d\n",
@@ -104,21 +113,21 @@ static void qmc_audio_pcm_read_complete(void *context, size_t length, unsigned i
struct qmc_dai_prtd *prtd = context;
int ret;
- if (length != prtd->period_size) {
+ if (length != prtd->ch_dma_size) {
dev_err(prtd->qmc_dai->dev, "read complete length = %zu, exp %zu\n",
- length, prtd->period_size);
+ length, prtd->ch_dma_size);
}
- prtd->period_ptr_ended += prtd->period_size;
- if (prtd->period_ptr_ended >= prtd->dma_buffer_end)
- prtd->period_ptr_ended = prtd->dma_buffer_start;
+ prtd->buffer_ended += prtd->period_size;
+ if (prtd->buffer_ended >= prtd->buffer_size)
+ prtd->buffer_ended = 0;
- prtd->period_ptr_submitted += prtd->period_size;
- if (prtd->period_ptr_submitted >= prtd->dma_buffer_end)
- prtd->period_ptr_submitted = prtd->dma_buffer_start;
+ prtd->ch_dma_addr_current += prtd->ch_dma_size;
+ if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
+ prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan,
- prtd->period_ptr_submitted, prtd->period_size,
+ prtd->ch_dma_addr_current, prtd->ch_dma_size,
qmc_audio_pcm_read_complete, prtd);
if (ret) {
dev_err(prtd->qmc_dai->dev, "read_submit failed %d\n",
@@ -144,7 +153,7 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
/* Submit first chunk ... */
ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
- prtd->period_ptr_submitted, prtd->period_size,
+ prtd->ch_dma_addr_current, prtd->ch_dma_size,
qmc_audio_pcm_write_complete, prtd);
if (ret) {
dev_err(component->dev, "write_submit failed %d\n",
@@ -153,13 +162,13 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
}
/* ... prepare next one ... */
- prtd->period_ptr_submitted += prtd->period_size;
- if (prtd->period_ptr_submitted >= prtd->dma_buffer_end)
- prtd->period_ptr_submitted = prtd->dma_buffer_start;
+ prtd->ch_dma_addr_current += prtd->ch_dma_size;
+ if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
+ prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
/* ... and send it */
ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
- prtd->period_ptr_submitted, prtd->period_size,
+ prtd->ch_dma_addr_current, prtd->ch_dma_size,
qmc_audio_pcm_write_complete, prtd);
if (ret) {
dev_err(component->dev, "write_submit failed %d\n",
@@ -169,7 +178,7 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
} else {
/* Submit first chunk ... */
ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan,
- prtd->period_ptr_submitted, prtd->period_size,
+ prtd->ch_dma_addr_current, prtd->ch_dma_size,
qmc_audio_pcm_read_complete, prtd);
if (ret) {
dev_err(component->dev, "read_submit failed %d\n",
@@ -178,13 +187,13 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
}
/* ... prepare next one ... */
- prtd->period_ptr_submitted += prtd->period_size;
- if (prtd->period_ptr_submitted >= prtd->dma_buffer_end)
- prtd->period_ptr_submitted = prtd->dma_buffer_start;
+ prtd->ch_dma_addr_current += prtd->ch_dma_size;
+ if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
+ prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
/* ... and send it */
ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan,
- prtd->period_ptr_submitted, prtd->period_size,
+ prtd->ch_dma_addr_current, prtd->ch_dma_size,
qmc_audio_pcm_read_complete, prtd);
if (ret) {
dev_err(component->dev, "write_submit failed %d\n",
@@ -215,8 +224,7 @@ static snd_pcm_uframes_t qmc_audio_pcm_pointer(struct snd_soc_component *compone
{
struct qmc_dai_prtd *prtd = substream->runtime->private_data;
- return bytes_to_frames(substream->runtime,
- prtd->period_ptr_ended - prtd->dma_buffer_start);
+ return prtd->buffer_ended;
}
static int qmc_audio_of_xlate_dai_name(struct snd_soc_component *component,
--
2.45.0
next prev parent reply other threads:[~2024-06-20 8:43 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-20 8:42 [PATCH 00/10] Add support for non-interleaved mode in qmc_audio Herve Codina
2024-06-20 8:42 ` [PATCH 01/10] ASoC: fsl: fsl_qmc_audio: Check devm_kasprintf() returned value Herve Codina
2024-06-20 8:42 ` [PATCH 02/10] ASoC: fsl: fsl_qmc_audio: Fix issues detected by checkpatch Herve Codina
2024-06-20 8:42 ` Herve Codina [this message]
2024-06-20 8:42 ` [PATCH 04/10] ASoC: fsl: fsl_qmc_audio: Identify the QMC channel involved in completion routines Herve Codina
2024-06-20 8:42 ` [PATCH 05/10] ASoC: fsl: fsl_qmc_audio: Introduce qmc_audio_pcm_{read,write}_submit() Herve Codina
2024-06-20 8:42 ` [PATCH 06/10] ASoC: fsl: fsl_qmc_audio: Introduce qmc_dai_constraints_interleaved() Herve Codina
2024-06-20 8:42 ` [PATCH 07/10] soc: fsl: cpm1: qmc: Introduce functions to get a channel from a phandle list Herve Codina
2024-06-20 8:42 ` [PATCH 08/10] soc: fsl: cpm1: qmc: Introduce qmc_chan_count_phandles() Herve Codina
2024-06-20 8:42 ` [PATCH 09/10] dt-bindings: sound: fsl,qmc-audio: Add support for multiple QMC channels per DAI Herve Codina
2024-06-27 21:25 ` Rob Herring (Arm)
2024-06-20 8:42 ` [PATCH 10/10] ASoC: fsl: fsl_qmc_audio: Add support for non-interleaved mode Herve Codina
2024-07-01 7:47 ` Herve Codina
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240620084300.397853-4-herve.codina@bootlin.com \
--to=herve.codina@bootlin.com \
--cc=Xiubo.Lee@gmail.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@kernel.org \
--cc=christophe.leroy@csgroup.eu \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=festevam@gmail.com \
--cc=krzk+dt@kernel.org \
--cc=lgirdwood@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=nicoleotsuka@gmail.com \
--cc=perex@perex.cz \
--cc=qiang.zhao@nxp.com \
--cc=robh@kernel.org \
--cc=shengjiu.wang@gmail.com \
--cc=thomas.petazzoni@bootlin.com \
--cc=tiwai@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).