All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update
@ 2023-03-27 11:29 Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 01/18] Documentation: sound: add description of Intel HDaudio multi-links Peter Ujfalusi
                   ` (17 more replies)
  0 siblings, 18 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

Hi,

The following series adds the core support to handle the recently updated
HDaudio multi-link support to hanlde non HDA links, like SoundWire/DMIC/SSP on
Intel platform.

For details, please see the first patch which documents the current mlink
support (introduced at Skylake) and the new extensions, arriving with LNL.

There is no change in functionality for existing HDA support, the extension is
backwards compatible with existing implementations.

Regards,
Peter
---
Pierre-Louis Bossart (18):
  Documentation: sound: add description of Intel HDaudio multi-links
  ALSA: hda: add HDaudio Extended link definitions
  ASoC: SOF: Intel: hda-mlink: improve hda_bus_ml_free() helper
  ASoC: SOF: Intel: hda-mlink: add return value for
    hda_bus_ml_get_capabilities()
  ASoC: SOF: Intel: hda-mlink: move to a dedicated module
  ASoC: SOF: Intel: hda-mlink: add structures to parse ALT links
  ASoC: SOF: Intel: hda-mlink: special-case HDaudio regular links
  ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM
  ASoC: SOF: Intel: hda-mlink: add convenience helpers for SoundWire PM
  ASoC: SOF: Intel: hda-mlink: add helper to return sublink count
  ASoC: SOF: Intel: hda-mlink: add helpers to enable/check interrupts
  ASoC: SOF: Intel: hda-mlink: add helpers to set link SYNC frequency
  ASoC: SOF: Intel: hda-mlink: add helpers for sync_arm/sync_go
  ASoC: SOF: Intel: hda-mlink: add helper to check cmdsync
  ASoC: SOF: Intel: hda-mlink: program SoundWire LSDIID registers
  ASoC: SOF: Intel: hda-mlink: add helpers to retrieve DMIC/SSP hlink
  ASoC: SOF: Intel: hda-mlink: add helper to offload link ownership
  ASoC: SOF: Intel: hda-mlink: add helper to retrieve eml_lock

 Documentation/sound/hd-audio/index.rst        |   1 +
 .../sound/hd-audio/intel-multi-link.rst       | 312 +++++++
 include/sound/hda-mlink.h                     | 166 ++++
 include/sound/hda_register.h                  |  40 +-
 sound/soc/sof/intel/Kconfig                   |   7 +
 sound/soc/sof/intel/Makefile                  |   5 +-
 sound/soc/sof/intel/hda-ctrl.c                |   1 +
 sound/soc/sof/intel/hda-dsp.c                 |   1 +
 sound/soc/sof/intel/hda-mlink.c               | 822 +++++++++++++++++-
 sound/soc/sof/intel/hda.c                     |   2 +
 sound/soc/sof/intel/hda.h                     |  20 -
 11 files changed, 1331 insertions(+), 46 deletions(-)
 create mode 100644 Documentation/sound/hd-audio/intel-multi-link.rst
 create mode 100644 include/sound/hda-mlink.h

-- 
2.40.0


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/18] Documentation: sound: add description of Intel HDaudio multi-links
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 02/18] ALSA: hda: add HDaudio Extended link definitions Peter Ujfalusi
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Add description of 'Skylake' multi-link structure added in 2015 and
recent extensions to support SoundWire/DMIC/SSP interfaces.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 Documentation/sound/hd-audio/index.rst        |   1 +
 .../sound/hd-audio/intel-multi-link.rst       | 312 ++++++++++++++++++
 2 files changed, 313 insertions(+)
 create mode 100644 Documentation/sound/hd-audio/intel-multi-link.rst

diff --git a/Documentation/sound/hd-audio/index.rst b/Documentation/sound/hd-audio/index.rst
index 6e12de9fc34e..baefe4a5d165 100644
--- a/Documentation/sound/hd-audio/index.rst
+++ b/Documentation/sound/hd-audio/index.rst
@@ -9,3 +9,4 @@ HD-Audio
    controls
    dp-mst
    realtek-pc-beep
+   intel-multi-link
diff --git a/Documentation/sound/hd-audio/intel-multi-link.rst b/Documentation/sound/hd-audio/intel-multi-link.rst
new file mode 100644
index 000000000000..bf0bb78833e7
--- /dev/null
+++ b/Documentation/sound/hd-audio/intel-multi-link.rst
@@ -0,0 +1,312 @@
+.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+.. include:: <isonum.txt>
+
+================================================
+HDAudio multi-link extensions on Intel platforms
+================================================
+
+:Copyright: |copy| 2023 Intel Corporation
+
+This file documents the 'multi-link structure' introduced in 2015 with
+the Skylake processor and recently extended in newer Intel platforms
+
+HDaudio existing link mapping (2015 addition in SkyLake)
+========================================================
+
+External HDAudio codecs are handled with link #0, while iDISP codec
+for HDMI/DisplayPort is handled with link #1.
+
+The only change to the 2015 definitions is the declaration of the
+LCAP.ALT=0x0 - since the ALT bit was previously reserved, this is a
+backwards-compatible change.
+
+LCTL.SPA and LCTL.CPA are automatically set when exiting reset. They
+are only used in existing drivers when the SCF value needs to be
+corrected.
+
+Basic structure for HDaudio codecs
+----------------------------------
+
+::
+
+  +-----------+
+  | ML cap #0 |
+  +-----------+
+  | ML cap #1 |---+
+  +-----------+   |
+                  |
+                  +--> 0x0 +---------------+ LCAP
+                           | ALT=0         |
+                           +---------------+
+                           | S192          |
+                           +---------------+
+                           | S96           |
+                           +---------------+
+                           | S48           |
+                           +---------------+
+                           | S24           |
+                           +---------------+
+                           | S12           |
+                           +---------------+
+                           | S6            |
+                           +---------------+
+
+                       0x4 +---------------+ LCTL
+                           | INTSTS        |
+                           +---------------+
+                           | CPA           |
+                           +---------------+
+                           | SPA           |
+                           +---------------+
+                           | SCF           |
+                           +---------------+
+
+                       0x8 +---------------+ LOSIDV
+                           | L1OSIVD15     |
+                           +---------------+
+                           | L1OSIDV..     |
+                           +---------------+
+                           | L1OSIDV1      |
+                           +---------------+
+
+                       0xC +---------------+ LSDIID
+                           | SDIID14       |
+                           +---------------+
+                           | SDIID...      |
+                           +---------------+
+                           | SDIID0        |
+                           +---------------+
+
+SoundWire HDaudio extended link mapping
+=======================================
+
+A SoundWire extended link is identified when LCAP.ALT=1 and
+LEPTR.ID=0.
+
+DMA control uses the existing LOSIDV register.
+
+Changes include additional descriptions for enumeration that were not
+present in earlier generations.
+
+- multi-link synchronization: capabilities in LCAP.LSS and control in LSYNC
+- number of sublinks (manager IP) in LCAP.LSCOUNT
+- power management moved from SHIM to LCTL.SPA bits
+- hand-over to the DSP for access to multi-link registers, SHIM/IP with LCTL.OFLEN
+- mapping of SoundWire codecs to SDI ID bits
+- move of SHIM and Cadence registers to different offsets, with no
+  change in functionality. The LEPTR.PTR value is an offset from the
+  ML address, with a default value of 0x30000.
+
+Extended structure for SoundWire (assuming 4 Manager IP)
+--------------------------------------------------------
+
+::
+
+  +-----------+
+  | ML cap #0 |
+  +-----------+
+  | ML cap #1 |
+  +-----------+
+  | ML cap #2 |---+
+  +-----------+   |
+                  |
+                  +--> 0x0 +---------------+ LCAP
+                           | ALT=1         |
+                           +---------------+
+                           | INTC          |
+                           +---------------+
+                           | OFLS          |
+                           +---------------+
+                           | LSS           |
+                           +---------------+
+                           | SLCOUNT=4     |-----------+
+                           +---------------+           |
+                                                       |
+                       0x4 +---------------+ LCTL      |
+                           | INTSTS        |           |
+                           +---------------+           |
+                           | CPA (x bits)  |           |
+                           +---------------+           |
+                           | SPA (x bits)  |           |
+                           +---------------+         for each sublink x
+                           | INTEN         |           |
+                           +---------------+           |
+                           | OFLEN         |           |
+                           +---------------+           |
+                                                       |
+                       0x8 +---------------+ LOSIDV    |
+                           | L1OSIVD15     |           |
+                           +---------------+           |
+                           | L1OSIDV..     |           |
+                           +---------------+           |
+                           | L1OSIDV1      |       +---+----------------------------------------------------------+
+                           +---------------+       |                                                              |
+                                                   v                                                              |
+             0xC + 0x2 * x +---------------+ LSDIIDx    +---> 0x30000  +-----------------+  0x00030000            |
+                           | SDIID14       |            |              | SoundWire SHIM  |                        |
+                           +---------------+            |              | generic         |                        |
+                           | SDIID...      |            |              +-----------------+  0x00030100            |
+                           +---------------+            |              | SoundWire IP    |                        |
+                           | SDIID0        |            |              +-----------------+  0x00036000            |
+                           +---------------+            |              | SoundWire SHIM  |                        |
+                                                        |              | vendor-specific |                        |
+                      0x1C +---------------+ LSYNC      |              +-----------------+                        |
+                           | CMDSYNC       |            |                                                         v
+                           +---------------+            |              +-----------------+  0x00030000 + 0x8000 * x
+                           | SYNCGO        |            |              | SoundWire SHIM  |
+                           +---------------+            |              | generic         |
+                           | SYNCPU        |            |              +-----------------+  0x00030100 + 0x8000 * x
+                           +---------------+            |              | SoundWire IP    |
+                           | SYNPRD        |            |              +-----------------+  0x00036000 + 0x8000 * x
+                           +---------------+            |              | SoundWire SHIM  |
+                                                        |              | vendor-specific |
+                      0x20 +---------------+ LEPTR      |              +-----------------+
+                           | ID = 0        |            |
+                           +---------------+            |
+                           | VER           |            |
+                           +---------------+            |
+                           | PTR           |------------+
+                           +---------------+
+
+
+DMIC HDaudio extended link mapping
+==================================
+
+A DMIC extended link is identified when LCAP.ALT=1 and
+LEPTR.ID=0xC1 are set.
+
+DMA control uses the existing LOSIDV register
+
+Changes include additional descriptions for enumeration that were not
+present in earlier generations.
+
+- multi-link synchronization: capabilities in LCAP.LSS and control in LSYNC
+- power management with LCTL.SPA bits
+- hand-over to the DSP for access to multi-link registers, SHIM/IP with LCTL.OFLEN
+
+- move of DMIC registers to different offsets, with no change in
+  functionality. The LEPTR.PTR value is an offset from the ML
+  address, with a default value of 0x10000.
+
+Extended structure for DMIC
+---------------------------
+
+::
+
+  +-----------+
+  | ML cap #0 |
+  +-----------+
+  | ML cap #1 |
+  +-----------+
+  | ML cap #2 |---+
+  +-----------+   |
+                  |
+                  +--> 0x0 +---------------+ LCAP
+                           | ALT=1         |
+                           +---------------+
+                           | INTC          |
+                           +---------------+
+                           | OFLS          |
+                           +---------------+
+                           | SLCOUNT=1     |
+                           +---------------+
+
+                       0x4 +---------------+ LCTL
+                           | INTSTS        |
+                           +---------------+
+                           | CPA           |
+                           +---------------+
+                           | SPA           |
+                           +---------------+
+                           | INTEN         |
+                           +---------------+
+                           | OFLEN         |
+                           +---------------+           +---> 0x10000  +-----------------+  0x00010000
+                                                       |              | DMIC SHIM       |
+                       0x8 +---------------+ LOSIDV    |              | generic         |
+                           | L1OSIVD15     |           |              +-----------------+  0x00010100
+                           +---------------+           |              | DMIC IP         |
+                           | L1OSIDV..     |           |              +-----------------+  0x00016000
+                           +---------------+           |              | DMIC SHIM       |
+                           | L1OSIDV1      |           |              | vendor-specific |
+                           +---------------+           |              +-----------------+
+                                                       |
+                      0x20 +---------------+ LEPTR     |
+                           | ID = 0xC1     |           |
+                           +---------------+           |
+                           | VER           |           |
+                           +---------------+           |
+                           | PTR           |-----------+
+                           +---------------+
+
+
+SSP HDaudio extended link mapping
+=================================
+
+A DMIC extended link is identified when LCAP.ALT=1 and
+LEPTR.ID=0xC0 are set.
+
+DMA control uses the existing LOSIDV register
+
+Changes include additional descriptions for enumeration and control that were not
+present in earlier generations:
+- number of sublinks (SSP IP instances) in LCAP.LSCOUNT
+- power management moved from SHIM to LCTL.SPA bits
+- hand-over to the DSP for access to multi-link registers, SHIM/IP
+with LCTL.OFLEN
+- move of SHIM and SSP IP registers to different offsets, with no
+change in functionality.  The LEPTR.PTR value is an offset from the ML
+address, with a default value of 0x28000.
+
+Extended structure for SSP (assuming 3 instances of the IP)
+-----------------------------------------------------------
+
+::
+
+  +-----------+
+  | ML cap #0 |
+  +-----------+
+  | ML cap #1 |
+  +-----------+
+  | ML cap #2 |---+
+  +-----------+   |
+                  |
+                  +--> 0x0 +---------------+ LCAP
+                           | ALT=1         |
+                           +---------------+
+                           | INTC          |
+                           +---------------+
+                           | OFLS          |
+                           +---------------+
+                           | SLCOUNT=3     |-------------------------for each sublink x -------------------------+
+                           +---------------+                                                                     |
+                                                                                                                 |
+                       0x4 +---------------+ LCTL                                                                |
+                           | INTSTS        |                                                                     |
+                           +---------------+                                                                     |
+                           | CPA (x bits)  |                                                                     |
+                           +---------------+                                                                     |
+                           | SPA (x bits)  |                                                                     |
+                           +---------------+                                                                     |
+                           | INTEN         |                                                                     |
+                           +---------------+                                                                     |
+                           | OFLEN         |                                                                     |
+                           +---------------+           +---> 0x28000  +-----------------+  0x00028000            |
+                                                       |              | SSP SHIM        |                        |
+                       0x8 +---------------+ LOSIDV    |              | generic         |                        |
+                           | L1OSIVD15     |           |              +-----------------+  0x00028100            |
+                           +---------------+           |              | SSP IP          |                        |
+                           | L1OSIDV..     |           |              +-----------------+  0x00028C00            |
+                           +---------------+           |              | SSP SHIM        |                        |
+                           | L1OSIDV1      |           |              | vendor-specific |                        |
+                           +---------------+           |              +-----------------+                        |
+                                                       |                                                         v
+                      0x20 +---------------+ LEPTR     |              +-----------------+  0x00028000 + 0x1000 * x
+                           | ID = 0xC0     |           |              | SSP SHIM        |
+                           +---------------+           |              | generic         |
+                           | VER           |           |              +-----------------+  0x00028100 + 0x1000 * x
+                           +---------------+           |              | SSP IP          |
+                           | PTR           |-----------+              +-----------------+  0x00028C00 + 0x1000 * x
+                           +---------------+                          | SSP SHIM        |
+                                                                      | vendor-specific |
+                                                                      +-----------------+
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 02/18] ALSA: hda: add HDaudio Extended link definitions
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 01/18] Documentation: sound: add description of Intel HDaudio multi-links Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 03/18] ASoC: SOF: Intel: hda-mlink: improve hda_bus_ml_free() helper Peter Ujfalusi
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Add new definitions for the HDaudio Extended link support,
specifically new registers for SoundWire, Intel DMIC and INTEL SSP
interfaces.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda_register.h | 40 ++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h
index d37cf43546eb..9c7872c0ca79 100644
--- a/include/sound/hda_register.h
+++ b/include/sound/hda_register.h
@@ -258,14 +258,27 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 #define AZX_ML_BASE			0x40
 #define AZX_ML_INTERVAL			0x40
 
+/* HDaudio registers valid for HDaudio and HDaudio extended links */
 #define AZX_REG_ML_LCAP			0x00
-#define AZX_REG_ML_LCTL			0x04
 
+#define AZX_ML_HDA_LCAP_ALT		BIT(28)
+#define AZX_ML_HDA_LCAP_ALT_HDA		0x0
+#define AZX_ML_HDA_LCAP_ALT_HDA_EXT	0x1
+
+#define AZX_ML_HDA_LCAP_INTC		BIT(27)		/* only used if ALT == 1 */
+#define AZX_ML_HDA_LCAP_OFLS		BIT(26)		/* only used if ALT == 1 */
+#define AZX_ML_HDA_LCAP_LSS		BIT(23)		/* only used if ALT == 1 */
+#define AZX_ML_HDA_LCAP_SLCOUNT		GENMASK(22, 20)	/* only used if ALT == 1 */
+
+#define AZX_REG_ML_LCTL			0x04
+#define AZX_ML_LCTL_INTSTS		BIT(31)		/* only used if ALT == 1 */
 #define AZX_ML_LCTL_CPA			BIT(23)
 #define AZX_ML_LCTL_CPA_SHIFT		23
 #define AZX_ML_LCTL_SPA			BIT(16)
 #define AZX_ML_LCTL_SPA_SHIFT		16
-#define AZX_ML_LCTL_SCF			GENMASK(3, 0)
+#define AZX_ML_LCTL_INTEN		BIT(5)		/* only used if ALT == 1 */
+#define AZX_ML_LCTL_OFLEN		BIT(4)		/* only used if ALT == 1 */
+#define AZX_ML_LCTL_SCF			GENMASK(3, 0)	/* only used if ALT == 0 */
 
 #define AZX_REG_ML_LOSIDV		0x08
 
@@ -273,12 +286,35 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 #define AZX_ML_LOSIDV_STREAM_MASK	0xFFFE
 
 #define AZX_REG_ML_LSDIID		0x0C
+#define AZX_REG_ML_LSDIID_OFFSET(x)	(0x0C + (x) * 0x02)	/* only used if ALT == 1 */
+
+/* HDaudio registers only valid if LCAP.ALT == 0 */
 #define AZX_REG_ML_LPSOO		0x10
 #define AZX_REG_ML_LPSIO		0x12
 #define AZX_REG_ML_LWALFC		0x18
 #define AZX_REG_ML_LOUTPAY		0x20
 #define AZX_REG_ML_LINPAY		0x30
 
+/* HDaudio Extended link registers only valid if LCAP.ALT == 1 */
+#define AZX_REG_ML_LSYNC		0x1C
+
+#define AZX_REG_ML_LSYNC_CMDSYNC	BIT(24)
+#define AZX_REG_ML_LSYNC_CMDSYNC_SHIFT	24
+#define AZX_REG_ML_LSYNC_SYNCGO		BIT(23)
+#define AZX_REG_ML_LSYNC_SYNCPU		BIT(20)
+#define AZX_REG_ML_LSYNC_SYNCPRD	GENMASK(19, 0)
+
+#define AZX_REG_ML_LEPTR		0x20
+
+#define AZX_REG_ML_LEPTR_ID		GENMASK(31, 24)
+#define AZX_REG_ML_LEPTR_ID_SHIFT	24
+#define AZX_REG_ML_LEPTR_ID_SDW		0x00
+#define AZX_REG_ML_LEPTR_ID_INTEL_SSP	0xC0
+#define AZX_REG_ML_LEPTR_ID_INTEL_DMIC  0xC1
+#define AZX_REG_ML_LEPTR_ID_INTEL_UAOL  0xC2
+#define AZX_REG_ML_LEPTR_VER		GENMASK(23, 20)
+#define AZX_REG_ML_LEPTR_PTR		GENMASK(19, 0)
+
 /* registers for DMA Resume Capability Structure */
 #define AZX_DRSM_CAP_ID			0x5
 #define AZX_REG_DRSM_CTL		0x4
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 03/18] ASoC: SOF: Intel: hda-mlink: improve hda_bus_ml_free() helper
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 01/18] Documentation: sound: add description of Intel HDaudio multi-links Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 02/18] ALSA: hda: add HDaudio Extended link definitions Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 04/18] ASoC: SOF: Intel: hda-mlink: add return value for hda_bus_ml_get_capabilities() Peter Ujfalusi
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Use list_for_each_entry_safe() instead of open-coding.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 sound/soc/sof/intel/hda-mlink.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index 76ab9a2e7bb3..ac9bf477f413 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -36,13 +36,12 @@ void hda_bus_ml_get_capabilities(struct hdac_bus *bus)
 
 void hda_bus_ml_free(struct hdac_bus *bus)
 {
-	struct hdac_ext_link *hlink;
+	struct hdac_ext_link *hlink, *_h;
 
 	if (!bus->mlcap)
 		return;
 
-	while (!list_empty(&bus->hlink_list)) {
-		hlink = list_first_entry(&bus->hlink_list, struct hdac_ext_link, list);
+	list_for_each_entry_safe(hlink, _h, &bus->hlink_list, list) {
 		list_del(&hlink->list);
 		kfree(hlink);
 	}
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 04/18] ASoC: SOF: Intel: hda-mlink: add return value for hda_bus_ml_get_capabilities()
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (2 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 03/18] ASoC: SOF: Intel: hda-mlink: improve hda_bus_ml_free() helper Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 05/18] ASoC: SOF: Intel: hda-mlink: move to a dedicated module Peter Ujfalusi
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Add return value - this will need additional work in the caller.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 sound/soc/sof/intel/hda-mlink.c | 5 +++--
 sound/soc/sof/intel/hda.h       | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index ac9bf477f413..e426d5e41e52 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -28,10 +28,11 @@
 
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 
-void hda_bus_ml_get_capabilities(struct hdac_bus *bus)
+int hda_bus_ml_get_capabilities(struct hdac_bus *bus)
 {
 	if (bus->mlcap)
-		snd_hdac_ext_bus_get_ml_capabilities(bus);
+		return snd_hdac_ext_bus_get_ml_capabilities(bus);
+	return 0;
 }
 
 void hda_bus_ml_free(struct hdac_bus *bus)
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 2a43bfc14583..259b34eea677 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -765,7 +765,7 @@ static inline int hda_codec_i915_exit(struct snd_sof_dev *sdev) { return 0; }
 
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 
-void hda_bus_ml_get_capabilities(struct hdac_bus *bus);
+int hda_bus_ml_get_capabilities(struct hdac_bus *bus);
 void hda_bus_ml_free(struct hdac_bus *bus);
 void hda_bus_ml_put_all(struct hdac_bus *bus);
 void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
@@ -774,7 +774,7 @@ int hda_bus_ml_suspend(struct hdac_bus *bus);
 
 #else
 
-static inline void hda_bus_ml_get_capabilities(struct hdac_bus *bus) { }
+static inline int hda_bus_ml_get_capabilities(struct hdac_bus *bus) { return 0; }
 static inline void hda_bus_ml_free(struct hdac_bus *bus) { }
 static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
 static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 05/18] ASoC: SOF: Intel: hda-mlink: move to a dedicated module
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (3 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 04/18] ASoC: SOF: Intel: hda-mlink: add return value for hda_bus_ml_get_capabilities() Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 06/18] ASoC: SOF: Intel: hda-mlink: add structures to parse ALT links Peter Ujfalusi
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Some of the functions will be used for SoundWire enumeration and power
management, to avoid cycles in module dependencies and simplify
integration all the HDaudio multi-link needs to move to a dedicated
module.

Drop no longer needed headers at the same time.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       | 31 +++++++++++++++++++++++++++++++
 sound/soc/sof/intel/Kconfig     |  7 +++++++
 sound/soc/sof/intel/Makefile    |  5 ++++-
 sound/soc/sof/intel/hda-ctrl.c  |  1 +
 sound/soc/sof/intel/hda-dsp.c   |  1 +
 sound/soc/sof/intel/hda-mlink.c | 24 +++++++++++-------------
 sound/soc/sof/intel/hda.c       |  2 ++
 sound/soc/sof/intel/hda.h       | 20 --------------------
 8 files changed, 57 insertions(+), 34 deletions(-)
 create mode 100644 include/sound/hda-mlink.h

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
new file mode 100644
index 000000000000..beef5f509e47
--- /dev/null
+++ b/include/sound/hda-mlink.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Copyright(c) 2022-2023 Intel Corporation. All rights reserved.
+ */
+
+struct hdac_bus;
+
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_MLINK)
+
+int hda_bus_ml_get_capabilities(struct hdac_bus *bus);
+void hda_bus_ml_free(struct hdac_bus *bus);
+void hda_bus_ml_put_all(struct hdac_bus *bus);
+void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
+int hda_bus_ml_resume(struct hdac_bus *bus);
+int hda_bus_ml_suspend(struct hdac_bus *bus);
+
+#else
+
+static inline int
+hda_bus_ml_get_capabilities(struct hdac_bus *bus) { return 0; }
+
+static inline void hda_bus_ml_free(struct hdac_bus *bus) { }
+static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
+static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
+static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }
+static inline int hda_bus_ml_suspend(struct hdac_bus *bus) { return 0; }
+
+#endif /* CONFIG_SND_SOC_SOF_HDA */
diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
index 715ba8a7f2f8..f4eeacf1f281 100644
--- a/sound/soc/sof/intel/Kconfig
+++ b/sound/soc/sof/intel/Kconfig
@@ -269,6 +269,13 @@ config SND_SOC_SOF_HDA_COMMON
 	select SND_INTEL_DSP_CONFIG
 	select SND_SOC_SOF_HDA_LINK_BASELINE
 	select SND_SOC_SOF_HDA_PROBES
+	select SND_SOC_SOF_HDA_MLINK if SND_SOC_SOF_HDA_LINK
+	help
+	  This option is not user-selectable but automagically handled by
+	  'select' statements at a higher level.
+
+config SND_SOC_SOF_HDA_MLINK
+	tristate
 	help
 	  This option is not user-selectable but automagically handled by
 	  'select' statements at a higher level.
diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile
index 38ab86b6a9fe..fdb463c12e91 100644
--- a/sound/soc/sof/intel/Makefile
+++ b/sound/soc/sof/intel/Makefile
@@ -5,10 +5,12 @@ snd-sof-acpi-intel-bdw-objs := bdw.o
 
 snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \
 				 hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \
-				 hda-dai.o hda-dai-ops.o hda-bus.o hda-mlink.o \
+				 hda-dai.o hda-dai-ops.o hda-bus.o \
 				 skl.o hda-loader-skl.o \
 				 apl.o cnl.o tgl.o icl.o mtl.o hda-common-ops.o
 
+snd-sof-intel-hda-mlink-objs := hda-mlink.o
+
 snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-probes.o
 
 snd-sof-intel-hda-objs := hda-codec.o
@@ -19,6 +21,7 @@ obj-$(CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP) += snd-sof-intel-atom.o
 obj-$(CONFIG_SND_SOC_SOF_BAYTRAIL) += snd-sof-acpi-intel-byt.o
 obj-$(CONFIG_SND_SOC_SOF_BROADWELL) += snd-sof-acpi-intel-bdw.o
 obj-$(CONFIG_SND_SOC_SOF_HDA_COMMON) += snd-sof-intel-hda-common.o
+obj-$(CONFIG_SND_SOC_SOF_HDA_MLINK) += snd-sof-intel-hda-mlink.o
 obj-$(CONFIG_SND_SOC_SOF_HDA) += snd-sof-intel-hda.o
 
 snd-sof-pci-intel-tng-objs := pci-tng.o
diff --git a/sound/soc/sof/intel/hda-ctrl.c b/sound/soc/sof/intel/hda-ctrl.c
index e1dba6b79065..84bf01bd360a 100644
--- a/sound/soc/sof/intel/hda-ctrl.c
+++ b/sound/soc/sof/intel/hda-ctrl.c
@@ -19,6 +19,7 @@
 #include <sound/hdaudio_ext.h>
 #include <sound/hda_register.h>
 #include <sound/hda_component.h>
+#include <sound/hda-mlink.h>
 #include "../ops.h"
 #include "hda.h"
 
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index c9231aeacc53..a8722f0774b1 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <sound/hdaudio_ext.h>
 #include <sound/hda_register.h>
+#include <sound/hda-mlink.h>
 #include <trace/events/sof_intel.h>
 #include "../sof-audio.h"
 #include "../ops.h"
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index e426d5e41e52..fbf86f2350fb 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -12,21 +12,11 @@
 
 #include <sound/hdaudio_ext.h>
 #include <sound/hda_register.h>
+#include <sound/hda-mlink.h>
 
-#include <linux/acpi.h>
 #include <linux/module.h>
-#include <linux/soundwire/sdw.h>
-#include <linux/soundwire/sdw_intel.h>
-#include <sound/intel-dsp-config.h>
-#include <sound/intel-nhlt.h>
-#include <sound/sof.h>
-#include <sound/sof/xtensa.h>
-#include "../sof-audio.h"
-#include "../sof-pci-dev.h"
-#include "../ops.h"
-#include "hda.h"
-
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_MLINK)
 
 int hda_bus_ml_get_capabilities(struct hdac_bus *bus)
 {
@@ -34,6 +24,7 @@ int hda_bus_ml_get_capabilities(struct hdac_bus *bus)
 		return snd_hdac_ext_bus_get_ml_capabilities(bus);
 	return 0;
 }
+EXPORT_SYMBOL_NS(hda_bus_ml_get_capabilities, SND_SOC_SOF_HDA_MLINK);
 
 void hda_bus_ml_free(struct hdac_bus *bus)
 {
@@ -47,6 +38,7 @@ void hda_bus_ml_free(struct hdac_bus *bus)
 		kfree(hlink);
 	}
 }
+EXPORT_SYMBOL_NS(hda_bus_ml_free, SND_SOC_SOF_HDA_MLINK);
 
 void hda_bus_ml_put_all(struct hdac_bus *bus)
 {
@@ -55,6 +47,7 @@ void hda_bus_ml_put_all(struct hdac_bus *bus)
 	list_for_each_entry(hlink, &bus->hlink_list, list)
 		snd_hdac_ext_bus_link_put(bus, hlink);
 }
+EXPORT_SYMBOL_NS(hda_bus_ml_put_all, SND_SOC_SOF_HDA_MLINK);
 
 void hda_bus_ml_reset_losidv(struct hdac_bus *bus)
 {
@@ -64,6 +57,7 @@ void hda_bus_ml_reset_losidv(struct hdac_bus *bus)
 	list_for_each_entry(hlink, &bus->hlink_list, list)
 		writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
 }
+EXPORT_SYMBOL_NS(hda_bus_ml_reset_losidv, SND_SOC_SOF_HDA_MLINK);
 
 int hda_bus_ml_resume(struct hdac_bus *bus)
 {
@@ -80,10 +74,14 @@ int hda_bus_ml_resume(struct hdac_bus *bus)
 	}
 	return 0;
 }
+EXPORT_SYMBOL_NS(hda_bus_ml_resume, SND_SOC_SOF_HDA_MLINK);
 
 int hda_bus_ml_suspend(struct hdac_bus *bus)
 {
 	return snd_hdac_ext_bus_link_power_down_all(bus);
 }
+EXPORT_SYMBOL_NS(hda_bus_ml_suspend, SND_SOC_SOF_HDA_MLINK);
 
 #endif
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 65389c7278e2..ac61233029b7 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -26,6 +26,7 @@
 #include <sound/intel-nhlt.h>
 #include <sound/sof.h>
 #include <sound/sof/xtensa.h>
+#include <sound/hda-mlink.h>
 #include "../sof-audio.h"
 #include "../sof-pci-dev.h"
 #include "../ops.h"
@@ -1647,3 +1648,4 @@ MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
 MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI);
 MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT);
 MODULE_IMPORT_NS(SOUNDWIRE_INTEL);
+MODULE_IMPORT_NS(SND_SOC_SOF_HDA_MLINK);
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 259b34eea677..0e0cfa81a8f2 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -763,26 +763,6 @@ static inline int hda_codec_i915_exit(struct snd_sof_dev *sdev) { return 0; }
 
 #endif
 
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
-
-int hda_bus_ml_get_capabilities(struct hdac_bus *bus);
-void hda_bus_ml_free(struct hdac_bus *bus);
-void hda_bus_ml_put_all(struct hdac_bus *bus);
-void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
-int hda_bus_ml_resume(struct hdac_bus *bus);
-int hda_bus_ml_suspend(struct hdac_bus *bus);
-
-#else
-
-static inline int hda_bus_ml_get_capabilities(struct hdac_bus *bus) { return 0; }
-static inline void hda_bus_ml_free(struct hdac_bus *bus) { }
-static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
-static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
-static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }
-static inline int hda_bus_ml_suspend(struct hdac_bus *bus) { return 0; }
-
-#endif /* CONFIG_SND_SOC_SOF_HDA */
-
 /*
  * Trace Control.
  */
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 06/18] ASoC: SOF: Intel: hda-mlink: add structures to parse ALT links
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (4 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 05/18] ASoC: SOF: Intel: hda-mlink: move to a dedicated module Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-30 15:51   ` Takashi Iwai
  2023-03-27 11:29 ` [PATCH 07/18] ASoC: SOF: Intel: hda-mlink: special-case HDaudio regular links Peter Ujfalusi
                   ` (11 subsequent siblings)
  17 siblings, 1 reply; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Extend hdac_ext_link to store information needed for ALT
