mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Cezary Rojewski <cezary.rojewski@intel.com>
To: linux-sound@vger.kernel.org
Cc: broonie@kernel.org, tiwai@suse.com, perex@perex.cz,
	amade@asmblr.net, linux-kernel@vger.kernel.org,
	yung-chuan.liao@linux.intel.com, pierre-louis.bossart@linux.dev,
	vkoul@kernel.org, Cezary Rojewski <cezary.rojewski@intel.com>
Subject: [PATCH 2/7] soundwire: intel: Allow for dynamic assignment of PDIs
Date: Mon,  2 Nov 2026 19:10:37 +0100	[thread overview]
Message-ID: <20261102181042.1922005-3-cezary.rojewski@intel.com> (raw)
In-Reply-To: <20261102181042.1922005-1-cezary.rojewski@intel.com>

Currently, PDIs are assigned upfront based on the DAI IDs. Some drivers
do not assign anything upfront and request a free PDI when streaming is
about to start.

Provide assign/release() functions to allow them to be assigned
dynamically. This also streamlines the process of assigning/releasing
PDIs with what is done in HDAudio library (sound/hda) for HDAudio
streams, see snd_hdac_stream_assign/release().

As resource availability-check is typically done during dai->startup()
whilst hardware/firmware configuration occurs on dai->hw_params(), add
sdw_intel_pdi_config() to maintain this logical split - assign on
start(), configure on hw_params(). Existing code does all of that in
intel_hw_params() so the logical split is not possible.

Cc: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 drivers/soundwire/cadence_master.c    | 64 +++++++++++++++++++++++++++
 drivers/soundwire/cadence_master.h    | 24 ++--------
 drivers/soundwire/intel.c             | 16 +++++++
 include/linux/soundwire/sdw_cadence.h | 35 +++++++++++++++
 include/linux/soundwire/sdw_intel.h   |  7 +++
 5 files changed, 125 insertions(+), 21 deletions(-)
 create mode 100644 include/linux/soundwire/sdw_cadence.h

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index a0a63b76793e..9375db9c08a2 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -17,6 +17,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/soundwire/sdw_registers.h>
 #include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_cadence.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <linux/workqueue.h>
@@ -1835,6 +1836,7 @@ int sdw_cdns_probe(struct sdw_cdns *cdns)
 
 	mutex_init(&cdns->status_update_lock);
 
+	spin_lock_init(&cdns->pdi_lock);
 	INIT_WORK(&cdns->work, cdns_update_slave_status_work);
 	INIT_DELAYED_WORK(&cdns->attach_dwork, cdns_check_attached_status_dwork);
 
@@ -1991,6 +1993,68 @@ struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns,
 }
 EXPORT_SYMBOL(sdw_cdns_alloc_pdi);
 
