]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: amd: ps: add soundwire dma interrupts handling for ACP7.0 platform
authorVijendar Mukunda <Vijendar.Mukunda@amd.com>
Fri, 7 Feb 2025 06:28:10 +0000 (11:58 +0530)
committerMark Brown <broonie@kernel.org>
Fri, 7 Feb 2025 13:33:52 +0000 (13:33 +0000)
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>
Link: https://patch.msgid.link/20250207062819.1527184-17-Vijendar.Mukunda@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/amd/ps/acp63.h
sound/soc/amd/ps/pci-ps.c
sound/soc/amd/ps/ps-common.c

index 0aef3a852ff1e33994f631a34b71bb9291500ea9..48dac2a044c222a3c3028b35b74169aba0d864e2 100644 (file)
@@ -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);
index 8f73d2ce21976d98084ad78cf8818caae49fd099..a9e140ca129616e2cbedf8c7b5b121ae0f39b3e8 100644 (file)
@@ -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;
 }
index 6639dac0a4155b1c7ef671d177706a46844d44aa..1c89fb5fe1da5d9b83473b26ecc2a5c1defda7c6 100644 (file)
@@ -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;