links. Follow-up patches will include more functional patches for
power-up and down.

Note that this patch suggests the use of an 'eml_lock' to serialize
access to shared registers. SoundWire-specific sequence require the
lock to be taken at a higher level, as a result the helpers added in
follow-up patches will provide 'unlocked' versions when needed.

Also note that the low-level sequences with the 'hdaml_' prefix are
taken directly from the hardware specifications - naming conventions
included. The code will be split in two, with locking and linked-list
management handled separately to avoid mixing required hardware setup
and Linux-based resource management.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 sound/soc/sof/intel/hda-mlink.c | 217 +++++++++++++++++++++++++++++++-
 1 file changed, 214 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index fbf86f2350fb..cc944311a671 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -14,14 +14,221 @@
 #include <sound/hda_register.h>
 #include <sound/hda-mlink.h>
 
+#include <linux/bitfield.h>
 #include <linux/module.h>
 
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_MLINK)
 
+/**
+ * struct hdac_ext2_link - HDAudio extended+alternate link
+ *
+ * @hext_link:		hdac_ext_link
+ * @alt:		flag set for alternate extended links
+ * @intc:		boolean for interrupt capable
+ * @ofls:		boolean for offload support
+ * @lss:		boolean for link synchronization capabilities
+ * @slcount:		sublink count
+ * @elid:		extended link ID (AZX_REG_ML_LEPTR_ID_ defines)
+ * @elver:		extended link version
+ * @leptr:		extended link pointer
+ * @eml_lock:		mutual exclusion to access shared registers e.g. CPA/SPA bits
+ * in LCTL register
+ * @base_ptr:		pointer to shim/ip/shim_vs space
+ * @instance_offset:	offset between each of @slcount instances managed by link
+ * @shim_offset:	offset to SHIM register base
+ * @ip_offset:		offset to IP register base
+ * @shim_vs_offset:	offset to vendor-specific (VS) SHIM base
+ */
+struct hdac_ext2_link {
+	struct hdac_ext_link hext_link;
+
+	/* read directly from LCAP register */
+	bool alt;
+	bool intc;
+	bool ofls;
+	bool lss;
+	int slcount;
+	int elid;
+	int elver;
+	u32 leptr;
+
+	struct mutex eml_lock; /* prevent concurrent access to e.g. CPA/SPA */
+
+	/* internal values computed from LCAP contents */
+	void __iomem *base_ptr;
+	u32 instance_offset;
+	u32 shim_offset;
+	u32 ip_offset;
+	u32 shim_vs_offset;
+};
+
+#define hdac_ext_link_to_ext2(h) container_of(h, struct hdac_ext2_link, hext_link)
+
+#define AZX_REG_SDW_INSTANCE_OFFSET			0x8000
+#define AZX_REG_SDW_SHIM_OFFSET				0x0
+#define AZX_REG_SDW_IP_OFFSET				0x100
+#define AZX_REG_SDW_VS_SHIM_OFFSET			0x6000
+
+/* only one instance supported */
+#define AZX_REG_INTEL_DMIC_SHIM_OFFSET			0x0
+#define AZX_REG_INTEL_DMIC_IP_OFFSET			0x100
+#define AZX_REG_INTEL_DMIC_VS_SHIM_OFFSET		0x6000
+
+#define AZX_REG_INTEL_SSP_INSTANCE_OFFSET		0x1000
+#define AZX_REG_INTEL_SSP_SHIM_OFFSET			0x0
+#define AZX_REG_INTEL_SSP_IP_OFFSET			0x100
+#define AZX_REG_INTEL_SSP_VS_SHIM_OFFSET		0xC00
+
+/* only one instance supported */
+#define AZX_REG_INTEL_UAOL_SHIM_OFFSET			0x0
+#define AZX_REG_INTEL_UAOL_IP_OFFSET			0x100
+#define AZX_REG_INTEL_UAOL_VS_SHIM_OFFSET		0xC00
+
+/* HDAML section - this part follows sequences in the hardware specification,
+ * including naming conventions and the use of the hdaml_ prefix.
+ * The code is intentionally minimal with limited dependencies on frameworks or
+ * helpers. Locking and scanning lists is handled at a higher level
+ */
+
+static int hdaml_lnk_enum(struct device *dev, struct hdac_ext2_link *h2link,
+			  void __iomem *ml_addr, int link_idx)
+{
+	struct hdac_ext_link *hlink = &h2link->hext_link;
+	u32 base_offset;
+
+	hlink->lcaps  = readl(ml_addr + AZX_REG_ML_LCAP);
+
+	h2link->alt = FIELD_GET(AZX_ML_HDA_LCAP_ALT, hlink->lcaps);
+
+	/* handle alternate extensions */
+	if (!h2link->alt) {
+		h2link->slcount = 1;
+
+		/*
+		 * LSDIID is initialized by hardware for HDaudio link,
+		 * it needs to be setup by software for alternate links
+		 */
+		hlink->lsdiid = readw(ml_addr + AZX_REG_ML_LSDIID);
+
+		dev_dbg(dev, "Link %d: HDAudio - lsdiid=%d\n",
+			link_idx, hlink->lsdiid);
+
+		return 0;
+	}
+
+	h2link->intc = FIELD_GET(AZX_ML_HDA_LCAP_INTC, hlink->lcaps);
+	h2link->ofls = FIELD_GET(AZX_ML_HDA_LCAP_OFLS, hlink->lcaps);
+	h2link->lss = FIELD_GET(AZX_ML_HDA_LCAP_LSS, hlink->lcaps);
+
+	/* read slcount (increment due to zero-based hardware representation */
+	h2link->slcount = FIELD_GET(AZX_ML_HDA_LCAP_SLCOUNT, hlink->lcaps) + 1;
+	dev_dbg(dev, "Link %d: HDAudio extended - sublink count %d\n",
+		link_idx, h2link->slcount);
+
+	/* find IP ID and offsets */
+	h2link->leptr = readl(hlink->ml_addr + AZX_REG_ML_LEPTR);
+
+	h2link->elid = FIELD_GET(AZX_REG_ML_LEPTR_ID, h2link->leptr);
+
+	base_offset = FIELD_GET(AZX_REG_ML_LEPTR_PTR, h2link->leptr);
+	h2link->base_ptr = hlink->ml_addr + base_offset;
+
+	switch (h2link->elid) {
+	case AZX_REG_ML_LEPTR_ID_SDW:
+		h2link->shim_offset = AZX_REG_SDW_SHIM_OFFSET;
+		h2link->ip_offset = AZX_REG_SDW_IP_OFFSET;
+		h2link->shim_vs_offset = AZX_REG_SDW_VS_SHIM_OFFSET;
+		dev_dbg(dev, "Link %d: HDAudio extended - SoundWire alternate link, leptr.ptr %#x\n",
+			link_idx, base_offset);
+		break;
+	case AZX_REG_ML_LEPTR_ID_INTEL_DMIC:
+		h2link->shim_offset = AZX_REG_INTEL_DMIC_SHIM_OFFSET;
+		h2link->ip_offset = AZX_REG_INTEL_DMIC_IP_OFFSET;
+		h2link->shim_vs_offset = AZX_REG_INTEL_DMIC_VS_SHIM_OFFSET;
+		dev_dbg(dev, "Link %d: HDAudio extended - INTEL DMIC alternate link, leptr.ptr %#x\n",
+			link_idx, base_offset);
+		break;
+	case AZX_REG_ML_LEPTR_ID_INTEL_SSP:
+		h2link->shim_offset = AZX_REG_INTEL_SSP_SHIM_OFFSET;
+		h2link->ip_offset = AZX_REG_INTEL_SSP_IP_OFFSET;
+		h2link->shim_vs_offset = AZX_REG_INTEL_SSP_VS_SHIM_OFFSET;
+		dev_dbg(dev, "Link %d: HDAudio extended - INTEL SSP alternate link, leptr.ptr %#x\n",
+			link_idx, base_offset);
+		break;
+	case AZX_REG_ML_LEPTR_ID_INTEL_UAOL:
+		h2link->shim_offset = AZX_REG_INTEL_UAOL_SHIM_OFFSET;
+		h2link->ip_offset = AZX_REG_INTEL_UAOL_IP_OFFSET;
+		h2link->shim_vs_offset = AZX_REG_INTEL_UAOL_VS_SHIM_OFFSET;
+		dev_dbg(dev, "Link %d: HDAudio extended - INTEL UAOL alternate link, leptr.ptr %#x\n",
+			link_idx, base_offset);
+		break;
+	default:
+		dev_err(dev, "Link %d: HDAudio extended - Unsupported alternate link, leptr.id=%#02x value\n",
+			link_idx, h2link->elid);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* END HDAML section */
+
+static int hda_ml_alloc_h2link(struct hdac_bus *bus, int index)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+	int ret;
+
+	h2link  = kzalloc(sizeof(*h2link), GFP_KERNEL);
+	if (!h2link)
+		return -ENOMEM;
+
+	/* basic initialization */
+	hlink = &h2link->hext_link;
+
+	hlink->index = index;
+	hlink->bus = bus;
+	hlink->ml_addr = bus->mlcap + AZX_ML_BASE + (AZX_ML_INTERVAL * index);
+
+	ret = hdaml_lnk_enum(bus->dev, h2link, hlink->ml_addr, index);
+	if (ret < 0) {
+		kfree(h2link);
+		return ret;
+	}
+
+	mutex_init(&h2link->eml_lock);
+
+	list_add_tail(&hlink->list, &bus->hlink_list);
+
+	/*
+	 * HDaudio regular links are powered-on by default, the
+	 * refcount needs to be initialized.
+	 */
+	if (!h2link->alt)
+		hlink->ref_count = 1;
+
+	return 0;
+}
+
 int hda_bus_ml_get_capabilities(struct hdac_bus *bus)
 {
-	if (bus->mlcap)
-		return snd_hdac_ext_bus_get_ml_capabilities(bus);
+	u32 link_count;
+	int ret;
+	int i;
+
+	if (!bus->mlcap)
+		return 0;
+
+	link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1;
+
+	dev_dbg(bus->dev, "HDAudio Multi-Link count: %d\n", link_count);
+
+	for (i = 0; i < link_count; i++) {
+		ret = hda_ml_alloc_h2link(bus, i);
+		if (ret < 0) {
+			hda_bus_ml_free(bus);
+			return ret;
+		}
+	}
 	return 0;
 }
 EXPORT_SYMBOL_NS(hda_bus_ml_get_capabilities, SND_SOC_SOF_HDA_MLINK);
@@ -29,13 +236,17 @@ EXPORT_SYMBOL_NS(hda_bus_ml_get_capabilities, SND_SOC_SOF_HDA_MLINK);
 void hda_bus_ml_free(struct hdac_bus *bus)
 {
 	struct hdac_ext_link *hlink, *_h;
+	struct hdac_ext2_link *h2link;
 
 	if (!bus->mlcap)
 		return;
 
 	list_for_each_entry_safe(hlink, _h, &bus->hlink_list, list) {
 		list_del(&hlink->list);
-		kfree(hlink);
+		h2link = hdac_ext_link_to_ext2(hlink);
+
+		mutex_destroy(&h2link->eml_lock);
+		kfree(h2link);
 	}
 }
 EXPORT_SYMBOL_NS(hda_bus_ml_free, SND_SOC_SOF_HDA_MLINK);
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 07/18] ASoC: SOF: Intel: hda-mlink: special-case HDaudio regular links
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (5 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 06/18] ASoC: SOF: Intel: hda-mlink: add structures to parse ALT links Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 08/18] ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM Peter Ujfalusi
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

