Unverified Commit 96eb8185 authored by Vijendar Mukunda's avatar Vijendar Mukunda Committed by Mark Brown
Browse files

ASoC: SOF: amd: add interrupt handling for SoundWire manager devices



Add support for interrupt handling for soundwire manager platform
devices.

Signed-off-by: default avatarVijendar Mukunda <Vijendar.Mukunda@amd.com>
Link: https://msgid.link/r/20240129055147.1493853-9-Vijendar.Mukunda@amd.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent d9482184
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -78,6 +78,10 @@
#define ACP5X_AXI2DAGB_SEM_0			0x1884
#define ACP6X_AXI2DAGB_SEM_0			0x1874

/* ACP common registers to report errors related to I2S & SoundWire interfaces */
#define ACP_SW0_I2S_ERROR_REASON		0x18B4
#define ACP_SW1_I2S_ERROR_REASON		0x1A50

/* Registers from ACP_SHA block */
#define ACP_SHA_DSP_FW_QUALIFIER		0x1C70
#define ACP_SHA_DMA_CMD				0x1CB0
+37 −1
Original line number Diff line number Diff line
@@ -375,10 +375,13 @@ static irqreturn_t acp_irq_thread(int irq, void *context)

static irqreturn_t acp_irq_handler(int irq, void *dev_id)
{
	struct amd_sdw_manager *amd_manager;
	struct snd_sof_dev *sdev = dev_id;
	const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
	struct acp_dev_data *adata = sdev->pdata->hw_pdata;
	unsigned int base = desc->dsp_intr_base;
	unsigned int val;
	int irq_flag = 0;

	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET);
	if (val & ACP_DSP_TO_HOST_IRQ) {
@@ -387,6 +390,37 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id)
		return IRQ_WAKE_THREAD;
	}

	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat);
	if (val & ACP_SDW0_IRQ_MASK) {
		amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);
		snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat, ACP_SDW0_IRQ_MASK);
		if (amd_manager)
			schedule_work(&amd_manager->amd_sdw_irq_thread);
		irq_flag = 1;
	}

	if (val & ACP_ERROR_IRQ_MASK) {
		snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat, ACP_ERROR_IRQ_MASK);
		snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + ACP_SW0_I2S_ERROR_REASON, 0);
		snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + ACP_SW1_I2S_ERROR_REASON, 0);
		snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + ACP_ERROR_STATUS, 0);
		irq_flag = 1;
	}

	if (desc->ext_intr_stat1) {
		val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat1);
		if (val & ACP_SDW1_IRQ_MASK) {
			amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);
			snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat1,
					  ACP_SDW1_IRQ_MASK);
			if (amd_manager)
				schedule_work(&amd_manager->amd_sdw_irq_thread);
			irq_flag = 1;
		}
	}
	if (irq_flag)
		return IRQ_HANDLED;
	else
		return IRQ_NONE;
}

@@ -443,6 +477,8 @@ static int acp_reset(struct snd_sof_dev *sdev)
	if (desc->ext_intr_enb)
		snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_enb, 0x01);

	if (desc->ext_intr_cntl)
		snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_cntl, ACP_ERROR_IRQ_MASK);
	return ret;
}

+5 −0
Original line number Diff line number Diff line
@@ -93,6 +93,9 @@
#define PROBE_STATUS_BIT			BIT(31)

#define ACP_FIRMWARE_SIGNATURE			0x100
#define ACP_ERROR_IRQ_MASK			BIT(29)
#define ACP_SDW0_IRQ_MASK			BIT(21)
#define ACP_SDW1_IRQ_MASK			BIT(2)
#define ACP_DEFAULT_SRAM_LENGTH			0x00080000
#define ACP_SRAM_PAGE_COUNT			128

@@ -184,7 +187,9 @@ struct sof_amd_acp_desc {
	unsigned int host_bridge_id;
	u32 pgfsm_base;
	u32 ext_intr_enb;
	u32 ext_intr_cntl;
	u32 ext_intr_stat;
	u32 ext_intr_stat1;
	u32 dsp_intr_base;
	u32 sram_pte_offset;
	u32 hw_semaphore_offset;