All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mohammad Rafi Shaik <quic_mohs@quicinc.com>
To: <krzysztof.kozlowski+dt@linaro.org>, <agross@kernel.org>,
	<andersson@kernel.org>, <lgirdwood@gmail.com>,
	<broonie@kernel.org>, <robh+dt@kernel.org>,
	<quic_plai@quicinc.com>, <bgoswami@quicinc.com>,
	<srinivas.kandagatla@linaro.org>, <quic_rohkumar@quicinc.com>,
	<linux-arm-msm@vger.kernel.org>, <alsa-devel@alsa-project.org>,
	<linux-kernel@vger.kernel.org>, <swboyd@chromium.org>,
	<judyhsiao@chromium.org>, <devicetree@vger.kernel.org>,
	<konrad.dybcio@linaro.org>
Cc: Mohammad Rafi Shaik <quic_mohs@quicinc.com>
Subject: [PATCH 08/14] ASoC: q6dsp: q6apm-dai: Add open/free compress DAI callbacks
Date: Wed, 1 Feb 2023 19:19:41 +0530	[thread overview]
Message-ID: <20230201134947.1638197-9-quic_mohs@quicinc.com> (raw)
In-Reply-To: <20230201134947.1638197-1-quic_mohs@quicinc.com>

Add q6apm open and free compress DAI callbacks to support compress
offload playback.
Include compress event handler callback also.

Signed-off-by: Mohammad Rafi Shaik <quic_mohs@quicinc.com>
Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 sound/soc/qcom/qdsp6/q6apm-dai.c | 135 +++++++++++++++++++++++++++++++
 1 file changed, 135 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index e621e31294a1..fd134c268189 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -27,6 +27,8 @@
 #define CAPTURE_MIN_PERIOD_SIZE		320
 #define BUFFER_BYTES_MAX (PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE)
 #define BUFFER_BYTES_MIN (PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE)
+#define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024)
+#define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4)
 #define SID_MASK_DEFAULT	0xF
 
 enum stream_state {
@@ -130,6 +132,69 @@ static void event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, vo
 	}
 }
 
+void event_handler_compr(uint32_t opcode, uint32_t token,
+				uint32_t *payload, void *priv)
+{
+	struct q6apm_dai_rtd *prtd = priv;
+	struct snd_compr_stream *substream = prtd->cstream;
+	unsigned long flags;
+	uint32_t wflags = 0;
+	uint64_t avail;
+	uint32_t bytes_written, bytes_to_write;
+	bool is_last_buffer = false;
+
+	switch (opcode) {
+	case APM_CLIENT_EVENT_CMD_EOS_DONE:
+		spin_lock_irqsave(&prtd->lock, flags);
+		if (prtd->notify_on_drain) {
+			snd_compr_drain_notify(prtd->cstream);
+			prtd->notify_on_drain = false;
+		} else {
+			prtd->state = Q6APM_STREAM_STOPPED;
+		}
+		spin_unlock_irqrestore(&prtd->lock, flags);
+		break;
+	case APM_CLIENT_EVENT_DATA_WRITE_DONE:
+		spin_lock_irqsave(&prtd->lock, flags);
+		bytes_written = token >> APM_WRITE_TOKEN_LEN_SHIFT;
+		prtd->copied_total += bytes_written;
+		snd_compr_fragment_elapsed(substream);
+
+		if (prtd->state != Q6APM_STREAM_RUNNING) {
+			spin_unlock_irqrestore(&prtd->lock, flags);
+			break;
+		}
+
+		avail = prtd->bytes_received - prtd->bytes_sent;
+
+		if (avail > prtd->pcm_count) {
+			bytes_to_write = prtd->pcm_count;
+		} else {
+			if (substream->partial_drain || prtd->notify_on_drain)
+				is_last_buffer = true;
+			bytes_to_write = avail;
+		}
+
+		if (bytes_to_write) {
+			if (substream->partial_drain && is_last_buffer)
+				wflags |= APM_LAST_BUFFER_FLAG;
+
+			q6apm_write_async_compr(prtd->graph,
+						bytes_to_write, 0, 0, wflags);
+
+			prtd->bytes_sent += bytes_to_write;
+
+			if (prtd->notify_on_drain && is_last_buffer)
+				audioreach_shared_memory_send_eos(prtd->graph);
+		}
+
+		spin_unlock_irqrestore(&prtd->lock, flags);
+		break;
+	default:
+		break;
+	}
+}
+
 static int q6apm_dai_prepare(struct snd_soc_component *component,
 			     struct snd_pcm_substream *substream)
 {
@@ -378,6 +443,75 @@ static int q6apm_dai_pcm_new(struct snd_soc_component *component, struct snd_soc
 	return snd_pcm_set_fixed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, component->dev, size);
 }
 