For backwards compatibility, HDaudio/iDISP links are powered-on when
exiting reset, and the existing driver forces them to be powered-off
when entering S0ix. In addition, the get/put helpers are invoked
directly by the ASoC codec drivers, which a historical layering
violation.

Extended links are powered-on by software only, during the probe and
DAI startup phases. This calls for a different handling of the
'regular' and 'extended' audio links.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 sound/soc/sof/intel/hda-mlink.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index cc944311a671..90b68ae2564c 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -255,8 +255,12 @@ void hda_bus_ml_put_all(struct hdac_bus *bus)
 {
 	struct hdac_ext_link *hlink;
 
-	list_for_each_entry(hlink, &bus->hlink_list, list)
-		snd_hdac_ext_bus_link_put(bus, hlink);
+	list_for_each_entry(hlink, &bus->hlink_list, list) {
+		struct hdac_ext2_link *h2link = hdac_ext_link_to_ext2(hlink);
+
+		if (!h2link->alt)
+			snd_hdac_ext_bus_link_put(bus, hlink);
+	}
 }
 EXPORT_SYMBOL_NS(hda_bus_ml_put_all, SND_SOC_SOF_HDA_MLINK);
 
@@ -277,7 +281,9 @@ int hda_bus_ml_resume(struct hdac_bus *bus)
 
 	/* power up links that were active before suspend */
 	list_for_each_entry(hlink, &bus->hlink_list, list) {
-		if (hlink->ref_count) {
+		struct hdac_ext2_link *h2link = hdac_ext_link_to_ext2(hlink);
+
+		if (!h2link->alt && hlink->ref_count) {
 			ret = snd_hdac_ext_bus_link_power_up(hlink);
 			if (ret < 0)
 				return ret;
@@ -289,7 +295,19 @@ EXPORT_SYMBOL_NS(hda_bus_ml_resume, SND_SOC_SOF_HDA_MLINK);
 
 int hda_bus_ml_suspend(struct hdac_bus *bus)
 {
-	return snd_hdac_ext_bus_link_power_down_all(bus);
+	struct hdac_ext_link *hlink;
+	int ret;
+
+	list_for_each_entry(hlink, &bus->hlink_list, list) {
+		struct hdac_ext2_link *h2link = hdac_ext_link_to_ext2(hlink);
+
+		if (!h2link->alt) {
+			ret = snd_hdac_ext_bus_link_power_down(hlink);
+			if (ret < 0)
+				return ret;
+		}
+	}
+	return 0;
 }
 EXPORT_SYMBOL_NS(hda_bus_ml_suspend, SND_SOC_SOF_HDA_MLINK);
 
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 08/18] ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (6 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 07/18] ASoC: SOF: Intel: hda-mlink: special-case HDaudio regular links Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-28 10:34   ` Amadeusz Sławiński
  2023-03-30 15:54   ` Takashi Iwai
  2023-03-27 11:29 ` [PATCH 09/18] ASoC: SOF: Intel: hda-mlink: add convenience helpers for SoundWire PM Peter Ujfalusi
                   ` (9 subsequent siblings)
  17 siblings, 2 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Add helpers to program SPA/CPA bits, using a mutex to access the
shared LCTL register if required.

All links are managed with the same LCTLx.SPA bits. However there are
quite a few implementation details to be aware of:

Legacy HDaudio multi-links are powered-up when exiting reset, which
requires the ref_count to be manually set to one when initializing the
link.

Alternate links for SoundWire/DMIC/SSP need to be explicitly
powered-up before accessing the SHIM/IP/Vendor-Specific SHIM space for
each sublink. DMIC/SSP/SoundWire are all different cases with a
different device/dai/hlink relationship.

SoundWire will handle power management with the auxiliary device
resume/suspend routine. The ref_count is not necessary in this case.

The DMIC/SSP will by contrast handle the power management from DAI
.startup and .shutdown callbacks.

The SSP has a 1:1 mapping between sublink and DAI, but it's
bidirectional so the ref_count will help avoid turning off the sublink
when one of the two directions is still in use.

The DMIC has a single link but two DAIs for data generated at
different sampling frequencies, again the ref_count will make sure the
two DAIs can be used concurrently.

And last the SoundWire Intel require power-up/down and bank switch to
be handled with a lock already taken, so the 'eml_lock' is made
optional with the _unlocked versions of the helpers.

Note that the _check_power_active() implementation is similar to
previous helpers in sound/hda/ext, with sleep duration and timeout
aligned with hardware recommendations. If desired, this helper could
be modified in a second step with .e.g. readl_poll_timeout()

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       |  32 +++++++
 sound/soc/sof/intel/hda-mlink.c | 163 ++++++++++++++++++++++++++++++++
 2 files changed, 195 insertions(+)

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
index beef5f509e47..6908af849dd5 100644
--- a/include/sound/hda-mlink.h
+++ b/include/sound/hda-mlink.h
@@ -12,6 +12,13 @@ struct hdac_bus;
 
 int hda_bus_ml_get_capabilities(struct hdac_bus *bus);
 void hda_bus_ml_free(struct hdac_bus *bus);
+
+int hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink);
+int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
+
+int hdac_bus_eml_power_down(struct hdac_bus *bus, bool alt, int elid, int sublink);
+int hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
+
 void hda_bus_ml_put_all(struct hdac_bus *bus);
 void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
 int hda_bus_ml_resume(struct hdac_bus *bus);
@@ -23,6 +30,31 @@ static inline int
 hda_bus_ml_get_capabilities(struct hdac_bus *bus) { return 0; }
 
 static inline void hda_bus_ml_free(struct hdac_bus *bus) { }
+
+static inline int
+hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink)
+{
+	return 0;
+}
+
+static inline int
+hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
+{
+	return 0;
+}
+
+static inline int
+hdac_bus_eml_power_down(struct hdac_bus *bus, bool alt, int elid, int sublink)
+{
+	return 0;
+}
+
+static inline int
+hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
+{
+	return 0;
+}
+
 static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
 static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
 static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index 90b68ae2564c..4cfef4007d0c 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -170,6 +170,68 @@ static int hdaml_lnk_enum(struct device *dev, struct hdac_ext2_link *h2link,
 	return 0;
 }
 
