[PATCH V3 16/25] ASoC: amd: ps: add soundwire dma interrupts handling for ACP7.0 platform
From: Vijendar Mukunda
Date: Fri Feb 07 2025 - 01:32:19 EST
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@xxxxxxx>
---
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(-)
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;
--
2.34.1