Unverified Commit 0b6914a0 authored by Vijendar Mukunda's avatar Vijendar Mukunda Committed by Mark Brown
Browse files

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: default avatarVijendar Mukunda <Vijendar.Mukunda@amd.com>
Link: https://patch.msgid.link/20250207062819.1527184-17-Vijendar.Mukunda@amd.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 1c35755f
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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);
+51 −10
Original line number Diff line number Diff line
@@ -52,21 +52,62 @@ static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32
					stream_id = ACP63_SDW0_AUDIO2_RX;
					break;
				}
				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 (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);
			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);
			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;
}

+24 −0
Original line number Diff line number Diff line
@@ -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;