+/*
+ * Hardware recommendations are to wait ~10us before checking any hardware transition
+ * reported by bits changing status.
+ * This value does not need to be super-precise, a slack of 5us is perfectly acceptable.
+ * The worst-case is about 1ms before reporting an issue
+ */
+#define HDAML_POLL_DELAY_MIN_US 10
+#define HDAML_POLL_DELAY_SLACK_US 5
+#define HDAML_POLL_DELAY_RETRY  100
+
+static int check_power_active(u32 __iomem *lctl, int sublink, bool enable)
+{
+	int mask = BIT(sublink) << AZX_ML_LCTL_CPA_SHIFT;
+	int retry = HDAML_POLL_DELAY_RETRY;
+	u32 val;
+
+	usleep_range(HDAML_POLL_DELAY_MIN_US,
+		     HDAML_POLL_DELAY_MIN_US + HDAML_POLL_DELAY_SLACK_US);
+	do {
+		val = readl(lctl);
+		if (enable) {
+			if (val & mask)
+				return 0;
+		} else {
+			if (!(val & mask))
+				return 0;
+		}
+		usleep_range(HDAML_POLL_DELAY_MIN_US,
+			     HDAML_POLL_DELAY_MIN_US + HDAML_POLL_DELAY_SLACK_US);
+
+	} while (--retry);
+
+	return -EIO;
+}
+
+static int hdaml_link_init(u32 __iomem *lctl, int sublink)
+{
+	u32 val;
+	u32 mask = BIT(sublink) << AZX_ML_LCTL_SPA_SHIFT;
+
+	val = readl(lctl);
+	val |= mask;
+
+	writel(val, lctl);
+
+	return check_power_active(lctl, sublink, true);
+}
+
+static int hdaml_link_shutdown(u32 __iomem *lctl, int sublink)
+{
+	u32 val;
+	u32 mask;
+
+	val = readl(lctl);
+	mask = BIT(sublink) << AZX_ML_LCTL_SPA_SHIFT;
+	val &= ~mask;
+
+	writel(val, lctl);
+
+	return check_power_active(lctl, sublink, false);
+}
+
 /* END HDAML section */
 
 static int hda_ml_alloc_h2link(struct hdac_bus *bus, int index)
@@ -251,6 +313,107 @@ void hda_bus_ml_free(struct hdac_bus *bus)
 }
 EXPORT_SYMBOL_NS(hda_bus_ml_free, SND_SOC_SOF_HDA_MLINK);
 
