* [PATCH 01/10] ASoC: qcom: q6apm: fix array out of bounds on lpass ports
2026-02-05 17:14 [PATCH 00/10] ASoC: qcom: q6dsp: few fixes and enhancements Srinivas Kandagatla
@ 2026-02-05 17:14 ` Srinivas Kandagatla
2026-02-05 17:46 ` Mark Brown
2026-02-06 8:01 ` Krzysztof Kozlowski
2026-02-05 17:14 ` [PATCH 02/10] ASoC: qcom: q6apm-lpass-dai: Fix multiple graph opens Srinivas Kandagatla
` (8 subsequent siblings)
9 siblings, 2 replies; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-05 17:14 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Srinivas Kandagatla, Stable
lpass ports numbers have been added but the apm driver never got updated
with new max port value that it uses to store dai specific data.
This will result in array out of bounds and weird driver behaviour.
Fix this by adding a new LPASS_MAX_PORT which is can be used by driver
instead of using number and any new port additional can only be done in
one place, which should avoid these type of mistakes in future.
Also update the driver to use this LPASS_MAX_PORT.
Fixes: 55b5fb369c02 ("ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add USB_RX port")
Cc: Stable@vger.kernel.org
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h | 1 +
sound/soc/qcom/lpass.h | 2 +-
sound/soc/qcom/qdsp6/q6afe.h | 3 ++-
sound/soc/qcom/qdsp6/q6apm.h | 2 +-
4 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
index 6d1ce7f5da51..609bc278f726 100644
--- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
+++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
@@ -140,6 +140,7 @@
#define DISPLAY_PORT_RX_6 134
#define DISPLAY_PORT_RX_7 135
#define USB_RX 136
+#define LPASS_MAX_PORT (USB_RX + 1)
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
index de3ec6f594c1..99b0b6651fad 100644
--- a/sound/soc/qcom/lpass.h
+++ b/sound/soc/qcom/lpass.h
@@ -17,7 +17,7 @@
#include "lpass-hdmi.h"
#define LPASS_AHBIX_CLOCK_FREQUENCY 131072000
-#define LPASS_MAX_PORTS (DISPLAY_PORT_RX_7 + 1)
+#define LPASS_MAX_PORTS (LPASS_MAX_PORT)
#define LPASS_MAX_MI2S_PORTS (8)
#define LPASS_MAX_DMA_CHANNELS (8)
#define LPASS_MAX_HDMI_DMA_CHANNELS (4)
diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h
index a29abe4ce436..ce4b04da1730 100644
--- a/sound/soc/qcom/qdsp6/q6afe.h
+++ b/sound/soc/qcom/qdsp6/q6afe.h
@@ -2,8 +2,9 @@
#ifndef __Q6AFE_H__
#define __Q6AFE_H__
+#include <dt-bindings/sound/qcom,q6afe.h>
-#define AFE_PORT_MAX 137
+#define AFE_PORT_MAX LPASS_MAX_PORT
#define MSM_AFE_PORT_TYPE_RX 0
#define MSM_AFE_PORT_TYPE_TX 1
diff --git a/sound/soc/qcom/qdsp6/q6apm.h b/sound/soc/qcom/qdsp6/q6apm.h
index 7ce08b401e31..189ed8a1a60d 100644
--- a/sound/soc/qcom/qdsp6/q6apm.h
+++ b/sound/soc/qcom/qdsp6/q6apm.h
@@ -16,7 +16,7 @@
#include <linux/soc/qcom/apr.h>
#include "audioreach.h"
-#define APM_PORT_MAX 127
+#define APM_PORT_MAX LPASS_MAX_PORT
#define APM_PORT_MAX_AUDIO_CHAN_CNT 8
#define PCM_CHANNEL_NULL 0
#define PCM_CHANNEL_FL 1 /* Front left channel. */
--
2.47.3
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 01/10] ASoC: qcom: q6apm: fix array out of bounds on lpass ports
2026-02-05 17:14 ` [PATCH 01/10] ASoC: qcom: q6apm: fix array out of bounds on lpass ports Srinivas Kandagatla
@ 2026-02-05 17:46 ` Mark Brown
2026-02-06 9:52 ` Srinivas Kandagatla
2026-02-06 8:01 ` Krzysztof Kozlowski
1 sibling, 1 reply; 22+ messages in thread
From: Mark Brown @ 2026-02-05 17:46 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: lgirdwood, robh, krzk+dt, conor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Stable
[-- Attachment #1: Type: text/plain, Size: 610 bytes --]
On Thu, Feb 05, 2026 at 12:14:02PM -0500, Srinivas Kandagatla wrote:
> lpass ports numbers have been added but the apm driver never got updated
> with new max port value that it uses to store dai specific data.
>
> This will result in array out of bounds and weird driver behaviour.
> Fix this by adding a new LPASS_MAX_PORT which is can be used by driver
> instead of using number and any new port additional can only be done in
> one place, which should avoid these type of mistakes in future.
It would probably be good to improve the valdiation in the driver when
it starts using port numbers.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 01/10] ASoC: qcom: q6apm: fix array out of bounds on lpass ports
2026-02-05 17:46 ` Mark Brown
@ 2026-02-06 9:52 ` Srinivas Kandagatla
0 siblings, 0 replies; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-06 9:52 UTC (permalink / raw)
To: Mark Brown
Cc: lgirdwood, robh, krzk+dt, conor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Stable
On 2/5/26 12:46 PM, Mark Brown wrote:
> On Thu, Feb 05, 2026 at 12:14:02PM -0500, Srinivas Kandagatla wrote:
>> lpass ports numbers have been added but the apm driver never got updated
>> with new max port value that it uses to store dai specific data.
>>
>> This will result in array out of bounds and weird driver behaviour.
>> Fix this by adding a new LPASS_MAX_PORT which is can be used by driver
>> instead of using number and any new port additional can only be done in
>> one place, which should avoid these type of mistakes in future.
>
> It would probably be good to improve the valdiation in the driver when
> it starts using port numbers.
Good idea, will try that out in next spin.
--srini
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 01/10] ASoC: qcom: q6apm: fix array out of bounds on lpass ports
2026-02-05 17:14 ` [PATCH 01/10] ASoC: qcom: q6apm: fix array out of bounds on lpass ports Srinivas Kandagatla
2026-02-05 17:46 ` Mark Brown
@ 2026-02-06 8:01 ` Krzysztof Kozlowski
1 sibling, 0 replies; 22+ messages in thread
From: Krzysztof Kozlowski @ 2026-02-06 8:01 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: broonie, lgirdwood, robh, krzk+dt, conor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Stable
On Thu, Feb 05, 2026 at 12:14:02PM -0500, Srinivas Kandagatla wrote:
> lpass ports numbers have been added but the apm driver never got updated
> with new max port value that it uses to store dai specific data.
>
> This will result in array out of bounds and weird driver behaviour.
> Fix this by adding a new LPASS_MAX_PORT which is can be used by driver
> instead of using number and any new port additional can only be done in
> one place, which should avoid these type of mistakes in future.
>
> Also update the driver to use this LPASS_MAX_PORT.
>
> Fixes: 55b5fb369c02 ("ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add USB_RX port")
> Cc: Stable@vger.kernel.org
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> ---
> include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h | 1 +
Why do you send this patch multiple times? I already replied to it.
NAK
And also impossible to reply via korg:
sendmail: server message: 550 5.1.1 <cnor+dt@kernel.org>: Recipient address rejected: User unknown in local recipient table
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 02/10] ASoC: qcom: q6apm-lpass-dai: Fix multiple graph opens
2026-02-05 17:14 [PATCH 00/10] ASoC: qcom: q6dsp: few fixes and enhancements Srinivas Kandagatla
2026-02-05 17:14 ` [PATCH 01/10] ASoC: qcom: q6apm: fix array out of bounds on lpass ports Srinivas Kandagatla
@ 2026-02-05 17:14 ` Srinivas Kandagatla
2026-02-07 9:17 ` Dmitry Baryshkov
2026-02-05 17:14 ` [PATCH 03/10] ASoC: qcom: q6apm-dai: reset queue ptr on trigger stop Srinivas Kandagatla
` (7 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-05 17:14 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Srinivas Kandagatla, Stable
As prepare can be called mulitple times, this can result in multiple
graph opens for playback path, fix this by checking if there is already a
graph instance.
This will result in a memory leaks, fix this by adding a check before
opening.
Fixes: be1fae62cf25 ("ASoC: q6apm-lpass-dai: close graph on prepare errors")
Cc: Stable@vger.kernel.org
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
index 528756f1332b..f68d4b4974f3 100644
--- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
+++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
@@ -181,7 +181,7 @@ static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct s
* It is recommend to load DSP with source graph first and then sink
* graph, so sequence for playback and capture will be different
*/
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && dai_data->graph[dai->id] == NULL) {
graph = q6apm_graph_open(dai->dev, NULL, dai->dev, graph_id);
if (IS_ERR(graph)) {
dev_err(dai->dev, "Failed to open graph (%d)\n", graph_id);
--
2.47.3
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 02/10] ASoC: qcom: q6apm-lpass-dai: Fix multiple graph opens
2026-02-05 17:14 ` [PATCH 02/10] ASoC: qcom: q6apm-lpass-dai: Fix multiple graph opens Srinivas Kandagatla
@ 2026-02-07 9:17 ` Dmitry Baryshkov
0 siblings, 0 replies; 22+ messages in thread
From: Dmitry Baryshkov @ 2026-02-07 9:17 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: broonie, lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
konrad.dybcio, linux-arm-msm, linux-sound, devicetree,
linux-kernel, Stable
On Thu, Feb 05, 2026 at 12:14:03PM -0500, Srinivas Kandagatla wrote:
> As prepare can be called mulitple times, this can result in multiple
> graph opens for playback path, fix this by checking if there is already a
> graph instance.
>
> This will result in a memory leaks, fix this by adding a check before
> opening.
I think, the commit message should be improved by removing the first
'fix this' sentence.
>
> Fixes: be1fae62cf25 ("ASoC: q6apm-lpass-dai: close graph on prepare errors")
> Cc: Stable@vger.kernel.org
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> ---
> sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> index 528756f1332b..f68d4b4974f3 100644
> --- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> +++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> @@ -181,7 +181,7 @@ static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct s
> * It is recommend to load DSP with source graph first and then sink
> * graph, so sequence for playback and capture will be different
> */
> - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && dai_data->graph[dai->id] == NULL) {
> graph = q6apm_graph_open(dai->dev, NULL, dai->dev, graph_id);
> if (IS_ERR(graph)) {
> dev_err(dai->dev, "Failed to open graph (%d)\n", graph_id);
> --
> 2.47.3
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 03/10] ASoC: qcom: q6apm-dai: reset queue ptr on trigger stop
2026-02-05 17:14 [PATCH 00/10] ASoC: qcom: q6dsp: few fixes and enhancements Srinivas Kandagatla
2026-02-05 17:14 ` [PATCH 01/10] ASoC: qcom: q6apm: fix array out of bounds on lpass ports Srinivas Kandagatla
2026-02-05 17:14 ` [PATCH 02/10] ASoC: qcom: q6apm-lpass-dai: Fix multiple graph opens Srinivas Kandagatla
@ 2026-02-05 17:14 ` Srinivas Kandagatla
2026-02-05 17:14 ` [PATCH 04/10] ASoC: qcom: qdapm-lpass-dai: correct the error message Srinivas Kandagatla
` (6 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-05 17:14 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Srinivas Kandagatla, Stable
Reset queue pointer on SNDRV_PCM_TRIGGER_STOP event to be inline
with resetting appl_ptr. Without this we will end up with a queue_ptr
out of sync and driver could try to send data that is not ready yet.
Fix this by resetting the queue_ptr.
Fixes: 3d4a4411aa8bb ("ASoC: q6apm-dai: schedule all available frames to avoid dsp under-runs")
Cc: Stable@vger.kernel.org
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
sound/soc/qcom/qdsp6/q6apm-dai.c | 1 +
sound/soc/qcom/qdsp6/q6apm.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index aaeeadded7aa..87e4474d680a 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -317,6 +317,7 @@ static int q6apm_dai_trigger(struct snd_soc_component *component,
case SNDRV_PCM_TRIGGER_STOP:
/* TODO support be handled via SoftPause Module */
prtd->state = Q6APM_STREAM_STOPPED;
+ prtd->queue_ptr = 0;
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index 1d5edf285793..2cfebd622be2 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -215,6 +215,8 @@ int q6apm_map_memory_regions(struct q6apm_graph *graph, unsigned int dir, phys_a
mutex_lock(&graph->lock);
+ data->dsp_buf = 0;
+
if (data->buf) {
mutex_unlock(&graph->lock);
return 0;
--
2.47.3
^ permalink raw reply [flat|nested] 22+ messages in thread* [PATCH 04/10] ASoC: qcom: qdapm-lpass-dai: correct the error message
2026-02-05 17:14 [PATCH 00/10] ASoC: qcom: q6dsp: few fixes and enhancements Srinivas Kandagatla
` (2 preceding siblings ...)
2026-02-05 17:14 ` [PATCH 03/10] ASoC: qcom: q6apm-dai: reset queue ptr on trigger stop Srinivas Kandagatla
@ 2026-02-05 17:14 ` Srinivas Kandagatla
2026-02-05 17:14 ` [PATCH 05/10] ASoC: qcom: q6dsp: add support for LPASS LPI MI2S dais Srinivas Kandagatla
` (5 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-05 17:14 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Srinivas Kandagatla
Fix the error message to reflect the actual graph stop error
instead of graph close error.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
index f68d4b4974f3..fc246485e326 100644
--- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
+++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
@@ -150,7 +150,7 @@ static void q6apm_lpass_dai_shutdown(struct snd_pcm_substream *substream, struct
rc = q6apm_graph_stop(dai_data->graph[dai->id]);
dai_data->is_port_started[dai->id] = false;
if (rc < 0)
- dev_err(dai->dev, "fail to close APM port (%d)\n", rc);
+ dev_err(dai->dev, "fail to stop APM port (%d)\n", rc);
}
if (dai_data->graph[dai->id]) {
--
2.47.3
^ permalink raw reply [flat|nested] 22+ messages in thread* [PATCH 05/10] ASoC: qcom: q6dsp: add support for LPASS LPI MI2S dais
2026-02-05 17:14 [PATCH 00/10] ASoC: qcom: q6dsp: few fixes and enhancements Srinivas Kandagatla
` (3 preceding siblings ...)
2026-02-05 17:14 ` [PATCH 04/10] ASoC: qcom: qdapm-lpass-dai: correct the error message Srinivas Kandagatla
@ 2026-02-05 17:14 ` Srinivas Kandagatla
2026-02-06 8:00 ` Krzysztof Kozlowski
2026-02-05 17:14 ` [PATCH 06/10] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add Senary MI2S port Srinivas Kandagatla
` (4 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-05 17:14 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Srinivas Kandagatla
Add new dai ids and dai driver entries ior LPASS LPI MI2S lines
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
.../sound/qcom,q6dsp-lpass-ports.h | 12 ++++-
sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c | 47 +++++++++++++++++++
2 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
index 609bc278f726..0febc641f351 100644
--- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
+++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
@@ -140,7 +140,17 @@
#define DISPLAY_PORT_RX_6 134
#define DISPLAY_PORT_RX_7 135
#define USB_RX 136
-#define LPASS_MAX_PORT (USB_RX + 1)
+#define LPI_MI2S_RX_0 137
+#define LPI_MI2S_TX_0 138
+#define LPI_MI2S_RX_1 139
+#define LPI_MI2S_TX_1 140
+#define LPI_MI2S_RX_2 141
+#define LPI_MI2S_TX_2 142
+#define LPI_MI2S_RX_3 143
+#define LPI_MI2S_TX_3 144
+#define LPI_MI2S_RX_4 145
+#define LPI_MI2S_TX_4 146
+#define LPASS_MAX_PORT (LPI_MI2S_TX_4 + 1)
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
diff --git a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
index 4eed54b071a5..d31388ed3ccf 100644
--- a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
+++ b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
@@ -96,6 +96,42 @@
.id = did, \
}
+#define Q6AFE_MI2S_RX_DAI(pre, did) { \
+ .playback = { \
+ .stream_name = pre" MI2S Playback", \
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
+ SNDRV_PCM_RATE_176400, \
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE, \
+ .channels_min = 1, \
+ .channels_max = 8, \
+ .rate_min = 8000, \
+ .rate_max = 176400, \
+ }, \
+ .name = #did, \
+ .id = did, \
+ }
+
+#define Q6AFE_MI2S_TX_DAI(pre, did) { \
+ .capture = { \
+ .stream_name = pre" MI2S Capture", \
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
+ SNDRV_PCM_RATE_176400, \
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE, \
+ .channels_min = 1, \
+ .channels_max = 8, \
+ .rate_min = 8000, \
+ .rate_max = 176400, \
+ }, \
+ .name = #did, \
+ .id = did, \
+ }
+
static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = {
{
.playback = {
@@ -484,6 +520,16 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = {
.id = QUINARY_MI2S_TX,
.name = "QUIN_MI2S_TX",
},
+ Q6AFE_MI2S_RX_DAI("LPI RX0", LPI_MI2S_RX_0),
+ Q6AFE_MI2S_RX_DAI("LPI RX1", LPI_MI2S_RX_1),
+ Q6AFE_MI2S_RX_DAI("LPI RX2", LPI_MI2S_RX_2),
+ Q6AFE_MI2S_RX_DAI("LPI RX3", LPI_MI2S_RX_3),
+ Q6AFE_MI2S_RX_DAI("LPI RX4", LPI_MI2S_RX_4),
+ Q6AFE_MI2S_TX_DAI("LPI TX0", LPI_MI2S_TX_0),
+ Q6AFE_MI2S_TX_DAI("LPI TX1", LPI_MI2S_TX_1),
+ Q6AFE_MI2S_TX_DAI("LPI TX2", LPI_MI2S_TX_2),
+ Q6AFE_MI2S_TX_DAI("LPI TX3", LPI_MI2S_TX_3),
+ Q6AFE_MI2S_TX_DAI("LPI TX4", LPI_MI2S_TX_4),
Q6AFE_TDM_PB_DAI("Primary", 0, PRIMARY_TDM_RX_0),
Q6AFE_TDM_PB_DAI("Primary", 1, PRIMARY_TDM_RX_1),
Q6AFE_TDM_PB_DAI("Primary", 2, PRIMARY_TDM_RX_2),
@@ -636,6 +682,7 @@ struct snd_soc_dai_driver *q6dsp_audio_ports_set_config(struct device *dev,
break;
case QUINARY_MI2S_RX ... QUINARY_MI2S_TX:
case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
+ case LPI_MI2S_RX_0 ... LPI_MI2S_TX_4:
q6dsp_audio_fe_dais[i].ops = cfg->q6i2s_ops;
break;
case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7:
--
2.47.3
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 05/10] ASoC: qcom: q6dsp: add support for LPASS LPI MI2S dais
2026-02-05 17:14 ` [PATCH 05/10] ASoC: qcom: q6dsp: add support for LPASS LPI MI2S dais Srinivas Kandagatla
@ 2026-02-06 8:00 ` Krzysztof Kozlowski
2026-02-06 10:02 ` Srinivas Kandagatla
0 siblings, 1 reply; 22+ messages in thread
From: Krzysztof Kozlowski @ 2026-02-06 8:00 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: broonie, lgirdwood, robh, krzk+dt, conor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel
On Thu, Feb 05, 2026 at 12:14:06PM -0500, Srinivas Kandagatla wrote:
> Add new dai ids and dai driver entries ior LPASS LPI MI2S lines
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> ---
> .../sound/qcom,q6dsp-lpass-ports.h | 12 ++++-
> sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c | 47 +++++++++++++++++++
> 2 files changed, 58 insertions(+), 1 deletion(-)
>
It's impossible to reply via korg - wrong address of Conor...
> diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> index 609bc278f726..0febc641f351 100644
> --- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> +++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> @@ -140,7 +140,17 @@
> #define DISPLAY_PORT_RX_6 134
> #define DISPLAY_PORT_RX_7 135
> #define USB_RX 136
> -#define LPASS_MAX_PORT (USB_RX + 1)
> +#define LPI_MI2S_RX_0 137
Odd indentation appeared.
> +#define LPI_MI2S_TX_0 138
> +#define LPI_MI2S_RX_1 139
> +#define LPI_MI2S_TX_1 140
> +#define LPI_MI2S_RX_2 141
> +#define LPI_MI2S_TX_2 142
> +#define LPI_MI2S_RX_3 143
> +#define LPI_MI2S_TX_3 144
> +#define LPI_MI2S_RX_4 145
> +#define LPI_MI2S_TX_4 146
> +#define LPASS_MAX_PORT (LPI_MI2S_TX_4 + 1)
Confusing change or actual proof that my previous comments for similar
patch are valid:
1. not a binding
or
2. you cannot change this, because you break ABI.
Choose only one from these options.
Drop.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 05/10] ASoC: qcom: q6dsp: add support for LPASS LPI MI2S dais
2026-02-06 8:00 ` Krzysztof Kozlowski
@ 2026-02-06 10:02 ` Srinivas Kandagatla
2026-02-06 10:52 ` Krzysztof Kozlowski
0 siblings, 1 reply; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-06 10:02 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: broonie, lgirdwood, robh, krzk+dt, conor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel
On 2/6/26 3:00 AM, Krzysztof Kozlowski wrote:
> On Thu, Feb 05, 2026 at 12:14:06PM -0500, Srinivas Kandagatla wrote:
>> Add new dai ids and dai driver entries ior LPASS LPI MI2S lines
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>> ---
>> .../sound/qcom,q6dsp-lpass-ports.h | 12 ++++-
>> sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c | 47 +++++++++++++++++++
>> 2 files changed, 58 insertions(+), 1 deletion(-)
>>
>
> It's impossible to reply via korg - wrong address of Conor...
>
>> diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
>> index 609bc278f726..0febc641f351 100644
>> --- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
>> +++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
>> @@ -140,7 +140,17 @@
>> #define DISPLAY_PORT_RX_6 134
>> #define DISPLAY_PORT_RX_7 135
>> #define USB_RX 136
>> -#define LPASS_MAX_PORT (USB_RX + 1)
>> +#define LPI_MI2S_RX_0 137
>
> Odd indentation appeared.
>
>> +#define LPI_MI2S_TX_0 138
>> +#define LPI_MI2S_RX_1 139
>> +#define LPI_MI2S_TX_1 140
>> +#define LPI_MI2S_RX_2 141
>> +#define LPI_MI2S_TX_2 142
>> +#define LPI_MI2S_RX_3 143
>> +#define LPI_MI2S_TX_3 144
>> +#define LPI_MI2S_RX_4 145
>> +#define LPI_MI2S_TX_4 146
>> +#define LPASS_MAX_PORT (LPI_MI2S_TX_4 + 1)
>
> Confusing change or actual proof that my previous comments for similar
> patch are valid:
> 1. not a binding> or
> 2. you cannot change this, because you break ABI.
> Choose only one from these options.
Is this because the max port keeps changing?, I can try to see how this
can be dealt within the drivers in next version without adding
LPASS_MAX_PORT to bindings.
--srini
>
> Drop.
>
> Best regards,
> Krzysztof
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 05/10] ASoC: qcom: q6dsp: add support for LPASS LPI MI2S dais
2026-02-06 10:02 ` Srinivas Kandagatla
@ 2026-02-06 10:52 ` Krzysztof Kozlowski
0 siblings, 0 replies; 22+ messages in thread
From: Krzysztof Kozlowski @ 2026-02-06 10:52 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: broonie, lgirdwood, robh, krzk+dt, conor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel
On 06/02/2026 11:02, Srinivas Kandagatla wrote:
>> Confusing change or actual proof that my previous comments for similar
>> patch are valid:
>> 1. not a binding> or
>> 2. you cannot change this, because you break ABI.
>> Choose only one from these options.
> Is this because the max port keeps changing?, I can try to see how this
Yes.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 06/10] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add Senary MI2S port
2026-02-05 17:14 [PATCH 00/10] ASoC: qcom: q6dsp: few fixes and enhancements Srinivas Kandagatla
` (4 preceding siblings ...)
2026-02-05 17:14 ` [PATCH 05/10] ASoC: qcom: q6dsp: add support for LPASS LPI MI2S dais Srinivas Kandagatla
@ 2026-02-05 17:14 ` Srinivas Kandagatla
2026-02-06 8:03 ` Krzysztof Kozlowski
2026-02-07 9:19 ` Dmitry Baryshkov
2026-02-05 17:14 ` [PATCH 07/10] ASoC: qcom: q6dsp: Add Senary MI2S audio interface support Srinivas Kandagatla
` (3 subsequent siblings)
9 siblings, 2 replies; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-05 17:14 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Srinivas Kandagatla
From: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
Qualcomm platforms support the Senary MI2S interface for audio playback
and capture. Add a new definitions for the Senary MI2S RX and TX ports,
which are required for boards that utilize the Senary MI2S interface
for audio routing.
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
index 0febc641f351..715bcf1bccdd 100644
--- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
+++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
@@ -150,7 +150,9 @@
#define LPI_MI2S_TX_3 144
#define LPI_MI2S_RX_4 145
#define LPI_MI2S_TX_4 146
-#define LPASS_MAX_PORT (LPI_MI2S_TX_4 + 1)
+#define SENARY_MI2S_RX 147
+#define SENARY_MI2S_TX 148
+#define LPASS_MAX_PORT (SENARY_MI2S_TX + 1)
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
--
2.47.3
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 06/10] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add Senary MI2S port
2026-02-05 17:14 ` [PATCH 06/10] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add Senary MI2S port Srinivas Kandagatla
@ 2026-02-06 8:03 ` Krzysztof Kozlowski
2026-02-07 9:19 ` Dmitry Baryshkov
1 sibling, 0 replies; 22+ messages in thread
From: Krzysztof Kozlowski @ 2026-02-06 8:03 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: broonie, lgirdwood, robh, krzk+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel
On Thu, Feb 05, 2026 at 12:14:07PM -0500, Srinivas Kandagatla wrote:
> From: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>
> Qualcomm platforms support the Senary MI2S interface for audio playback
> and capture. Add a new definitions for the Senary MI2S RX and TX ports,
> which are required for boards that utilize the Senary MI2S interface
> for audio routing.
>
> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> ---
> include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> index 0febc641f351..715bcf1bccdd 100644
> --- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> +++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> @@ -150,7 +150,9 @@
> #define LPI_MI2S_TX_3 144
> #define LPI_MI2S_RX_4 145
> #define LPI_MI2S_TX_4 146
> -#define LPASS_MAX_PORT (LPI_MI2S_TX_4 + 1)
You just added it in previous patch. It makes absolutely no sense to
add a line and then change it IMMEDIATELY and then change it again.
It's the same patchset!
And again I cannot send it because of typo in your address and I must
correct it by hand.
NAK
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 06/10] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add Senary MI2S port
2026-02-05 17:14 ` [PATCH 06/10] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add Senary MI2S port Srinivas Kandagatla
2026-02-06 8:03 ` Krzysztof Kozlowski
@ 2026-02-07 9:19 ` Dmitry Baryshkov
2026-02-09 8:28 ` Konrad Dybcio
1 sibling, 1 reply; 22+ messages in thread
From: Dmitry Baryshkov @ 2026-02-07 9:19 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: broonie, lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
konrad.dybcio, linux-arm-msm, linux-sound, devicetree,
linux-kernel
On Thu, Feb 05, 2026 at 12:14:07PM -0500, Srinivas Kandagatla wrote:
> From: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>
> Qualcomm platforms support the Senary MI2S interface for audio playback
What is Senary MI2S?
> and capture. Add a new definitions for the Senary MI2S RX and TX ports,
> which are required for boards that utilize the Senary MI2S interface
> for audio routing.
>
> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> ---
> include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> index 0febc641f351..715bcf1bccdd 100644
> --- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> +++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> @@ -150,7 +150,9 @@
> #define LPI_MI2S_TX_3 144
> #define LPI_MI2S_RX_4 145
> #define LPI_MI2S_TX_4 146
> -#define LPASS_MAX_PORT (LPI_MI2S_TX_4 + 1)
> +#define SENARY_MI2S_RX 147
> +#define SENARY_MI2S_TX 148
> +#define LPASS_MAX_PORT (SENARY_MI2S_TX + 1)
>
> #define LPASS_CLK_ID_PRI_MI2S_IBIT 1
> #define LPASS_CLK_ID_PRI_MI2S_EBIT 2
> --
> 2.47.3
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 06/10] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add Senary MI2S port
2026-02-07 9:19 ` Dmitry Baryshkov
@ 2026-02-09 8:28 ` Konrad Dybcio
0 siblings, 0 replies; 22+ messages in thread
From: Konrad Dybcio @ 2026-02-09 8:28 UTC (permalink / raw)
To: Dmitry Baryshkov, Srinivas Kandagatla
Cc: broonie, lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
linux-arm-msm, linux-sound, devicetree, linux-kernel
On 2/7/26 10:19 AM, Dmitry Baryshkov wrote:
> On Thu, Feb 05, 2026 at 12:14:07PM -0500, Srinivas Kandagatla wrote:
>> From: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>>
>> Qualcomm platforms support the Senary MI2S interface for audio playback
>
> What is Senary MI2S?
primary
secondary
tertiary
quaternary
quinary
senary
Konrad
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 07/10] ASoC: qcom: q6dsp: Add Senary MI2S audio interface support
2026-02-05 17:14 [PATCH 00/10] ASoC: qcom: q6dsp: few fixes and enhancements Srinivas Kandagatla
` (5 preceding siblings ...)
2026-02-05 17:14 ` [PATCH 06/10] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add Senary MI2S port Srinivas Kandagatla
@ 2026-02-05 17:14 ` Srinivas Kandagatla
2026-02-05 17:14 ` [PATCH 08/10] ASoC: qcom: q6apm-lpass-dai: move graph start to trigger Srinivas Kandagatla
` (2 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-05 17:14 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Srinivas Kandagatla
From: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
Introduces support for the Senary MI2S audio interface in the Qualcomm
q6dsp. Add new AFE port IDs for Senary MI2S RX and TX and include the
necessary mappings in the port configuration to allow audio routing
over the Senary MI2S interface.
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
sound/soc/qcom/qdsp6/q6afe-dai.c | 6 +++++
sound/soc/qcom/qdsp6/q6afe.c | 6 +++++
sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c | 29 ++++++++++++++++++++++++
3 files changed, 41 insertions(+)
diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c
index 0f47aadaabe1..a0d21034a626 100644
--- a/sound/soc/qcom/qdsp6/q6afe-dai.c
+++ b/sound/soc/qcom/qdsp6/q6afe-dai.c
@@ -409,6 +409,7 @@ static int q6afe_dai_prepare(struct snd_pcm_substream *substream,
q6afe_slim_port_prepare(dai_data->port[dai->id],
&dai_data->port_config[dai->id].slim);
break;
+ case SENARY_MI2S_RX ... SENARY_MI2S_TX:
case QUINARY_MI2S_RX ... QUINARY_MI2S_TX:
case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
rc = q6afe_i2s_port_prepare(dai_data->port[dai->id],
@@ -540,6 +541,7 @@ static const struct snd_soc_dapm_route q6afe_dapm_routes[] = {
{"Tertiary MI2S Playback", NULL, "TERT_MI2S_RX"},
{"Quaternary MI2S Playback", NULL, "QUAT_MI2S_RX"},
{"Quinary MI2S Playback", NULL, "QUIN_MI2S_RX"},
+ {"Senary MI2S Playback", NULL, "SEN_MI2S_RX"},
{"Primary TDM0 Playback", NULL, "PRIMARY_TDM_RX_0"},
{"Primary TDM1 Playback", NULL, "PRIMARY_TDM_RX_1"},
@@ -636,6 +638,7 @@ static const struct snd_soc_dapm_route q6afe_dapm_routes[] = {
{"SEC_MI2S_TX", NULL, "Secondary MI2S Capture"},
{"QUAT_MI2S_TX", NULL, "Quaternary MI2S Capture"},
{"QUIN_MI2S_TX", NULL, "Quinary MI2S Capture"},
+ {"SEN_MI2S_TX", NULL, "Senary MI2S Capture"},
{"WSA_CODEC_DMA_RX_0 Playback", NULL, "WSA_CODEC_DMA_RX_0"},
{"WSA_CODEC_DMA_TX_0", NULL, "WSA_CODEC_DMA_TX_0 Capture"},
@@ -770,6 +773,8 @@ static const struct snd_soc_dapm_widget q6afe_dai_widgets[] = {
SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SEN_MI2S_RX", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SEN_MI2S_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("QUIN_MI2S_RX", NULL,
0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_TX", NULL,
@@ -1037,6 +1042,7 @@ static void of_q6afe_parse_dai_data(struct device *dev,
switch (id) {
/* MI2S specific properties */
+ case SENARY_MI2S_RX ... SENARY_MI2S_TX:
case QUINARY_MI2S_RX ... QUINARY_MI2S_TX:
case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
priv = &data->priv[id];
diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c
index 76e14fc1b2b5..037a281d6f61 100644
--- a/sound/soc/qcom/qdsp6/q6afe.c
+++ b/sound/soc/qcom/qdsp6/q6afe.c
@@ -130,6 +130,8 @@
#define AFE_PORT_ID_QUATERNARY_MI2S_TX 0x1007
#define AFE_PORT_ID_QUINARY_MI2S_RX 0x1016
#define AFE_PORT_ID_QUINARY_MI2S_TX 0x1017
+#define AFE_PORT_ID_SENARY_MI2S_RX 0x1018
+#define AFE_PORT_ID_SENARY_MI2S_TX 0x1019
/* Start of the range of port IDs for TDM devices. */
#define AFE_PORT_ID_TDM_PORT_RANGE_START 0x9000
@@ -718,6 +720,10 @@ static struct afe_port_map port_maps[AFE_PORT_MAX] = {
QUINARY_MI2S_RX, 1, 1},
[QUINARY_MI2S_TX] = { AFE_PORT_ID_QUINARY_MI2S_TX,
QUINARY_MI2S_TX, 0, 1},
+ [SENARY_MI2S_RX] = { AFE_PORT_ID_SENARY_MI2S_RX,
+ SENARY_MI2S_RX, 1, 1},
+ [SENARY_MI2S_TX] = { AFE_PORT_ID_SENARY_MI2S_TX,
+ SENARY_MI2S_TX, 0, 1},
[PRIMARY_TDM_RX_0] = { AFE_PORT_ID_PRIMARY_TDM_RX,
PRIMARY_TDM_RX_0, 1, 1},
[PRIMARY_TDM_TX_0] = { AFE_PORT_ID_PRIMARY_TDM_TX,
diff --git a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
index d31388ed3ccf..e5cd82f77b55 100644
--- a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
+++ b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
@@ -519,6 +519,34 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = {
},
.id = QUINARY_MI2S_TX,
.name = "QUIN_MI2S_TX",
+ }, {
+ .playback = {
+ .stream_name = "Senary MI2S Playback",
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .id = SENARY_MI2S_RX,
+ .name = "SEN_MI2S_RX",
+ }, {
+ .capture = {
+ .stream_name = "Senary MI2S Capture",
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .id = SENARY_MI2S_TX,
+ .name = "SEN_MI2S_TX",
},
Q6AFE_MI2S_RX_DAI("LPI RX0", LPI_MI2S_RX_0),
Q6AFE_MI2S_RX_DAI("LPI RX1", LPI_MI2S_RX_1),
@@ -680,6 +708,7 @@ struct snd_soc_dai_driver *q6dsp_audio_ports_set_config(struct device *dev,
case SLIMBUS_0_RX ... SLIMBUS_6_TX:
q6dsp_audio_fe_dais[i].ops = cfg->q6slim_ops;
break;
+ case SENARY_MI2S_RX ... SENARY_MI2S_TX:
case QUINARY_MI2S_RX ... QUINARY_MI2S_TX:
case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
case LPI_MI2S_RX_0 ... LPI_MI2S_TX_4:
--
2.47.3
^ permalink raw reply [flat|nested] 22+ messages in thread* [PATCH 08/10] ASoC: qcom: q6apm-lpass-dai: move graph start to trigger
2026-02-05 17:14 [PATCH 00/10] ASoC: qcom: q6dsp: few fixes and enhancements Srinivas Kandagatla
` (6 preceding siblings ...)
2026-02-05 17:14 ` [PATCH 07/10] ASoC: qcom: q6dsp: Add Senary MI2S audio interface support Srinivas Kandagatla
@ 2026-02-05 17:14 ` Srinivas Kandagatla
2026-02-07 9:20 ` Dmitry Baryshkov
2026-02-05 17:14 ` [PATCH 09/10] ASoC: qcom: qdsp6: remove search for module iid in hot path Srinivas Kandagatla
2026-02-05 17:14 ` [PATCH 10/10] ASoC: qcom: q6apm: Add support for early buffer mapping on DSP Srinivas Kandagatla
9 siblings, 1 reply; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-05 17:14 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Srinivas Kandagatla
Start the graph at trigger callback. Staring the graph at prepare does
not make sense as there is no data transfer at this point.
Moving this to trigger will also helps fix some of the issues seen with
pipewire and display port. This should also fix some of the Qualcomm DP codec
issues discussed at https://lkml.org/lkml/2025/5/29/102
CC: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 39 +++++++++++++++++--------
1 file changed, 27 insertions(+), 12 deletions(-)
diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
index fc246485e326..21624a2803a6 100644
--- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
+++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
@@ -159,6 +159,30 @@ static void q6apm_lpass_dai_shutdown(struct snd_pcm_substream *substream, struct
}
}
+static int q6apm_lpass_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
+{
+ struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
+ int ret = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (!dai_data->is_port_started[dai->id]) {
+ ret = q6apm_graph_start(dai_data->graph[dai->id]);
+ if (ret < 0)
+ dev_err(dai->dev, "Failed to start APM port %d\n", dai->id);
+ else
+ dai_data->is_port_started[dai->id] = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
@@ -171,10 +195,6 @@ static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct s
q6apm_graph_stop(dai_data->graph[dai->id]);
dai_data->is_port_started[dai->id] = false;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- q6apm_graph_close(dai_data->graph[dai->id]);
- dai_data->graph[dai->id] = NULL;
- }
}
/**
@@ -203,14 +223,6 @@ static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct s
dev_err(dai->dev, "Failed to prepare Graph %d\n", rc);
goto err;
}
-
- rc = q6apm_graph_start(dai_data->graph[dai->id]);
- if (rc < 0) {
- dev_err(dai->dev, "Failed to start APM port %d\n", dai->id);
- goto err;
- }
- dai_data->is_port_started[dai->id] = true;
-
return 0;
err:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -254,6 +266,7 @@ static const struct snd_soc_dai_ops q6dma_ops = {
.shutdown = q6apm_lpass_dai_shutdown,
.set_channel_map = q6dma_set_channel_map,
.hw_params = q6dma_hw_params,
+ .trigger = q6apm_lpass_dai_trigger,
};
static const struct snd_soc_dai_ops q6i2s_ops = {
@@ -263,6 +276,7 @@ static const struct snd_soc_dai_ops q6i2s_ops = {
.set_channel_map = q6dma_set_channel_map,
.hw_params = q6dma_hw_params,
.set_fmt = q6i2s_set_fmt,
+ .trigger = q6apm_lpass_dai_trigger,
};
static const struct snd_soc_dai_ops q6hdmi_ops = {
@@ -271,6 +285,7 @@ static const struct snd_soc_dai_ops q6hdmi_ops = {
.shutdown = q6apm_lpass_dai_shutdown,
.hw_params = q6hdmi_hw_params,
.set_fmt = q6i2s_set_fmt,
+ .trigger = q6apm_lpass_dai_trigger,
};
static const struct snd_soc_component_driver q6apm_lpass_dai_component = {
--
2.47.3
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 08/10] ASoC: qcom: q6apm-lpass-dai: move graph start to trigger
2026-02-05 17:14 ` [PATCH 08/10] ASoC: qcom: q6apm-lpass-dai: move graph start to trigger Srinivas Kandagatla
@ 2026-02-07 9:20 ` Dmitry Baryshkov
0 siblings, 0 replies; 22+ messages in thread
From: Dmitry Baryshkov @ 2026-02-07 9:20 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: broonie, lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
konrad.dybcio, linux-arm-msm, linux-sound, devicetree,
linux-kernel
On Thu, Feb 05, 2026 at 12:14:09PM -0500, Srinivas Kandagatla wrote:
> Start the graph at trigger callback. Staring the graph at prepare does
> not make sense as there is no data transfer at this point.
> Moving this to trigger will also helps fix some of the issues seen with
> pipewire and display port. This should also fix some of the Qualcomm DP codec
> issues discussed at https://lkml.org/lkml/2025/5/29/102
There is exactly one issue discussed there. Is it now fixed or not? If
it is, then you need a proper Fixes, Reported-by, Closes, etc. If it is
not, please drop it from the commit message.
>
> CC: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> ---
> sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 39 +++++++++++++++++--------
> 1 file changed, 27 insertions(+), 12 deletions(-)
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 09/10] ASoC: qcom: qdsp6: remove search for module iid in hot path
2026-02-05 17:14 [PATCH 00/10] ASoC: qcom: q6dsp: few fixes and enhancements Srinivas Kandagatla
` (7 preceding siblings ...)
2026-02-05 17:14 ` [PATCH 08/10] ASoC: qcom: q6apm-lpass-dai: move graph start to trigger Srinivas Kandagatla
@ 2026-02-05 17:14 ` Srinivas Kandagatla
2026-02-05 17:14 ` [PATCH 10/10] ASoC: qcom: q6apm: Add support for early buffer mapping on DSP Srinivas Kandagatla
9 siblings, 0 replies; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-05 17:14 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Srinivas Kandagatla
Remove searching for Shared Memory module instance id on every
read/write call, this is ineffecient and becomes un-necessary
if we can cache the shared memory module instance id per PCM graph.
Add new member to graph struct to store sharedmemory module instance id
to avoid searching for this in hot path.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
sound/soc/qcom/qdsp6/q6apm-dai.c | 5 +++--
sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 4 ++--
sound/soc/qcom/qdsp6/q6apm.c | 14 +++++++++-----
sound/soc/qcom/qdsp6/q6apm.h | 3 ++-
4 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index 87e4474d680a..94066b69b5b5 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -355,7 +355,7 @@ static int q6apm_dai_open(struct snd_soc_component *component,
spin_lock_init(&prtd->lock);
prtd->substream = substream;
- prtd->graph = q6apm_graph_open(dev, event_handler, prtd, graph_id);
+ prtd->graph = q6apm_graph_open(dev, event_handler, prtd, graph_id, substream->stream);
if (IS_ERR(prtd->graph)) {
dev_err(dev, "%s: Could not allocate memory\n", __func__);
ret = PTR_ERR(prtd->graph);
@@ -496,7 +496,8 @@ static int q6apm_dai_compr_open(struct snd_soc_component *component,
return -ENOMEM;
prtd->cstream = stream;
- prtd->graph = q6apm_graph_open(dev, event_handler_compr, prtd, graph_id);
+ prtd->graph = q6apm_graph_open(dev, event_handler_compr, prtd, graph_id,
+ SNDRV_PCM_STREAM_PLAYBACK);
if (IS_ERR(prtd->graph)) {
ret = PTR_ERR(prtd->graph);
kfree(prtd);
diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
index 21624a2803a6..569ba1991992 100644
--- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
+++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
@@ -202,7 +202,7 @@ static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct s
* graph, so sequence for playback and capture will be different
*/
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && dai_data->graph[dai->id] == NULL) {
- graph = q6apm_graph_open(dai->dev, NULL, dai->dev, graph_id);
+ graph = q6apm_graph_open(dai->dev, NULL, dai->dev, graph_id, substream->stream);
if (IS_ERR(graph)) {
dev_err(dai->dev, "Failed to open graph (%d)\n", graph_id);
rc = PTR_ERR(graph);
@@ -239,7 +239,7 @@ static int q6apm_lpass_dai_startup(struct snd_pcm_substream *substream, struct s
int graph_id = dai->id;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- graph = q6apm_graph_open(dai->dev, NULL, dai->dev, graph_id);
+ graph = q6apm_graph_open(dai->dev, NULL, dai->dev, graph_id, substream->stream);
if (IS_ERR(graph)) {
dev_err(dai->dev, "Failed to open graph (%d)\n", graph_id);
return PTR_ERR(graph);
diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index 2cfebd622be2..282ba22938e7 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -411,12 +411,11 @@ int q6apm_write_async(struct q6apm_graph *graph, uint32_t len, uint32_t msw_ts,
{
struct apm_data_cmd_wr_sh_mem_ep_data_buffer_v2 *write_buffer;
struct audio_buffer *ab;
- int iid = q6apm_graph_get_rx_shmem_module_iid(graph);
struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_pkt(sizeof(*write_buffer),
DATA_CMD_WR_SH_MEM_EP_DATA_BUFFER_V2,
graph->rx_data.dsp_buf | (len << APM_WRITE_TOKEN_LEN_SHIFT),
- graph->port->id, iid);
+ graph->port->id, graph->shm_iid);
if (IS_ERR(pkt))
return PTR_ERR(pkt);
@@ -449,11 +448,10 @@ int q6apm_read(struct q6apm_graph *graph)
struct data_cmd_rd_sh_mem_ep_data_buffer_v2 *read_buffer;
struct audioreach_graph_data *port;
struct audio_buffer *ab;
- int iid = q6apm_graph_get_tx_shmem_module_iid(graph);
struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_pkt(sizeof(*read_buffer),
DATA_CMD_RD_SH_MEM_EP_DATA_BUFFER_V2,
- graph->tx_data.dsp_buf, graph->port->id, iid);
+ graph->tx_data.dsp_buf, graph->port->id, graph->shm_iid);
if (IS_ERR(pkt))
return PTR_ERR(pkt);
@@ -604,7 +602,7 @@ static int graph_callback(const struct gpr_resp_pkt *data, void *priv, int op)
}
struct q6apm_graph *q6apm_graph_open(struct device *dev, q6apm_cb cb,
- void *priv, int graph_id)
+ void *priv, int graph_id, int dir)
{
struct q6apm *apm = dev_get_drvdata(dev->parent);
struct audioreach_graph *ar_graph;
@@ -631,6 +629,12 @@ struct q6apm_graph *q6apm_graph_open(struct device *dev, q6apm_cb cb,
graph->id = ar_graph->id;
graph->dev = dev;
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK)
+ graph->shm_iid = q6apm_graph_get_rx_shmem_module_iid(graph);
+ else
+ graph->shm_iid = q6apm_graph_get_tx_shmem_module_iid(graph);
+
+
mutex_init(&graph->lock);
init_waitqueue_head(&graph->cmd_wait);
diff --git a/sound/soc/qcom/qdsp6/q6apm.h b/sound/soc/qcom/qdsp6/q6apm.h
index 189ed8a1a60d..19e223635edf 100644
--- a/sound/soc/qcom/qdsp6/q6apm.h
+++ b/sound/soc/qcom/qdsp6/q6apm.h
@@ -98,6 +98,7 @@ struct q6apm_graph {
void *priv;
q6apm_cb cb;
uint32_t id;
+ uint32_t shm_iid;
struct device *dev;
struct q6apm *apm;
gpr_port_t *port;
@@ -112,7 +113,7 @@ struct q6apm_graph {
/* Graph Operations */
struct q6apm_graph *q6apm_graph_open(struct device *dev, q6apm_cb cb,
- void *priv, int graph_id);
+ void *priv, int graph_id, int dir);
int q6apm_graph_close(struct q6apm_graph *graph);
int q6apm_graph_prepare(struct q6apm_graph *graph);
int q6apm_graph_start(struct q6apm_graph *graph);
--
2.47.3
^ permalink raw reply [flat|nested] 22+ messages in thread* [PATCH 10/10] ASoC: qcom: q6apm: Add support for early buffer mapping on DSP
2026-02-05 17:14 [PATCH 00/10] ASoC: qcom: q6dsp: few fixes and enhancements Srinivas Kandagatla
` (8 preceding siblings ...)
2026-02-05 17:14 ` [PATCH 09/10] ASoC: qcom: qdsp6: remove search for module iid in hot path Srinivas Kandagatla
@ 2026-02-05 17:14 ` Srinivas Kandagatla
9 siblings, 0 replies; 22+ messages in thread
From: Srinivas Kandagatla @ 2026-02-05 17:14 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, robh, krzk+dt, cnor+dt, srini, perex, tiwai,
alexey.klimov, mohammad.rafi.shaik, quic_wcheng, johan,
dmitry.baryshkov, konrad.dybcio, linux-arm-msm, linux-sound,
devicetree, linux-kernel, Srinivas Kandagatla
Buffers are allocated on pcm_new and mapped in the dsp on every prepare call,
which is inefficient and unnecessary.
Improve this situation by adding adding a functions
q6apm_[un]map_memory_fixed_region to map it on to dsp only once after
allocation.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
sound/soc/qcom/qdsp6/audioreach.c | 60 -----------
sound/soc/qcom/qdsp6/audioreach.h | 5 +-
sound/soc/qcom/qdsp6/q6apm-dai.c | 99 ++++++++++++++++---
sound/soc/qcom/qdsp6/q6apm.c | 159 ++++++++++++++++++++----------
sound/soc/qcom/qdsp6/q6apm.h | 15 ++-
5 files changed, 208 insertions(+), 130 deletions(-)
diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index 241c3b4479c6..b2975eebab71 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -1396,66 +1396,6 @@ void audioreach_graph_free_buf(struct q6apm_graph *graph)
}
EXPORT_SYMBOL_GPL(audioreach_graph_free_buf);
-int audioreach_map_memory_regions(struct q6apm_graph *graph, unsigned int dir, size_t period_sz,
- unsigned int periods, bool is_contiguous)
-{
- struct apm_shared_map_region_payload *mregions;
- struct apm_cmd_shared_mem_map_regions *cmd;
- uint32_t num_regions, buf_sz, payload_size;
- struct audioreach_graph_data *data;
- struct gpr_pkt *pkt __free(kfree) = NULL;
- void *p;
- int i;
-
- if (dir == SNDRV_PCM_STREAM_PLAYBACK)
- data = &graph->rx_data;
- else
- data = &graph->tx_data;
-
- if (is_contiguous) {
- num_regions = 1;
- buf_sz = period_sz * periods;
- } else {
- buf_sz = period_sz;
- num_regions = periods;
- }
-
- /* DSP expects size should be aligned to 4K */
- buf_sz = ALIGN(buf_sz, 4096);
-
- payload_size = sizeof(*cmd) + (sizeof(*mregions) * num_regions);
-
- pkt = audioreach_alloc_apm_pkt(payload_size, APM_CMD_SHARED_MEM_MAP_REGIONS, dir,
- graph->port->id);
- if (IS_ERR(pkt))
- return PTR_ERR(pkt);
-
- p = (void *)pkt + GPR_HDR_SIZE;
- cmd = p;
- cmd->mem_pool_id = APM_MEMORY_MAP_SHMEM8_4K_POOL;
- cmd->num_regions = num_regions;
-
- cmd->property_flag = 0x0;
-
- mregions = p + sizeof(*cmd);
-
- mutex_lock(&graph->lock);
-
- for (i = 0; i < num_regions; i++) {
- struct audio_buffer *ab;
-
- ab = &data->buf[i];
- mregions->shm_addr_lsw = lower_32_bits(ab->phys);
- mregions->shm_addr_msw = upper_32_bits(ab->phys);
- mregions->mem_size_bytes = buf_sz;
- ++mregions;
- }
- mutex_unlock(&graph->lock);
-
- return audioreach_graph_send_cmd_sync(graph, pkt, APM_CMD_RSP_SHARED_MEM_MAP_REGIONS);
-}
-EXPORT_SYMBOL_GPL(audioreach_map_memory_regions);
-
int audioreach_shared_memory_send_eos(struct q6apm_graph *graph)
{
struct data_cmd_wr_sh_mem_ep_eos *eos;
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index 89f172aab8c0..6ddc287f0fb4 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -722,6 +722,7 @@ struct audioreach_connection {
struct audioreach_graph_info {
int id;
+ uint32_t mem_map_handle;
uint32_t num_sub_graphs;
struct list_head sg_list;
/* DPCM connection from FE Graph to BE graph */
@@ -838,10 +839,6 @@ int audioreach_tplg_init(struct snd_soc_component *component);
/* Module specific */
void audioreach_graph_free_buf(struct q6apm_graph *graph);
-int audioreach_map_memory_regions(struct q6apm_graph *graph,
- unsigned int dir, size_t period_sz,
- unsigned int periods,
- bool is_contiguous);
int audioreach_send_cmd_sync(struct device *dev, gpr_device_t *gdev, struct gpr_ibasic_rsp_result_t *result,
struct mutex *cmd_lock, gpr_port_t *port, wait_queue_head_t *cmd_wait,
struct gpr_pkt *pkt, uint32_t rsp_opcode);
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index 94066b69b5b5..35ec05fa90bc 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -228,11 +228,10 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
cfg.bit_width = prtd->bits_per_sample;
cfg.fmt = SND_AUDIOCODEC_PCM;
audioreach_set_default_channel_mapping(cfg.channel_map, runtime->channels);
-
if (prtd->state) {
/* clear the previous setup if any */
q6apm_graph_stop(prtd->graph);
- q6apm_unmap_memory_regions(prtd->graph, substream->stream);
+ q6apm_free_fragments(prtd->graph, substream->stream);
}
prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
@@ -247,8 +246,8 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
if (ret < 0)
dev_err(dev, "%s: CMD Format block failed\n", __func__);
- ret = q6apm_map_memory_regions(prtd->graph, substream->stream, prtd->phys,
- (prtd->pcm_size / prtd->periods), prtd->periods);
+ ret = q6apm_alloc_fragments(prtd->graph, substream->stream, prtd->phys,
+ (prtd->pcm_size / prtd->periods), prtd->periods);
if (ret < 0) {
dev_err(dev, "Audio Start: Buffer Allocation failed rc = %d\n", ret);
@@ -403,6 +402,12 @@ static int q6apm_dai_open(struct snd_soc_component *component,
else
prtd->phys = substream->dma_buffer.addr | (pdata->sid << 32);
+ ret = q6apm_set_memory_map_handle(prtd->graph, substream->stream);
+ if (ret < 0) {
+ dev_err(dev, "Audio Start: Buffer Allocation failed rc = %d\n", ret);
+ goto err;
+ }
+
return 0;
err:
kfree(prtd);
@@ -416,9 +421,10 @@ static int q6apm_dai_close(struct snd_soc_component *component,
struct snd_pcm_runtime *runtime = substream->runtime;
struct q6apm_dai_rtd *prtd = runtime->private_data;
- if (prtd->state) { /* only stop graph that is started */
+ if (prtd->state) {
+ /* only stop graph that is started */
q6apm_graph_stop(prtd->graph);
- q6apm_unmap_memory_regions(prtd->graph, substream->stream);
+ q6apm_free_fragments(prtd->graph, substream->stream);
}
q6apm_graph_close(prtd->graph);
@@ -467,11 +473,80 @@ static int q6apm_dai_hw_params(struct snd_soc_component *component,
return 0;
}
+static int q6apm_dai_memory_map(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream, int graph_id)
+{
+ struct q6apm_dai_data *pdata;
+ struct device *dev = component->dev;
+ phys_addr_t phys;
+ int ret;
+
+ pdata = snd_soc_component_get_drvdata(component);
+ if (!pdata) {
+ dev_err(component->dev, "Drv data not found ..\n");
+ return -EINVAL;
+ }
+
+ if (pdata->sid < 0)
+ phys = substream->dma_buffer.addr;
+ else
+ phys = substream->dma_buffer.addr | (pdata->sid << 32);
+
+ ret = q6apm_map_memory_fixed_region(dev, graph_id, phys, BUFFER_BYTES_MAX);
+ if (ret < 0)
+ dev_err(dev, "Audio Start: Buffer Allocation failed rc = %d\n", ret);
+
+ return ret;
+}
+
static int q6apm_dai_pcm_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd)
{
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct snd_pcm *pcm = rtd->pcm;
int size = BUFFER_BYTES_MAX;
+ int graph_id, ret;
+ struct snd_pcm_substream *substream;
+
+ graph_id = cpu_dai->driver->id;
+
+ ret = snd_pcm_set_fixed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, component->dev, size);
+ if (ret)
+ return ret;
+
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+ substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ ret = q6apm_dai_memory_map(component, substream, graph_id);
+ if (ret)
+ return ret;
+ }
+
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
+ substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
+ q6apm_dai_memory_map(component, substream, graph_id);
+ if (ret)
+ return ret;
+ }
- return snd_pcm_set_fixed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, component->dev, size);
+ return 0;
+}
+
+static void q6apm_dai_pcm_destruct(struct snd_soc_component *component, struct snd_pcm *pcm)
+{
+ struct snd_pcm_substream *substream;
+ struct snd_soc_pcm_runtime *soc_prtd;
+ struct snd_soc_dai *cpu_dai;
+ int graph_id;
+
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
+ substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ else
+ substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
+
+ soc_prtd = snd_soc_substream_to_rtd(substream);
+ cpu_dai = snd_soc_rtd_to_cpu(soc_prtd, 0);
+
+ graph_id = cpu_dai->driver->id;
+ q6apm_unmap_memory_fixed_region(component->dev, graph_id);
}
static int q6apm_dai_compr_open(struct snd_soc_component *component,
@@ -530,7 +605,8 @@ static int q6apm_dai_compr_free(struct snd_soc_component *component,
struct q6apm_dai_rtd *prtd = runtime->private_data;
q6apm_graph_stop(prtd->graph);
- q6apm_unmap_memory_regions(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK);
+ q6apm_free_fragments(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK);
+ q6apm_unmap_memory_fixed_region(component->dev, prtd->graph->id);
q6apm_graph_close(prtd->graph);
snd_dma_free_pages(&prtd->dma_buffer);
prtd->graph = NULL;
@@ -679,9 +755,9 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
if (ret)
return ret;
- ret = q6apm_map_memory_regions(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK,
- prtd->phys, (prtd->pcm_size / prtd->periods),
- prtd->periods);
+ ret = q6apm_alloc_fragments(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK,
+ prtd->phys, (prtd->pcm_size / prtd->periods),
+ prtd->periods);
if (ret < 0)
return -ENOMEM;
@@ -834,6 +910,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = {
.close = q6apm_dai_close,
.prepare = q6apm_dai_prepare,
.pcm_construct = q6apm_dai_pcm_new,
+ .pcm_destruct = q6apm_dai_pcm_destruct,
.hw_params = q6apm_dai_hw_params,
.pointer = q6apm_dai_pointer,
.trigger = q6apm_dai_trigger,
diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index 282ba22938e7..7b5f76955cae 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -200,13 +200,61 @@ int q6apm_graph_media_format_shmem(struct q6apm_graph *graph,
}
EXPORT_SYMBOL_GPL(q6apm_graph_media_format_shmem);
-int q6apm_map_memory_regions(struct q6apm_graph *graph, unsigned int dir, phys_addr_t phys,
- size_t period_sz, unsigned int periods)
+int q6apm_set_memory_map_handle(struct q6apm_graph *graph, unsigned int dir)
+{
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK)
+ graph->rx_data.mem_map_handle = graph->info->mem_map_handle;
+ else
+ graph->tx_data.mem_map_handle = graph->info->mem_map_handle;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(q6apm_set_memory_map_handle);
+
+int q6apm_map_memory_fixed_region(struct device *dev, unsigned int graph_id, phys_addr_t phys,
+ size_t sz)
+{
+ struct audioreach_graph_info *info;
+ struct q6apm *apm = dev_get_drvdata(dev->parent);
+ struct apm_shared_map_region_payload *mregions;
+ struct apm_cmd_shared_mem_map_regions *cmd;
+ int payload_size = sizeof(*cmd) + (sizeof(*mregions));
+ uint32_t buf_sz;
+ void *p;
+ struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(payload_size,
+ APM_CMD_SHARED_MEM_MAP_REGIONS, graph_id);
+ if (IS_ERR(pkt))
+ return PTR_ERR(pkt);
+
+ info = idr_find(&apm->graph_info_idr, graph_id);
+ if (!info)
+ return -ENODEV;
+
+ /* DSP expects size should be aligned to 4K */
+ buf_sz = ALIGN(sz, 4096);
+
+ p = (void *)pkt + GPR_HDR_SIZE;
+ cmd = p;
+ cmd->mem_pool_id = APM_MEMORY_MAP_SHMEM8_4K_POOL;
+ cmd->num_regions = 1;
+ cmd->property_flag = 0x0;
+
+ mregions = p + sizeof(*cmd);
+
+ mregions->shm_addr_lsw = lower_32_bits(phys);
+ mregions->shm_addr_msw = upper_32_bits(phys);
+ mregions->mem_size_bytes = buf_sz;
+
+ return q6apm_send_cmd_sync(apm, pkt, APM_CMD_RSP_SHARED_MEM_MAP_REGIONS);
+}
+EXPORT_SYMBOL_GPL(q6apm_map_memory_fixed_region);
+
+int q6apm_alloc_fragments(struct q6apm_graph *graph, unsigned int dir, phys_addr_t phys,
+ size_t period_sz, unsigned int periods)
{
struct audioreach_graph_data *data;
struct audio_buffer *buf;
int cnt;
- int rc;
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
data = &graph->rx_data;
@@ -248,21 +296,37 @@ int q6apm_map_memory_regions(struct q6apm_graph *graph, unsigned int dir, phys_a
mutex_unlock(&graph->lock);
- rc = audioreach_map_memory_regions(graph, dir, period_sz, periods, 1);
- if (rc < 0) {
- dev_err(graph->dev, "Memory_map_regions failed\n");
- audioreach_graph_free_buf(graph);
- }
-
- return rc;
+ return 0;
}
-EXPORT_SYMBOL_GPL(q6apm_map_memory_regions);
+EXPORT_SYMBOL_GPL(q6apm_alloc_fragments);
-int q6apm_unmap_memory_regions(struct q6apm_graph *graph, unsigned int dir)
+int q6apm_unmap_memory_fixed_region(struct device *dev, unsigned int graph_id)
{
struct apm_cmd_shared_mem_unmap_regions *cmd;
+ struct q6apm *apm = dev_get_drvdata(dev->parent);
+ struct audioreach_graph_info *info;
+ struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(sizeof(*cmd),
+ APM_CMD_SHARED_MEM_UNMAP_REGIONS, graph_id);
+ if (IS_ERR(pkt))
+ return PTR_ERR(pkt);
+
+ info = idr_find(&apm->graph_info_idr, graph_id);
+ if (!info)
+ return -ENODEV;
+
+ if (!info->mem_map_handle)
+ return 0;
+
+ cmd = (void *)pkt + GPR_HDR_SIZE;
+ cmd->mem_map_handle = info->mem_map_handle;
+
+ return q6apm_send_cmd_sync(apm, pkt, APM_CMD_SHARED_MEM_UNMAP_REGIONS);
+}
+EXPORT_SYMBOL_GPL(q6apm_unmap_memory_fixed_region);
+
+int q6apm_free_fragments(struct q6apm_graph *graph, unsigned int dir)
+{
struct audioreach_graph_data *data;
- int rc;
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
data = &graph->rx_data;
@@ -272,22 +336,11 @@ int q6apm_unmap_memory_regions(struct q6apm_graph *graph, unsigned int dir)
if (!data->mem_map_handle)
return 0;
- struct gpr_pkt *pkt __free(kfree) =
- audioreach_alloc_apm_pkt(sizeof(*cmd), APM_CMD_SHARED_MEM_UNMAP_REGIONS,
- dir, graph->port->id);
- if (IS_ERR(pkt))
- return PTR_ERR(pkt);
-
- cmd = (void *)pkt + GPR_HDR_SIZE;
- cmd->mem_map_handle = data->mem_map_handle;
-
- rc = audioreach_graph_send_cmd_sync(graph, pkt, APM_CMD_SHARED_MEM_UNMAP_REGIONS);
-
audioreach_graph_free_buf(graph);
- return rc;
+ return 0;
}
-EXPORT_SYMBOL_GPL(q6apm_unmap_memory_regions);
+EXPORT_SYMBOL_GPL(q6apm_free_fragments);
int q6apm_remove_initial_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples)
{
@@ -494,7 +547,6 @@ static int graph_callback(const struct gpr_resp_pkt *data, void *priv, int op)
{
struct data_cmd_rsp_rd_sh_mem_ep_data_buffer_done_v2 *rd_done;
struct data_cmd_rsp_wr_sh_mem_ep_data_buffer_done_v2 *done;
- struct apm_cmd_rsp_shared_mem_map_regions *rsp;
const struct gpr_ibasic_rsp_result_t *result;
struct q6apm_graph *graph = priv;
const struct gpr_hdr *hdr = &data->hdr;
@@ -529,18 +581,6 @@ static int graph_callback(const struct gpr_resp_pkt *data, void *priv, int op)
done->buf_addr_msw);
}
- break;
- case APM_CMD_RSP_SHARED_MEM_MAP_REGIONS:
- graph->result.opcode = hdr->opcode;
- graph->result.status = 0;
- rsp = data->payload;
-
- if (hdr->token == SNDRV_PCM_STREAM_PLAYBACK)
- graph->rx_data.mem_map_handle = rsp->mem_map_handle;
- else
- graph->tx_data.mem_map_handle = rsp->mem_map_handle;
-
- wake_up(&graph->cmd_wait);
break;
case DATA_CMD_RSP_RD_SH_MEM_EP_DATA_BUFFER_V2:
if (!graph->ar_graph)
@@ -571,17 +611,6 @@ static int graph_callback(const struct gpr_resp_pkt *data, void *priv, int op)
break;
case GPR_BASIC_RSP_RESULT:
switch (result->opcode) {
- case APM_CMD_SHARED_MEM_UNMAP_REGIONS:
- graph->result.opcode = result->opcode;
- graph->result.status = 0;
- if (hdr->token == SNDRV_PCM_STREAM_PLAYBACK)
- graph->rx_data.mem_map_handle = 0;
- else
- graph->tx_data.mem_map_handle = 0;
-
- wake_up(&graph->cmd_wait);
- break;
- case APM_CMD_SHARED_MEM_MAP_REGIONS:
case DATA_CMD_WR_SH_MEM_EP_MEDIA_FORMAT:
case APM_CMD_SET_CFG:
graph->result.opcode = result->opcode;
@@ -773,7 +802,9 @@ struct audioreach_module *q6apm_find_module_by_mid(struct q6apm_graph *graph, ui
static int apm_callback(const struct gpr_resp_pkt *data, void *priv, int op)
{
gpr_device_t *gdev = priv;
+ struct audioreach_graph_info *info;
struct q6apm *apm = dev_get_drvdata(&gdev->dev);
+ struct apm_cmd_rsp_shared_mem_map_regions *rsp;
struct device *dev = &gdev->dev;
struct gpr_ibasic_rsp_result_t *result;
const struct gpr_hdr *hdr = &data->hdr;
@@ -790,6 +821,7 @@ static int apm_callback(const struct gpr_resp_pkt *data, void *priv, int op)
break;
case GPR_BASIC_RSP_RESULT:
switch (result->opcode) {
+ case APM_CMD_SHARED_MEM_MAP_REGIONS:
case APM_CMD_GRAPH_START:
case APM_CMD_GRAPH_OPEN:
case APM_CMD_GRAPH_PREPARE:
@@ -804,10 +836,37 @@ static int apm_callback(const struct gpr_resp_pkt *data, void *priv, int op)
result->opcode);
wake_up(&apm->wait);
break;
+ case APM_CMD_SHARED_MEM_UNMAP_REGIONS:
+ apm->result.opcode = hdr->opcode;
+ apm->result.status = 0;
+ rsp = data->payload;
+
+ info = idr_find(&apm->graph_info_idr, hdr->token);
+ if (info)
+ info->mem_map_handle = 0;
+ else
+ dev_err(dev, "Error (%d) Processing 0x%08x cmd\n", result->status,
+ result->opcode);
+ wake_up(&apm->wait);
+ break;
default:
break;
}
break;
+ case APM_CMD_RSP_SHARED_MEM_MAP_REGIONS:
+ apm->result.opcode = hdr->opcode;
+ apm->result.status = 0;
+ rsp = data->payload;
+
+ info = idr_find(&apm->graph_info_idr, hdr->token);
+ if (info)
+ info->mem_map_handle = rsp->mem_map_handle;
+ else
+ dev_err(dev, "Error (%d) Processing 0x%08x cmd\n", result->status,
+ result->opcode);
+
+ wake_up(&apm->wait);
+ break;
default:
break;
}
diff --git a/sound/soc/qcom/qdsp6/q6apm.h b/sound/soc/qcom/qdsp6/q6apm.h
index 19e223635edf..6bdc63c7dc01 100644
--- a/sound/soc/qcom/qdsp6/q6apm.h
+++ b/sound/soc/qcom/qdsp6/q6apm.h
@@ -133,11 +133,16 @@ int q6apm_write_async(struct q6apm_graph *graph, uint32_t len, uint32_t msw_ts,
uint32_t lsw_ts, uint32_t wflags);
/* Memory Map related */
-int q6apm_map_memory_regions(struct q6apm_graph *graph,
- unsigned int dir, phys_addr_t phys,
- size_t period_sz, unsigned int periods);
-int q6apm_unmap_memory_regions(struct q6apm_graph *graph,
- unsigned int dir);
+int q6apm_map_memory_fixed_region(struct device *dev,
+ unsigned int graph_id, phys_addr_t phys,
+ size_t sz);
+int q6apm_set_memory_map_handle(struct q6apm_graph *graph,
+ unsigned int dir);
+int q6apm_alloc_fragments(struct q6apm_graph *graph,
+ unsigned int dir, phys_addr_t phys,
+ size_t period_sz, unsigned int periods);
+int q6apm_free_fragments(struct q6apm_graph *graph, unsigned int dir);
+int q6apm_unmap_memory_fixed_region(struct device *dev, unsigned int graph_id);
/* Helpers */
int q6apm_send_cmd_sync(struct q6apm *apm, struct gpr_pkt *pkt,
uint32_t rsp_opcode);
--
2.47.3
^ permalink raw reply [flat|nested] 22+ messages in thread