All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support
@ 2023-06-12  9:58 Vijendar Mukunda
  2023-06-12  9:58 ` [PATCH V4 1/9] ASoC: amd: ps: create platform devices based on acp config Vijendar Mukunda
                   ` (10 more replies)
  0 siblings, 11 replies; 25+ messages in thread
From: Vijendar Mukunda @ 2023-06-12  9:58 UTC (permalink / raw)
  To: broonie
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Vijendar Mukunda

This patch series add support for
	- Platform device creation for SoundWire Manager instances and
	  PDM controller.
	- SoundWire DMA driver.
	- Interrupt handling for SoundWire manager related interrupts,
	  SoundWire DMA interrupts and ACP error interrupts.
	- ACP PCI driver PM ops modification with respect to SoundWire
	  Power modes.

Changes since v3:
	- use pdev_config instead of pdev_mask in the code.
	- define platform device configuration macros rather than enums
	- add comments for MIPI DisCo version
	- refactor SoundWire DMA start/stop sequence using single
	  function
	- refactor "acp_reset" flag related functionality.

Changes since v2:
	- add comments in irq handler.
	- remove workqueue for SoundWire DMA interrupts and use thread
	  implementation for DMA interrupt handling.
	- add error checks in sdw_amd_scan_controller()
	- remove passing "acp_lock" as platform resource for SoundWire DMA driver
	  and PDM driver.
	- retrieve "acp_lock" reference from parent driver directly and
	  use the reference in SoundWire DMA driver.
	- add handling for acp pci driver probe even when no ACP PDM or
	  SoundWire manager platform devices created.
	- Fix indentation for acp_sdw_dma_count structure variables.
	- Use macro instead of hard coded values for FIFO offset and PTE offset.
	- Change pm_runtime enable sequence in SoundWire DMA driver
	  probe function.
	- Refactor system level resume callback in SoundWire DMA

Changes since v1:
	- update "soundwire" as "SoundWire" in code.
	- add comments for platform device mask and platform device
	  count
	- remove unused variables in acp pci driver private data
	  structure
	- refactor dma enable register structures in SoundWire DMA driver
	- add TODO comments in IRQ handler
	- update IRQ mask values using bit macros
	- Fix build error reported in Makefile
	- rename "sdw_dma_stream_instance" structure name as "acp_sdw_dma_stream"
 
Vijendar Mukunda (9):
  ASoC: amd: ps: create platform devices based on acp config
  ASoC: amd: ps: handle SoundWire interrupts in acp pci driver
  ASoC: amd: ps: add SoundWire dma driver
  ASoC: amd: ps: add SoundWire dma driver dma ops
  ASoC: amd: ps: add support for SoundWire DMA interrupts
  ASoC: amd: ps: add pm ops support for SoundWire dma driver
  ASoC: amd: ps: enable SoundWire dma driver build
  ASoC: amd: update comments in Kconfig file
  ASoC: amd: ps: add acp_reset flag check in acp pci driver pm ops.

 sound/soc/amd/Kconfig         |   3 +-
 sound/soc/amd/ps/Makefile     |   2 +
 sound/soc/amd/ps/acp63.h      | 172 ++++++++++-
 sound/soc/amd/ps/pci-ps.c     | 419 +++++++++++++++++++++++--
 sound/soc/amd/ps/ps-sdw-dma.c | 555 ++++++++++++++++++++++++++++++++++
 5 files changed, 1115 insertions(+), 36 deletions(-)
 create mode 100644 sound/soc/amd/ps/ps-sdw-dma.c

-- 
2.34.1


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

* [PATCH V4 1/9] ASoC: amd: ps: create platform devices based on acp config
  2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
@ 2023-06-12  9:58 ` Vijendar Mukunda
  2023-06-12 18:09   ` Pierre-Louis Bossart
  2023-06-12  9:58 ` [PATCH V4 2/9] ASoC: amd: ps: handle SoundWire interrupts in acp pci driver Vijendar Mukunda
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 25+ messages in thread
From: Vijendar Mukunda @ 2023-06-12  9:58 UTC (permalink / raw)
  To: broonie
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Vijendar Mukunda, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem, open list

Based on ACP pin configuration and scanning child devices
under ACP pci device ACPI scope, platform device configuration
(pdev_config) and platform device count(pdev_count) will be
calculated.

Using pdev_config and pdev_count values, ACP PCI driver will
create platform devices for Pink Sardine platform.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/amd/ps/acp63.h  |  73 +++++++++-
 sound/soc/amd/ps/pci-ps.c | 271 +++++++++++++++++++++++++++++++++++---
 2 files changed, 323 insertions(+), 21 deletions(-)

diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h
index 2f94448102d0..80ab542529a7 100644
--- a/sound/soc/amd/ps/acp63.h
+++ b/sound/soc/amd/ps/acp63.h
@@ -10,7 +10,7 @@
 #define ACP_DEVICE_ID 0x15E2
 #define ACP63_REG_START		0x1240000
 #define ACP63_REG_END		0x1250200
-#define ACP63_DEVS		3
+#define ACP63_DEVS		5
 
 #define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK	0x00010001
 #define ACP_PGFSM_CNTL_POWER_ON_MASK	1
@@ -53,14 +53,53 @@
 /* time in ms for runtime suspend delay */
 #define ACP_SUSPEND_DELAY_MS	2000
 
-#define ACP63_DMIC_ADDR		2
-#define ACP63_PDM_MODE_DEVS		3
-#define ACP63_PDM_DEV_MASK		1
 #define ACP_DMIC_DEV	2
 
+/* ACP63_PDM_MODE_DEVS corresponds to platform devices count for ACP PDM configuration */
+#define ACP63_PDM_MODE_DEVS		3
+
+/*
+ * ACP63_SDW0_MODE_DEVS corresponds to platform devices count for
+ * SW0 SoundWire manager instance configuration
+ */
+#define ACP63_SDW0_MODE_DEVS		2
+
+/*
+ * ACP63_SDW0_SDW1_MODE_DEVS corresponds to platform devices count for SW0 + SW1 SoundWire manager
+ * instances configuration
+ */
+#define ACP63_SDW0_SDW1_MODE_DEVS	3
+
+/*
+ * ACP63_SDW0_PDM_MODE_DEVS corresponds to platform devices count for SW0 manager
+ * instance + ACP PDM controller configuration
+ */
+#define ACP63_SDW0_PDM_MODE_DEVS	4
+
+/*
+ * ACP63_SDW0_SDW1_PDM_MODE_DEVS corresponds to platform devices count for
+ * SW0 + SW1 SoundWire manager instances + ACP PDM controller configuration
+ */
+#define ACP63_SDW0_SDW1_PDM_MODE_DEVS   5
+#define ACP63_DMIC_ADDR			2
+#define ACP63_SDW_ADDR			5
+#define AMD_SDW_MAX_MANAGERS		2
+
 /* time in ms for acp timeout */
 #define ACP_TIMEOUT		500
 
+/* ACP63_PDM_DEV_CONFIG corresponds to platform device configuration for ACP PDM controller */
+#define ACP63_PDM_DEV_CONFIG		BIT(0)
+
+/* ACP63_SDW_DEV_CONFIG corresponds to platform device configuration for SDW manager instances */
+#define ACP63_SDW_DEV_CONFIG		BIT(1)
+
+/*
+ * ACP63_SDW_PDM_DEV_CONFIG corresponds to platform device configuration for ACP PDM + SoundWire
+ * manager instance combination.
+ */
+#define ACP63_SDW_PDM_DEV_CONFIG	GENMASK(1, 0)
+
 enum acp_config {
 	ACP_CONFIG_0 = 0,
 	ACP_CONFIG_1,
@@ -95,14 +134,38 @@ struct pdm_dev_data {
 	struct snd_pcm_substream *capture_stream;
 };
 
+/**
+ * struct acp63_dev_data - acp pci driver context
+ * @acp63_base: acp mmio base
+ * @res: resource
+ * @pdev: array of child platform device node structures
+ * @acp_lock: used to protect acp common registers
+ * @sdw_fw_node: SoundWire controller fw node handle
+ * @pdev_config: platform device configuration
+ * @pdev_count: platform devices count
+ * @pdm_dev_index: pdm platform device index
+ * @sdw_manager_count: SoundWire manager instance count
+ * @sdw0_dev_index: SoundWire Manager-0 platform device index
+ * @sdw1_dev_index: SoundWire Manager-1 platform device index
+ * @sdw_dma_dev_index: SoundWire DMA controller platform device index
+ * @acp_reset: flag set to true when bus reset is applied across all
+ * the active SoundWire manager instances
+ */
+
 struct acp63_dev_data {
 	void __iomem *acp63_base;
 	struct resource *res;
 	struct platform_device *pdev[ACP63_DEVS];
 	struct mutex acp_lock; /* protect shared registers */
-	u16 pdev_mask;
+	struct fwnode_handle *sdw_fw_node;
+	u16 pdev_config;
 	u16 pdev_count;
 	u16 pdm_dev_index;
+	u8 sdw_manager_count;
+	u16 sdw0_dev_index;
+	u16 sdw1_dev_index;
+	u16 sdw_dma_dev_index;
+	bool acp_reset;
 };
 
 int snd_amd_acp_find_config(struct pci_dev *pci);
diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
index 54752d6040d6..cf57ad2d7ccc 100644
--- a/sound/soc/amd/ps/pci-ps.c
+++ b/sound/soc/amd/ps/pci-ps.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/delay.h>
@@ -15,6 +16,7 @@
 #include <sound/pcm_params.h>
 #include <linux/pm_runtime.h>
 #include <linux/iopoll.h>
+#include <linux/soundwire/sdw_amd.h>
 
 #include "acp63.h"
 
@@ -119,37 +121,164 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
 	return IRQ_NONE;
 }
 
-static void get_acp63_device_config(u32 config, struct pci_dev *pci,
-				    struct acp63_dev_data *acp_data)
+static int sdw_amd_scan_controller(struct device *dev)
+{
+	struct acp63_dev_data *acp_data;
+	struct fwnode_handle *link;
+	char name[32];
+	u32 sdw_manager_bitmap;
+	u8 count = 0;
+	u32 acp_sdw_power_mode = 0;
+	int index;
+	int ret;
+
+	acp_data = dev_get_drvdata(dev);
+	/*
+	 * Current implementation is based on MIPI DisCo 2.0 spec.
+	 * Found controller, find links supported.
+	 */
+	ret = fwnode_property_read_u32_array((acp_data->sdw_fw_node), "mipi-sdw-manager-list",
+					     &sdw_manager_bitmap, 1);
+
+	if (ret) {
+		dev_err(dev, "Failed to read mipi-sdw-manager-list: %d\n", ret);
+		return -EINVAL;
+	}
+	count = hweight32(sdw_manager_bitmap);
+	/* Check count is within bounds */
+	if (count > AMD_SDW_MAX_MANAGERS) {
+		dev_err(dev, "Manager count %d exceeds max %d\n", count, AMD_SDW_MAX_MANAGERS);
+		return -EINVAL;
+	}
+
+	if (!count) {
+		dev_dbg(dev, "No SoundWire Managers detected\n");
+		return -EINVAL;
+	}
+	dev_dbg(dev, "ACPI reports %d SoundWire Manager devices\n", count);
+	acp_data->sdw_manager_count = count;
+	for (index = 0; index < count; index++) {
+		snprintf(name, sizeof(name), "mipi-sdw-link-%d-subproperties", index);
+		link = fwnode_get_named_child_node(acp_data->sdw_fw_node, name);
+		if (!link) {
+			dev_err(dev, "Manager node %s not found\n", name);
+			return -EIO;
+		}
+
+		ret = fwnode_property_read_u32(link, "amd-sdw-power-mode", &acp_sdw_power_mode);
+		if (ret)
+			return ret;
+		/*
+		 * when SoundWire configuration is selected from acp pin config,
+		 * based on manager instances count, acp init/de-init sequence should be
+		 * executed as part of PM ops only when Bus reset is applied for the active
+		 * SoundWire manager instances.
+		 */
+		if (acp_sdw_power_mode != AMD_SDW_POWER_OFF_MODE) {
+			acp_data->acp_reset = false;
+			return 0;
+		}
+	}
+	return 0;
+}
+
+static int get_acp63_device_config(u32 config, struct pci_dev *pci, struct acp63_dev_data *acp_data)
 {
 	struct acpi_device *dmic_dev;
+	struct acpi_device *sdw_dev;
 	const union acpi_object *obj;
 	bool is_dmic_dev = false;
+	bool is_sdw_dev = false;
+	int ret;
 
 	dmic_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0);
 	if (dmic_dev) {
+		/* is_dmic_dev flag will be set when ACP PDM controller device exists */
 		if (!acpi_dev_get_property(dmic_dev, "acp-audio-device-type",
 					   ACPI_TYPE_INTEGER, &obj) &&
 					   obj->integer.value == ACP_DMIC_DEV)
 			is_dmic_dev = true;
 	}
 
+	sdw_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_SDW_ADDR, 0);
+	if (sdw_dev) {
+		acp_data->sdw_fw_node = acpi_fwnode_handle(sdw_dev);
+		ret = sdw_amd_scan_controller(&pci->dev);
+		/* is_sdw_dev flag will be set when SoundWire Manager device exists */
+		if (!ret)
+			is_sdw_dev = true;
+	}
+	if (!is_dmic_dev && !is_sdw_dev)
+		return -ENODEV;
+	dev_dbg(&pci->dev, "Audio Mode %d\n", config);
 	switch (config) {
-	case ACP_CONFIG_0:
-	case ACP_CONFIG_1:
+	case ACP_CONFIG_4:
+	case ACP_CONFIG_5:
+	case ACP_CONFIG_10:
+	case ACP_CONFIG_11:
+		if (is_dmic_dev) {
+			acp_data->pdev_config = ACP63_PDM_DEV_CONFIG;
+			acp_data->pdev_count = ACP63_PDM_MODE_DEVS;
+		}
+		break;
 	case ACP_CONFIG_2:
 	case ACP_CONFIG_3:
-	case ACP_CONFIG_9:
-	case ACP_CONFIG_15:
-		dev_dbg(&pci->dev, "Audio Mode %d\n", config);
+		if (is_sdw_dev) {
+			switch (acp_data->sdw_manager_count) {
+			case 1:
+				acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
+				acp_data->pdev_count = ACP63_SDW0_MODE_DEVS;
+				break;
+			case 2:
+				acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
+				acp_data->pdev_count = ACP63_SDW0_SDW1_MODE_DEVS;
+				break;
+			default:
+				return -EINVAL;
+			}
+		}
 		break;
-	default:
-		if (is_dmic_dev) {
-			acp_data->pdev_mask = ACP63_PDM_DEV_MASK;
+	case ACP_CONFIG_6:
+	case ACP_CONFIG_7:
+	case ACP_CONFIG_12:
+	case ACP_CONFIG_8:
+	case ACP_CONFIG_13:
+	case ACP_CONFIG_14:
+		if (is_dmic_dev && is_sdw_dev) {
+			switch (acp_data->sdw_manager_count) {
+			case 1:
+				acp_data->pdev_config = ACP63_SDW_PDM_DEV_CONFIG;
+				acp_data->pdev_count = ACP63_SDW0_PDM_MODE_DEVS;
+				break;
+			case 2:
+				acp_data->pdev_config = ACP63_SDW_PDM_DEV_CONFIG;
+				acp_data->pdev_count = ACP63_SDW0_SDW1_PDM_MODE_DEVS;
+				break;
+			default:
+				return -EINVAL;
+			}
+		} else if (is_dmic_dev) {
+			acp_data->pdev_config = ACP63_PDM_DEV_CONFIG;
 			acp_data->pdev_count = ACP63_PDM_MODE_DEVS;
+		} else if (is_sdw_dev) {
+			switch (acp_data->sdw_manager_count) {
+			case 1:
+				acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
+				acp_data->pdev_count = ACP63_SDW0_MODE_DEVS;
+				break;
+			case 2:
+				acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
+				acp_data->pdev_count = ACP63_SDW0_SDW1_MODE_DEVS;
+				break;
+			default:
+				return -EINVAL;
+			}
 		}
 		break;
+	default:
+		break;
 	}
+	return 0;
 }
 
 static void acp63_fill_platform_dev_info(struct platform_device_info *pdevinfo,
@@ -173,6 +302,7 @@ static void acp63_fill_platform_dev_info(struct platform_device_info *pdevinfo,
 
 static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data *adata, u32 addr)
 {
+	struct acp_sdw_pdata *sdw_pdata;
 	struct platform_device_info pdevinfo[ACP63_DEVS];
 	struct device *parent;
 	int index;
@@ -180,9 +310,9 @@ static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data
 
 	parent = &pci->dev;
 	dev_dbg(&pci->dev,
-		"%s pdev_mask:0x%x pdev_count:0x%x\n", __func__, adata->pdev_mask,
+		"%s pdev_config:0x%x pdev_count:0x%x\n", __func__, adata->pdev_config,
 		adata->pdev_count);
-	if (adata->pdev_mask) {
+	if (adata->pdev_config) {
 		adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL);
 		if (!adata->res) {
 			ret = -ENOMEM;
@@ -194,8 +324,8 @@ static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data
 		memset(&pdevinfo, 0, sizeof(pdevinfo));
 	}
 
-	switch (adata->pdev_mask) {
-	case ACP63_PDM_DEV_MASK:
+	switch (adata->pdev_config) {
+	case ACP63_PDM_DEV_CONFIG:
 		adata->pdm_dev_index  = 0;
 		acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma",
 					     0, adata->res, 1, NULL, 0);
@@ -204,8 +334,104 @@ static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data
 		acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "acp_ps_mach",
 					     0, NULL, 0, NULL, 0);
 		break;
+	case ACP63_SDW_DEV_CONFIG:
+		if (adata->pdev_count == ACP63_SDW0_MODE_DEVS) {
+			sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata),
+						 GFP_KERNEL);
+			if (!sdw_pdata) {
+				ret = -ENOMEM;
+				goto de_init;
+			}
+
+			sdw_pdata->instance = 0;
+			sdw_pdata->acp_sdw_lock = &adata->acp_lock;
+			adata->sdw0_dev_index = 0;
+			adata->sdw_dma_dev_index = 1;
+			acp63_fill_platform_dev_info(&pdevinfo[0], parent, adata->sdw_fw_node,
+						     "amd_sdw_manager", 0, adata->res, 1,
+						     sdw_pdata, sizeof(struct acp_sdw_pdata));
+			acp63_fill_platform_dev_info(&pdevinfo[1], parent, NULL, "amd_ps_sdw_dma",
+						     0, adata->res, 1, NULL, 0);
+		} else if (adata->pdev_count == ACP63_SDW0_SDW1_MODE_DEVS) {
+			sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata) * 2,
+						 GFP_KERNEL);
+			if (!sdw_pdata) {
+				ret = -ENOMEM;
+				goto de_init;
+			}
+
+			sdw_pdata[0].instance = 0;
+			sdw_pdata[1].instance = 1;
+			sdw_pdata[0].acp_sdw_lock = &adata->acp_lock;
+			sdw_pdata[1].acp_sdw_lock = &adata->acp_lock;
+			sdw_pdata->acp_sdw_lock = &adata->acp_lock;
+			adata->sdw0_dev_index = 0;
+			adata->sdw1_dev_index = 1;
+			adata->sdw_dma_dev_index = 2;
+			acp63_fill_platform_dev_info(&pdevinfo[0], parent, adata->sdw_fw_node,
+						     "amd_sdw_manager", 0, adata->res, 1,
+						     &sdw_pdata[0], sizeof(struct acp_sdw_pdata));
+			acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node,
+						     "amd_sdw_manager", 1, adata->res, 1,
+						     &sdw_pdata[1], sizeof(struct acp_sdw_pdata));
+			acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "amd_ps_sdw_dma",
+						     0, adata->res, 1, NULL, 0);
+		}
+		break;
+	case ACP63_SDW_PDM_DEV_CONFIG:
+		if (adata->pdev_count == ACP63_SDW0_PDM_MODE_DEVS) {
+			sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata),
+						 GFP_KERNEL);
+			if (!sdw_pdata) {
+				ret = -ENOMEM;
+				goto de_init;
+			}
+
+			sdw_pdata->instance = 0;
+			sdw_pdata->acp_sdw_lock = &adata->acp_lock;
+			adata->pdm_dev_index = 0;
+			adata->sdw0_dev_index = 1;
+			adata->sdw_dma_dev_index = 2;
+			acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma",
+						     0, adata->res, 1, NULL, 0);
+			acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node,
+						     "amd_sdw_manager", 0, adata->res, 1,
+						     sdw_pdata, sizeof(struct acp_sdw_pdata));
+			acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "amd_ps_sdw_dma",
+						     0, adata->res, 1, NULL, 0);
+			acp63_fill_platform_dev_info(&pdevinfo[3], parent, NULL, "dmic-codec",
+						     0, NULL, 0, NULL, 0);
+		} else if (adata->pdev_count == ACP63_SDW0_SDW1_PDM_MODE_DEVS) {
+			sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata) * 2,
+						 GFP_KERNEL);
+			if (!sdw_pdata) {
+				ret = -ENOMEM;
+				goto de_init;
+			}
+			sdw_pdata[0].instance = 0;
+			sdw_pdata[1].instance = 1;
+			sdw_pdata[0].acp_sdw_lock = &adata->acp_lock;
+			sdw_pdata[1].acp_sdw_lock = &adata->acp_lock;
+			adata->pdm_dev_index = 0;
+			adata->sdw0_dev_index = 1;
+			adata->sdw1_dev_index = 2;
+			adata->sdw_dma_dev_index = 3;
+			acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma",
+						     0, adata->res, 1, NULL, 0);
+			acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node,
+						     "amd_sdw_manager", 0, adata->res, 1,
+						     &sdw_pdata[0], sizeof(struct acp_sdw_pdata));
+			acp63_fill_platform_dev_info(&pdevinfo[2], parent, adata->sdw_fw_node,
+						     "amd_sdw_manager", 1, adata->res, 1,
+						     &sdw_pdata[1], sizeof(struct acp_sdw_pdata));
+			acp63_fill_platform_dev_info(&pdevinfo[3], parent, NULL, "amd_ps_sdw_dma",
+						     0, adata->res, 1, NULL, 0);
+			acp63_fill_platform_dev_info(&pdevinfo[4], parent, NULL, "dmic-codec",
+						     0, NULL, 0, NULL, 0);
+		}
+		break;
 	default:
-		dev_dbg(&pci->dev, "No PDM devices found\n");
+		dev_dbg(&pci->dev, "No PDM or SoundWire manager devices found\n");
 		return 0;
 	}
 
@@ -276,6 +502,13 @@ static int snd_acp63_probe(struct pci_dev *pci,
 		ret = -ENOMEM;
 		goto release_regions;
 	}
+	/*
+	 * By default acp_reset flag is set to true. i.e acp_deinit() and acp_init()
+	 * will be invoked for all ACP configurations during suspend/resume callbacks.
+	 * This flag should be set to false only when SoundWire manager power mode
+	 * set to ClockStopMode.
+	 */
+	adata->acp_reset = true;
 	pci_set_master(pci);
 	pci_set_drvdata(pci, adata);
 	mutex_init(&adata->acp_lock);
@@ -289,12 +522,18 @@ static int snd_acp63_probe(struct pci_dev *pci,
 		goto de_init;
 	}
 	val = readl(adata->acp63_base + ACP_PIN_CONFIG);
-	get_acp63_device_config(val, pci, adata);
+	ret = get_acp63_device_config(val, pci, adata);
+	/* ACP PCI driver probe should be continued even PDM or SoundWire Devices are not found */
+	if (ret) {
+		dev_err(&pci->dev, "get acp device config failed:%d\n", ret);
+		goto skip_pdev_creation;
+	}
 	ret = create_acp63_platform_devs(pci, adata, addr);
 	if (ret < 0) {
 		dev_err(&pci->dev, "ACP platform devices creation failed\n");
 		goto de_init;
 	}
+skip_pdev_creation:
 	pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
 	pm_runtime_use_autosuspend(&pci->dev);
 	pm_runtime_put_noidle(&pci->dev);
-- 
2.34.1


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

* [PATCH V4 2/9] ASoC: amd: ps: handle SoundWire interrupts in acp pci driver
  2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
  2023-06-12  9:58 ` [PATCH V4 1/9] ASoC: amd: ps: create platform devices based on acp config Vijendar Mukunda