+static struct hdac_ext2_link *
+find_ext2_link(struct hdac_bus *bus, bool alt, int elid)
+{
+	struct hdac_ext_link *hlink;
+
+	list_for_each_entry(hlink, &bus->hlink_list, list) {
+		struct hdac_ext2_link *h2link = hdac_ext_link_to_ext2(hlink);
+
+		if (h2link->alt == alt && h2link->elid == elid)
+			return h2link;
+	}
+
+	return NULL;
+}
+
+static int hdac_bus_eml_power_up_base(struct hdac_bus *bus, bool alt, int elid, int sublink,
+				      bool eml_lock)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+	int ret = 0;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return -ENODEV;
+
+	if (sublink >= h2link->slcount)
+		return -EINVAL;
+
+	hlink = &h2link->hext_link;
+
+	if (eml_lock)
+		mutex_lock(&h2link->eml_lock);
+
+	if (++hlink->ref_count > 1)
+		goto skip_init;
+
+	ret = hdaml_link_init(hlink->ml_addr + AZX_REG_ML_LCTL, sublink);
+
+skip_init:
+	if (eml_lock)
+		mutex_unlock(&h2link->eml_lock);
+
+	return ret;
+}
+
+int hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink)
+{
+	return hdac_bus_eml_power_up_base(bus, alt, elid, sublink, true);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_power_up, SND_SOC_SOF_HDA_MLINK);
+
+int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
+{
+	return hdac_bus_eml_power_up_base(bus, alt, elid, sublink, false);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_power_up_unlocked, SND_SOC_SOF_HDA_MLINK);
+
+static int hdac_bus_eml_power_down_base(struct hdac_bus *bus, bool alt, int elid, int sublink,
+					bool eml_lock)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+	int ret = 0;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return -ENODEV;
+
+	if (sublink >= h2link->slcount)
+		return -EINVAL;
+
+	hlink = &h2link->hext_link;
+
+	if (eml_lock)
+		mutex_lock(&h2link->eml_lock);
+
+	if (--hlink->ref_count > 0)
+		goto skip_shutdown;
+
+	ret = hdaml_link_shutdown(hlink->ml_addr + AZX_REG_ML_LCTL, sublink);
+
+skip_shutdown:
+	if (eml_lock)
+		mutex_unlock(&h2link->eml_lock);
+
+	return ret;
+}
+
+int hdac_bus_eml_power_down(struct hdac_bus *bus, bool alt, int elid, int sublink)
+{
+	return hdac_bus_eml_power_down_base(bus, alt, elid, sublink, true);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_power_down, SND_SOC_SOF_HDA_MLINK);
+
+int hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
+{
+	return hdac_bus_eml_power_down_base(bus, alt, elid, sublink, false);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_power_down_unlocked, SND_SOC_SOF_HDA_MLINK);
+
 void hda_bus_ml_put_all(struct hdac_bus *bus)
 {
 	struct hdac_ext_link *hlink;
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 09/18] ASoC: SOF: Intel: hda-mlink: add convenience helpers for SoundWire PM
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (7 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 08/18] ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 10/18] ASoC: SOF: Intel: hda-mlink: add helper to return sublink count Peter Ujfalusi
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

The updated SoundWire Intel driver will need to rely on Extended
HDaudio links for power management, but it doesn't need to be aware of
all the HDaudio structures. Add convenience helpers to avoid polluting
SoundWire drivers too much with HDaudio information.

Since the SoundWire/Intel solution already takes the lock at a higher
level, the _unlocked PM helpers are used.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       |  9 +++++++++
 sound/soc/sof/intel/hda-mlink.c | 12 ++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
index 6908af849dd5..74737032a632 100644
--- a/include/sound/hda-mlink.h
+++ b/include/sound/hda-mlink.h
@@ -19,6 +19,9 @@ int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int
 int hdac_bus_eml_power_down(struct hdac_bus *bus, bool alt, int elid, int sublink);
 int hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
 
+int hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink);
+int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink);
+
 void hda_bus_ml_put_all(struct hdac_bus *bus);
 void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
 int hda_bus_ml_resume(struct hdac_bus *bus);
@@ -55,6 +58,12 @@ hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, int s
 	return 0;
 }
 
+static inline int
+hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink) { return 0; }
+
+static inline int
+hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink) { return 0; }
+
 static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
 static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
 static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index 4cfef4007d0c..310bb4c6822e 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -414,6 +414,18 @@ int hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, i
 }
 EXPORT_SYMBOL_NS(hdac_bus_eml_power_down_unlocked, SND_SOC_SOF_HDA_MLINK);
 
+int hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink)
+{
+	return hdac_bus_eml_power_up_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW, sublink);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_power_up_unlocked, SND_SOC_SOF_HDA_MLINK);
+
+int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink)
+{
+	return hdac_bus_eml_power_down_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW, sublink);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_power_down_unlocked, SND_SOC_SOF_HDA_MLINK);
+
 void hda_bus_ml_put_all(struct hdac_bus *bus)
 {
 	struct hdac_ext_link *hlink;
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 10/18] ASoC: SOF: Intel: hda-mlink: add helper to return sublink count
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (8 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 09/18] ASoC: SOF: Intel: hda-mlink: add convenience helpers for SoundWire PM Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 11/18] ASoC: SOF: Intel: hda-mlink: add helpers to enable/check interrupts Peter Ujfalusi
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

This is needed for SoundWire integration.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       |  5 +++++
 sound/soc/sof/intel/hda-mlink.c | 12 ++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
index 74737032a632..b8f889fa46c4 100644
--- a/include/sound/hda-mlink.h
+++ b/include/sound/hda-mlink.h
@@ -13,6 +13,8 @@ struct hdac_bus;
 int hda_bus_ml_get_capabilities(struct hdac_bus *bus);
 void hda_bus_ml_free(struct hdac_bus *bus);
 
+int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid);
+
 int hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink);
 int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
 
@@ -34,6 +36,9 @@ hda_bus_ml_get_capabilities(struct hdac_bus *bus) { return 0; }
 
 static inline void hda_bus_ml_free(struct hdac_bus *bus) { }
 
+static inline int
+hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid) { return 0; }
+
 static inline int
 hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink)
 {
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index 310bb4c6822e..93d532acd1c2 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -328,6 +328,18 @@ find_ext2_link(struct hdac_bus *bus, bool alt, int elid)
 	return NULL;
 }
 
+int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid)
+{
+	struct hdac_ext2_link *h2link;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return 0;
+
+	return h2link->slcount;
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_get_count, SND_SOC_SOF_HDA_MLINK);
+
 static int hdac_bus_eml_power_up_base(struct hdac_bus *bus, bool alt, int elid, int sublink,
 				      bool eml_lock)
 {
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 11/18] ASoC: SOF: Intel: hda-mlink: add helpers to enable/check interrupts
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (9 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 10/18] ASoC: SOF: Intel: hda-mlink: add helper to return sublink count Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 12/18] ASoC: SOF: Intel: hda-mlink: add helpers to set link SYNC frequency Peter Ujfalusi
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

When INTC is set, LCTL exposes INTEN and INTSTS fields.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       |  8 +++++
 sound/soc/sof/intel/hda-mlink.c | 62 +++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+)

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
index b8f889fa46c4..ebc7c5b07557 100644
--- a/include/sound/hda-mlink.h
+++ b/include/sound/hda-mlink.h
@@ -14,6 +14,8 @@ int hda_bus_ml_get_capabilities(struct hdac_bus *bus);
 void hda_bus_ml_free(struct hdac_bus *bus);
 
 int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid);
+void hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable);
+bool hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid);
 
 int hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink);
 int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
@@ -39,6 +41,12 @@ static inline void hda_bus_ml_free(struct hdac_bus *bus) { }
 static inline int
 hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid) { return 0; }
 
+static inline void
+hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable) { }
+
+static inline bool
+hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid) { return false; }
+
 static inline int
 hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink)
 {
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index 93d532acd1c2..cd5bbfa3684d 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -232,6 +232,28 @@ static int hdaml_link_shutdown(u32 __iomem *lctl, int sublink)
 	return check_power_active(lctl, sublink, false);
 }
 
+static void hdaml_link_enable_interrupt(u32 __iomem *lctl, bool enable)
+{
+	u32 val;
+
+	val = readl(lctl);
+	if (enable)
+		val |= AZX_ML_LCTL_INTEN;
+	else
+		val &= ~AZX_ML_LCTL_INTEN;
+
+	writel(val, lctl);
+}
+
+static bool hdaml_link_check_interrupt(u32 __iomem *lctl)
+{
+	u32 val;
+
+	val = readl(lctl);
+
+	return val & AZX_ML_LCTL_INTSTS;
+}
+
 /* END HDAML section */
 
 static int hda_ml_alloc_h2link(struct hdac_bus *bus, int index)
@@ -340,6 +362,46 @@ int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid)
 }
 EXPORT_SYMBOL_NS(hdac_bus_eml_get_count, SND_SOC_SOF_HDA_MLINK);
 
+void hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return;
+
+	if (!h2link->intc)
+		return;
+
+	hlink = &h2link->hext_link;
+
+	mutex_lock(&h2link->eml_lock);
+
+	hdaml_link_enable_interrupt(hlink->ml_addr + AZX_REG_ML_LCTL, enable);
+
+	mutex_unlock(&h2link->eml_lock);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_enable_interrupt, SND_SOC_SOF_HDA_MLINK);
+
+bool hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return false;
+
+	if (!h2link->intc)
+		return false;
+
+	hlink = &h2link->hext_link;
+
+	return hdaml_link_check_interrupt(hlink->ml_addr + AZX_REG_ML_LCTL);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_check_interrupt, SND_SOC_SOF_HDA_MLINK);
+
 static int hdac_bus_eml_power_up_base(struct hdac_bus *bus, bool alt, int elid, int sublink,
 				      bool eml_lock)
 {
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 12/18] ASoC: SOF: Intel: hda-mlink: add helpers to set link SYNC frequency
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (10 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 11/18] ASoC: SOF: Intel: hda-mlink: add helpers to enable/check interrupts Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 13/18] ASoC: SOF: Intel: hda-mlink: add helpers for sync_arm/sync_go Peter Ujfalusi
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

These helpers configure the ratio between the base clock and the
hardware signal used for link synchronization.

The SYNCPRD is written before the first sublink is powered-up. The
SYNCPU bit is set, but it will only be cleared after the link is
powered-up, hence the implementation with a set/wait pattern.

These helpers are currently only needed by SoundWire support, where
the lock is taken at a higher level, so only the _unlocked versions
are exposed for now.

Note that the _wait_bit() implementation is similar to previous
helpers in drivers/soundwire, but with sleep duration and timeout
aligned with hardware recommendations. If desired, this helper could
be modified in a second step with e.g. readl_poll_timeout().

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       | 27 ++++++++++
 sound/soc/sof/intel/hda-mlink.c | 90 +++++++++++++++++++++++++++++++++
 2 files changed, 117 insertions(+)

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
index ebc7c5b07557..7ef1cd9b72ec 100644
--- a/include/sound/hda-mlink.h
+++ b/include/sound/hda-mlink.h
@@ -17,6 +17,12 @@ int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid);
 void hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable);
 bool hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid);
 
+int hdac_bus_eml_set_syncprd_unlocked(struct hdac_bus *bus, bool alt, int elid, u32 syncprd);
+int hdac_bus_eml_sdw_set_syncprd_unlocked(struct hdac_bus *bus, u32 syncprd);
+
+int hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid);
+int hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus);
+
 int hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink);
 int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
 
@@ -47,6 +53,27 @@ hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool ena
 static inline bool
 hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid) { return false; }
 
+static inline int
+hdac_bus_eml_set_syncprd_unlocked(struct hdac_bus *bus, bool alt, int elid, u32 syncprd)
+{
+	return 0;
+}
+
+static inline int
+hdac_bus_eml_sdw_set_syncprd_unlocked(struct hdac_bus *bus, u32 syncprd)
+{
+	return 0;
+}
+
+static inline int
+hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid)
+{
+	return 0;
+}
+
+static inline int
+hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus) { return 0; }
+
 static inline int
 hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink)
 {
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index cd5bbfa3684d..1515c2327130 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -254,6 +254,46 @@ static bool hdaml_link_check_interrupt(u32 __iomem *lctl)
 	return val & AZX_ML_LCTL_INTSTS;
 }
 
+static int hdaml_wait_bit(void __iomem *base, int offset, u32 mask, u32 target)
+{
+	int timeout = HDAML_POLL_DELAY_RETRY;
+	u32 reg_read;
+
+	do {
+		reg_read = readl(base + offset);
+		if ((reg_read & mask) == target)
+			return 0;
+
+		timeout--;
+		usleep_range(HDAML_POLL_DELAY_MIN_US,
+			     HDAML_POLL_DELAY_MIN_US + HDAML_POLL_DELAY_SLACK_US);
+	} while (timeout != 0);
+
+	return -EAGAIN;
+}
+
+static void hdaml_link_set_syncprd(u32 __iomem *lsync, u32 syncprd)
+{
+	u32 val;
+
+	val = readl(lsync);
+	val &= ~AZX_REG_ML_LSYNC_SYNCPRD;
+	val |= (syncprd & AZX_REG_ML_LSYNC_SYNCPRD);
+
+	/*
+	 * set SYNCPU but do not wait. The bit is cleared by hardware when
+	 * the link becomes active.
+	 */
+	val |= AZX_REG_ML_LSYNC_SYNCPU;
+
+	writel(val, lsync);
+}
+
+static int hdaml_link_wait_syncpu(u32 __iomem *lsync)
+{
+	return hdaml_wait_bit(lsync, 0, AZX_REG_ML_LSYNC_SYNCPU, 0);
+}
+
 /* END HDAML section */
 
 static int hda_ml_alloc_h2link(struct hdac_bus *bus, int index)
@@ -402,6 +442,56 @@ bool hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid)
 }
 EXPORT_SYMBOL_NS(hdac_bus_eml_check_interrupt, SND_SOC_SOF_HDA_MLINK);
 