+/**
+ * sdw_cdns_assign_pdi - Assign a PDI
+ * @bus: SoundWire bus instance
+ * @dir: Data direction
+ *
+ * Return: A valid PDI instance or %NULL if none available.
+ */
+struct sdw_cdns_pdi *sdw_cdns_assign_pdi(struct sdw_bus *bus, u32 dir)
+{
+	struct sdw_cdns *cdns = bus_to_cdns(bus);
+	struct sdw_cdns_streams *stream = &cdns->pcm;
+	struct sdw_cdns_pdi *pdis, *pdi;
+	size_t num_pdis;
+	int i;
+
+	if (dir == SDW_DATA_DIR_RX) {
+		num_pdis = stream->num_in;
+		pdis = stream->in;
+	} else {
+		num_pdis = stream->num_out;
+		pdis = stream->out;
+	}
+
+	spin_lock(&cdns->pdi_lock);
+	for (i = 0; i < num_pdis; i++) {
+		if (!pdis[i].assigned) {
+			pdi = &pdis[i];
+			goto found;
+		}
+	}
+
+	/* Indexes 0/1 are reserved for the Bulk transfer. */
+	for (i = 2; i < stream->num_bd; i++) {
+		if (!stream->bd[i].assigned) {
+			pdi = &stream->bd[i];
+			goto found;
+		}
+	}
+
+	spin_unlock(&cdns->pdi_lock);
+	return NULL;
+found:
+	pdi->dir = dir;
+	pdi->assigned = true;
+	spin_unlock(&cdns->pdi_lock);
+	return pdi;
+}
+EXPORT_SYMBOL(sdw_cdns_assign_pdi);
+
+/**
+ * sdw_cdns_release_pdi() - Release a PDI
+ * @pdi: PDI instance
+ */
+void sdw_cdns_release_pdi(struct sdw_bus *bus, struct sdw_cdns_pdi *pdi)
+{
+	struct sdw_cdns *cdns = bus_to_cdns(bus);
+
+	guard(spinlock)(&cdns->pdi_lock);
+	pdi->assigned = false;
+}
+EXPORT_SYMBOL(sdw_cdns_release_pdi);
+
 /*
  * the MIPI SoundWire CRC8 polynomial is X^8 + X^6 + X^3 + X^2 + 1, MSB first
  * The value is (1)01001101 = 0x4D
diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
index f4e41a9ab165..f52c9cbec8a9 100644
--- a/drivers/soundwire/cadence_master.h
+++ b/drivers/soundwire/cadence_master.h
@@ -6,6 +6,8 @@
 #ifndef __SDW_CADENCE_H
 #define __SDW_CADENCE_H
 
+#include <linux/soundwire/sdw_cadence.h>
+
 #define SDW_CADENCE_GSYNC_KHZ		4 /* 4 kHz */
 #define SDW_CADENCE_GSYNC_HZ		(SDW_CADENCE_GSYNC_KHZ * 1000)
 
@@ -17,27 +19,6 @@
 
 #define SDW_CADENCE_MCP_IP_OFFSET	0x4000
 