@ 2023-06-12  9:58 ` Vijendar Mukunda
  2023-06-12  9:58 ` [PATCH V4 3/9] ASoC: amd: ps: add SoundWire dma driver Vijendar Mukunda
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Vijendar Mukunda @ 2023-06-12  9:58 UTC (permalink / raw)
  To: broonie
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Vijendar Mukunda, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem, open list

Handle SoundWire manager related interrupts in ACP PCI driver
interrupt handler and schedule SoundWire manager work queue for
further processing.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/amd/ps/acp63.h  |  3 +++
 sound/soc/amd/ps/pci-ps.c | 48 +++++++++++++++++++++++++++++++++++----
 2 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h
index 80ab542529a7..494f498bdc91 100644
--- a/sound/soc/amd/ps/acp63.h
+++ b/sound/soc/amd/ps/acp63.h
@@ -99,6 +99,9 @@
  * manager instance combination.
  */
 #define ACP63_SDW_PDM_DEV_CONFIG	GENMASK(1, 0)
+#define ACP_SDW0_STAT			BIT(21)
+#define ACP_SDW1_STAT			BIT(2)
+#define ACP_ERROR_IRQ			BIT(29)
 
 enum acp_config {
 	ACP_CONFIG_0 = 0,
diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
index cf57ad2d7ccc..ac82dbe13351 100644
--- a/sound/soc/amd/ps/pci-ps.c
+++ b/sound/soc/amd/ps/pci-ps.c
@@ -56,6 +56,7 @@ static int acp63_reset(void __iomem *acp_base)
 static void acp63_enable_interrupts(void __iomem *acp_base)
 {
 	writel(1, acp_base + ACP_EXTERNAL_INTR_ENB);
+	writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL);
 }
 
 static void acp63_disable_interrupts(void __iomem *acp_base)
