diff mbox series

[V3,16/25] ASoC: amd: ps: add soundwire dma interrupts handling for ACP7.0 platform

Message ID 20250207062819.1527184-17-Vijendar.Mukunda@amd.com
State New
Headers show
Series ASoC: amd: Add support for ACP7.0 & ACP7.1 platforms | expand

Commit Message

Mukunda,Vijendar Feb. 7, 2025, 6:28 a.m. UTC
Add Soundwie dma interrupts handling for ACP7.0 & ACP7.1 platforms.
Add acp pci revision id conditional checks for handling platform specific
implementation.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/amd/ps/acp63.h     |  6 ++++
 sound/soc/amd/ps/pci-ps.c    | 61 ++++++++++++++++++++++++++++++------
 sound/soc/amd/ps/ps-common.c | 24 ++++++++++++++
 3 files changed, 81 insertions(+), 10 deletions(-)

Comments

Mark Brown Feb. 7, 2025, 1:32 p.m. UTC | #1
On Fri, Feb 07, 2025 at 11:58:10AM +0530, Vijendar Mukunda wrote:

> +	if (adata->acp_rev == ACP63_PCI_REV) {
> +	} else  {

Unless I find something major in the rest of the series I'll apply this
but it's much better to write these as case statements, that way if you
get additional types to handle it's easier to extend the code sensibly.
Please update this incrementally.
Mukunda,Vijendar Feb. 7, 2025, 2:02 p.m. UTC | #2
On 07/02/25 19:02, Mark Brown wrote:
> On Fri, Feb 07, 2025 at 11:58:10AM +0530, Vijendar Mukunda wrote:
>
>> +	if (adata->acp_rev == ACP63_PCI_REV) {
>> +	} else  {
> Unless I find something major in the rest of the series I'll apply this
> but it's much better to write these as case statements, that way if you
> get additional types to handle it's easier to extend the code sensibly.
> Please update this incrementally.
Will push it as an incremental patch.
diff mbox series

Patch

diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h
index 0aef3a852ff1..48dac2a044c2 100644
--- a/sound/soc/amd/ps/acp63.h
+++ b/sound/soc/amd/ps/acp63.h
@@ -332,6 +332,10 @@  struct acp_hw_ops {
  * manager-SW0 instance
  * @acp63_sdw_dma_intr_stat: DMA interrupt status array for ACP6.3 platform SoundWire
  * manager-SW1 instance
+ * @acp70_sdw0-dma_intr_stat: DMA interrupt status array for ACP7.0 platform SoundWire
+ * manager-SW0 instance
+ * @acp70_sdw_dma_intr_stat: DMA interrupt status array for ACP7.0 platform SoundWire
+ * manager-SW1 instance
  */
 
 struct acp63_dev_data {
@@ -357,6 +361,8 @@  struct acp63_dev_data {
 	u32 acp_rev;
 	u16 acp63_sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS];
 	u16 acp63_sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS];
+	u16 acp70_sdw0_dma_intr_stat[ACP70_SDW0_DMA_MAX_STREAMS];
+	u16 acp70_sdw1_dma_intr_stat[ACP70_SDW1_DMA_MAX_STREAMS];
 };
 
 void acp63_hw_init_ops(struct acp_hw_ops *hw_ops);
diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
index 8f73d2ce2197..a9e140ca1296 100644
--- a/sound/soc/amd/ps/pci-ps.c
+++ b/sound/soc/amd/ps/pci-ps.c
@@ -52,20 +52,61 @@  static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32
 					stream_id = ACP63_SDW0_AUDIO2_RX;
 					break;
 				}
-				adata->acp63_sdw0_dma_intr_stat[stream_id] = 1;
+				if (adata->acp_rev >= ACP70_PCI_REV)
+					adata->acp70_sdw0_dma_intr_stat[stream_id] = 1;
+				else
+					adata->acp63_sdw0_dma_intr_stat[stream_id] = 1;
+
 				sdw_dma_irq_flag = 1;
 			}
 		}
 	}