-/**
- * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance
- *
- * @num: pdi number
- * @intel_alh_id: link identifier
- * @l_ch_num: low channel for PDI
- * @h_ch_num: high channel for PDI
- * @ch_count: total channel count for PDI
- * @dir: data direction
- * @type: stream type, (only PCM supported)
- */
-struct sdw_cdns_pdi {
-	int num;
-	int intel_alh_id;
-	int l_ch_num;
-	int h_ch_num;
-	int ch_count;
-	enum sdw_data_direction dir;
-	enum sdw_stream_type type;
-};
-
 /**
  * struct sdw_cdns_streams: Cadence stream data structure
  *
@@ -140,6 +121,7 @@ struct sdw_cdns {
 	int num_ports;
 
 	struct sdw_cdns_streams pcm;
+	spinlock_t pdi_lock;
 
 	int pdi_loopback_source;
 	int pdi_loopback_target;
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index af65214836b4..d53fa3d299bc 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -674,6 +674,22 @@ intel_pdi_alh_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi)
 	intel_writel(alh, SDW_ALH_STRMZCFG(pdi->intel_alh_id), conf);
 }
 
+/**
+ * sdw_intel_pdi_config - Configure specified PDI
+ * @bus: SoundWire bus instance
+ * @pdi: PDI instance to configure
+ */
+void sdw_intel_pdi_config(struct sdw_bus *bus, struct sdw_cdns_pdi *pdi)
+{
+	struct sdw_cdns *cdns = bus_to_cdns(bus);
+	struct sdw_intel *sdw = cdns_to_intel(cdns);
+
+	intel_pdi_shim_configure(sdw, pdi);
+	intel_pdi_alh_configure(sdw, pdi);
+	sdw_cdns_config_stream(cdns, pdi->ch_count, pdi->dir, pdi);
+}
+EXPORT_SYMBOL(sdw_intel_pdi_config);
+
 static int intel_params_stream(struct sdw_intel *sdw,
 			       struct snd_pcm_substream *substream,
 			       struct snd_soc_dai *dai,
diff --git a/include/linux/soundwire/sdw_cadence.h b/include/linux/soundwire/sdw_cadence.h
new file mode 100644
index 000000000000..331b21adafc4
--- /dev/null
+++ b/include/linux/soundwire/sdw_cadence.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
+/* Copyright(c) 2024-2026 Intel Corporation */
+
+#ifndef ___SDW_CADENCE_H
+#define ___SDW_CADENCE_H
+
+#include <linux/soundwire/sdw.h>
+
+/**
+ * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance
+ *
+ * @num: pdi number
+ * @intel_alh_id: link identifier
+ * @l_ch_num: low channel for PDI
+ * @h_ch_num: high channel for PDI
+ * @ch_count: total channel count for PDI
+ * @dir: data direction
+ * @type: stream type, (only PCM supported)
+ * @assigned: whether PDI is in use
+ */
+struct sdw_cdns_pdi {
+	int num;
+	int intel_alh_id;
+	int l_ch_num;
+	int h_ch_num;
+	int ch_count;
+	enum sdw_data_direction dir;
+	enum sdw_stream_type type;
+	bool assigned;
+};
+
+struct sdw_cdns_pdi *sdw_cdns_assign_pdi(struct sdw_bus *bus, u32 dir);
+void sdw_cdns_release_pdi(struct sdw_bus *bus, struct sdw_cdns_pdi *pdi);
+
+#endif
diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h
index 83021cc0f5b8..120f16b8d478 100644
--- a/include/linux/soundwire/sdw_intel.h
+++ b/include/linux/soundwire/sdw_intel.h
@@ -7,6 +7,7 @@
 #include <linux/acpi.h>
 #include <linux/irqreturn.h>
 #include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_cadence.h>
 
 /*********************************************************************
  * cAVS and ACE1.x definitions
@@ -386,6 +387,8 @@ void sdw_intel_exit(struct sdw_intel_ctx *ctx);
 
 irqreturn_t sdw_intel_thread(int irq, void *dev_id);
 
+void sdw_intel_pdi_config(struct sdw_bus *bus, struct sdw_cdns_pdi *pdi);
+
 #else
 
 static inline int sdw_intel_acpi_scan(acpi_handle parent_handle, struct sdw_intel_acpi_info *info)
@@ -416,6 +419,10 @@ static inline irqreturn_t sdw_intel_thread(int irq, void *dev_id)
 	return 0;
 }
 
+static inline void sdw_intel_pdi_config(struct sdw_bus *bus, struct sdw_cdns_pdi *pdi)
+{
+}
+
 #endif
 
 #define SDW_INTEL_QUIRK_MASK_BUS_DISABLE      BIT(1)
-- 
2.34.1


  parent reply	other threads:[~2026-11-02 18:03 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02 18:10 [PATCH 0/7] ASoC: Intel: avs: Soundwire support Cezary Rojewski
2026-11-02 18:10 ` [PATCH 1/7] soundwire: intel: Define stubs when library is disabled Cezary Rojewski
2026-11-02 18:10 ` Cezary Rojewski [this message]
2026-11-02 18:10 ` [PATCH 3/7] soundwire: intel: Split PDIs and DAIs initialization Cezary Rojewski
2026-11-02 18:10 ` [PATCH 4/7] ASoC: Intel: avs: Pass irq to dsp_interrupt callback Cezary Rojewski
2026-11-02 18:10 ` [PATCH 5/7] ASoC: Intel: avs: SoundWire support Cezary Rojewski
2026-11-02 18:10 ` [PATCH 6/7] ASoC: Intel: avs: Expose common PCM functions Cezary Rojewski
2026-11-02 18:18   ` Amadeusz Sławiński
2026-11-02 18:20     ` Cezary Rojewski
2026-11-02 18:10 ` [PATCH 7/7] ASoC: Intel: avs: SoundWire PCM BE operations Cezary Rojewski

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=20261102181042.1922005-3-cezary.rojewski@intel.com \
    --to=cezary.rojewski@intel.com \
    --cc=amade@asmblr.net \
    --cc=broonie@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=pierre-louis.bossart@linux.dev \
    --cc=tiwai@suse.com \
    --cc=vkoul@kernel.org \
    --cc=yung-chuan.liao@linux.intel.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

all inboxes | Powered by JetHome®