@@ -102,23 +103,60 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
 {
 	struct acp63_dev_data *adata;
 	struct pdm_dev_data *ps_pdm_data;
-	u32 val;
+	struct amd_sdw_manager *amd_manager;
+	u32 ext_intr_stat, ext_intr_stat1;
+	u16 irq_flag = 0;
 	u16 pdev_index;
 
 	adata = dev_id;
 	if (!adata)
 		return IRQ_NONE;
+	/* ACP interrupts will be cleared by reading particular bit and writing
+	 * same value to the status register. writing zero's doesn't have any
+	 * effect.
+	 * Bit by bit checking of IRQ field is implemented.
+	 */
+	ext_intr_stat = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
+	if (ext_intr_stat & ACP_SDW0_STAT) {
+		writel(ACP_SDW0_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
+		pdev_index = adata->sdw0_dev_index;
+		amd_manager = dev_get_drvdata(&adata->pdev[pdev_index]->dev);
+		if (amd_manager)
+			schedule_work(&amd_manager->amd_sdw_irq_thread);
+		irq_flag = 1;
+	}
+
+	ext_intr_stat1 = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
+	if (ext_intr_stat1 & ACP_SDW1_STAT) {
+		writel(ACP_SDW1_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
+		pdev_index = adata->sdw1_dev_index;
+		amd_manager = dev_get_drvdata(&adata->pdev[pdev_index]->dev);
+		if (amd_manager)
+			schedule_work(&amd_manager->amd_sdw_irq_thread);
+		irq_flag = 1;
+	}
 
-	val = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
-	if (val & BIT(PDM_DMA_STAT)) {
+	if (ext_intr_stat & ACP_ERROR_IRQ) {
+		writel(ACP_ERROR_IRQ, adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
+		/* TODO: Report SoundWire Manager instance errors */
+		writel(0, adata->acp63_base + ACP_SW0_I2S_ERROR_REASON);
+		writel(0, adata->acp63_base + ACP_SW1_I2S_ERROR_REASON);
+		writel(0, adata->acp63_base + ACP_ERROR_STATUS);
+		irq_flag = 1;
+	}
+
+	if (ext_intr_stat & BIT(PDM_DMA_STAT)) {
 		pdev_index = adata->pdm_dev_index;
 		ps_pdm_data = dev_get_drvdata(&adata->pdev[pdev_index]->dev);
 		writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
 		if (ps_pdm_data->capture_stream)
 			snd_pcm_period_elapsed(ps_pdm_data->capture_stream);
-		return IRQ_HANDLED;
+		irq_flag = 1;
 	}
-	return IRQ_NONE;
+	if (irq_flag)
+		return IRQ_HANDLED;
+	else
+		return IRQ_NONE;
 }
 
 static int sdw_amd_scan_controller(struct device *dev)
-- 
2.34.1


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

* [PATCH V4 3/9] ASoC: amd: ps: add SoundWire dma driver
  2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
  2023-06-12  9:58 ` [PATCH V4 1/9] ASoC: amd: ps: create platform devices based on acp config Vijendar Mukunda
  2023-06-12  9:58 ` [PATCH V4 2/9] ASoC: amd: ps: handle SoundWire interrupts in acp pci driver Vijendar Mukunda
@ 2023-06-12  9:58 ` Vijendar Mukunda
  2023-06-12  9:58 ` [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops Vijendar Mukunda
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Vijendar Mukunda @ 2023-06-12  9:58 UTC (permalink / raw)
  To: broonie
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Vijendar Mukunda, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem, open list

SoundWire DMA platform driver binds to the platform device created by
ACP PCI device. SoundWire DMA driver registers ALSA DMA component
with ASoC framework.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/amd/ps/acp63.h      |  5 +++
 sound/soc/amd/ps/ps-sdw-dma.c | 70 +++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)
 create mode 100644 sound/soc/amd/ps/ps-sdw-dma.c

diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h
index 494f498bdc91..c95c57970a27 100644
--- a/sound/soc/amd/ps/acp63.h
+++ b/sound/soc/amd/ps/acp63.h
@@ -137,6 +137,11 @@ struct pdm_dev_data {
 	struct snd_pcm_substream *capture_stream;
 };
 
+struct sdw_dma_dev_data {
+	void __iomem *acp_base;
+	struct mutex *acp_lock; /* used to protect acp common register access */
+};
+
 /**
  * struct acp63_dev_data - acp pci driver context
  * @acp63_base: acp mmio base
diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c
new file mode 100644
index 000000000000..f4a8d4022dc8
--- /dev/null
+++ b/sound/soc/amd/ps/ps-sdw-dma.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * AMD ALSA SoC Pink Sardine SoundWire DMA Driver
+ *
+ * Copyright 2023 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include "acp63.h"
+
+#define DRV_NAME "amd_ps_sdw_dma"
+
+static const struct snd_soc_component_driver acp63_sdw_component = {
+	.name		= DRV_NAME,
+};
+
+static int acp63_sdw_platform_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct sdw_dma_dev_data *sdw_data;
+	struct acp63_dev_data *acp_data;
+	struct device *parent;
+	int status;
+
+	parent = pdev->dev.parent;
+	acp_data = dev_get_drvdata(parent);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+		return -ENODEV;
+	}
+
+	sdw_data = devm_kzalloc(&pdev->dev, sizeof(*sdw_data), GFP_KERNEL);
+	if (!sdw_data)
+		return -ENOMEM;
+
+	sdw_data->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!sdw_data->acp_base)
+		return -ENOMEM;
+
+	sdw_data->acp_lock = &acp_data->acp_lock;
+	dev_set_drvdata(&pdev->dev, sdw_data);
+	status = devm_snd_soc_register_component(&pdev->dev,
+						 &acp63_sdw_component,
+						 NULL, 0);
+	if (status)
+		dev_err(&pdev->dev, "Fail to register sdw dma component\n");
+
+	return status;
+}
+
+static struct platform_driver acp63_sdw_dma_driver = {
+	.probe = acp63_sdw_platform_probe,
+	.driver = {
+		.name = "amd_ps_sdw_dma",
+	},
+};
+
+module_platform_driver(acp63_sdw_dma_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP6.3 PS SDW DMA Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
-- 
2.34.1


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

* [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops
  2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
                   ` (2 preceding siblings ...)
  2023-06-12  9:58 ` [PATCH V4 3/9] ASoC: amd: ps: add SoundWire dma driver Vijendar Mukunda
@ 2023-06-12  9:58 ` Vijendar Mukunda
  2023-06-12 18:06   ` Pierre-Louis Bossart
  2023-06-12  9:58 ` [PATCH V4 5/9] ASoC: amd: ps: add support for SoundWire DMA interrupts Vijendar Mukunda
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 25+ messages in thread
From: Vijendar Mukunda @ 2023-06-12  9:58 UTC (permalink / raw)
  To: broonie
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Vijendar Mukunda, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem, open list

Add SoundWire DMA driver dma ops for Pink Sardine platform.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/amd/ps/acp63.h      |  73 +++++++
 sound/soc/amd/ps/ps-sdw-dma.c | 391 ++++++++++++++++++++++++++++++++++
 2 files changed, 464 insertions(+)

diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h
index c95c57970a27..5f7ddcc31842 100644
--- a/sound/soc/amd/ps/acp63.h
+++ b/sound/soc/amd/ps/acp63.h
@@ -103,6 +103,49 @@
 #define ACP_SDW1_STAT			BIT(2)
 #define ACP_ERROR_IRQ			BIT(29)
 
+#define ACP_AUDIO0_TX_THRESHOLD		0x1c
+#define ACP_AUDIO1_TX_THRESHOLD		0x1a
+#define ACP_AUDIO2_TX_THRESHOLD		0x18
+#define ACP_AUDIO0_RX_THRESHOLD		0x1b
+#define ACP_AUDIO1_RX_THRESHOLD		0x19
+#define ACP_AUDIO2_RX_THRESHOLD		0x17
+#define ACP_P1_AUDIO1_TX_THRESHOLD	BIT(6)
+#define ACP_P1_AUDIO1_RX_THRESHOLD	BIT(5)
+#define ACP_SDW_DMA_IRQ_MASK		0x1F800000
+#define ACP_P1_SDW_DMA_IRQ_MASK		0x60
+#define ACP63_SDW0_DMA_MAX_STREAMS	6
+#define ACP63_SDW1_DMA_MAX_STREAMS	2
+#define ACP_P1_AUDIO_TX_THRESHOLD	6
+#define SDW0_DMA_TX_IRQ_MASK(i)	(ACP_AUDIO0_TX_THRESHOLD - (2 * (i)))
+#define SDW0_DMA_RX_IRQ_MASK(i)	(ACP_AUDIO0_RX_THRESHOLD - (2 * (i)))
+#define SDW1_DMA_IRQ_MASK(i)	(ACP_P1_AUDIO_TX_THRESHOLD - (i))
+
+#define ACP_DELAY_US		5
+#define ACP_SDW_RING_BUFF_ADDR_OFFSET (128 * 1024)
+#define SDW0_MEM_WINDOW_START	0x4800000
+#define ACP_SDW_SRAM_PTE_OFFSET	0x03800400
+#define SDW0_PTE_OFFSET		0x400
+#define SDW_FIFO_SIZE		0x100
+#define SDW_DMA_SIZE		0x40
+#define ACP_SDW0_FIFO_OFFSET	0x100
+#define ACP_SDW_PTE_OFFSET	0x100
+#define SDW_FIFO_OFFSET		0x100
+#define SDW_PTE_OFFSET(i)	(SDW0_PTE_OFFSET + ((i) * 0x600))
+#define ACP_SDW_FIFO_OFFSET(i)	(ACP_SDW0_FIFO_OFFSET + ((i) * 0x500))
+#define SDW_MEM_WINDOW_START(i)	(SDW0_MEM_WINDOW_START + ((i) * 0xC0000))
+
+#define SDW_PLAYBACK_MIN_NUM_PERIODS    2
+#define SDW_PLAYBACK_MAX_NUM_PERIODS    8
+#define SDW_PLAYBACK_MAX_PERIOD_SIZE    8192
+#define SDW_PLAYBACK_MIN_PERIOD_SIZE    1024
+#define SDW_CAPTURE_MIN_NUM_PERIODS     2
+#define SDW_CAPTURE_MAX_NUM_PERIODS     8
+#define SDW_CAPTURE_MAX_PERIOD_SIZE     8192
+#define SDW_CAPTURE_MIN_PERIOD_SIZE     1024
+
+#define SDW_MAX_BUFFER (SDW_PLAYBACK_MAX_PERIOD_SIZE * SDW_PLAYBACK_MAX_NUM_PERIODS)
+#define SDW_MIN_BUFFER SDW_MAX_BUFFER
+
 enum acp_config {
 	ACP_CONFIG_0 = 0,
 	ACP_CONFIG_1,
@@ -140,6 +183,36 @@ struct pdm_dev_data {
 struct sdw_dma_dev_data {
 	void __iomem *acp_base;
 	struct mutex *acp_lock; /* used to protect acp common register access */
+	struct snd_pcm_substream *sdw0_dma_stream[ACP63_SDW0_DMA_MAX_STREAMS];
+	struct snd_pcm_substream *sdw1_dma_stream[ACP63_SDW1_DMA_MAX_STREAMS];
+};
+
+struct acp_sdw_dma_stream {
+	u16 num_pages;
+	u16 channels;
+	u32 stream_id;
+	u32 instance;
+	dma_addr_t dma_addr;
+	u64 bytescount;
+};
+
+union acp_sdw_dma_count {
+	struct {
+		u32 low;
+		u32 high;
+	} bcount;
+	u64 bytescount;
+};
+
+struct sdw_dma_ring_buf_reg {
+	u32 reg_dma_size;
+	u32 reg_fifo_addr;
+	u32 reg_fifo_size;
+	u32 reg_ring_buf_size;
+	u32 reg_ring_buf_addr;
+	u32 water_mark_size_reg;
+	u32 pos_low_reg;
+	u32 pos_high_reg;
 };
 
 /**
diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c
index f4a8d4022dc8..1de78948f859 100644
--- a/sound/soc/amd/ps/ps-sdw-dma.c
+++ b/sound/soc/amd/ps/ps-sdw-dma.c
@@ -12,12 +12,403 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc-dai.h>
+#include <linux/soundwire/sdw_amd.h>
 #include "acp63.h"
 
 #define DRV_NAME "amd_ps_sdw_dma"
 
+static struct sdw_dma_ring_buf_reg sdw0_dma_ring_buf_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
+	{ACP_AUDIO0_TX_DMA_SIZE, ACP_AUDIO0_TX_FIFOADDR, ACP_AUDIO0_TX_FIFOSIZE,
+	 ACP_AUDIO0_TX_RINGBUFSIZE, ACP_AUDIO0_TX_RINGBUFADDR, ACP_AUDIO0_TX_INTR_WATERMARK_SIZE,
+	 ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH},
+	{ACP_AUDIO1_TX_DMA_SIZE, ACP_AUDIO1_TX_FIFOADDR, ACP_AUDIO1_TX_FIFOSIZE,
+	 ACP_AUDIO1_TX_RINGBUFSIZE, ACP_AUDIO1_TX_RINGBUFADDR, ACP_AUDIO1_TX_INTR_WATERMARK_SIZE,
+	 ACP_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH},
+	{ACP_AUDIO2_TX_DMA_SIZE, ACP_AUDIO2_TX_FIFOADDR, ACP_AUDIO2_TX_FIFOSIZE,
+	 ACP_AUDIO2_TX_RINGBUFSIZE, ACP_AUDIO2_TX_RINGBUFADDR, ACP_AUDIO2_TX_INTR_WATERMARK_SIZE,
+	 ACP_AUDIO2_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH},
+	{ACP_AUDIO0_RX_DMA_SIZE, ACP_AUDIO0_RX_FIFOADDR, ACP_AUDIO0_RX_FIFOSIZE,
+	 ACP_AUDIO0_RX_RINGBUFSIZE, ACP_AUDIO0_RX_RINGBUFADDR, ACP_AUDIO0_RX_INTR_WATERMARK_SIZE,
+	 ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH},
+	{ACP_AUDIO1_RX_DMA_SIZE, ACP_AUDIO1_RX_FIFOADDR, ACP_AUDIO1_RX_FIFOSIZE,
+	 ACP_AUDIO1_RX_RINGBUFSIZE, ACP_AUDIO1_RX_RINGBUFADDR, ACP_AUDIO1_RX_INTR_WATERMARK_SIZE,
+	 ACP_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH},
+	{ACP_AUDIO2_RX_DMA_SIZE, ACP_AUDIO2_RX_FIFOADDR, ACP_AUDIO2_RX_FIFOSIZE,
+	 ACP_AUDIO2_RX_RINGBUFSIZE, ACP_AUDIO2_RX_RINGBUFADDR, ACP_AUDIO2_RX_INTR_WATERMARK_SIZE,
+	 ACP_AUDIO2_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH}
+};
+
+static struct sdw_dma_ring_buf_reg sdw1_dma_ring_buf_reg[ACP63_SDW1_DMA_MAX_STREAMS] =  {
+	{ACP_P1_AUDIO1_TX_DMA_SIZE, ACP_P1_AUDIO1_TX_FIFOADDR, ACP_P1_AUDIO1_TX_FIFOSIZE,
+	 ACP_P1_AUDIO1_TX_RINGBUFSIZE, ACP_P1_AUDIO1_TX_RINGBUFADDR,
+	 ACP_P1_AUDIO1_TX_INTR_WATERMARK_SIZE,
+	 ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH},
+	{ACP_P1_AUDIO1_RX_DMA_SIZE, ACP_P1_AUDIO1_RX_FIFOADDR, ACP_P1_AUDIO1_RX_FIFOSIZE,
+	 ACP_P1_AUDIO1_RX_RINGBUFSIZE, ACP_P1_AUDIO1_RX_RINGBUFADDR,
+	 ACP_P1_AUDIO1_RX_INTR_WATERMARK_SIZE,
+	 ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH},
+};
+
+static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
+	ACP_SW0_AUDIO0_TX_EN,
+	ACP_SW0_AUDIO1_TX_EN,
+	ACP_SW0_AUDIO2_TX_EN,
+	ACP_SW0_AUDIO0_RX_EN,
+	ACP_SW0_AUDIO1_RX_EN,
+	ACP_SW0_AUDIO2_RX_EN,
+};
+
+static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = {
+	ACP_SW1_AUDIO1_TX_EN,
+	ACP_SW1_AUDIO1_RX_EN,
+};
+
+static const struct snd_pcm_hardware acp63_sdw_hardware_playback = {
+	.info = SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+	.formats = SNDRV_PCM_FMTBIT_S16_LE |  SNDRV_PCM_FMTBIT_S8 |
+		   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
+	.channels_min = 2,
+	.channels_max = 2,
+	.rates = SNDRV_PCM_RATE_48000,
+	.rate_min = 48000,
+	.rate_max = 48000,
+	.buffer_bytes_max = SDW_PLAYBACK_MAX_NUM_PERIODS * SDW_PLAYBACK_MAX_PERIOD_SIZE,
+	.period_bytes_min = SDW_PLAYBACK_MIN_PERIOD_SIZE,
+	.period_bytes_max = SDW_PLAYBACK_MAX_PERIOD_SIZE,
+	.periods_min = SDW_PLAYBACK_MIN_NUM_PERIODS,
+	.periods_max = SDW_PLAYBACK_MAX_NUM_PERIODS,
+};
+
+static const struct snd_pcm_hardware acp63_sdw_hardware_capture = {
+	.info = SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+	.formats = SNDRV_PCM_FMTBIT_S16_LE |  SNDRV_PCM_FMTBIT_S8 |
+		   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
+	.channels_min = 2,
+	.channels_max = 2,
+	.rates = SNDRV_PCM_RATE_48000,
+	.rate_min = 48000,
+	.rate_max = 48000,
+	.buffer_bytes_max = SDW_CAPTURE_MAX_NUM_PERIODS * SDW_CAPTURE_MAX_PERIOD_SIZE,
+	.period_bytes_min = SDW_CAPTURE_MIN_PERIOD_SIZE,
+	.period_bytes_max = SDW_CAPTURE_MAX_PERIOD_SIZE,
+	.periods_min = SDW_CAPTURE_MIN_NUM_PERIODS,
+	.periods_max = SDW_CAPTURE_MAX_NUM_PERIODS,
+};
+
+static void acp63_config_dma(struct acp_sdw_dma_stream *stream, void __iomem *acp_base,
+			     u32 stream_id)
+{
+	u16 page_idx;
+	u32 low, high, val;
+	u32 sdw_dma_pte_offset;
+	dma_addr_t addr;
+
+	addr = stream->dma_addr;
+	sdw_dma_pte_offset = SDW_PTE_OFFSET(stream->instance);
+	val = sdw_dma_pte_offset + (stream_id * ACP_SDW_PTE_OFFSET);
+
+	/* Group Enable */
+	writel(ACP_SDW_SRAM_PTE_OFFSET | BIT(31), acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2);
+	writel(PAGE_SIZE_4K_ENABLE, acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2);
+	for (page_idx = 0; page_idx < stream->num_pages; page_idx++) {
+		/* Load the low address of page int ACP SRAM through SRBM */
+		low = lower_32_bits(addr);
+		high = upper_32_bits(addr);
+
+		writel(low, acp_base + ACP_SCRATCH_REG_0 + val);
+		high |= BIT(31);
+		writel(high, acp_base + ACP_SCRATCH_REG_0 + val + 4);
+		val += 8;
+		addr += PAGE_SIZE;
+	}
+	writel(0x1, acp_base + ACPAXI2AXI_ATU_CTRL);
+}
+
+static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id, u32 size,
+					  u32 manager_instance)
+{
+	u32 reg_dma_size;
+	u32 reg_fifo_addr;
+	u32 reg_fifo_size;
+	u32 reg_ring_buf_size;
+	u32 reg_ring_buf_addr;
+	u32 sdw_fifo_addr;
+	u32 sdw_fifo_offset;
+	u32 sdw_ring_buf_addr;
+	u32 sdw_ring_buf_size;
+	u32 sdw_mem_window_offset;
+
+	switch (manager_instance) {
+	case ACP_SDW0:
+		reg_dma_size = sdw0_dma_ring_buf_reg[stream_id].reg_dma_size;
+		reg_fifo_addr =	sdw0_dma_ring_buf_reg[stream_id].reg_fifo_addr;
+		reg_fifo_size = sdw0_dma_ring_buf_reg[stream_id].reg_fifo_size;
+		reg_ring_buf_size = sdw0_dma_ring_buf_reg[stream_id].reg_ring_buf_size;
+		reg_ring_buf_addr = sdw0_dma_ring_buf_reg[stream_id].reg_ring_buf_addr;
+		break;
+	case ACP_SDW1:
+		reg_dma_size = sdw1_dma_ring_buf_reg[stream_id].reg_dma_size;
+		reg_fifo_addr =	sdw1_dma_ring_buf_reg[stream_id].reg_fifo_addr;
+		reg_fifo_size = sdw1_dma_ring_buf_reg[stream_id].reg_fifo_size;
+		reg_ring_buf_size = sdw1_dma_ring_buf_reg[stream_id].reg_ring_buf_size;
+		reg_ring_buf_addr = sdw1_dma_ring_buf_reg[stream_id].reg_ring_buf_addr;
+		break;
+	default:
+		return -EINVAL;
+	}
+	sdw_fifo_offset = ACP_SDW_FIFO_OFFSET(manager_instance);
+	sdw_mem_window_offset = SDW_MEM_WINDOW_START(manager_instance);
+	sdw_fifo_addr = sdw_fifo_offset + (stream_id * SDW_FIFO_OFFSET);
+	sdw_ring_buf_addr = sdw_mem_window_offset + (stream_id * ACP_SDW_RING_BUFF_ADDR_OFFSET);
+	sdw_ring_buf_size = size;
+	writel(sdw_ring_buf_size, acp_base + reg_ring_buf_size);
+	writel(sdw_ring_buf_addr, acp_base + reg_ring_buf_addr);
+	writel(sdw_fifo_addr, acp_base + reg_fifo_addr);
+	writel(SDW_DMA_SIZE, acp_base + reg_dma_size);
+	writel(SDW_FIFO_SIZE, acp_base + reg_fifo_size);
+	return 0;
+}
+
+static int acp63_sdw_dma_open(struct snd_soc_component *component,
+			      struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime;
+	struct acp_sdw_dma_stream *stream;
+	struct snd_soc_dai *cpu_dai;
+	struct amd_sdw_manager *amd_manager;
+	struct snd_soc_pcm_runtime *prtd = substream->private_data;
+	int ret;
+
+	runtime = substream->runtime;
+	cpu_dai = asoc_rtd_to_cpu(prtd, 0);
+	amd_manager = snd_soc_dai_get_drvdata(cpu_dai);
+	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
+	if (!stream)
+		return -ENOMEM;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		runtime->hw = acp63_sdw_hardware_playback;
+	else
+		runtime->hw = acp63_sdw_hardware_capture;
+	ret = snd_pcm_hw_constraint_integer(runtime,
+					    SNDRV_PCM_HW_PARAM_PERIODS);
+	if (ret < 0) {
+		dev_err(component->dev, "set integer constraint failed\n");
+		kfree(stream);
+		return ret;
+	}
+
+	stream->stream_id = cpu_dai->id;
+	stream->instance = amd_manager->instance;
+	runtime->private_data = stream;
+	return ret;
+}
+
+static int acp63_sdw_dma_hw_params(struct snd_soc_component *component,
+				   struct snd_pcm_substream *substream,
+				   struct snd_pcm_hw_params *params)
+{
+	struct acp_sdw_dma_stream *stream;
+	struct sdw_dma_dev_data *sdw_data;
+	u32 period_bytes;
+	u32 water_mark_size_reg;
+	u32 irq_mask, ext_intr_ctrl;
+	u64 size;
+	u32 stream_id;
+	u32 acp_ext_intr_cntl_reg;
+	int ret;
+
+	sdw_data = dev_get_drvdata(component->dev);
+	stream = substream->runtime->private_data;
+	if (!stream)
+		return -EINVAL;
+	stream_id = stream->stream_id;
+	switch (stream->instance) {
+	case ACP_SDW0:
+		sdw_data->sdw0_dma_stream[stream_id] = substream;
+		water_mark_size_reg = sdw0_dma_ring_buf_reg[stream_id].water_mark_size_reg;
+		acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL;
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			irq_mask = BIT(SDW0_DMA_TX_IRQ_MASK(stream_id));
+		else
+			irq_mask = BIT(SDW0_DMA_RX_IRQ_MASK(stream_id));
+		break;
+	case ACP_SDW1:
+		sdw_data->sdw1_dma_stream[stream_id] = substream;
+		acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1;
+		water_mark_size_reg = sdw1_dma_ring_buf_reg[stream_id].water_mark_size_reg;
+		irq_mask = BIT(SDW1_DMA_IRQ_MASK(stream_id));
+		break;
+	default:
+		return -EINVAL;
+	}
+	size = params_buffer_bytes(params);
+	period_bytes = params_period_bytes(params);
+	stream->dma_addr = substream->runtime->dma_addr;
+	stream->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
+	acp63_config_dma(stream, sdw_data->acp_base, stream_id);
+	ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, stream_id, size,
+					     stream->instance);
+	if (ret) {
+		dev_err(component->dev, "Invalid DMA channel\n");
+		return -EINVAL;
+	}
+	ext_intr_ctrl = readl(sdw_data->acp_base + acp_ext_intr_cntl_reg);
+	ext_intr_ctrl |= irq_mask;
+	writel(ext_intr_ctrl, sdw_data->acp_base + acp_ext_intr_cntl_reg);
+	writel(period_bytes, sdw_data->acp_base + water_mark_size_reg);
+	return 0;
+}
+
+static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base)
+{
+	union acp_sdw_dma_count byte_count;
+	u32 pos_low_reg, pos_high_reg;
+
+	byte_count.bytescount = 0;
+	switch (stream->instance) {
+	case ACP_SDW0:
+		pos_low_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
+		pos_high_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
+		break;
+	case ACP_SDW1:
+		pos_low_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
+		pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (pos_low_reg) {
+		byte_count.bcount.high = readl(acp_base + pos_high_reg);
+		byte_count.bcount.low = readl(acp_base + pos_low_reg);
+	}
+	return byte_count.bytescount;
+}
+
+static snd_pcm_uframes_t acp63_sdw_dma_pointer(struct snd_soc_component *comp,
+					       struct snd_pcm_substream *substream)
+{
+	struct sdw_dma_dev_data *sdw_data;
+	struct acp_sdw_dma_stream *stream;
+	u32 pos, buffersize;
+	u64 bytescount;
+
+	sdw_data = dev_get_drvdata(comp->dev);
+	stream = substream->runtime->private_data;
+	buffersize = frames_to_bytes(substream->runtime,
+				     substream->runtime->buffer_size);
+	bytescount = acp63_sdw_get_byte_count(stream, sdw_data->acp_base);
+	if (bytescount > stream->bytescount)
+		bytescount -= stream->bytescount;
+	pos = do_div(bytescount, buffersize);
+	return bytes_to_frames(substream->runtime, pos);
+}
+
+static int acp63_sdw_dma_new(struct snd_soc_component *component,
+			     struct snd_soc_pcm_runtime *rtd)
+{
+	struct device *parent = component->dev->parent;
+
+	snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
+				       parent, SDW_MIN_BUFFER, SDW_MAX_BUFFER);
+	return 0;
+}
+
+static int acp63_sdw_dma_close(struct snd_soc_component *component,
+			       struct snd_pcm_substream *substream)
+{
+	struct sdw_dma_dev_data *sdw_data;
+	struct acp_sdw_dma_stream *stream;
+
+	sdw_data = dev_get_drvdata(component->dev);
+	stream = substream->runtime->private_data;
+	if (!stream)
+		return -EINVAL;
+	switch (stream->instance) {
+	case ACP_SDW0:
+		sdw_data->sdw0_dma_stream[stream->stream_id] = NULL;
+		break;
+	case ACP_SDW1:
+		sdw_data->sdw1_dma_stream[stream->stream_id] = NULL;
+		break;
+	default:
+		return -EINVAL;
+	}
+	kfree(stream);
+	return 0;
+}
+
+static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream,
+				void __iomem *acp_base, bool sdw_dma_enable)
+{
+	struct acp_sdw_dma_stream *stream;
+	u32 stream_id;
+	u32 sdw_dma_en_reg;
+	u32 sdw_dma_en_stat_reg;
+	u32 sdw_dma_stat;
+	u32 dma_enable;
+
+	stream = substream->runtime->private_data;
+	stream_id = stream->stream_id;
+	switch (stream->instance) {
+	case ACP_SDW0:
+		sdw_dma_en_reg = sdw0_dma_enable_reg[stream_id];
+		break;
+	case ACP_SDW1:
+		sdw_dma_en_reg = sdw1_dma_enable_reg[stream_id];
+		break;
+	default:
+		return -EINVAL;
+	}
+	sdw_dma_en_stat_reg = sdw_dma_en_reg + 4;
+	dma_enable = sdw_dma_enable;
+	writel(dma_enable, acp_base + sdw_dma_en_reg);
+	return readl_poll_timeout(acp_base + sdw_dma_en_stat_reg, sdw_dma_stat,
+				  (sdw_dma_stat == dma_enable), ACP_DELAY_US, ACP_COUNTER);
+}
+
+static int acp63_sdw_dma_trigger(struct snd_soc_component *comp,
+				 struct snd_pcm_substream *substream,
+				 int cmd)
+{
+	struct sdw_dma_dev_data *sdw_data;
+	int ret;
+
+	sdw_data = dev_get_drvdata(comp->dev);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+	case SNDRV_PCM_TRIGGER_RESUME:
+		ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, true);
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_STOP:
+		ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, false);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	if (ret)
+		dev_err(comp->dev, "trigger %d failed: %d", cmd, ret);
+	return ret;
+}
+
 static const struct snd_soc_component_driver acp63_sdw_component = {
 	.name		= DRV_NAME,
+	.open		= acp63_sdw_dma_open,
+	.close		= acp63_sdw_dma_close,
+	.hw_params	= acp63_sdw_dma_hw_params,
+	.trigger	= acp63_sdw_dma_trigger,
+	.pointer	= acp63_sdw_dma_pointer,
+	.pcm_construct	= acp63_sdw_dma_new,
 };
 
 static int acp63_sdw_platform_probe(struct platform_device *pdev)