+static int q6apm_dai_compr_open(struct snd_soc_component *component,
+				struct snd_compr_stream *stream)
+{
+	struct snd_soc_pcm_runtime *rtd = stream->private_data;
+	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+	struct snd_compr_runtime *runtime = stream->runtime;
+	struct q6apm_dai_rtd *prtd;
+	struct q6apm_dai_data *pdata;
+	struct device *dev = component->dev;
+	int ret, size;
+	int graph_id;
+
+	graph_id = cpu_dai->driver->id;
+	pdata = snd_soc_component_get_drvdata(component);
+	if (!pdata)
+		return -EINVAL;
+
+	prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
+	if (prtd == NULL)
+		return -ENOMEM;
+
+	prtd->cstream = stream;
+	prtd->graph = q6apm_graph_open(dev, (q6apm_cb)event_handler_compr, prtd, graph_id);
+	if (IS_ERR(prtd->graph)) {
+		ret = PTR_ERR(prtd->graph);
+		kfree(prtd);
+		return ret;
+	}
+
+	runtime->private_data = prtd;
+	runtime->dma_bytes = BUFFER_BYTES_MAX;
+	size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE * COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
+	ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, &prtd->dma_buffer);
+	if (ret)
+		return ret;
+
+	if (pdata->sid < 0)
+		prtd->phys = prtd->dma_buffer.addr;
+	else
+		prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32);
+
+	snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer);
+	spin_lock_init(&prtd->lock);
+
+	q6apm_enable_compress_module(dev, prtd->graph, true);
+	return 0;
+}
+
+static int q6apm_dai_compr_free(struct snd_soc_component *component,
+				struct snd_compr_stream *stream)
+{
+	struct snd_compr_runtime *runtime = stream->runtime;
+	struct q6apm_dai_rtd *prtd = runtime->private_data;
+
+	q6apm_graph_stop(prtd->graph);
+	q6apm_unmap_memory_regions(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK);
+	q6apm_graph_close(prtd->graph);
+	snd_dma_free_pages(&prtd->dma_buffer);
+	prtd->graph = NULL;
+	kfree(prtd);
+	runtime->private_data = NULL;
+
+	return 0;
+}
+static const struct snd_compress_ops q6apm_dai_compress_ops = {
+	.open		= q6apm_dai_compr_open,
+	.free		= q6apm_dai_compr_free,
+};
+
 static const struct snd_soc_component_driver q6apm_fe_dai_component = {
 	.name		= DRV_NAME,
 	.open		= q6apm_dai_open,
@@ -387,6 +521,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = {
 	.hw_params	= q6apm_dai_hw_params,
 	.pointer	= q6apm_dai_pointer,
 	.trigger	= q6apm_dai_trigger,
+	.compress_ops	= &q6apm_dai_compress_ops,
 };
 
 static int q6apm_dai_probe(struct platform_device *pdev)
-- 
2.25.1


  parent reply	other threads:[~2023-02-01 13:52 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-01 13:49 [PATCH 00/14] Add support for compress offload and gapless playback Mohammad Rafi Shaik
2023-02-01 13:49 ` [PATCH 01/14] ALSA: compress: Update compress set params for " Mohammad Rafi Shaik
2023-02-01 13:49 ` [PATCH 02/14] ASoC: qcom: SC7280: audioreach: Add sc7280 hardware param fixup callback Mohammad Rafi Shaik
2023-02-01 14:40   ` Mark Brown
2023-02-01 14:40     ` Mark Brown
2023-02-03  6:33     ` Mohammad Rafi Shaik
2023-02-03  6:33       ` Mohammad Rafi Shaik
2023-02-01 13:49 ` [PATCH 03/14] ASoC: q6dsp: audioreach: Add placeholder decoder for compress playback Mohammad Rafi Shaik
2023-02-01 13:49 ` [PATCH 04/14] ASoC: q6dsp: audioreach: Add support for compress offload commands Mohammad Rafi Shaik
2023-02-01 15:18   ` kernel test robot
2023-02-01 15:18     ` kernel test robot
2023-02-01 13:49 ` [PATCH 05/14] ASoC: q6dsp: audioreach: Add support to set compress params Mohammad Rafi Shaik
2023-02-01 13:49 ` [PATCH 06/14] ASoC: q6dsp: audioreach: Add support for sending real module ID to ADSP Mohammad Rafi Shaik
2023-02-01 13:49 ` [PATCH 07/14] ASoC: q6dsp: q6apm-dai: Add async compress write support Mohammad Rafi Shaik
2023-02-01 13:49 ` Mohammad Rafi Shaik [this message]
2023-02-01 16:09   ` [PATCH 08/14] ASoC: q6dsp: q6apm-dai: Add open/free compress DAI callbacks kernel test robot
2023-02-01 16:09     ` kernel test robot
2023-02-01 13:49 ` [PATCH 09/14] ASoC: q6dsp: q6apm-dai: Add compress DAI and codec caps get callbacks Mohammad Rafi Shaik
2023-02-01 13:49 ` [PATCH 10/14] ASoC: q6dsp: q6apm-dai: Add trigger/pointer compress DAI callbacks Mohammad Rafi Shaik
2023-02-01 16:50   ` kernel test robot
2023-02-01 16:50     ` kernel test robot
2023-02-01 13:49 ` [PATCH 11/14] ASoC: q6dsp: q6apm-dai: Add compress set params and metadata " Mohammad Rafi Shaik
2023-02-01 15:18   ` kernel test robot
2023-02-01 15:18     ` kernel test robot
2023-02-01 13:49 ` [PATCH 12/14] ASoC: q6dsp: q6apm-dai: Add mmap and copy compress " Mohammad Rafi Shaik
2023-02-01 13:49 ` [PATCH 13/14] ASoC: qdsp6: audioreach: Add MP3, AAC and FLAC compress format support Mohammad Rafi Shaik
2023-02-01 13:49 ` [PATCH 14/14] ASoC: q6dsp: audioreach: Add gapless feature support Mohammad Rafi Shaik

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=20230201134947.1638197-9-quic_mohs@quicinc.com \
    --to=quic_mohs@quicinc.com \
    --cc=agross@kernel.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=andersson@kernel.org \
    --cc=bgoswami@quicinc.com \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=judyhsiao@chromium.org \
    --cc=konrad.dybcio@linaro.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=quic_plai@quicinc.com \
    --cc=quic_rohkumar@quicinc.com \
    --cc=robh+dt@kernel.org \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=swboyd@chromium.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.