ASoC: amd: ps: add soundwire dma interrupts handling for ACP7.0 platform

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>
This commit is contained in:
Vijendar Mukunda 2025-02-07 11:58:10 +05:30 committed by Mark Brown
parent 1c35755f46
commit 0b6914a012
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
3 changed files with 81 additions and 10 deletions

View 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);

View 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;
}

View 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;