-- 
2.34.1


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

* [PATCH V4 5/9] ASoC: amd: ps: add support for SoundWire DMA interrupts
  2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
                   ` (3 preceding siblings ...)
  2023-06-12  9:58 ` [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops Vijendar Mukunda
@ 2023-06-12  9:58 ` Vijendar Mukunda
  2023-06-12  9:59 ` [PATCH V4 6/9] ASoC: amd: ps: add pm ops support for SoundWire dma driver Vijendar Mukunda
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Vijendar Mukunda @ 2023-06-12  9:58 UTC (permalink / raw)
  To: broonie
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Vijendar Mukunda, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem, open list

Move to request_threaded_irq and use thread for handling
SoundWire DMA interrupts.
Whenever audio data equal to the SoundWire FIFO watermark level
are produced/consumed, interrupt is generated.
Acknowledge the interrupt and wake up the irq thread.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/amd/ps/acp63.h  | 18 +++++++++
 sound/soc/amd/ps/pci-ps.c | 82 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h
index 5f7ddcc31842..e96e6dc9d90f 100644
--- a/sound/soc/amd/ps/acp63.h
+++ b/sound/soc/amd/ps/acp63.h
@@ -165,6 +165,20 @@ enum acp_config {
 	ACP_CONFIG_15,
 };
 
+enum amd_sdw0_channel {
+	ACP_SDW0_AUDIO0_TX = 0,
+	ACP_SDW0_AUDIO1_TX,
+	ACP_SDW0_AUDIO2_TX,
+	ACP_SDW0_AUDIO0_RX,
+	ACP_SDW0_AUDIO1_RX,
+	ACP_SDW0_AUDIO2_RX,
+};
+
+enum amd_sdw1_channel {
+	ACP_SDW1_AUDIO1_TX,
+	ACP_SDW1_AUDIO1_RX,
+};
+
 struct pdm_stream_instance {
 	u16 num_pages;
 	u16 channels;
@@ -229,6 +243,8 @@ struct sdw_dma_ring_buf_reg {
  * @sdw0_dev_index: SoundWire Manager-0 platform device index
  * @sdw1_dev_index: SoundWire Manager-1 platform device index
  * @sdw_dma_dev_index: SoundWire DMA controller platform device index
+ * @sdw0-dma_intr_stat: DMA interrupt status array for SoundWire manager-SW0 instance
+ * @sdw_dma_intr_stat: DMA interrupt status array for SoundWire manager-SW1 instance
  * @acp_reset: flag set to true when bus reset is applied across all
  * the active SoundWire manager instances
  */
@@ -246,6 +262,8 @@ struct acp63_dev_data {
 	u16 sdw0_dev_index;
 	u16 sdw1_dev_index;
 	u16 sdw_dma_dev_index;
+	u16 sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS];
+	u16 sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS];
 	bool acp_reset;
 };
 
diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
index ac82dbe13351..ff734a90951b 100644
--- a/sound/soc/amd/ps/pci-ps.c
+++ b/sound/soc/amd/ps/pci-ps.c
@@ -99,14 +99,44 @@ static int acp63_deinit(void __iomem *acp_base, struct device *dev)
 	return 0;
 }
 
+static irqreturn_t acp63_irq_thread(int irq, void *context)
+{
+	struct sdw_dma_dev_data *sdw_dma_data;
+	struct acp63_dev_data *adata = context;
+	u32 stream_index;
+	u16 pdev_index;
+
+	pdev_index = adata->sdw_dma_dev_index;
+	sdw_dma_data = dev_get_drvdata(&adata->pdev[pdev_index]->dev);
+
+	for (stream_index = 0; stream_index < ACP63_SDW0_DMA_MAX_STREAMS; stream_index++) {
+		if (adata->sdw0_dma_intr_stat[stream_index]) {
+			if (sdw_dma_data->sdw0_dma_stream[stream_index])
+				snd_pcm_period_elapsed(sdw_dma_data->sdw0_dma_stream[stream_index]);
+			adata->sdw0_dma_intr_stat[stream_index] = 0;
+		}
+	}
+	for (stream_index = 0; stream_index < ACP63_SDW1_DMA_MAX_STREAMS; stream_index++) {
+		if (adata->sdw1_dma_intr_stat[stream_index]) {
+			if (sdw_dma_data->sdw1_dma_stream[stream_index])
+				snd_pcm_period_elapsed(sdw_dma_data->sdw1_dma_stream[stream_index]);
+			adata->sdw1_dma_intr_stat[stream_index] = 0;
+		}
+	}
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
 {
 	struct acp63_dev_data *adata;
 	struct pdm_dev_data *ps_pdm_data;
 	struct amd_sdw_manager *amd_manager;
 	u32 ext_intr_stat, ext_intr_stat1;
+	u32 stream_id = 0;
 	u16 irq_flag = 0;
+	u16 sdw_dma_irq_flag = 0;
 	u16 pdev_index;
+	u16 index;
 
 	adata = dev_id;
 	if (!adata)
@@ -153,6 +183,54 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
 			snd_pcm_period_elapsed(ps_pdm_data->capture_stream);
 		irq_flag = 1;
 	}
+	if (ext_intr_stat & ACP_SDW_DMA_IRQ_MASK) {
+		for (index = ACP_AUDIO2_RX_THRESHOLD; index <= ACP_AUDIO0_TX_THRESHOLD; index++) {
+			if (ext_intr_stat & BIT(index)) {
+				writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
+				switch (index) {
+				case ACP_AUDIO0_TX_THRESHOLD:
+					stream_id = ACP_SDW0_AUDIO0_TX;
+					break;
+				case ACP_AUDIO1_TX_THRESHOLD:
+					stream_id = ACP_SDW0_AUDIO1_TX;
+					break;
+				case ACP_AUDIO2_TX_THRESHOLD:
+					stream_id = ACP_SDW0_AUDIO2_TX;
+					break;
+				case ACP_AUDIO0_RX_THRESHOLD:
+					stream_id = ACP_SDW0_AUDIO0_RX;
+					break;
+				case ACP_AUDIO1_RX_THRESHOLD:
+					stream_id = ACP_SDW0_AUDIO1_RX;
+					break;
+				case ACP_AUDIO2_RX_THRESHOLD:
+					stream_id = ACP_SDW0_AUDIO2_RX;
+					break;
+				}
+
+				adata->sdw0_dma_intr_stat[stream_id] = 1;
+				sdw_dma_irq_flag = 1;
+			}
+		}
+	}
+
+	if (ext_intr_stat1 & ACP_P1_AUDIO1_RX_THRESHOLD) {
+		writel(ACP_P1_AUDIO1_RX_THRESHOLD,
+		       adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
+		adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_RX] = 1;
+		sdw_dma_irq_flag = 1;
+	}
+
+	if (ext_intr_stat1 & ACP_P1_AUDIO1_TX_THRESHOLD) {
+		writel(ACP_P1_AUDIO1_TX_THRESHOLD,
+		       adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
+		adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_TX] = 1;
+		sdw_dma_irq_flag = 1;
+	}
+
+	if (sdw_dma_irq_flag)
+		return IRQ_WAKE_THREAD;
+
 	if (irq_flag)
 		return IRQ_HANDLED;
 	else
@@ -553,8 +631,8 @@ static int snd_acp63_probe(struct pci_dev *pci,
 	ret = acp63_init(adata->acp63_base, &pci->dev);
 	if (ret)
 		goto release_regions;
-	ret = devm_request_irq(&pci->dev, pci->irq, acp63_irq_handler,
-			       irqflags, "ACP_PCI_IRQ", adata);
+	ret = devm_request_threaded_irq(&pci->dev, pci->irq, acp63_irq_handler,
+					acp63_irq_thread, irqflags, "ACP_PCI_IRQ", adata);
 	if (ret) {
 		dev_err(&pci->dev, "ACP PCI IRQ request failed\n");
 		goto de_init;
-- 
2.34.1


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

* [PATCH V4 6/9] ASoC: amd: ps: add pm ops support for SoundWire dma driver
  2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
                   ` (4 preceding siblings ...)
  2023-06-12  9:58 ` [PATCH V4 5/9] ASoC: amd: ps: add support for SoundWire DMA interrupts Vijendar Mukunda
@ 2023-06-12  9:59 ` Vijendar Mukunda
  2023-06-12  9:59 ` [PATCH V4 7/9] ASoC: amd: ps: enable SoundWire dma driver build Vijendar Mukunda
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Vijendar Mukunda @ 2023-06-12  9:59 UTC (permalink / raw)
  To: broonie
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Vijendar Mukunda, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, open list

Add support pm ops support for SoundWire dma driver.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/amd/ps/ps-sdw-dma.c | 98 ++++++++++++++++++++++++++++++++++-
 1 file changed, 96 insertions(+), 2 deletions(-)

diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c
index 1de78948f859..ade130a8062a 100644
--- a/sound/soc/amd/ps/ps-sdw-dma.c
+++ b/sound/soc/amd/ps/ps-sdw-dma.c
@@ -12,6 +12,7 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc-dai.h>
+#include <linux/pm_runtime.h>
 #include <linux/soundwire/sdw_amd.h>
 #include "acp63.h"
 
@@ -102,6 +103,29 @@ static const struct snd_pcm_hardware acp63_sdw_hardware_capture = {
 	.periods_max = SDW_CAPTURE_MAX_NUM_PERIODS,
 };
 
+static void acp63_enable_disable_sdw_dma_interrupts(void __iomem *acp_base, bool enable)
+{
+	u32 ext_intr_cntl, ext_intr_cntl1;
+	u32 irq_mask = ACP_SDW_DMA_IRQ_MASK;
+	u32 irq_mask1 = ACP_P1_SDW_DMA_IRQ_MASK;
+
+	if (enable) {
+		ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+		ext_intr_cntl |= irq_mask;
+		writel(ext_intr_cntl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+		ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1);
+		ext_intr_cntl1 |= irq_mask1;
+		writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1);
+	} else {
+		ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+		ext_intr_cntl &= ~irq_mask;
+		writel(ext_intr_cntl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+		ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1);
+		ext_intr_cntl1 &= ~irq_mask1;
+		writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1);
+	}
+}
+
 static void acp63_config_dma(struct acp_sdw_dma_stream *stream, void __iomem *acp_base,
 			     u32 stream_id)
 {
@@ -440,16 +464,86 @@ static int acp63_sdw_platform_probe(struct platform_device *pdev)
 	status = devm_snd_soc_register_component(&pdev->dev,
 						 &acp63_sdw_component,
 						 NULL, 0);
-	if (status)
+	if (status) {
 		dev_err(&pdev->dev, "Fail to register sdw dma component\n");
+		return status;
+	}
+	pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_mark_last_busy(&pdev->dev);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	return 0;
+}
 
-	return status;
+static int acp63_sdw_platform_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+	return 0;
 }
 
+static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data)
+{
+	struct acp_sdw_dma_stream *stream;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
+	u32 period_bytes, buf_size, water_mark_size_reg;
+	u32 stream_count;
+	int index, instance, ret;
+
+	for (instance = 0; instance < AMD_SDW_MAX_MANAGERS; instance++) {
+		if (instance == ACP_SDW0)
+			stream_count = ACP63_SDW0_DMA_MAX_STREAMS;
+		else
+			stream_count = ACP63_SDW1_DMA_MAX_STREAMS;
+
+		for (index = 0; index < stream_count; index++) {
+			if (instance == ACP_SDW0) {
+				substream = sdw_data->sdw0_dma_stream[index];
+				water_mark_size_reg =
+						sdw0_dma_ring_buf_reg[index].water_mark_size_reg;
+			} else {
+				substream = sdw_data->sdw1_dma_stream[index];
+				water_mark_size_reg =
+						sdw1_dma_ring_buf_reg[index].water_mark_size_reg;
+			}
+
+			if (substream && substream->runtime) {
+				runtime = substream->runtime;
+				stream = runtime->private_data;
+				period_bytes = frames_to_bytes(runtime, runtime->period_size);
+				buf_size = frames_to_bytes(runtime, runtime->buffer_size);
+				acp63_config_dma(stream, sdw_data->acp_base, index);
+				ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, index,
+								     buf_size, instance);
+				if (ret)
+					return ret;
+				writel(period_bytes, sdw_data->acp_base + water_mark_size_reg);
+			}
+		}
+	}
+	acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, true);
+	return 0;
+}
+
+static int __maybe_unused acp63_sdw_pcm_resume(struct device *dev)
+{
+	struct sdw_dma_dev_data *sdw_data;
+
+	sdw_data = dev_get_drvdata(dev);
+	return acp_restore_sdw_dma_config(sdw_data);
+}
+
+static const struct dev_pm_ops acp63_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(NULL, acp63_sdw_pcm_resume)
+};
+
 static struct platform_driver acp63_sdw_dma_driver = {
 	.probe = acp63_sdw_platform_probe,
+	.remove = acp63_sdw_platform_remove,
 	.driver = {
 		.name = "amd_ps_sdw_dma",
+		.pm = &acp63_pm_ops,
 	},
 };
 
-- 
2.34.1


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

* [PATCH V4 7/9] ASoC: amd: ps: enable SoundWire dma driver build
  2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
                   ` (5 preceding siblings ...)
  2023-06-12  9:59 ` [PATCH V4 6/9] ASoC: amd: ps: add pm ops support for SoundWire dma driver Vijendar Mukunda
@ 2023-06-12  9:59 ` Vijendar Mukunda
  2023-06-12  9:59 ` [PATCH V4 8/9] ASoC: amd: update comments in Kconfig file Vijendar Mukunda
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Vijendar Mukunda @ 2023-06-12  9:59 UTC (permalink / raw)
  To: broonie
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Vijendar Mukunda, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem, open list

Enable SoundWire dma driver build for PS platform.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/amd/ps/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/soc/amd/ps/Makefile b/sound/soc/amd/ps/Makefile
index 383973a12f6a..f2a5eaf2fa4d 100644
--- a/sound/soc/amd/ps/Makefile
+++ b/sound/soc/amd/ps/Makefile
@@ -3,7 +3,9 @@
 snd-pci-ps-objs := pci-ps.o
 snd-ps-pdm-dma-objs := ps-pdm-dma.o
 snd-soc-ps-mach-objs := ps-mach.o
+snd-ps-sdw-dma-objs := ps-sdw-dma.o
 
 obj-$(CONFIG_SND_SOC_AMD_PS) += snd-pci-ps.o
 obj-$(CONFIG_SND_SOC_AMD_PS) += snd-ps-pdm-dma.o
+obj-$(CONFIG_SND_SOC_AMD_PS) += snd-ps-sdw-dma.o
 obj-$(CONFIG_SND_SOC_AMD_PS_MACH)   += snd-soc-ps-mach.o
-- 
2.34.1


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

* [PATCH V4 8/9] ASoC: amd: update comments in Kconfig file
  2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
                   ` (6 preceding siblings ...)
  2023-06-12  9:59 ` [PATCH V4 7/9] ASoC: amd: ps: enable SoundWire dma driver build Vijendar Mukunda
@ 2023-06-12  9:59 ` Vijendar Mukunda
  2023-06-12  9:59 ` [PATCH V4 9/9] ASoC: amd: ps: add acp_reset flag check in acp pci driver pm ops Vijendar Mukunda
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Vijendar Mukunda @ 2023-06-12  9:59 UTC (permalink / raw)
  To: broonie
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Vijendar Mukunda, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem, Randy Dunlap,
	open list