+int hdac_bus_eml_set_syncprd_unlocked(struct hdac_bus *bus, bool alt, int elid, u32 syncprd)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return 0;
+
+	if (!h2link->lss)
+		return 0;
+
+	hlink = &h2link->hext_link;
+
+	hdaml_link_set_syncprd(hlink->ml_addr + AZX_REG_ML_LSYNC, syncprd);
+
+	return 0;
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_set_syncprd_unlocked, SND_SOC_SOF_HDA_MLINK);
+
+int hdac_bus_eml_sdw_set_syncprd_unlocked(struct hdac_bus *bus, u32 syncprd)
+{
+	return hdac_bus_eml_set_syncprd_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW, syncprd);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_set_syncprd_unlocked, SND_SOC_SOF_HDA_MLINK);
+
+int hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return 0;
+
+	if (!h2link->lss)
+		return 0;
+
+	hlink = &h2link->hext_link;
+
+	return hdaml_link_wait_syncpu(hlink->ml_addr + AZX_REG_ML_LSYNC);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_wait_syncpu_unlocked, SND_SOC_SOF_HDA_MLINK);
+
+int hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus)
+{
+	return hdac_bus_eml_wait_syncpu_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_wait_syncpu_unlocked, SND_SOC_SOF_HDA_MLINK);
+
 static int hdac_bus_eml_power_up_base(struct hdac_bus *bus, bool alt, int elid, int sublink,
 				      bool eml_lock)
 {
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 13/18] ASoC: SOF: Intel: hda-mlink: add helpers for sync_arm/sync_go
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (11 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 12/18] ASoC: SOF: Intel: hda-mlink: add helpers to set link SYNC frequency Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 14/18] ASoC: SOF: Intel: hda-mlink: add helper to check cmdsync Peter Ujfalusi
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

The multi-link synchronization uses the same concept and registers,
but moved to the HDAudio extended links.

Add helpers for sync_arm and sync_go which are the basic for the bus
reset, bank switch and clock stop.

Since SoundWire is the only user of those helpers, only expose the
_unlocked versions for now.

Note that SYNCGO is a write-only bit, so no error can be reported. We
still return 0 for compatibility with the SoundWire stream management
headers.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       | 18 +++++++++
 sound/soc/sof/intel/hda-mlink.c | 70 +++++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+)

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
index 7ef1cd9b72ec..6be0fb63652c 100644
--- a/include/sound/hda-mlink.h
+++ b/include/sound/hda-mlink.h
@@ -23,6 +23,12 @@ int hdac_bus_eml_sdw_set_syncprd_unlocked(struct hdac_bus *bus, u32 syncprd);
 int hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid);
 int hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus);
 
+void hdac_bus_eml_sync_arm_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
+void hdac_bus_eml_sdw_sync_arm_unlocked(struct hdac_bus *bus, int sublink);
+
+int hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid);
+int hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus);
+
 int hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink);
 int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
 
@@ -74,6 +80,18 @@ hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid)
 static inline int
 hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus) { return 0; }
 
+static inline void
+hdac_bus_eml_sync_arm_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink) { }
+
+static inline void
+hdac_bus_eml_sdw_sync_arm_unlocked(struct hdac_bus *bus, int sublink) { }
+
+static inline int
+hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid) { return 0; }
+
+static inline int
+hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus) { return 0; }
+
 static inline int
 hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink)
 {
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index 1515c2327130..19df0253261a 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -294,6 +294,26 @@ static int hdaml_link_wait_syncpu(u32 __iomem *lsync)
 	return hdaml_wait_bit(lsync, 0, AZX_REG_ML_LSYNC_SYNCPU, 0);
 }
 
+static void hdaml_link_sync_arm(u32 __iomem *lsync, int sublink)
+{
+	u32 val;
+
+	val = readl(lsync);
+	val |= (AZX_REG_ML_LSYNC_CMDSYNC << sublink);
+
+	writel(val, lsync);
+}
+
+static void hdaml_link_sync_go(u32 __iomem *lsync)
+{
+	u32 val;
+
+	val = readl(lsync);
+	val |= AZX_REG_ML_LSYNC_SYNCGO;
+
+	writel(val, lsync);
+}
+
 /* END HDAML section */
 
 static int hda_ml_alloc_h2link(struct hdac_bus *bus, int index)
@@ -492,6 +512,56 @@ int hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus)
 }
 EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_wait_syncpu_unlocked, SND_SOC_SOF_HDA_MLINK);
 
+void hdac_bus_eml_sync_arm_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return;
+
+	if (!h2link->lss)
+		return;
+
+	hlink = &h2link->hext_link;
+
+	hdaml_link_sync_arm(hlink->ml_addr + AZX_REG_ML_LSYNC, sublink);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_sync_arm_unlocked, SND_SOC_SOF_HDA_MLINK);
+
+void hdac_bus_eml_sdw_sync_arm_unlocked(struct hdac_bus *bus, int sublink)
+{
+	hdac_bus_eml_sync_arm_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW, sublink);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_sync_arm_unlocked, SND_SOC_SOF_HDA_MLINK);
+
+int hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return 0;
+
+	if (!h2link->lss)
+		return 0;
+
+	hlink = &h2link->hext_link;
+
+	hdaml_link_sync_go(hlink->ml_addr + AZX_REG_ML_LSYNC);
+
+	return 0;
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_sync_go_unlocked, SND_SOC_SOF_HDA_MLINK);
+
+int hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus)
+{
+	return hdac_bus_eml_sync_go_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_sync_go_unlocked, SND_SOC_SOF_HDA_MLINK);
+
 static int hdac_bus_eml_power_up_base(struct hdac_bus *bus, bool alt, int elid, int sublink,
 				      bool eml_lock)
 {
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 14/18] ASoC: SOF: Intel: hda-mlink: add helper to check cmdsync
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (12 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 13/18] ASoC: SOF: Intel: hda-mlink: add helpers for sync_arm/sync_go Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 15/18] ASoC: SOF: Intel: hda-mlink: program SoundWire LSDIID registers Peter Ujfalusi
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

This helper is an optimization where sync_go is only called when the
cmdsync field is actually set to a non-zero value.

Since this is also only used by SoundWire for now, only expose the
_unlocked version.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       |  9 ++++++++
 sound/soc/sof/intel/hda-mlink.c | 38 +++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
index 6be0fb63652c..64106d439fd8 100644
--- a/include/sound/hda-mlink.h
+++ b/include/sound/hda-mlink.h
@@ -29,6 +29,9 @@ void hdac_bus_eml_sdw_sync_arm_unlocked(struct hdac_bus *bus, int sublink);
 int hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid);
 int hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus);
 
+bool hdac_bus_eml_check_cmdsync_unlocked(struct hdac_bus *bus, bool alt, int elid);
+bool hdac_bus_eml_sdw_check_cmdsync_unlocked(struct hdac_bus *bus);
+
 int hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink);
 int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
 
@@ -92,6 +95,12 @@ hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid) { return
 static inline int
 hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus) { return 0; }
 
+static inline bool
+hdac_bus_eml_check_cmdsync_unlocked(struct hdac_bus *bus, bool alt, int elid) { return false; }
+
+static inline bool
+hdac_bus_eml_sdw_check_cmdsync_unlocked(struct hdac_bus *bus) { return false; }
+
 static inline int
 hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink)
 {
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index 19df0253261a..0912989ce729 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -314,6 +314,15 @@ static void hdaml_link_sync_go(u32 __iomem *lsync)
 	writel(val, lsync);
 }
 
+static bool hdaml_link_check_cmdsync(u32 __iomem *lsync, u32 cmdsync_mask)
+{
+	u32 val;
+
+	val = readl(lsync);
+
+	return !!(val & cmdsync_mask);
+}
+
 /* END HDAML section */
 
 static int hda_ml_alloc_h2link(struct hdac_bus *bus, int index)
@@ -562,6 +571,35 @@ int hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus)
 }
 EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_sync_go_unlocked, SND_SOC_SOF_HDA_MLINK);
 
+bool hdac_bus_eml_check_cmdsync_unlocked(struct hdac_bus *bus, bool alt, int elid)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+	u32 cmdsync_mask;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return 0;
+
+	if (!h2link->lss)
+		return 0;
+
+	hlink = &h2link->hext_link;
+
+	cmdsync_mask = GENMASK(AZX_REG_ML_LSYNC_CMDSYNC_SHIFT + h2link->slcount - 1,
+			       AZX_REG_ML_LSYNC_CMDSYNC_SHIFT);
+
+	return hdaml_link_check_cmdsync(hlink->ml_addr + AZX_REG_ML_LSYNC,
+					cmdsync_mask);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_check_cmdsync_unlocked, SND_SOC_SOF_HDA_MLINK);
+
+bool hdac_bus_eml_sdw_check_cmdsync_unlocked(struct hdac_bus *bus)
+{
+	return hdac_bus_eml_check_cmdsync_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW);
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_check_cmdsync_unlocked, SND_SOC_SOF_HDA_MLINK);
+
 static int hdac_bus_eml_power_up_base(struct hdac_bus *bus, bool alt, int elid, int sublink,
 				      bool eml_lock)
 {
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 15/18] ASoC: SOF: Intel: hda-mlink: program SoundWire LSDIID registers
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (13 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 14/18] ASoC: SOF: Intel: hda-mlink: add helper to check cmdsync Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 16/18] ASoC: SOF: Intel: hda-mlink: add helpers to retrieve DMIC/SSP hlink Peter Ujfalusi
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Each SoundWire peripheral can be programmed from the manager side
either with a regular command FIFO, or with the HDaudio CORB/RIRB
DMA-based mechanism. The mapping between SoundWire peripheral and SDI
address is handled with the LSDIID register.

This mapping only works of course if each peripheral has a unique
address across all links. This has already been enforced in previous
Intel contributions allowing for an IDA-based solution for the device
number allocation.

The checks on the dev_num are handled at the SoundWire level, but the
locking is handled at the hda-mlink level.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       |  5 +++++
 sound/soc/sof/intel/hda-mlink.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
index 64106d439fd8..fc63aec97119 100644
--- a/include/sound/hda-mlink.h
+++ b/include/sound/hda-mlink.h
@@ -41,6 +41,8 @@ int hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, i
 int hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink);
 int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink);
 
+int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num);
+
 void hda_bus_ml_put_all(struct hdac_bus *bus);
 void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
 int hda_bus_ml_resume(struct hdac_bus *bus);
@@ -131,6 +133,9 @@ hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink) { return 0
 static inline int
 hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink) { return 0; }
 
+static inline int
+hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num) { return 0; }
+
 static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
 static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
 static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index 0912989ce729..87e6c5f2f3ea 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -323,6 +323,16 @@ static bool hdaml_link_check_cmdsync(u32 __iomem *lsync, u32 cmdsync_mask)
 	return !!(val & cmdsync_mask);
 }
 
+static void hdaml_link_set_lsdiid(u32 __iomem *lsdiid, int dev_num)
+{
+	u32 val;
+
+	val = readl(lsdiid);
+	val |= BIT(dev_num);
+
+	writel(val, lsdiid);
+}
+
 /* END HDAML section */
 
 static int hda_ml_alloc_h2link(struct hdac_bus *bus, int index)
@@ -698,6 +708,26 @@ int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink)
 }
 EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_power_down_unlocked, SND_SOC_SOF_HDA_MLINK);
 
+int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+
+	h2link = find_ext2_link(bus, true, AZX_REG_ML_LEPTR_ID_SDW);
+	if (!h2link)
+		return -ENODEV;
+
+	hlink = &h2link->hext_link;
+
+	mutex_lock(&h2link->eml_lock);
+
+	hdaml_link_set_lsdiid(hlink->ml_addr + AZX_REG_ML_LSDIID_OFFSET(sublink), dev_num);
+
+	mutex_unlock(&h2link->eml_lock);
+
+	return 0;
+} EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_set_lsdiid, SND_SOC_SOF_HDA_MLINK);
+
 void hda_bus_ml_put_all(struct hdac_bus *bus)
 {
 	struct hdac_ext_link *hlink;
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 16/18] ASoC: SOF: Intel: hda-mlink: add helpers to retrieve DMIC/SSP hlink
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (14 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 15/18] ASoC: SOF: Intel: hda-mlink: program SoundWire LSDIID registers Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 17/18] ASoC: SOF: Intel: hda-mlink: add helper to offload link ownership Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 18/18] ASoC: SOF: Intel: hda-mlink: add helper to retrieve eml_lock Peter Ujfalusi
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Small helpers to make DAI ops simpler.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       | 10 ++++++++++
 sound/soc/sof/intel/hda-mlink.c | 24 ++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
index fc63aec97119..c3f31fa85104 100644
--- a/include/sound/hda-mlink.h
+++ b/include/sound/hda-mlink.h
@@ -7,6 +7,7 @@
  */
 
 struct hdac_bus;
+struct hdac_ext_link;
 
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_MLINK)
 
@@ -48,6 +49,9 @@ void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
 int hda_bus_ml_resume(struct hdac_bus *bus);
 int hda_bus_ml_suspend(struct hdac_bus *bus);
 
+struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus);
+struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus);
+
 #else
 
 static inline int
@@ -141,4 +145,10 @@ static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
 static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }
 static inline int hda_bus_ml_suspend(struct hdac_bus *bus) { return 0; }
 
+static inline struct hdac_ext_link *
+hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus) { return NULL; }
+
+static inline struct hdac_ext_link *
+hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus) { return NULL; }
+
 #endif /* CONFIG_SND_SOC_SOF_HDA */
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index 87e6c5f2f3ea..2e0ca6eb322d 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -788,6 +788,30 @@ int hda_bus_ml_suspend(struct hdac_bus *bus)
 }
 EXPORT_SYMBOL_NS(hda_bus_ml_suspend, SND_SOC_SOF_HDA_MLINK);
 
+struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus)
+{
+	struct hdac_ext2_link *h2link;
+
+	h2link = find_ext2_link(bus, true, AZX_REG_ML_LEPTR_ID_INTEL_SSP);
+	if (!h2link)
+		return NULL;
+
+	return &h2link->hext_link;
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_ssp_get_hlink, SND_SOC_SOF_HDA_MLINK);
+
+struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus)
+{
+	struct hdac_ext2_link *h2link;
+
+	h2link = find_ext2_link(bus, true, AZX_REG_ML_LEPTR_ID_INTEL_DMIC);
+	if (!h2link)
+		return NULL;
+
+	return &h2link->hext_link;
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_dmic_get_hlink, SND_SOC_SOF_HDA_MLINK);
+
 #endif
 
 MODULE_LICENSE("Dual BSD/GPL");
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 17/18] ASoC: SOF: Intel: hda-mlink: add helper to offload link ownership
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (15 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 16/18] ASoC: SOF: Intel: hda-mlink: add helpers to retrieve DMIC/SSP hlink Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  2023-03-27 11:29 ` [PATCH 18/18] ASoC: SOF: Intel: hda-mlink: add helper to retrieve eml_lock Peter Ujfalusi
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

For DMIC and SSP, the DSP will be responsible for programming the
blobs and link registers.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       |  7 +++++++
 sound/soc/sof/intel/hda-mlink.c | 36 +++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
index c3f31fa85104..17adb748597a 100644
--- a/include/sound/hda-mlink.h
+++ b/include/sound/hda-mlink.h
@@ -52,6 +52,8 @@ int hda_bus_ml_suspend(struct hdac_bus *bus);
 struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus);
 struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus);
 
+int hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enable);
+
 #else
 
 static inline int
@@ -151,4 +153,9 @@ hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus) { return NULL; }
 static inline struct hdac_ext_link *
 hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus) { return NULL; }
 
+static inline int
+hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enable)
+{
+	return 0;
+}
 #endif /* CONFIG_SND_SOC_SOF_HDA */
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index 2e0ca6eb322d..e38f00bd72ad 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -333,6 +333,18 @@ static void hdaml_link_set_lsdiid(u32 __iomem *lsdiid, int dev_num)
 	writel(val, lsdiid);
 }
 
+static void hdaml_lctl_offload_enable(u32 __iomem *lctl, bool enable)
+{
+	u32 val = readl(lctl);
+
+	if (enable)
+		val |=  AZX_ML_LCTL_OFLEN;
+	else
+		val &=  ~AZX_ML_LCTL_OFLEN;
+
+	writel(val, lctl);
+}
+
 /* END HDAML section */
 
 static int hda_ml_alloc_h2link(struct hdac_bus *bus, int index)
@@ -812,6 +824,30 @@ struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus)
 }
 EXPORT_SYMBOL_NS(hdac_bus_eml_dmic_get_hlink, SND_SOC_SOF_HDA_MLINK);
 
+int hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enable)
+{
+	struct hdac_ext2_link *h2link;
+	struct hdac_ext_link *hlink;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return -ENODEV;
+
+	if (!h2link->ofls)
+		return 0;
+
+	hlink = &h2link->hext_link;
+
+	mutex_lock(&h2link->eml_lock);
+
+	hdaml_lctl_offload_enable(hlink->ml_addr + AZX_REG_ML_LCTL, enable);
+
+	mutex_unlock(&h2link->eml_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_enable_offload, SND_SOC_SOF_HDA_MLINK);
+
 #endif
 
 MODULE_LICENSE("Dual BSD/GPL");
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 18/18] ASoC: SOF: Intel: hda-mlink: add helper to retrieve eml_lock
  2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
                   ` (16 preceding siblings ...)
  2023-03-27 11:29 ` [PATCH 17/18] ASoC: SOF: Intel: hda-mlink: add helper to offload link ownership Peter Ujfalusi
@ 2023-03-27 11:29 ` Peter Ujfalusi
  17 siblings, 0 replies; 28+ messages in thread
From: Peter Ujfalusi @ 2023-03-27 11:29 UTC (permalink / raw)
  To: lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

For SoundWire usages, we need to use the global eml_lock to
serialize/protect all accesses to shared registers.  Due to the split
implementation across two subsystems, we need to pass a pointer
around.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
 include/sound/hda-mlink.h       |  5 +++++
 sound/soc/sof/intel/hda-mlink.c | 12 ++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h
index 17adb748597a..7b6ad0429034 100644
--- a/include/sound/hda-mlink.h
+++ b/include/sound/hda-mlink.h
@@ -52,6 +52,8 @@ int hda_bus_ml_suspend(struct hdac_bus *bus);
 struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus);
 struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus);
 
+struct mutex *hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid);
+
 int hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enable);
 
 #else
@@ -153,6 +155,9 @@ hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus) { return NULL; }
 static inline struct hdac_ext_link *
 hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus) { return NULL; }
 
+static inline struct mutex *
+hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid) { return NULL; }
+
 static inline int
 hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enable)
 {
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
index e38f00bd72ad..a3e5af7319ae 100644
--- a/sound/soc/sof/intel/hda-mlink.c
+++ b/sound/soc/sof/intel/hda-mlink.c
@@ -800,6 +800,18 @@ int hda_bus_ml_suspend(struct hdac_bus *bus)
 }
 EXPORT_SYMBOL_NS(hda_bus_ml_suspend, SND_SOC_SOF_HDA_MLINK);
 
+struct mutex *hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid)
+{
+	struct hdac_ext2_link *h2link;
+
+	h2link = find_ext2_link(bus, alt, elid);
+	if (!h2link)
+		return NULL;
+
+	return &h2link->eml_lock;
+}
+EXPORT_SYMBOL_NS(hdac_bus_eml_get_mutex, SND_SOC_SOF_HDA_MLINK);
+
 struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus)
 {
 	struct hdac_ext2_link *h2link;
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/18] ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM
  2023-03-27 11:29 ` [PATCH 08/18] ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM Peter Ujfalusi
@ 2023-03-28 10:34   ` Amadeusz Sławiński
  2023-03-28 13:24     ` Pierre-Louis Bossart
  2023-03-30 15:54   ` Takashi Iwai
  1 sibling, 1 reply; 28+ messages in thread
From: Amadeusz Sławiński @ 2023-03-28 10:34 UTC (permalink / raw)
  To: Peter Ujfalusi, lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, pierre-louis.bossart, ranjani.sridharan,
	kai.vehmanen, rander.wang

On 3/27/2023 1:29 PM, Peter Ujfalusi wrote:
> From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> 
> Add helpers to program SPA/CPA bits, using a mutex to access the
> shared LCTL register if required.
> 
> All links are managed with the same LCTLx.SPA bits. However there are
> quite a few implementation details to be aware of:
> 
> Legacy HDaudio multi-links are powered-up when exiting reset, which
> requires the ref_count to be manually set to one when initializing the
> link.
> 
> Alternate links for SoundWire/DMIC/SSP need to be explicitly
> powered-up before accessing the SHIM/IP/Vendor-Specific SHIM space for
> each sublink. DMIC/SSP/SoundWire are all different cases with a
> different device/dai/hlink relationship.
> 
> SoundWire will handle power management with the auxiliary device
> resume/suspend routine. The ref_count is not necessary in this case.
> 
> The DMIC/SSP will by contrast handle the power management from DAI
> .startup and .shutdown callbacks.
> 
> The SSP has a 1:1 mapping between sublink and DAI, but it's
> bidirectional so the ref_count will help avoid turning off the sublink
> when one of the two directions is still in use.
> 
> The DMIC has a single link but two DAIs for data generated at
> different sampling frequencies, again the ref_count will make sure the
> two DAIs can be used concurrently.
> 
> And last the SoundWire Intel require power-up/down and bank switch to
> be handled with a lock already taken, so the 'eml_lock' is made
> optional with the _unlocked versions of the helpers.
> 
> Note that the _check_power_active() implementation is similar to
> previous helpers in sound/hda/ext, with sleep duration and timeout
> aligned with hardware recommendations. If desired, this helper could
> be modified in a second step with .e.g. readl_poll_timeout()
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Reviewed-by: Rander Wang <rander.wang@intel.com>
> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
> ---
>   include/sound/hda-mlink.h       |  32 +++++++
>   sound/soc/sof/intel/hda-mlink.c | 163 ++++++++++++++++++++++++++++++++
>   2 files changed, 195 insertions(+)
> 

...

> diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
> index 90b68ae2564c..4cfef4007d0c 100644
> --- a/sound/soc/sof/intel/hda-mlink.c
> +++ b/sound/soc/sof/intel/hda-mlink.c
> @@ -170,6 +170,68 @@ static int hdaml_lnk_enum(struct device *dev, struct hdac_ext2_link *h2link,
>   	return 0;
>   }
>   
> +/*
> + * Hardware recommendations are to wait ~10us before checking any hardware transition
> + * reported by bits changing status.
> + * This value does not need to be super-precise, a slack of 5us is perfectly acceptable.
> + * The worst-case is about 1ms before reporting an issue
> + */
> +#define HDAML_POLL_DELAY_MIN_US 10
> +#define HDAML_POLL_DELAY_SLACK_US 5
> +#define HDAML_POLL_DELAY_RETRY  100
> +
> +static int check_power_active(u32 __iomem *lctl, int sublink, bool enable)

Should last argument be named 'active' instead of 'enable'? It would 
make more sense to me.

> +{
> +	int mask = BIT(sublink) << AZX_ML_LCTL_CPA_SHIFT;
> +	int retry = HDAML_POLL_DELAY_RETRY;
> +	u32 val;
> +
> +	usleep_range(HDAML_POLL_DELAY_MIN_US,
> +		     HDAML_POLL_DELAY_MIN_US + HDAML_POLL_DELAY_SLACK_US);
> +	do {
> +		val = readl(lctl);
> +		if (enable) {
> +			if (val & mask)
> +				return 0;
> +		} else {
> +			if (!(val & mask))
> +				return 0;
> +		}
> +		usleep_range(HDAML_POLL_DELAY_MIN_US,
> +			     HDAML_POLL_DELAY_MIN_US + HDAML_POLL_DELAY_SLACK_US);
> +
> +	} while (--retry);
> +
> +	return -EIO;
> +}
> +

...

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/18] ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM
  2023-03-28 10:34   ` Amadeusz Sławiński
@ 2023-03-28 13:24     ` Pierre-Louis Bossart
  2023-03-30 11:42       ` Amadeusz Sławiński
  0 siblings, 1 reply; 28+ messages in thread
From: Pierre-Louis Bossart @ 2023-03-28 13:24 UTC (permalink / raw)
  To: Amadeusz Sławiński, Peter Ujfalusi, lgirdwood, broonie,
	tiwai, perex
  Cc: alsa-devel, ranjani.sridharan, kai.vehmanen, rander.wang




>> +static int check_power_active(u32 __iomem *lctl, int sublink, bool
>> enable)
> 
> Should last argument be named 'active' instead of 'enable'? It would
> make more sense to me.

Naming is the hardest part, eh?

I am not super happy with 'active', since the 'not-active' part is not
very clear: it's not suspended, it's really powered-off/disabled.

I also didn't want to introduce a power state, since again it's on or
off and we don't want to introduce the Dx concepts here.

If I had to revisit this, my preference would be:

static int check_sublink_power(u32 __iomem *lctl, int sublink, bool enabled)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/18] ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM
  2023-03-28 13:24     ` Pierre-Louis Bossart
@ 2023-03-30 11:42       ` Amadeusz Sławiński
  0 siblings, 0 replies; 28+ messages in thread
From: Amadeusz Sławiński @ 2023-03-30 11:42 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Peter Ujfalusi, lgirdwood, broonie, tiwai, perex
  Cc: alsa-devel, ranjani.sridharan, kai.vehmanen, rander.wang

On 3/28/2023 3:24 PM, Pierre-Louis Bossart wrote:
> 
> 
> 
>>> +static int check_power_active(u32 __iomem *lctl, int sublink, bool
>>> enable)
>>
>> Should last argument be named 'active' instead of 'enable'? It would
>> make more sense to me.
> 
> Naming is the hardest part, eh?
> 

I don't disagree ;)

> I am not super happy with 'active', since the 'not-active' part is not
> very clear: it's not suspended, it's really powered-off/disabled.
> 
> I also didn't want to introduce a power state, since again it's on or
> off and we don't want to introduce the Dx concepts here.
> 
> If I had to revisit this, my preference would be:
> 
> static int check_sublink_power(u32 __iomem *lctl, int sublink, bool enabled)

Yes that reads better to me.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 06/18] ASoC: SOF: Intel: hda-mlink: add structures to parse ALT links
  2023-03-27 11:29 ` [PATCH 06/18] ASoC: SOF: Intel: hda-mlink: add structures to parse ALT links Peter Ujfalusi
@ 2023-03-30 15:51   ` Takashi Iwai
  2023-03-30 16:09     ` Pierre-Louis Bossart
  0 siblings, 1 reply; 28+ messages in thread
From: Takashi Iwai @ 2023-03-30 15:51 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: lgirdwood, broonie, alsa-devel, pierre-louis.bossart,
	ranjani.sridharan, kai.vehmanen, rander.wang

On Mon, 27 Mar 2023 13:29:19 +0200,
Peter Ujfalusi wrote:
> 
>  int hda_bus_ml_get_capabilities(struct hdac_bus *bus)
>  {
> -	if (bus->mlcap)
> -		return snd_hdac_ext_bus_get_ml_capabilities(bus);
> +	u32 link_count;
> +	int ret;
> +	int i;
> +
> +	if (!bus->mlcap)
> +		return 0;
> +
> +	link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1;
> +
> +	dev_dbg(bus->dev, "HDAudio Multi-Link count: %d\n", link_count);
> +
> +	for (i = 0; i < link_count; i++) {
> +		ret = hda_ml_alloc_h2link(bus, i);
> +		if (ret < 0) {
> +			hda_bus_ml_free(bus);
> +			return ret;
> +		}
> +	}
>  	return 0;

This makes that each call of hda_bus_ml_get_capabilities() adds the
h2link entries blindly.  If the driver calls it multiple times
mistakenly (the function name sounds as if it's just a helper to query
the capability bits), it'll lead to doubly entries.  Maybe adding some
check would be safer, IMO.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/18] ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM
  2023-03-27 11:29 ` [PATCH 08/18] ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM Peter Ujfalusi
  2023-03-28 10:34   ` Amadeusz Sławiński