-	if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) {
-		writel(ACP63_P1_AUDIO1_RX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
-		adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1;
-		sdw_dma_irq_flag = 1;
-	}
-	if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) {
-		writel(ACP63_P1_AUDIO1_TX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
-		adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1;
-		sdw_dma_irq_flag = 1;
+	if (adata->acp_rev == ACP63_PCI_REV) {
+		if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) {
+			writel(ACP63_P1_AUDIO1_RX_THRESHOLD,
+			       adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
+		       adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1;
+			sdw_dma_irq_flag = 1;
+		}
+		if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) {
+			writel(ACP63_P1_AUDIO1_TX_THRESHOLD,
+			       adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
+			adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1;
+			sdw_dma_irq_flag = 1;
+		}
+	} else  {
+		if (ext_intr_stat1 & ACP70_P1_SDW_DMA_IRQ_MASK) {
+			for (index = ACP70_P1_AUDIO2_RX_THRESHOLD;
+			     index <= ACP70_P1_AUDIO0_TX_THRESHOLD; index++) {
+				if (ext_intr_stat1 & BIT(index)) {
+					writel(BIT(index),
+					       adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
+					switch (index) {
+					case ACP70_P1_AUDIO0_TX_THRESHOLD:
+						stream_id = ACP70_SDW_AUDIO0_TX;
+						break;
+					case ACP70_P1_AUDIO1_TX_THRESHOLD:
+						stream_id = ACP70_SDW_AUDIO1_TX;
+						break;
+					case ACP70_P1_AUDIO2_TX_THRESHOLD:
+						stream_id = ACP70_SDW_AUDIO2_TX;
+						break;
+					case ACP70_P1_AUDIO0_RX_THRESHOLD:
+						stream_id = ACP70_SDW_AUDIO0_RX;
+						break;
+					case ACP70_P1_AUDIO1_RX_THRESHOLD:
+						 stream_id = ACP70_SDW_AUDIO1_RX;
+						break;
+					case ACP70_P1_AUDIO2_RX_THRESHOLD:
+						stream_id = ACP70_SDW_AUDIO2_RX;
+						break;
+					}
+
+					adata->acp70_sdw1_dma_intr_stat[stream_id] = 1;
+					sdw_dma_irq_flag = 1;
+				}
+			}
+		}
 	}
 	return sdw_dma_irq_flag;
 }
diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c
index 6639dac0a415..1c89fb5fe1da 100644
--- a/sound/soc/amd/ps/ps-common.c
+++ b/sound/soc/amd/ps/ps-common.c
@@ -378,6 +378,29 @@  static void acp70_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_dat
 	}
 }
 
+static void acp70_sdw_dma_irq_thread(struct acp63_dev_data *adata)
+{
+	struct sdw_dma_dev_data *sdw_data;
+	u32 stream_id;
+
+	sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev);
+
+	for (stream_id = 0; stream_id < ACP70_SDW0_DMA_MAX_STREAMS; stream_id++) {
+		if (adata->acp70_sdw0_dma_intr_stat[stream_id]) {
+			if (sdw_data->acp70_sdw0_dma_stream[stream_id])
+				snd_pcm_period_elapsed(sdw_data->acp70_sdw0_dma_stream[stream_id]);
+			adata->acp70_sdw0_dma_intr_stat[stream_id] = 0;
+		}
+	}
+	for (stream_id = 0; stream_id < ACP70_SDW1_DMA_MAX_STREAMS; stream_id++) {
+		if (adata->acp70_sdw1_dma_intr_stat[stream_id]) {
+			if (sdw_data->acp70_sdw1_dma_stream[stream_id])
+				snd_pcm_period_elapsed(sdw_data->acp70_sdw1_dma_stream[stream_id]);
+			adata->acp70_sdw1_dma_intr_stat[stream_id] = 0;
+		}
+	}
+}
+
 static int __maybe_unused snd_acp70_suspend(struct device *dev)
 {
 	struct acp63_dev_data *adata;
@@ -444,6 +467,7 @@  void acp70_hw_init_ops(struct acp_hw_ops *hw_ops)
 	hw_ops->acp_init = acp70_init;
 	hw_ops->acp_deinit = acp70_deinit;
 	hw_ops->acp_get_config = acp70_get_config;
+	hw_ops->acp_sdw_dma_irq_thread = acp70_sdw_dma_irq_thread;
 	hw_ops->acp_suspend = snd_acp70_suspend;
 	hw_ops->acp_resume = snd_acp70_resume;
 	hw_ops->acp_suspend_runtime = snd_acp70_suspend;