Update comments in Kconfig file for Pink Sardine platform.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/amd/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig
index 08e42082f5e9..2f0d444b21fa 100644
--- a/sound/soc/amd/Kconfig
+++ b/sound/soc/amd/Kconfig
@@ -136,7 +136,8 @@ config SND_SOC_AMD_PS
         help
           This option enables Audio Coprocessor i.e ACP v6.3 support on
           AMD Pink sardine platform. By enabling this flag build will be
-          triggered for ACP PCI driver, ACP PDM DMA driver.
+          triggered for ACP PCI driver, ACP PDM DMA driver, ACP SoundWire
+          DMA driver.
           Say m if you have such a device.
           If unsure select "N".
 
-- 
2.34.1


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

* [PATCH V4 9/9] ASoC: amd: ps: add acp_reset flag check in acp pci driver pm ops.
  2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
                   ` (7 preceding siblings ...)
  2023-06-12  9:59 ` [PATCH V4 8/9] ASoC: amd: update comments in Kconfig file Vijendar Mukunda
@ 2023-06-12  9:59 ` Vijendar Mukunda
  2023-06-19  5:32 ` [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Mukunda,Vijendar
  2023-06-21  0:34 ` Mark Brown
  10 siblings, 0 replies; 25+ messages in thread
From: Vijendar Mukunda @ 2023-06-12  9:59 UTC (permalink / raw)
  To: broonie
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Vijendar Mukunda, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem, open list

AMD SoundWire manager supports different power modes.
acp_reset flag will be set to false only when SoundWire manager power
mode is selected as ClockStop Mode. For rest of the combinations
(ACP PDM + SDW), acp_reset flag will be set to true.
When acp_reset flag is set, acp de-init and acp init sequence should
be invoked during suspend/resume callbacks.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/amd/ps/pci-ps.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
index ff734a90951b..5b46dc8573f8 100644
--- a/sound/soc/amd/ps/pci-ps.c
+++ b/sound/soc/amd/ps/pci-ps.c
@@ -669,24 +669,28 @@ static int snd_acp63_probe(struct pci_dev *pci,
 static int __maybe_unused snd_acp63_suspend(struct device *dev)
 {
 	struct acp63_dev_data *adata;
-	int ret;
+	int ret = 0;
 
 	adata = dev_get_drvdata(dev);
-	ret = acp63_deinit(adata->acp63_base, dev);
-	if (ret)
-		dev_err(dev, "ACP de-init failed\n");
+	if (adata->acp_reset) {
+		ret = acp63_deinit(adata->acp63_base, dev);
+		if (ret)
+			dev_err(dev, "ACP de-init failed\n");
+	}
 	return ret;
 }
 
 static int __maybe_unused snd_acp63_resume(struct device *dev)
 {
 	struct acp63_dev_data *adata;
-	int ret;
+	int ret = 0;
 
 	adata = dev_get_drvdata(dev);
-	ret = acp63_init(adata->acp63_base, dev);
-	if (ret)
-		dev_err(dev, "ACP init failed\n");
+	if (adata->acp_reset) {
+		ret = acp63_init(adata->acp63_base, dev);
+		if (ret)
+			dev_err(dev, "ACP init failed\n");
+	}
 	return ret;
 }
 
-- 
2.34.1


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

* Re: [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops
  2023-06-12  9:58 ` [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops Vijendar Mukunda
@ 2023-06-12 18:06   ` Pierre-Louis Bossart
  2023-06-13  7:00     ` Mukunda,Vijendar
  0 siblings, 1 reply; 25+ messages in thread
From: Pierre-Louis Bossart @ 2023-06-12 18:06 UTC (permalink / raw)
  To: Vijendar Mukunda, broonie
  Cc: alsa-devel, Basavaraj.Hiregoudar, Sunil-kumar.Dommati,
	Mastan.Katragadda, Arungopal.kondaveeti, mario.limonciello,
	Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem,
	open list


> +#define SDW_PLAYBACK_MIN_NUM_PERIODS    2
> +#define SDW_PLAYBACK_MAX_NUM_PERIODS    8
> +#define SDW_PLAYBACK_MAX_PERIOD_SIZE    8192

that's a fairly small max period. That's 21ms for 2ch S32_LE 48kHz.

Does this come from specific limitations or is this an arbitrary number?

A comment on this wouldn't hurt.

> +static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
> +	ACP_SW0_AUDIO0_TX_EN,
> +	ACP_SW0_AUDIO1_TX_EN,
> +	ACP_SW0_AUDIO2_TX_EN,
> +	ACP_SW0_AUDIO0_RX_EN,
> +	ACP_SW0_AUDIO1_RX_EN,
> +	ACP_SW0_AUDIO2_RX_EN,
> +};
> +
> +static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = {
> +	ACP_SW1_AUDIO1_TX_EN,
> +	ACP_SW1_AUDIO1_RX_EN,
> +};

Still no explanation as to why SDW0 indices start at zero and SDW1
indices start at one?

> +
> +static const struct snd_pcm_hardware acp63_sdw_hardware_playback = {
> +	.info = SNDRV_PCM_INFO_INTERLEAVED |
> +		SNDRV_PCM_INFO_BLOCK_TRANSFER |
> +		SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
> +		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
> +	.formats = SNDRV_PCM_FMTBIT_S16_LE |  SNDRV_PCM_FMTBIT_S8 |
> +		   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
> +	.channels_min = 2,
> +	.channels_max = 2,
> +	.rates = SNDRV_PCM_RATE_48000,
> +	.rate_min = 48000,
> +	.rate_max = 48000,
> +	.buffer_bytes_max = SDW_PLAYBACK_MAX_NUM_PERIODS * SDW_PLAYBACK_MAX_PERIOD_SIZE,
> +	.period_bytes_min = SDW_PLAYBACK_MIN_PERIOD_SIZE,
> +	.period_bytes_max = SDW_PLAYBACK_MAX_PERIOD_SIZE,
> +	.periods_min = SDW_PLAYBACK_MIN_NUM_PERIODS,
> +	.periods_max = SDW_PLAYBACK_MAX_NUM_PERIODS,
> +};
> +
> +static const struct snd_pcm_hardware acp63_sdw_hardware_capture = {
> +	.info = SNDRV_PCM_INFO_INTERLEAVED |
> +		SNDRV_PCM_INFO_BLOCK_TRANSFER |
> +		SNDRV_PCM_INFO_MMAP |
> +		SNDRV_PCM_INFO_MMAP_VALID |
> +		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
> +	.formats = SNDRV_PCM_FMTBIT_S16_LE |  SNDRV_PCM_FMTBIT_S8 |
> +		   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
> +	.channels_min = 2,
> +	.channels_max = 2,
> +	.rates = SNDRV_PCM_RATE_48000,
> +	.rate_min = 48000,
> +	.rate_max = 48000,
> +	.buffer_bytes_max = SDW_CAPTURE_MAX_NUM_PERIODS * SDW_CAPTURE_MAX_PERIOD_SIZE,
> +	.period_bytes_min = SDW_CAPTURE_MIN_PERIOD_SIZE,
> +	.period_bytes_max = SDW_CAPTURE_MAX_PERIOD_SIZE,
> +	.periods_min = SDW_CAPTURE_MIN_NUM_PERIODS,
> +	.periods_max = SDW_CAPTURE_MAX_NUM_PERIODS,
> +};

> +static int acp63_sdw_dma_open(struct snd_soc_component *component,
> +			      struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime;
> +	struct acp_sdw_dma_stream *stream;
> +	struct snd_soc_dai *cpu_dai;
> +	struct amd_sdw_manager *amd_manager;
> +	struct snd_soc_pcm_runtime *prtd = substream->private_data;
> +	int ret;
> +
> +	runtime = substream->runtime;
> +	cpu_dai = asoc_rtd_to_cpu(prtd, 0);
> +	amd_manager = snd_soc_dai_get_drvdata(cpu_dai);
> +	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
> +	if (!stream)
> +		return -ENOMEM;
> +
> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
> +		runtime->hw = acp63_sdw_hardware_playback;
> +	else
> +		runtime->hw = acp63_sdw_hardware_capture;
> +	ret = snd_pcm_hw_constraint_integer(runtime,
> +					    SNDRV_PCM_HW_PARAM_PERIODS);
> +	if (ret < 0) {
> +		dev_err(component->dev, "set integer constraint failed\n");
> +		kfree(stream);
> +		return ret;
> +	}

it's not clear to me why you have to add this specific constraint, isn't
this checked already with the sdw_hardware_playback information.

> +static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base)
> +{
> +	union acp_sdw_dma_count byte_count;
> +	u32 pos_low_reg, pos_high_reg;
> +
> +	byte_count.bytescount = 0;
> +	switch (stream->instance) {
> +	case ACP_SDW0:
> +		pos_low_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
> +		pos_high_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
> +		break;
> +	case ACP_SDW1:
> +		pos_low_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
> +		pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
> +		break;
> +	default:
> +		return -EINVAL;

returning -EINVAL as a u64 doesn't seem quite right to me?

> +	}
> +	if (pos_low_reg) {
> +		byte_count.bcount.high = readl(acp_base + pos_high_reg);
> +		byte_count.bcount.low = readl(acp_base + pos_low_reg);
> +	}
> +	return byte_count.bytescount;
> +}

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

* Re: [PATCH V4 1/9] ASoC: amd: ps: create platform devices based on acp config
  2023-06-12  9:58 ` [PATCH V4 1/9] ASoC: amd: ps: create platform devices based on acp config Vijendar Mukunda
@ 2023-06-12 18:09   ` Pierre-Louis Bossart
  2023-06-13  5:42     ` Mukunda,Vijendar
  0 siblings, 1 reply; 25+ messages in thread
From: Pierre-Louis Bossart @ 2023-06-12 18:09 UTC (permalink / raw)
  To: Vijendar Mukunda, broonie
  Cc: alsa-devel, Basavaraj.Hiregoudar, Sunil-kumar.Dommati,
	Mastan.Katragadda, Arungopal.kondaveeti, mario.limonciello,
	Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem,
	open list

=
> +static int sdw_amd_scan_controller(struct device *dev)
> +{
> +	struct acp63_dev_data *acp_data;
> +	struct fwnode_handle *link;
> +	char name[32];
> +	u32 sdw_manager_bitmap;
> +	u8 count = 0;
> +	u32 acp_sdw_power_mode = 0;
> +	int index;
> +	int ret;
> +
> +	acp_data = dev_get_drvdata(dev);
> +	/*
> +	 * Current implementation is based on MIPI DisCo 2.0 spec.
> +	 * Found controller, find links supported.
> +	 */
> +	ret = fwnode_property_read_u32_array((acp_data->sdw_fw_node), "mipi-sdw-manager-list",
> +					     &sdw_manager_bitmap, 1);
> +
> +	if (ret) {
> +		dev_err(dev, "Failed to read mipi-sdw-manager-list: %d\n", ret);
> +		return -EINVAL;
> +	}
> +	count = hweight32(sdw_manager_bitmap);
> +	/* Check count is within bounds */
> +	if (count > AMD_SDW_MAX_MANAGERS) {
> +		dev_err(dev, "Manager count %d exceeds max %d\n", count, AMD_SDW_MAX_MANAGERS);
> +		return -EINVAL;
> +	}

nit-pick: the count is not enough, you should also check that only bits
0 and 1 are set in mipi-sdw-manager-list...

> +
> +	if (!count) {
> +		dev_dbg(dev, "No SoundWire Managers detected\n");
> +		return -EINVAL;
> +	}
> +	dev_dbg(dev, "ACPI reports %d SoundWire Manager devices\n", count);
> +	acp_data->sdw_manager_count = count;
> +	for (index = 0; index < count; index++) {
> +		snprintf(name, sizeof(name), "mipi-sdw-link-%d-subproperties", index);

... otherwise this will be wrong.

> +		link = fwnode_get_named_child_node(acp_data->sdw_fw_node, name);
> +		if (!link) {
> +			dev_err(dev, "Manager node %s not found\n", name);
> +			return -EIO;
> +		}
> +
> +		ret = fwnode_property_read_u32(link, "amd-sdw-power-mode", &acp_sdw_power_mode);
> +		if (ret)
> +			return ret;
> +		/*
> +		 * when SoundWire configuration is selected from acp pin config,
> +		 * based on manager instances count, acp init/de-init sequence should be
> +		 * executed as part of PM ops only when Bus reset is applied for the active
> +		 * SoundWire manager instances.
> +		 */
> +		if (acp_sdw_power_mode != AMD_SDW_POWER_OFF_MODE) {
> +			acp_data->acp_reset = false;
> +			return 0;
> +		}
> +	}
> +	return 0;
> +}


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

* Re: [PATCH V4 1/9] ASoC: amd: ps: create platform devices based on acp config
  2023-06-12 18:09   ` Pierre-Louis Bossart
@ 2023-06-13  5:42     ` Mukunda,Vijendar
  2023-06-15 16:23       ` Pierre-Louis Bossart
  0 siblings, 1 reply; 25+ messages in thread
From: Mukunda,Vijendar @ 2023-06-13  5:42 UTC (permalink / raw)
  To: Pierre-Louis Bossart, broonie
  Cc: alsa-devel, Basavaraj.Hiregoudar, Sunil-kumar.Dommati,
	Mastan.Katragadda, Arungopal.kondaveeti, mario.limonciello,
	Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem,
	open list

On 12/06/23 23:39, Pierre-Louis Bossart wrote:
> =
>> +static int sdw_amd_scan_controller(struct device *dev)
>> +{
>> +	struct acp63_dev_data *acp_data;
>> +	struct fwnode_handle *link;
>> +	char name[32];
>> +	u32 sdw_manager_bitmap;
>> +	u8 count = 0;
>> +	u32 acp_sdw_power_mode = 0;
>> +	int index;
>> +	int ret;
>> +
>> +	acp_data = dev_get_drvdata(dev);
>> +	/*
>> +	 * Current implementation is based on MIPI DisCo 2.0 spec.
>> +	 * Found controller, find links supported.
>> +	 */
>> +	ret = fwnode_property_read_u32_array((acp_data->sdw_fw_node), "mipi-sdw-manager-list",
>> +					     &sdw_manager_bitmap, 1);
>> +
>> +	if (ret) {
>> +		dev_err(dev, "Failed to read mipi-sdw-manager-list: %d\n", ret);
>> +		return -EINVAL;
>> +	}
>> +	count = hweight32(sdw_manager_bitmap);
>> +	/* Check count is within bounds */
>> +	if (count > AMD_SDW_MAX_MANAGERS) {
>> +		dev_err(dev, "Manager count %d exceeds max %d\n", count, AMD_SDW_MAX_MANAGERS);
>> +		return -EINVAL;
>> +	}
> nit-pick: the count is not enough, you should also check that only bits
> 0 and 1 are set in mipi-sdw-manager-list...
As per our design for PS platform,
we will go with two bit map values as 0x03 and 0x01.
1. As per ACP PIN CONFIG, we support Single SDW Manager instance
which refers to SW0 manager instance. For this, we need to use bitmap
value as 0x01.
2. Other bit map value - 0x03 will be used to populate two SoundWire
manager instances.
We have extra sub property "amd-sdw-enable" to invoke the init sequence
for SoundWire manager.

As we are supporting two bit map value combinations here, it's not required
to check bit set value. count value is enough to know manager instance count.
It doesn't break anything.

>> +
>> +	if (!count) {
>> +		dev_dbg(dev, "No SoundWire Managers detected\n");
>> +		return -EINVAL;
>> +	}
>> +	dev_dbg(dev, "ACPI reports %d SoundWire Manager devices\n", count);
>> +	acp_data->sdw_manager_count = count;
>> +	for (index = 0; index < count; index++) {
>> +		snprintf(name, sizeof(name), "mipi-sdw-link-%d-subproperties", index);
> ... otherwise this will be wrong.
>
>> +		link = fwnode_get_named_child_node(acp_data->sdw_fw_node, name);
>> +		if (!link) {
>> +			dev_err(dev, "Manager node %s not found\n", name);
>> +			return -EIO;
>> +		}
>> +
>> +		ret = fwnode_property_read_u32(link, "amd-sdw-power-mode", &acp_sdw_power_mode);
>> +		if (ret)
>> +			return ret;
>> +		/*
>> +		 * when SoundWire configuration is selected from acp pin config,
>> +		 * based on manager instances count, acp init/de-init sequence should be
>> +		 * executed as part of PM ops only when Bus reset is applied for the active
>> +		 * SoundWire manager instances.
>> +		 */
>> +		if (acp_sdw_power_mode != AMD_SDW_POWER_OFF_MODE) {
>> +			acp_data->acp_reset = false;
>> +			return 0;
>> +		}
>> +	}
>> +	return 0;
>> +}


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

* Re: [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops
  2023-06-12 18:06   ` Pierre-Louis Bossart
@ 2023-06-13  7:00     ` Mukunda,Vijendar
  2023-06-15 15:50       ` Mukunda,Vijendar
  2023-06-15 16:21       ` Pierre-Louis Bossart
  0 siblings, 2 replies; 25+ messages in thread
From: Mukunda,Vijendar @ 2023-06-13  7:00 UTC (permalink / raw)
  To: Pierre-Louis Bossart, broonie
  Cc: alsa-devel, Basavaraj.Hiregoudar, Sunil-kumar.Dommati,
	Mastan.Katragadda, Arungopal.kondaveeti, mario.limonciello,
	Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem,
	open list

On 12/06/23 23:36, Pierre-Louis Bossart wrote:
>> +#define SDW_PLAYBACK_MIN_NUM_PERIODS    2
>> +#define SDW_PLAYBACK_MAX_NUM_PERIODS    8
>> +#define SDW_PLAYBACK_MAX_PERIOD_SIZE    8192
> that's a fairly small max period. That's 21ms for 2ch S32_LE 48kHz.
>
> Does this come from specific limitations or is this an arbitrary number?
>
> A comment on this wouldn't hurt.
This is the initial version. We haven't exercised different sample
rates/bit depth combinations much. Currently, targeted for 2Ch, 48Khz,
16bit audio streams only with 64k as buffer size.

We will extend support for different sample rates/bit depths combinations
in the future.
>> +static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
>> +	ACP_SW0_AUDIO0_TX_EN,
>> +	ACP_SW0_AUDIO1_TX_EN,
>> +	ACP_SW0_AUDIO2_TX_EN,
>> +	ACP_SW0_AUDIO0_RX_EN,
>> +	ACP_SW0_AUDIO1_RX_EN,
>> +	ACP_SW0_AUDIO2_RX_EN,
>> +};
>> +
>> +static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = {
>> +	ACP_SW1_AUDIO1_TX_EN,
>> +	ACP_SW1_AUDIO1_RX_EN,
>> +};
> Still no explanation as to why SDW0 indices start at zero and SDW1
> indices start at one?
We have already provided reply in previous thread, i.e. for v3 patch set.

https://lore.kernel.org/alsa-devel/de3c86cc-6cba-0cbd-0e04-43711b4c9bc2@amd.com/




>
>> +
>> +static const struct snd_pcm_hardware acp63_sdw_hardware_playback = {
>> +	.info = SNDRV_PCM_INFO_INTERLEAVED |
>> +		SNDRV_PCM_INFO_BLOCK_TRANSFER |
>> +		SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
>> +		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
>> +	.formats = SNDRV_PCM_FMTBIT_S16_LE |  SNDRV_PCM_FMTBIT_S8 |
>> +		   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
>> +	.channels_min = 2,
>> +	.channels_max = 2,
>> +	.rates = SNDRV_PCM_RATE_48000,
>> +	.rate_min = 48000,
>> +	.rate_max = 48000,
>> +	.buffer_bytes_max = SDW_PLAYBACK_MAX_NUM_PERIODS * SDW_PLAYBACK_MAX_PERIOD_SIZE,
>> +	.period_bytes_min = SDW_PLAYBACK_MIN_PERIOD_SIZE,
>> +	.period_bytes_max = SDW_PLAYBACK_MAX_PERIOD_SIZE,
>> +	.periods_min = SDW_PLAYBACK_MIN_NUM_PERIODS,
>> +	.periods_max = SDW_PLAYBACK_MAX_NUM_PERIODS,
>> +};
>> +
>> +static const struct snd_pcm_hardware acp63_sdw_hardware_capture = {
>> +	.info = SNDRV_PCM_INFO_INTERLEAVED |
>> +		SNDRV_PCM_INFO_BLOCK_TRANSFER |
>> +		SNDRV_PCM_INFO_MMAP |
>> +		SNDRV_PCM_INFO_MMAP_VALID |
>> +		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
>> +	.formats = SNDRV_PCM_FMTBIT_S16_LE |  SNDRV_PCM_FMTBIT_S8 |
>> +		   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
>> +	.channels_min = 2,
>> +	.channels_max = 2,
>> +	.rates = SNDRV_PCM_RATE_48000,
>> +	.rate_min = 48000,
>> +	.rate_max = 48000,
>> +	.buffer_bytes_max = SDW_CAPTURE_MAX_NUM_PERIODS * SDW_CAPTURE_MAX_PERIOD_SIZE,
>> +	.period_bytes_min = SDW_CAPTURE_MIN_PERIOD_SIZE,
>> +	.period_bytes_max = SDW_CAPTURE_MAX_PERIOD_SIZE,
>> +	.periods_min = SDW_CAPTURE_MIN_NUM_PERIODS,
>> +	.periods_max = SDW_CAPTURE_MAX_NUM_PERIODS,
>> +};
>> +static int acp63_sdw_dma_open(struct snd_soc_component *component,
>> +			      struct snd_pcm_substream *substream)
>> +{
>> +	struct snd_pcm_runtime *runtime;
>> +	struct acp_sdw_dma_stream *stream;
>> +	struct snd_soc_dai *cpu_dai;
>> +	struct amd_sdw_manager *amd_manager;
>> +	struct snd_soc_pcm_runtime *prtd = substream->private_data;
>> +	int ret;
>> +
>> +	runtime = substream->runtime;
>> +	cpu_dai = asoc_rtd_to_cpu(prtd, 0);
>> +	amd_manager = snd_soc_dai_get_drvdata(cpu_dai);
>> +	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
>> +	if (!stream)
>> +		return -ENOMEM;
>> +
>> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
>> +		runtime->hw = acp63_sdw_hardware_playback;
>> +	else
>> +		runtime->hw = acp63_sdw_hardware_capture;
>> +	ret = snd_pcm_hw_constraint_integer(runtime,
>> +					    SNDRV_PCM_HW_PARAM_PERIODS);
>> +	if (ret < 0) {
>> +		dev_err(component->dev, "set integer constraint failed\n");
>> +		kfree(stream);
>> +		return ret;
>> +	}
> it's not clear to me why you have to add this specific constraint, isn't
> this checked already with the sdw_hardware_playback information.
In above code, first we are assigning runtime->hw structures.
As per our understanding, we are not assigning any hw_constraints.

This snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS) constraint assures that the number
of periods is integer, hence the buffer size is aligned with the period size.

>
>> +static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base)
>> +{
>> +	union acp_sdw_dma_count byte_count;
>> +	u32 pos_low_reg, pos_high_reg;
>> +
>> +	byte_count.bytescount = 0;
>> +	switch (stream->instance) {
>> +	case ACP_SDW0:
>> +		pos_low_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
>> +		pos_high_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
>> +		break;
>> +	case ACP_SDW1:
>> +		pos_low_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
>> +		pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
>> +		break;
>> +	default:
>> +		return -EINVAL;
> returning -EINVAL as a u64 doesn't seem quite right to me?
Agreed. Default case needs to be corrected. In case of invalid
SDW instance, it should return default byte count which is zero
instead of returning -EINVAL.

We have identified similar fix has to be implemented in our other
dma driver as well.
https://elixir.bootlin.com/linux/v6.4-rc6/source/sound/soc/amd/acp/amd.h#L174

Will push a supplement patch to fix it at one go.
>
>> +	}
>> +	if (pos_low_reg) {
>> +		byte_count.bcount.high = readl(acp_base + pos_high_reg);
>> +		byte_count.bcount.low = readl(acp_base + pos_low_reg);
>> +	}
>> +	return byte_count.bytescount;
>> +}


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