@ 2023-03-30 15:54   ` Takashi Iwai
  2023-03-30 16:22     ` Pierre-Louis Bossart
  1 sibling, 1 reply; 28+ messages in thread
From: Takashi Iwai @ 2023-03-30 15:54 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: lgirdwood, broonie, alsa-devel, pierre-louis.bossart,
	ranjani.sridharan, kai.vehmanen, rander.wang

On Mon, 27 Mar 2023 13:29:21 +0200,
Peter Ujfalusi wrote:
> 
> +/*
> + * Hardware recommendations are to wait ~10us before checking any hardware transition
> + * reported by bits changing status.
> + * This value does not need to be super-precise, a slack of 5us is perfectly acceptable.
> + * The worst-case is about 1ms before reporting an issue
> + */
> +#define HDAML_POLL_DELAY_MIN_US 10
> +#define HDAML_POLL_DELAY_SLACK_US 5
> +#define HDAML_POLL_DELAY_RETRY  100
> +
> +static int check_power_active(u32 __iomem *lctl, int sublink, bool enable)
> +{
> +	int mask = BIT(sublink) << AZX_ML_LCTL_CPA_SHIFT;
> +	int retry = HDAML_POLL_DELAY_RETRY;
> +	u32 val;
> +
> +	usleep_range(HDAML_POLL_DELAY_MIN_US,
> +		     HDAML_POLL_DELAY_MIN_US + HDAML_POLL_DELAY_SLACK_US);
> +	do {
> +		val = readl(lctl);
> +		if (enable) {
> +			if (val & mask)
> +				return 0;
> +		} else {
> +			if (!(val & mask))
> +				return 0;
> +		}
> +		usleep_range(HDAML_POLL_DELAY_MIN_US,
> +			     HDAML_POLL_DELAY_MIN_US + HDAML_POLL_DELAY_SLACK_US);
> +
> +	} while (--retry);
> +
> +	return -EIO;
> +}

Can read_poll_timeout() and co be alternative?


thanks,

Takashi

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 06/18] ASoC: SOF: Intel: hda-mlink: add structures to parse ALT links
  2023-03-30 15:51   ` Takashi Iwai
@ 2023-03-30 16:09     ` Pierre-Louis Bossart
  2023-03-30 18:07       ` Takashi Iwai
  0 siblings, 1 reply; 28+ messages in thread
From: Pierre-Louis Bossart @ 2023-03-30 16:09 UTC (permalink / raw)
  To: Takashi Iwai, Peter Ujfalusi
  Cc: lgirdwood, broonie, alsa-devel, ranjani.sridharan, kai.vehmanen,
	rander.wang



On 3/30/23 10:51, Takashi Iwai wrote:
> On Mon, 27 Mar 2023 13:29:19 +0200,
> Peter Ujfalusi wrote:
>>
>>  int hda_bus_ml_get_capabilities(struct hdac_bus *bus)
>>  {
>> -	if (bus->mlcap)
>> -		return snd_hdac_ext_bus_get_ml_capabilities(bus);
>> +	u32 link_count;
>> +	int ret;
>> +	int i;
>> +
>> +	if (!bus->mlcap)
>> +		return 0;
>> +
>> +	link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1;
>> +
>> +	dev_dbg(bus->dev, "HDAudio Multi-Link count: %d\n", link_count);
>> +
>> +	for (i = 0; i < link_count; i++) {
>> +		ret = hda_ml_alloc_h2link(bus, i);
>> +		if (ret < 0) {
>> +			hda_bus_ml_free(bus);
>> +			return ret;
>> +		}
>> +	}
>>  	return 0;
> 
> This makes that each call of hda_bus_ml_get_capabilities() adds the
> h2link entries blindly.  If the driver calls it multiple times
> mistakenly (the function name sounds as if it's just a helper to query
> the capability bits), it'll lead to doubly entries.  Maybe adding some
> check would be safer, IMO.

Interesting comment, I didn't think of that one.

This function is currently called in the probe and indirectly via
hda_init_caps(). I think the driver framework guarantees the probe is
only called once, doesn't it?

we can also rename this function to make it clearer if there are any
suggestions, but the name is aligned with previous implementations of
the snd_hdac_ext stuff.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/18] ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM
  2023-03-30 15:54   ` Takashi Iwai
@ 2023-03-30 16:22     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 28+ messages in thread
From: Pierre-Louis Bossart @ 2023-03-30 16:22 UTC (permalink / raw)
  To: Takashi Iwai, Peter Ujfalusi
  Cc: lgirdwood, broonie, alsa-devel, ranjani.sridharan, kai.vehmanen,
	rander.wang




>> +/*
>> + * Hardware recommendations are to wait ~10us before checking any hardware transition
>> + * reported by bits changing status.
>> + * This value does not need to be super-precise, a slack of 5us is perfectly acceptable.
>> + * The worst-case is about 1ms before reporting an issue
>> + */
>> +#define HDAML_POLL_DELAY_MIN_US 10
>> +#define HDAML_POLL_DELAY_SLACK_US 5
>> +#define HDAML_POLL_DELAY_RETRY  100
>> +
>> +static int check_power_active(u32 __iomem *lctl, int sublink, bool enable)
>> +{
>> +	int mask = BIT(sublink) << AZX_ML_LCTL_CPA_SHIFT;
>> +	int retry = HDAML_POLL_DELAY_RETRY;
>> +	u32 val;
>> +
>> +	usleep_range(HDAML_POLL_DELAY_MIN_US,
>> +		     HDAML_POLL_DELAY_MIN_US + HDAML_POLL_DELAY_SLACK_US);
>> +	do {
>> +		val = readl(lctl);
>> +		if (enable) {
>> +			if (val & mask)
>> +				return 0;
>> +		} else {
>> +			if (!(val & mask))
>> +				return 0;
>> +		}
>> +		usleep_range(HDAML_POLL_DELAY_MIN_US,
>> +			     HDAML_POLL_DELAY_MIN_US + HDAML_POLL_DELAY_SLACK_US);
>> +
>> +	} while (--retry);
>> +
>> +	return -EIO;
>> +}
> 
> Can read_poll_timeout() and co be alternative?

Yes they can. I chose the simple route because I find it clearer, and
because we modified the sleep/retries compared to previous implementations.

here's what I wrote in the commit message:

"
Note that the _check_power_active() implementation is similar to
previous helpers in sound/hda/ext, with sleep duration and timeout
aligned with hardware recommendations. If desired, this helper could
be modified in a second step with .e.g. readl_poll_timeout()
"

If you want to jump directly to the next step that'd be fine. Peter had
the same comment, so I'll go with the flow.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 06/18] ASoC: SOF: Intel: hda-mlink: add structures to parse ALT links
  2023-03-30 16:09     ` Pierre-Louis Bossart
@ 2023-03-30 18:07       ` Takashi Iwai
  2023-03-31  3:05         ` Pierre-Louis Bossart
  0 siblings, 1 reply; 28+ messages in thread
From: Takashi Iwai @ 2023-03-30 18:07 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: Peter Ujfalusi, lgirdwood, broonie, alsa-devel,
	ranjani.sridharan, kai.vehmanen, rander.wang

On Thu, 30 Mar 2023 18:09:36 +0200,
Pierre-Louis Bossart wrote:
> 
> 
> 
> On 3/30/23 10:51, Takashi Iwai wrote:
> > On Mon, 27 Mar 2023 13:29:19 +0200,
> > Peter Ujfalusi wrote:
> >>
> >>  int hda_bus_ml_get_capabilities(struct hdac_bus *bus)
> >>  {
> >> -	if (bus->mlcap)
> >> -		return snd_hdac_ext_bus_get_ml_capabilities(bus);
> >> +	u32 link_count;
> >> +	int ret;
> >> +	int i;
> >> +
> >> +	if (!bus->mlcap)
> >> +		return 0;
> >> +
> >> +	link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1;
> >> +
> >> +	dev_dbg(bus->dev, "HDAudio Multi-Link count: %d\n", link_count);
> >> +
> >> +	for (i = 0; i < link_count; i++) {
> >> +		ret = hda_ml_alloc_h2link(bus, i);
> >> +		if (ret < 0) {
> >> +			hda_bus_ml_free(bus);
> >> +			return ret;
> >> +		}
> >> +	}
> >>  	return 0;
> > 
> > This makes that each call of hda_bus_ml_get_capabilities() adds the
> > h2link entries blindly.  If the driver calls it multiple times
> > mistakenly (the function name sounds as if it's just a helper to query
> > the capability bits), it'll lead to doubly entries.  Maybe adding some
> > check would be safer, IMO.
> 
> Interesting comment, I didn't think of that one.
> 
> This function is currently called in the probe and indirectly via
> hda_init_caps(). I think the driver framework guarantees the probe is
> only called once, doesn't it?
> 
> we can also rename this function to make it clearer if there are any
> suggestions, but the name is aligned with previous implementations of
> the snd_hdac_ext stuff.

Yeah, naming it as an init function would avoid the misuse.


Takashi

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 06/18] ASoC: SOF: Intel: hda-mlink: add structures to parse ALT links
  2023-03-30 18:07       ` Takashi Iwai
@ 2023-03-31  3:05         ` Pierre-Louis Bossart
  0 siblings, 0 replies; 28+ messages in thread
From: Pierre-Louis Bossart @ 2023-03-31  3:05 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Peter Ujfalusi, lgirdwood, broonie, alsa-devel,
	ranjani.sridharan, kai.vehmanen, rander.wang


>>>>  int hda_bus_ml_get_capabilities(struct hdac_bus *bus)
>>>>  {
>>>> -	if (bus->mlcap)
>>>> -		return snd_hdac_ext_bus_get_ml_capabilities(bus);
>>>> +	u32 link_count;
>>>> +	int ret;
>>>> +	int i;
>>>> +
>>>> +	if (!bus->mlcap)
>>>> +		return 0;
>>>> +
>>>> +	link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1;
>>>> +
>>>> +	dev_dbg(bus->dev, "HDAudio Multi-Link count: %d\n", link_count);
>>>> +
>>>> +	for (i = 0; i < link_count; i++) {
>>>> +		ret = hda_ml_alloc_h2link(bus, i);
>>>> +		if (ret < 0) {
>>>> +			hda_bus_ml_free(bus);
>>>> +			return ret;
>>>> +		}
>>>> +	}
>>>>  	return 0;
>>>
>>> This makes that each call of hda_bus_ml_get_capabilities() adds the
>>> h2link entries blindly.  If the driver calls it multiple times
>>> mistakenly (the function name sounds as if it's just a helper to query
>>> the capability bits), it'll lead to doubly entries.  Maybe adding some
>>> check would be safer, IMO.
>>
>> Interesting comment, I didn't think of that one.
>>
>> This function is currently called in the probe and indirectly via
>> hda_init_caps(). I think the driver framework guarantees the probe is
>> only called once, doesn't it?
>>
>> we can also rename this function to make it clearer if there are any
>> suggestions, but the name is aligned with previous implementations of
>> the snd_hdac_ext stuff.
> 
> Yeah, naming it as an init function would avoid the misuse.

Sure thing, I'll rename it as hda_bus_ml_init().

Thanks for the feedback.

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2023-03-31  3:21 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-27 11:29 [PATCH 00/18] ASoC: SOF: Intel: hda-mlink: HDaudio multi-link extension update Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 01/18] Documentation: sound: add description of Intel HDaudio multi-links Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 02/18] ALSA: hda: add HDaudio Extended link definitions Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 03/18] ASoC: SOF: Intel: hda-mlink: improve hda_bus_ml_free() helper Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 04/18] ASoC: SOF: Intel: hda-mlink: add return value for hda_bus_ml_get_capabilities() Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 05/18] ASoC: SOF: Intel: hda-mlink: move to a dedicated module Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 06/18] ASoC: SOF: Intel: hda-mlink: add structures to parse ALT links Peter Ujfalusi
2023-03-30 15:51   ` Takashi Iwai
2023-03-30 16:09     ` Pierre-Louis Bossart
2023-03-30 18:07       ` Takashi Iwai
2023-03-31  3:05         ` Pierre-Louis Bossart
2023-03-27 11:29 ` [PATCH 07/18] ASoC: SOF: Intel: hda-mlink: special-case HDaudio regular links Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 08/18] ASoC: SOF: Intel: hda-mlink: introduce helpers for 'extended links' PM Peter Ujfalusi
2023-03-28 10:34   ` Amadeusz Sławiński
2023-03-28 13:24     ` Pierre-Louis Bossart
2023-03-30 11:42       ` Amadeusz Sławiński
2023-03-30 15:54   ` Takashi Iwai
2023-03-30 16:22     ` Pierre-Louis Bossart
2023-03-27 11:29 ` [PATCH 09/18] ASoC: SOF: Intel: hda-mlink: add convenience helpers for SoundWire PM Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 10/18] ASoC: SOF: Intel: hda-mlink: add helper to return sublink count Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 11/18] ASoC: SOF: Intel: hda-mlink: add helpers to enable/check interrupts Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 12/18] ASoC: SOF: Intel: hda-mlink: add helpers to set link SYNC frequency Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 13/18] ASoC: SOF: Intel: hda-mlink: add helpers for sync_arm/sync_go Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 14/18] ASoC: SOF: Intel: hda-mlink: add helper to check cmdsync Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 15/18] ASoC: SOF: Intel: hda-mlink: program SoundWire LSDIID registers Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 16/18] ASoC: SOF: Intel: hda-mlink: add helpers to retrieve DMIC/SSP hlink Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 17/18] ASoC: SOF: Intel: hda-mlink: add helper to offload link ownership Peter Ujfalusi
2023-03-27 11:29 ` [PATCH 18/18] ASoC: SOF: Intel: hda-mlink: add helper to retrieve eml_lock Peter Ujfalusi

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.