* Re: [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops
  2023-06-13  7:00     ` Mukunda,Vijendar
@ 2023-06-15 15:50       ` Mukunda,Vijendar
  2023-06-15 15:56         ` Mark Brown
  2023-06-15 16:12         ` Mukunda,Vijendar
  2023-06-15 16:21       ` Pierre-Louis Bossart
  1 sibling, 2 replies; 25+ messages in thread
From: Mukunda,Vijendar @ 2023-06-15 15:50 UTC (permalink / raw)
  To: Pierre-Louis Bossart, broonie
  Cc: alsa-devel, Basavaraj.Hiregoudar, Sunil-kumar.Dommati,
	Mastan.Katragadda, Arungopal.kondaveeti, mario.limonciello,
	Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem,
	open list

On 13/06/23 12:30, Mukunda,Vijendar wrote:
> On 12/06/23 23:36, Pierre-Louis Bossart wrote:
>>> +#define SDW_PLAYBACK_MIN_NUM_PERIODS    2
>>> +#define SDW_PLAYBACK_MAX_NUM_PERIODS    8
>>> +#define SDW_PLAYBACK_MAX_PERIOD_SIZE    8192
>> that's a fairly small max period. That's 21ms for 2ch S32_LE 48kHz.
>>
>> Does this come from specific limitations or is this an arbitrary number?
>>
>> A comment on this wouldn't hurt.
> This is the initial version. We haven't exercised different sample
> rates/bit depth combinations much. Currently, targeted for 2Ch, 48Khz,
> 16bit audio streams only with 64k as buffer size.
>
> We will extend support for different sample rates/bit depths combinations
> in the future.
>>> +static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
>>> +	ACP_SW0_AUDIO0_TX_EN,
>>> +	ACP_SW0_AUDIO1_TX_EN,
>>> +	ACP_SW0_AUDIO2_TX_EN,
>>> +	ACP_SW0_AUDIO0_RX_EN,
>>> +	ACP_SW0_AUDIO1_RX_EN,
>>> +	ACP_SW0_AUDIO2_RX_EN,
>>> +};
>>> +
>>> +static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = {
>>> +	ACP_SW1_AUDIO1_TX_EN,
>>> +	ACP_SW1_AUDIO1_RX_EN,
>>> +};
>> Still no explanation as to why SDW0 indices start at zero and SDW1
>> indices start at one?
> We have already provided reply in previous thread, i.e. for v3 patch set.
>
> https://lore.kernel.org/alsa-devel/de3c86cc-6cba-0cbd-0e04-43711b4c9bc2@amd.com/
>
>
>
>
>>> +
>>> +static const struct snd_pcm_hardware acp63_sdw_hardware_playback = {
>>> +	.info = SNDRV_PCM_INFO_INTERLEAVED |
>>> +		SNDRV_PCM_INFO_BLOCK_TRANSFER |
>>> +		SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
>>> +		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
>>> +	.formats = SNDRV_PCM_FMTBIT_S16_LE |  SNDRV_PCM_FMTBIT_S8 |
>>> +		   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
>>> +	.channels_min = 2,
>>> +	.channels_max = 2,
>>> +	.rates = SNDRV_PCM_RATE_48000,
>>> +	.rate_min = 48000,
>>> +	.rate_max = 48000,
>>> +	.buffer_bytes_max = SDW_PLAYBACK_MAX_NUM_PERIODS * SDW_PLAYBACK_MAX_PERIOD_SIZE,
>>> +	.period_bytes_min = SDW_PLAYBACK_MIN_PERIOD_SIZE,
>>> +	.period_bytes_max = SDW_PLAYBACK_MAX_PERIOD_SIZE,
>>> +	.periods_min = SDW_PLAYBACK_MIN_NUM_PERIODS,
>>> +	.periods_max = SDW_PLAYBACK_MAX_NUM_PERIODS,
>>> +};
>>> +
>>> +static const struct snd_pcm_hardware acp63_sdw_hardware_capture = {
>>> +	.info = SNDRV_PCM_INFO_INTERLEAVED |
>>> +		SNDRV_PCM_INFO_BLOCK_TRANSFER |
>>> +		SNDRV_PCM_INFO_MMAP |
>>> +		SNDRV_PCM_INFO_MMAP_VALID |
>>> +		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
>>> +	.formats = SNDRV_PCM_FMTBIT_S16_LE |  SNDRV_PCM_FMTBIT_S8 |
>>> +		   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
>>> +	.channels_min = 2,
>>> +	.channels_max = 2,
>>> +	.rates = SNDRV_PCM_RATE_48000,
>>> +	.rate_min = 48000,
>>> +	.rate_max = 48000,
>>> +	.buffer_bytes_max = SDW_CAPTURE_MAX_NUM_PERIODS * SDW_CAPTURE_MAX_PERIOD_SIZE,
>>> +	.period_bytes_min = SDW_CAPTURE_MIN_PERIOD_SIZE,
>>> +	.period_bytes_max = SDW_CAPTURE_MAX_PERIOD_SIZE,
>>> +	.periods_min = SDW_CAPTURE_MIN_NUM_PERIODS,
>>> +	.periods_max = SDW_CAPTURE_MAX_NUM_PERIODS,
>>> +};
>>> +static int acp63_sdw_dma_open(struct snd_soc_component *component,
>>> +			      struct snd_pcm_substream *substream)
>>> +{
>>> +	struct snd_pcm_runtime *runtime;
>>> +	struct acp_sdw_dma_stream *stream;
>>> +	struct snd_soc_dai *cpu_dai;
>>> +	struct amd_sdw_manager *amd_manager;
>>> +	struct snd_soc_pcm_runtime *prtd = substream->private_data;
>>> +	int ret;
>>> +
>>> +	runtime = substream->runtime;
>>> +	cpu_dai = asoc_rtd_to_cpu(prtd, 0);
>>> +	amd_manager = snd_soc_dai_get_drvdata(cpu_dai);
>>> +	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
>>> +	if (!stream)
>>> +		return -ENOMEM;
>>> +
>>> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
>>> +		runtime->hw = acp63_sdw_hardware_playback;
>>> +	else
>>> +		runtime->hw = acp63_sdw_hardware_capture;
>>> +	ret = snd_pcm_hw_constraint_integer(runtime,
>>> +					    SNDRV_PCM_HW_PARAM_PERIODS);
>>> +	if (ret < 0) {
>>> +		dev_err(component->dev, "set integer constraint failed\n");
>>> +		kfree(stream);
>>> +		return ret;
>>> +	}
>> it's not clear to me why you have to add this specific constraint, isn't
>> this checked already with the sdw_hardware_playback information.
> In above code, first we are assigning runtime->hw structures.
> As per our understanding, we are not assigning any hw_constraints.
>
> This snd_pcm_hw_constraint_integer(runtime,
> SNDRV_PCM_HW_PARAM_PERIODS) constraint assures that the number
> of periods is integer, hence the buffer size is aligned with the period size.
>
>>> +static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base)
>>> +{
>>> +	union acp_sdw_dma_count byte_count;
>>> +	u32 pos_low_reg, pos_high_reg;
>>> +
>>> +	byte_count.bytescount = 0;
>>> +	switch (stream->instance) {
>>> +	case ACP_SDW0:
>>> +		pos_low_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
>>> +		pos_high_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
>>> +		break;
>>> +	case ACP_SDW1:
>>> +		pos_low_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
>>> +		pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
>>> +		break;
>>> +	default:
>>> +		return -EINVAL;
>> returning -EINVAL as a u64 doesn't seem quite right to me?
> Agreed. Default case needs to be corrected. In case of invalid
> SDW instance, it should return default byte count which is zero
> instead of returning -EINVAL.
>
> We have identified similar fix has to be implemented in our other
> dma driver as well.
> https://elixir.bootlin.com/linux/v6.4-rc6/source/sound/soc/amd/acp/amd.h#L174
>
> Will push a supplement patch to fix it at one go.
>> @Bossart: Let us know, if have any futher comments for our replies.
>>> +	}
>>> +	if (pos_low_reg) {
>>> +		byte_count.bcount.high = readl(acp_base + pos_high_reg);
>>> +		byte_count.bcount.low = readl(acp_base + pos_low_reg);
>>> +	}
>>> +	return byte_count.bytescount;
>>> +}


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

* Re: [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops
  2023-06-15 15:50       ` Mukunda,Vijendar
@ 2023-06-15 15:56         ` Mark Brown
  2023-06-15 16:09           ` Mukunda,Vijendar
  2023-06-15 16:12         ` Mukunda,Vijendar
  1 sibling, 1 reply; 25+ messages in thread
From: Mark Brown @ 2023-06-15 15:56 UTC (permalink / raw)
  To: Mukunda,Vijendar
  Cc: Pierre-Louis Bossart, alsa-devel, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Syed Saba Kareem, open list

[-- Attachment #1: Type: text/plain, Size: 299 bytes --]

On Thu, Jun 15, 2023 at 09:20:08PM +0530, Mukunda,Vijendar wrote:
> On 13/06/23 12:30, Mukunda,Vijendar wrote:
> > On 12/06/23 23:36, Pierre-Louis Bossart wrote:
> >>> +#define SDW_PLAYBACK_MIN_NUM_PERIODS    2
> >>> +#define SDW_PLAYBACK_MAX_NUM_PERIODS    8

Not seeing any new text in this mail?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops
  2023-06-15 15:56         ` Mark Brown
@ 2023-06-15 16:09           ` Mukunda,Vijendar
  0 siblings, 0 replies; 25+ messages in thread
From: Mukunda,Vijendar @ 2023-06-15 16:09 UTC (permalink / raw)
  To: Mark Brown
  Cc: Pierre-Louis Bossart, alsa-devel, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Syed Saba Kareem, open list

On 15/06/23 21:26, Mark Brown wrote:
> On Thu, Jun 15, 2023 at 09:20:08PM +0530, Mukunda,Vijendar wrote:
>> On 13/06/23 12:30, Mukunda,Vijendar wrote:
>>> On 12/06/23 23:36, Pierre-Louis Bossart wrote:
>>>>> +#define SDW_PLAYBACK_MIN_NUM_PERIODS    2
>>>>> +#define SDW_PLAYBACK_MAX_NUM_PERIODS    8
> Not seeing any new text in this mail?
Sorry it's my bad.
My reply got mixed with previous thread comments.


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

* Re: [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops
  2023-06-15 15:50       ` Mukunda,Vijendar
  2023-06-15 15:56         ` Mark Brown
@ 2023-06-15 16:12         ` Mukunda,Vijendar
  1 sibling, 0 replies; 25+ messages in thread
From: Mukunda,Vijendar @ 2023-06-15 16:12 UTC (permalink / raw)
  To: Pierre-Louis Bossart, broonie
  Cc: alsa-devel, Basavaraj.Hiregoudar, Sunil-kumar.Dommati,
	Mastan.Katragadda, Arungopal.kondaveeti, mario.limonciello,
	Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem,
	open list

On 15/06/23 21:20, Mukunda,Vijendar wrote:
> On 13/06/23 12:30, Mukunda,Vijendar wrote:
>> On 12/06/23 23:36, Pierre-Louis Bossart wrote:
>>>> +#define SDW_PLAYBACK_MIN_NUM_PERIODS    2
>>>> +#define SDW_PLAYBACK_MAX_NUM_PERIODS    8
>>>> +#define SDW_PLAYBACK_MAX_PERIOD_SIZE    8192
>>> that's a fairly small max period. That's 21ms for 2ch S32_LE 48kHz.
>>>
>>> Does this come from specific limitations or is this an arbitrary number?
>>>
>>> A comment on this wouldn't hurt.
>> This is the initial version. We haven't exercised different sample
>> rates/bit depth combinations much. Currently, targeted for 2Ch, 48Khz,
>> 16bit audio streams only with 64k as buffer size.
>>
>> We will extend support for different sample rates/bit depths combinations
>> in the future.
>>>> +static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
>>>> +	ACP_SW0_AUDIO0_TX_EN,
>>>> +	ACP_SW0_AUDIO1_TX_EN,
>>>> +	ACP_SW0_AUDIO2_TX_EN,
>>>> +	ACP_SW0_AUDIO0_RX_EN,
>>>> +	ACP_SW0_AUDIO1_RX_EN,
>>>> +	ACP_SW0_AUDIO2_RX_EN,
>>>> +};
>>>> +
>>>> +static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = {
>>>> +	ACP_SW1_AUDIO1_TX_EN,
>>>> +	ACP_SW1_AUDIO1_RX_EN,
>>>> +};
>>> Still no explanation as to why SDW0 indices start at zero and SDW1
>>> indices start at one?
>> We have already provided reply in previous thread, i.e. for v3 patch set.
>>
>> https://lore.kernel.org/alsa-devel/de3c86cc-6cba-0cbd-0e04-43711b4c9bc2@amd.com/
>>
>>
>>
>>
>>>> +
>>>> +static const struct snd_pcm_hardware acp63_sdw_hardware_playback = {
>>>> +	.info = SNDRV_PCM_INFO_INTERLEAVED |
>>>> +		SNDRV_PCM_INFO_BLOCK_TRANSFER |
>>>> +		SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
>>>> +		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
>>>> +	.formats = SNDRV_PCM_FMTBIT_S16_LE |  SNDRV_PCM_FMTBIT_S8 |
>>>> +		   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
>>>> +	.channels_min = 2,
>>>> +	.channels_max = 2,
>>>> +	.rates = SNDRV_PCM_RATE_48000,
>>>> +	.rate_min = 48000,
>>>> +	.rate_max = 48000,
>>>> +	.buffer_bytes_max = SDW_PLAYBACK_MAX_NUM_PERIODS * SDW_PLAYBACK_MAX_PERIOD_SIZE,
>>>> +	.period_bytes_min = SDW_PLAYBACK_MIN_PERIOD_SIZE,
>>>> +	.period_bytes_max = SDW_PLAYBACK_MAX_PERIOD_SIZE,
>>>> +	.periods_min = SDW_PLAYBACK_MIN_NUM_PERIODS,
>>>> +	.periods_max = SDW_PLAYBACK_MAX_NUM_PERIODS,
>>>> +};
>>>> +
>>>> +static const struct snd_pcm_hardware acp63_sdw_hardware_capture = {
>>>> +	.info = SNDRV_PCM_INFO_INTERLEAVED |
>>>> +		SNDRV_PCM_INFO_BLOCK_TRANSFER |
>>>> +		SNDRV_PCM_INFO_MMAP |
>>>> +		SNDRV_PCM_INFO_MMAP_VALID |
>>>> +		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
>>>> +	.formats = SNDRV_PCM_FMTBIT_S16_LE |  SNDRV_PCM_FMTBIT_S8 |
>>>> +		   SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
>>>> +	.channels_min = 2,
>>>> +	.channels_max = 2,
>>>> +	.rates = SNDRV_PCM_RATE_48000,
>>>> +	.rate_min = 48000,
>>>> +	.rate_max = 48000,
>>>> +	.buffer_bytes_max = SDW_CAPTURE_MAX_NUM_PERIODS * SDW_CAPTURE_MAX_PERIOD_SIZE,
>>>> +	.period_bytes_min = SDW_CAPTURE_MIN_PERIOD_SIZE,
>>>> +	.period_bytes_max = SDW_CAPTURE_MAX_PERIOD_SIZE,
>>>> +	.periods_min = SDW_CAPTURE_MIN_NUM_PERIODS,
>>>> +	.periods_max = SDW_CAPTURE_MAX_NUM_PERIODS,
>>>> +};
>>>> +static int acp63_sdw_dma_open(struct snd_soc_component *component,
>>>> +			      struct snd_pcm_substream *substream)
>>>> +{
>>>> +	struct snd_pcm_runtime *runtime;
>>>> +	struct acp_sdw_dma_stream *stream;
>>>> +	struct snd_soc_dai *cpu_dai;
>>>> +	struct amd_sdw_manager *amd_manager;
>>>> +	struct snd_soc_pcm_runtime *prtd = substream->private_data;
>>>> +	int ret;
>>>> +
>>>> +	runtime = substream->runtime;
>>>> +	cpu_dai = asoc_rtd_to_cpu(prtd, 0);
>>>> +	amd_manager = snd_soc_dai_get_drvdata(cpu_dai);
>>>> +	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
>>>> +	if (!stream)
>>>> +		return -ENOMEM;
>>>> +
>>>> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
>>>> +		runtime->hw = acp63_sdw_hardware_playback;
>>>> +	else
>>>> +		runtime->hw = acp63_sdw_hardware_capture;
>>>> +	ret = snd_pcm_hw_constraint_integer(runtime,
>>>> +					    SNDRV_PCM_HW_PARAM_PERIODS);
>>>> +	if (ret < 0) {
>>>> +		dev_err(component->dev, "set integer constraint failed\n");
>>>> +		kfree(stream);
>>>> +		return ret;
>>>> +	}
>>> it's not clear to me why you have to add this specific constraint, isn't
>>> this checked already with the sdw_hardware_playback information.
>> In above code, first we are assigning runtime->hw structures.
>> As per our understanding, we are not assigning any hw_constraints.
>>
>> This snd_pcm_hw_constraint_integer(runtime,
>> SNDRV_PCM_HW_PARAM_PERIODS) constraint assures that the number
>> of periods is integer, hence the buffer size is aligned with the period size.
>>
>>>> +static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base)
>>>> +{
>>>> +	union acp_sdw_dma_count byte_count;
>>>> +	u32 pos_low_reg, pos_high_reg;
>>>> +
>>>> +	byte_count.bytescount = 0;
>>>> +	switch (stream->instance) {
>>>> +	case ACP_SDW0:
>>>> +		pos_low_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
>>>> +		pos_high_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
>>>> +		break;
>>>> +	case ACP_SDW1:
>>>> +		pos_low_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
>>>> +		pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
>>>> +		break;
>>>> +	default:
>>>> +		return -EINVAL;
>>> returning -EINVAL as a u64 doesn't seem quite right to me?
>> Agreed. Default case needs to be corrected. In case of invalid
>> SDW instance, it should return default byte count which is zero
>> instead of returning -EINVAL.
>>
>> We have identified similar fix has to be implemented in our other
>> dma driver as well.
>> https://elixir.bootlin.com/linux/v6.4-rc6/source/sound/soc/amd/acp/amd.h#L174
>>
>> Will push a supplement patch to fix it at one go.
    @Bossart: Let us know if you have any further comments for our replies.
>>> .
>>>> +	}
>>>> +	if (pos_low_reg) {
>>>> +		byte_count.bcount.high = readl(acp_base + pos_high_reg);
>>>> +		byte_count.bcount.low = readl(acp_base + pos_low_reg);
>>>> +	}
>>>> +	return byte_count.bytescount;
>>>> +}


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

* Re: [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops
  2023-06-13  7:00     ` Mukunda,Vijendar
  2023-06-15 15:50       ` Mukunda,Vijendar
@ 2023-06-15 16:21       ` Pierre-Louis Bossart
  2023-06-15 17:13         ` Mukunda,Vijendar
  1 sibling, 1 reply; 25+ messages in thread
From: Pierre-Louis Bossart @ 2023-06-15 16:21 UTC (permalink / raw)
  To: Mukunda,Vijendar, broonie
  Cc: alsa-devel, Basavaraj.Hiregoudar, Sunil-kumar.Dommati,
	Mastan.Katragadda, Arungopal.kondaveeti, mario.limonciello,
	Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem,
	open list



On 6/13/23 09:00, Mukunda,Vijendar wrote:
> On 12/06/23 23:36, Pierre-Louis Bossart wrote:
>>> +#define SDW_PLAYBACK_MIN_NUM_PERIODS    2
>>> +#define SDW_PLAYBACK_MAX_NUM_PERIODS    8
>>> +#define SDW_PLAYBACK_MAX_PERIOD_SIZE    8192
>> that's a fairly small max period. That's 21ms for 2ch S32_LE 48kHz.
>>
>> Does this come from specific limitations or is this an arbitrary number?
>>
>> A comment on this wouldn't hurt.
> This is the initial version. We haven't exercised different sample
> rates/bit depth combinations much. Currently, targeted for 2Ch, 48Khz,
> 16bit audio streams only with 64k as buffer size.
> 
> We will extend support for different sample rates/bit depths combinations
> in the future.
>>> +static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
>>> +	ACP_SW0_AUDIO0_TX_EN,
>>> +	ACP_SW0_AUDIO1_TX_EN,
>>> +	ACP_SW0_AUDIO2_TX_EN,
>>> +	ACP_SW0_AUDIO0_RX_EN,
>>> +	ACP_SW0_AUDIO1_RX_EN,
>>> +	ACP_SW0_AUDIO2_RX_EN,
>>> +};
>>> +
>>> +static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = {
>>> +	ACP_SW1_AUDIO1_TX_EN,
>>> +	ACP_SW1_AUDIO1_RX_EN,
>>> +};
>> Still no explanation as to why SDW0 indices start at zero and SDW1
>> indices start at one?
> We have already provided reply in previous thread, i.e. for v3 patch set.
> 
> https://lore.kernel.org/alsa-devel/de3c86cc-6cba-0cbd-0e04-43711b4c9bc2@amd.com/

That reply was

"
Currently, SDW0 instance uses 3 TX, 3 RX  ports whereas SDW1 instance
uses 1 TX, 1 RX ports.

For SDW1 instance, It uses AUDIO1 register set as per our register spec.
We have mantained similar mapping convention here for enums as well.
"

It wouldn't hurt to add a comment in the code to remind the reviewer
that this is intentional and aligned with the hardware documentation.


>>> +static int acp63_sdw_dma_open(struct snd_soc_component *component,
>>> +			      struct snd_pcm_substream *substream)
>>> +{
>>> +	struct snd_pcm_runtime *runtime;
>>> +	struct acp_sdw_dma_stream *stream;
>>> +	struct snd_soc_dai *cpu_dai;
>>> +	struct amd_sdw_manager *amd_manager;
>>> +	struct snd_soc_pcm_runtime *prtd = substream->private_data;
>>> +	int ret;
>>> +
>>> +	runtime = substream->runtime;
>>> +	cpu_dai = asoc_rtd_to_cpu(prtd, 0);
>>> +	amd_manager = snd_soc_dai_get_drvdata(cpu_dai);
>>> +	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
>>> +	if (!stream)
>>> +		return -ENOMEM;
>>> +
>>> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
>>> +		runtime->hw = acp63_sdw_hardware_playback;
>>> +	else
>>> +		runtime->hw = acp63_sdw_hardware_capture;
>>> +	ret = snd_pcm_hw_constraint_integer(runtime,
>>> +					    SNDRV_PCM_HW_PARAM_PERIODS);
>>> +	if (ret < 0) {
>>> +		dev_err(component->dev, "set integer constraint failed\n");
>>> +		kfree(stream);
>>> +		return ret;
>>> +	}
>> it's not clear to me why you have to add this specific constraint, isn't
>> this checked already with the sdw_hardware_playback information.
> In above code, first we are assigning runtime->hw structures.
> As per our understanding, we are not assigning any hw_constraints.
> 
> This snd_pcm_hw_constraint_integer(runtime,
> SNDRV_PCM_HW_PARAM_PERIODS) constraint assures that the number
> of periods is integer, hence the buffer size is aligned with the period size.

This is surprising, I thought this was already ensured by the hw_info stuff?

>>> +static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base)
>>> +{
>>> +	union acp_sdw_dma_count byte_count;
>>> +	u32 pos_low_reg, pos_high_reg;
>>> +
>>> +	byte_count.bytescount = 0;
>>> +	switch (stream->instance) {
>>> +	case ACP_SDW0:
>>> +		pos_low_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
>>> +		pos_high_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
>>> +		break;
>>> +	case ACP_SDW1:
>>> +		pos_low_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
>>> +		pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
>>> +		break;
>>> +	default:
>>> +		return -EINVAL;
>> returning -EINVAL as a u64 doesn't seem quite right to me?
> Agreed. Default case needs to be corrected. In case of invalid
> SDW instance, it should return default byte count which is zero
> instead of returning -EINVAL.
> 
> We have identified similar fix has to be implemented in our other
> dma driver as well.
> https://elixir.bootlin.com/linux/v6.4-rc6/source/sound/soc/amd/acp/amd.h#L174
> 
> Will push a supplement patch to fix it at one go.

ok

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

* Re: [PATCH V4 1/9] ASoC: amd: ps: create platform devices based on acp config
  2023-06-13  5:42     ` Mukunda,Vijendar
@ 2023-06-15 16:23       ` Pierre-Louis Bossart
  0 siblings, 0 replies; 25+ messages in thread
From: Pierre-Louis Bossart @ 2023-06-15 16:23 UTC (permalink / raw)
  To: Mukunda,Vijendar, broonie
  Cc: alsa-devel, Basavaraj.Hiregoudar, Sunil-kumar.Dommati,
	Mastan.Katragadda, Arungopal.kondaveeti, mario.limonciello,
	Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem,
	open list



On 6/13/23 07:42, Mukunda,Vijendar wrote:
> On 12/06/23 23:39, Pierre-Louis Bossart wrote:
>> =
>>> +static int sdw_amd_scan_controller(struct device *dev)
>>> +{
>>> +	struct acp63_dev_data *acp_data;
>>> +	struct fwnode_handle *link;
>>> +	char name[32];
>>> +	u32 sdw_manager_bitmap;
>>> +	u8 count = 0;
>>> +	u32 acp_sdw_power_mode = 0;
>>> +	int index;
>>> +	int ret;
>>> +
>>> +	acp_data = dev_get_drvdata(dev);
>>> +	/*
>>> +	 * Current implementation is based on MIPI DisCo 2.0 spec.
>>> +	 * Found controller, find links supported.
>>> +	 */
>>> +	ret = fwnode_property_read_u32_array((acp_data->sdw_fw_node), "mipi-sdw-manager-list",
>>> +					     &sdw_manager_bitmap, 1);
>>> +
>>> +	if (ret) {
>>> +		dev_err(dev, "Failed to read mipi-sdw-manager-list: %d\n", ret);
>>> +		return -EINVAL;
>>> +	}
>>> +	count = hweight32(sdw_manager_bitmap);
>>> +	/* Check count is within bounds */
>>> +	if (count > AMD_SDW_MAX_MANAGERS) {
>>> +		dev_err(dev, "Manager count %d exceeds max %d\n", count, AMD_SDW_MAX_MANAGERS);
>>> +		return -EINVAL;
>>> +	}
>> nit-pick: the count is not enough, you should also check that only bits
>> 0 and 1 are set in mipi-sdw-manager-list...
> As per our design for PS platform,
> we will go with two bit map values as 0x03 and 0x01.
> 1. As per ACP PIN CONFIG, we support Single SDW Manager instance
> which refers to SW0 manager instance. For this, we need to use bitmap
> value as 0x01.
> 2. Other bit map value - 0x03 will be used to populate two SoundWire
> manager instances.
> We have extra sub property "amd-sdw-enable" to invoke the init sequence
> for SoundWire manager.
> 
> As we are supporting two bit map value combinations here, it's not required
> to check bit set value. count value is enough to know manager instance count.
> It doesn't break anything.

Not a blocker but you underestimate the creativity of UEFI BIOS writers...


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

* Re: [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops
  2023-06-15 16:21       ` Pierre-Louis Bossart
@ 2023-06-15 17:13         ` Mukunda,Vijendar
  0 siblings, 0 replies; 25+ messages in thread
From: Mukunda,Vijendar @ 2023-06-15 17:13 UTC (permalink / raw)
  To: Pierre-Louis Bossart, broonie
  Cc: alsa-devel, Basavaraj.Hiregoudar, Sunil-kumar.Dommati,
	Mastan.Katragadda, Arungopal.kondaveeti, mario.limonciello,
	Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Syed Saba Kareem,
	open list

On 15/06/23 21:51, Pierre-Louis Bossart wrote:
>
> On 6/13/23 09:00, Mukunda,Vijendar wrote:
>> On 12/06/23 23:36, Pierre-Louis Bossart wrote:
>>>> +#define SDW_PLAYBACK_MIN_NUM_PERIODS    2
>>>> +#define SDW_PLAYBACK_MAX_NUM_PERIODS    8
>>>> +#define SDW_PLAYBACK_MAX_PERIOD_SIZE    8192
>>> that's a fairly small max period. That's 21ms for 2ch S32_LE 48kHz.
>>>
>>> Does this come from specific limitations or is this an arbitrary number?
>>>
>>> A comment on this wouldn't hurt.
>> This is the initial version. We haven't exercised different sample
>> rates/bit depth combinations much. Currently, targeted for 2Ch, 48Khz,
>> 16bit audio streams only with 64k as buffer size.
>>
>> We will extend support for different sample rates/bit depths combinations
>> in the future.
>>>> +static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
>>>> +	ACP_SW0_AUDIO0_TX_EN,
>>>> +	ACP_SW0_AUDIO1_TX_EN,
>>>> +	ACP_SW0_AUDIO2_TX_EN,
>>>> +	ACP_SW0_AUDIO0_RX_EN,
>>>> +	ACP_SW0_AUDIO1_RX_EN,
>>>> +	ACP_SW0_AUDIO2_RX_EN,
>>>> +};
>>>> +
>>>> +static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = {
>>>> +	ACP_SW1_AUDIO1_TX_EN,
>>>> +	ACP_SW1_AUDIO1_RX_EN,
>>>> +};
>>> Still no explanation as to why SDW0 indices start at zero and SDW1
>>> indices start at one?
>> We have already provided reply in previous thread, i.e. for v3 patch set.
>>
>> https://lore.kernel.org/alsa-devel/de3c86cc-6cba-0cbd-0e04-43711b4c9bc2@amd.com/
> That reply was
>
> "
> Currently, SDW0 instance uses 3 TX, 3 RX  ports whereas SDW1 instance
> uses 1 TX, 1 RX ports.
>
> For SDW1 instance, It uses AUDIO1 register set as per our register spec.
> We have mantained similar mapping convention here for enums as well.
> "
>
> It wouldn't hurt to add a comment in the code to remind the reviewer
> that this is intentional and aligned with the hardware documentation.
>
>
>>>> +static int acp63_sdw_dma_open(struct snd_soc_component *component,
>>>> +			      struct snd_pcm_substream *substream)
>>>> +{
>>>> +	struct snd_pcm_runtime *runtime;
>>>> +	struct acp_sdw_dma_stream *stream;
>>>> +	struct snd_soc_dai *cpu_dai;
>>>> +	struct amd_sdw_manager *amd_manager;
>>>> +	struct snd_soc_pcm_runtime *prtd = substream->private_data;
>>>> +	int ret;
>>>> +
>>>> +	runtime = substream->runtime;
>>>> +	cpu_dai = asoc_rtd_to_cpu(prtd, 0);
>>>> +	amd_manager = snd_soc_dai_get_drvdata(cpu_dai);
>>>> +	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
>>>> +	if (!stream)
>>>> +		return -ENOMEM;
>>>> +
>>>> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
>>>> +		runtime->hw = acp63_sdw_hardware_playback;
>>>> +	else
>>>> +		runtime->hw = acp63_sdw_hardware_capture;
>>>> +	ret = snd_pcm_hw_constraint_integer(runtime,
>>>> +					    SNDRV_PCM_HW_PARAM_PERIODS);
>>>> +	if (ret < 0) {
>>>> +		dev_err(component->dev, "set integer constraint failed\n");
>>>> +		kfree(stream);
>>>> +		return ret;
>>>> +	}
>>> it's not clear to me why you have to add this specific constraint, isn't
>>> this checked already with the sdw_hardware_playback information.
>> In above code, first we are assigning runtime->hw structures.
>> As per our understanding, we are not assigning any hw_constraints.
>>
>> This snd_pcm_hw_constraint_integer(runtime,
>> SNDRV_PCM_HW_PARAM_PERIODS) constraint assures that the number
>> of periods is integer, hence the buffer size is aligned with the period size.
> This is surprising, I thought this was already ensured by the hw_info stuff?
As per our understanding, we are populating period size range,
to ensure always, buffer size should be multiples of period size use the
constraint. Reject the buffer size if it's not multiples of period size.

snd_pcm_hw structure will only list out period_bytes_min, period_bytes_max
and buffer_size. It doesn't do any check.

Similar implementation has been observed in most of the DMA drivers open
callback () including Intel.

Failed to understand your point.
Could you please elaborate, if we miss anything?

 
>
>>>> +static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base)
>>>> +{
>>>> +	union acp_sdw_dma_count byte_count;
>>>> +	u32 pos_low_reg, pos_high_reg;
>>>> +
>>>> +	byte_count.bytescount = 0;
>>>> +	switch (stream->instance) {
>>>> +	case ACP_SDW0:
>>>> +		pos_low_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
>>>> +		pos_high_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
>>>> +		break;
>>>> +	case ACP_SDW1:
>>>> +		pos_low_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_low_reg;
>>>> +		pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg;
>>>> +		break;
>>>> +	default:
>>>> +		return -EINVAL;
>>> returning -EINVAL as a u64 doesn't seem quite right to me?
>> Agreed. Default case needs to be corrected. In case of invalid
>> SDW instance, it should return default byte count which is zero
>> instead of returning -EINVAL.
>>
>> We have identified similar fix has to be implemented in our other
>> dma driver as well.
>> https://elixir.bootlin.com/linux/v6.4-rc6/source/sound/soc/amd/acp/amd.h#L174
>>
>> Will push a supplement patch to fix it at one go.
> ok


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

* Re: [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support
  2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
                   ` (8 preceding siblings ...)
  2023-06-12  9:59 ` [PATCH V4 9/9] ASoC: amd: ps: add acp_reset flag check in acp pci driver pm ops Vijendar Mukunda
@ 2023-06-19  5:32 ` Mukunda,Vijendar
  2023-06-19  7:31   ` Mukunda,Vijendar
  2023-06-19 12:52   ` Mark Brown
  2023-06-21  0:34 ` Mark Brown
  10 siblings, 2 replies; 25+ messages in thread
From: Mukunda,Vijendar @ 2023-06-19  5:32 UTC (permalink / raw)
  To: broonie
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello

On 12/06/23 15:28, Vijendar Mukunda wrote:
> This patch series add support for
> 	- Platform device creation for SoundWire Manager instances and
> 	  PDM controller.
> 	- SoundWire DMA driver.
> 	- Interrupt handling for SoundWire manager related interrupts,
> 	  SoundWire DMA interrupts and ACP error interrupts.
> 	- ACP PCI driver PM ops modification with respect to SoundWire
> 	  Power modes.
>
> Changes since v3:
> 	- use pdev_config instead of pdev_mask in the code.
> 	- define platform device configuration macros rather than enums
> 	- add comments for MIPI DisCo version
> 	- refactor SoundWire DMA start/stop sequence using single
> 	  function
> 	- refactor "acp_reset" flag related functionality.
>
> Changes since v2:
> 	- add comments in irq handler.
> 	- remove workqueue for SoundWire DMA interrupts and use thread
> 	  implementation for DMA interrupt handling.
> 	- add error checks in sdw_amd_scan_controller()
> 	- remove passing "acp_lock" as platform resource for SoundWire DMA driver
> 	  and PDM driver.
> 	- retrieve "acp_lock" reference from parent driver directly and
> 	  use the reference in SoundWire DMA driver.
> 	- add handling for acp pci driver probe even when no ACP PDM or
> 	  SoundWire manager platform devices created.
> 	- Fix indentation for acp_sdw_dma_count structure variables.
> 	- Use macro instead of hard coded values for FIFO offset and PTE offset.
> 	- Change pm_runtime enable sequence in SoundWire DMA driver
> 	  probe function.
> 	- Refactor system level resume callback in SoundWire DMA
>
> Changes since v1:
> 	- update "soundwire" as "SoundWire" in code.
> 	- add comments for platform device mask and platform device
> 	  count
> 	- remove unused variables in acp pci driver private data
> 	  structure
> 	- refactor dma enable register structures in SoundWire DMA driver
> 	- add TODO comments in IRQ handler
> 	- update IRQ mask values using bit macros
> 	- Fix build error reported in Makefile
> 	- rename "sdw_dma_stream_instance" structure name as "acp_sdw_dma_stream"
@Mark: We have provided replies for upstream review comments for V4 patch set.
We are going to push as supplement patches for minor fixes.
Should I resend the patch series?
>  
> Vijendar Mukunda (9):
>   ASoC: amd: ps: create platform devices based on acp config
>   ASoC: amd: ps: handle SoundWire interrupts in acp pci driver
>   ASoC: amd: ps: add SoundWire dma driver
>   ASoC: amd: ps: add SoundWire dma driver dma ops
>   ASoC: amd: ps: add support for SoundWire DMA interrupts
>   ASoC: amd: ps: add pm ops support for SoundWire dma driver
>   ASoC: amd: ps: enable SoundWire dma driver build
>   ASoC: amd: update comments in Kconfig file
>   ASoC: amd: ps: add acp_reset flag check in acp pci driver pm ops.
>
>  sound/soc/amd/Kconfig         |   3 +-
>  sound/soc/amd/ps/Makefile     |   2 +
>  sound/soc/amd/ps/acp63.h      | 172 ++++++++++-
>  sound/soc/amd/ps/pci-ps.c     | 419 +++++++++++++++++++++++--
>  sound/soc/amd/ps/ps-sdw-dma.c | 555 ++++++++++++++++++++++++++++++++++
>  5 files changed, 1115 insertions(+), 36 deletions(-)
>  create mode 100644 sound/soc/amd/ps/ps-sdw-dma.c
>


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

* Re: [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support
  2023-06-19  5:32 ` [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Mukunda,Vijendar
@ 2023-06-19  7:31   ` Mukunda,Vijendar
  2023-06-19 12:52   ` Mark Brown
  1 sibling, 0 replies; 25+ messages in thread
From: Mukunda,Vijendar @ 2023-06-19  7:31 UTC (permalink / raw)
  To: broonie, Pierre-Louis Bossart
  Cc: alsa-devel, Basavaraj.Hiregoudar, Sunil-kumar.Dommati,
	Mastan.Katragadda, Arungopal.kondaveeti, mario.limonciello

On 19/06/23 11:02, Mukunda,Vijendar wrote:
> On 12/06/23 15:28, Vijendar Mukunda wrote:
>> This patch series add support for
>> 	- Platform device creation for SoundWire Manager instances and
>> 	  PDM controller.
>> 	- SoundWire DMA driver.
>> 	- Interrupt handling for SoundWire manager related interrupts,
>> 	  SoundWire DMA interrupts and ACP error interrupts.
>> 	- ACP PCI driver PM ops modification with respect to SoundWire
>> 	  Power modes.
>>
>> Changes since v3:
>> 	- use pdev_config instead of pdev_mask in the code.
>> 	- define platform device configuration macros rather than enums
>> 	- add comments for MIPI DisCo version
>> 	- refactor SoundWire DMA start/stop sequence using single
>> 	  function
>> 	- refactor "acp_reset" flag related functionality.
>>
>> Changes since v2:
>> 	- add comments in irq handler.
>> 	- remove workqueue for SoundWire DMA interrupts and use thread
>> 	  implementation for DMA interrupt handling.
>> 	- add error checks in sdw_amd_scan_controller()
>> 	- remove passing "acp_lock" as platform resource for SoundWire DMA driver
>> 	  and PDM driver.
>> 	- retrieve "acp_lock" reference from parent driver directly and
>> 	  use the reference in SoundWire DMA driver.
>> 	- add handling for acp pci driver probe even when no ACP PDM or
>> 	  SoundWire manager platform devices created.
>> 	- Fix indentation for acp_sdw_dma_count structure variables.
>> 	- Use macro instead of hard coded values for FIFO offset and PTE offset.
>> 	- Change pm_runtime enable sequence in SoundWire DMA driver
>> 	  probe function.
>> 	- Refactor system level resume callback in SoundWire DMA
>>
>> Changes since v1:
>> 	- update "soundwire" as "SoundWire" in code.
>> 	- add comments for platform device mask and platform device
>> 	  count
>> 	- remove unused variables in acp pci driver private data
>> 	  structure
>> 	- refactor dma enable register structures in SoundWire DMA driver
>> 	- add TODO comments in IRQ handler
>> 	- update IRQ mask values using bit macros
>> 	- Fix build error reported in Makefile
>> 	- rename "sdw_dma_stream_instance" structure name as "acp_sdw_dma_stream"
> @Mark: We have provided replies for upstream review comments for V4 patch set.
> We are going to push as supplement patches for minor fixes.
> Should I resend the patch series?
@Bossart: If you don't have further comments, could you please provide
reviewed-by tag for this patch series?
>>  
>> Vijendar Mukunda (9):
>>   ASoC: amd: ps: create platform devices based on acp config
>>   ASoC: amd: ps: handle SoundWire interrupts in acp pci driver
>>   ASoC: amd: ps: add SoundWire dma driver
>>   ASoC: amd: ps: add SoundWire dma driver dma ops
>>   ASoC: amd: ps: add support for SoundWire DMA interrupts
>>   ASoC: amd: ps: add pm ops support for SoundWire dma driver
>>   ASoC: amd: ps: enable SoundWire dma driver build
>>   ASoC: amd: update comments in Kconfig file
>>   ASoC: amd: ps: add acp_reset flag check in acp pci driver pm ops.
>>
>>  sound/soc/amd/Kconfig         |   3 +-
>>  sound/soc/amd/ps/Makefile     |   2 +
>>  sound/soc/amd/ps/acp63.h      | 172 ++++++++++-
>>  sound/soc/amd/ps/pci-ps.c     | 419 +++++++++++++++++++++++--
>>  sound/soc/amd/ps/ps-sdw-dma.c | 555 ++++++++++++++++++++++++++++++++++
>>  5 files changed, 1115 insertions(+), 36 deletions(-)
>>  create mode 100644 sound/soc/amd/ps/ps-sdw-dma.c
>>


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

* Re: [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support
  2023-06-19  5:32 ` [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Mukunda,Vijendar
  2023-06-19  7:31   ` Mukunda,Vijendar
@ 2023-06-19 12:52   ` Mark Brown
  1 sibling, 0 replies; 25+ messages in thread
From: Mark Brown @ 2023-06-19 12:52 UTC (permalink / raw)
  To: Mukunda,Vijendar
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello

[-- Attachment #1: Type: text/plain, Size: 1245 bytes --]

On Mon, Jun 19, 2023 at 11:02:52AM +0530, Mukunda,Vijendar wrote:
> On 12/06/23 15:28, Vijendar Mukunda wrote:

> > 	- Fix build error reported in Makefile
> > 	- rename "sdw_dma_stream_instance" structure name as "acp_sdw_dma_stream"
> @Mark: We have provided replies for upstream review comments for V4 patch set.
> We are going to push as supplement patches for minor fixes.
> Should I resend the patch series?

My name doesn't have an @ in it, please don't add one.

Please don't send content free pings and please allow a reasonable time
for review.  People get busy, go on holiday, attend conferences and so 
on so unless there is some reason for urgency (like critical bug fixes)
please allow at least a couple of weeks for review.  If there have been
review comments then people may be waiting for those to be addressed.

Sending content free pings adds to the mail volume (if they are seen at
all) which is often the problem and since they can't be reviewed
directly if something has gone wrong you'll have to resend the patches
anyway, so sending again is generally a better approach though there are
some other maintainers who like them - if in doubt look at how patches
for the subsystem are normally handled.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support
  2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
                   ` (9 preceding siblings ...)
  2023-06-19  5:32 ` [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Mukunda,Vijendar
@ 2023-06-21  0:34 ` Mark Brown
  10 siblings, 0 replies; 25+ messages in thread
From: Mark Brown @ 2023-06-21  0:34 UTC (permalink / raw)
  To: Vijendar Mukunda
  Cc: alsa-devel, pierre-louis.bossart, Basavaraj.Hiregoudar,
	Sunil-kumar.Dommati, Mastan.Katragadda, Arungopal.kondaveeti,
	mario.limonciello

On Mon, 12 Jun 2023 15:28:54 +0530, Vijendar Mukunda wrote:
> This patch series add support for
> 	- Platform device creation for SoundWire Manager instances and
> 	  PDM controller.
> 	- SoundWire DMA driver.
> 	- Interrupt handling for SoundWire manager related interrupts,
> 	  SoundWire DMA interrupts and ACP error interrupts.
> 	- ACP PCI driver PM ops modification with respect to SoundWire
> 	  Power modes.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/9] ASoC: amd: ps: create platform devices based on acp config
      commit: d1351c30ac8a6cf61b0bbe9fcbc8d2851cd44f3c
[2/9] ASoC: amd: ps: handle SoundWire interrupts in acp pci driver
      commit: e1cb350610ce88d9995b8b287930d3ba821d9f2b
[3/9] ASoC: amd: ps: add SoundWire dma driver
      commit: 665dd181a97ff9588060f76887c3b61fd4ccb8b0
[4/9] ASoC: amd: ps: add SoundWire dma driver dma ops
      commit: f722917350ee0b802a62d888f4e8b23bd5f1f641
[5/9] ASoC: amd: ps: add support for SoundWire DMA interrupts
      commit: 298d4f7b176538d41356d145c044442b8456a14e
[6/9] ASoC: amd: ps: add pm ops support for SoundWire dma driver
      commit: 5a06c3ac4cf9a8ca5edf99a07a1129ae25ab581e
[7/9] ASoC: amd: ps: enable SoundWire dma driver build
      commit: 7b33594130405cbcfdef2a4c582f9c67aef8d292
[8/9] ASoC: amd: update comments in Kconfig file
      commit: 6e8f7cb4cbae8e2b03190d26674a14be22d7df53
[9/9] ASoC: amd: ps: add acp_reset flag check in acp pci driver pm ops.
      commit: 198c93e2fc0b74ae520393118d7cb02762c04bf3

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


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

end of thread, other threads:[~2023-06-21  0:37 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-12  9:58 [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Vijendar Mukunda
2023-06-12  9:58 ` [PATCH V4 1/9] ASoC: amd: ps: create platform devices based on acp config Vijendar Mukunda
2023-06-12 18:09   ` Pierre-Louis Bossart
2023-06-13  5:42     ` Mukunda,Vijendar
2023-06-15 16:23       ` Pierre-Louis Bossart
2023-06-12  9:58 ` [PATCH V4 2/9] ASoC: amd: ps: handle SoundWire interrupts in acp pci driver Vijendar Mukunda
2023-06-12  9:58 ` [PATCH V4 3/9] ASoC: amd: ps: add SoundWire dma driver Vijendar Mukunda
2023-06-12  9:58 ` [PATCH V4 4/9] ASoC: amd: ps: add SoundWire dma driver dma ops Vijendar Mukunda
2023-06-12 18:06   ` Pierre-Louis Bossart
2023-06-13  7:00     ` Mukunda,Vijendar
2023-06-15 15:50       ` Mukunda,Vijendar
2023-06-15 15:56         ` Mark Brown
2023-06-15 16:09           ` Mukunda,Vijendar
2023-06-15 16:12         ` Mukunda,Vijendar
2023-06-15 16:21       ` Pierre-Louis Bossart
2023-06-15 17:13         ` Mukunda,Vijendar
2023-06-12  9:58 ` [PATCH V4 5/9] ASoC: amd: ps: add support for SoundWire DMA interrupts Vijendar Mukunda
2023-06-12  9:59 ` [PATCH V4 6/9] ASoC: amd: ps: add pm ops support for SoundWire dma driver Vijendar Mukunda
2023-06-12  9:59 ` [PATCH V4 7/9] ASoC: amd: ps: enable SoundWire dma driver build Vijendar Mukunda
2023-06-12  9:59 ` [PATCH V4 8/9] ASoC: amd: update comments in Kconfig file Vijendar Mukunda
2023-06-12  9:59 ` [PATCH V4 9/9] ASoC: amd: ps: add acp_reset flag check in acp pci driver pm ops Vijendar Mukunda
2023-06-19  5:32 ` [PATCH V4 0/9] ASoC: amd: ps: add SoundWire support Mukunda,Vijendar
2023-06-19  7:31   ` Mukunda,Vijendar
2023-06-19 12:52   ` Mark Brown
2023-06-21  0:34 ` Mark Brown

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.