Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Add support for interrupt handling for soundwire manager platform
devices.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Link: https://msgid.link/r/20240129055147.1493853-9-Vijendar.Mukunda@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Vijendar Mukunda and committed by
Mark Brown
96eb8185 d9482184

+46 -1
+4
sound/soc/sof/amd/acp-dsp-offset.h
··· 78 78 #define ACP5X_AXI2DAGB_SEM_0 0x1884 79 79 #define ACP6X_AXI2DAGB_SEM_0 0x1874 80 80 81 + /* ACP common registers to report errors related to I2S & SoundWire interfaces */ 82 + #define ACP_SW0_I2S_ERROR_REASON 0x18B4 83 + #define ACP_SW1_I2S_ERROR_REASON 0x1A50 84 + 81 85 /* Registers from ACP_SHA block */ 82 86 #define ACP_SHA_DSP_FW_QUALIFIER 0x1C70 83 87 #define ACP_SHA_DMA_CMD 0x1CB0
+37 -1
sound/soc/sof/amd/acp.c
··· 375 375 376 376 static irqreturn_t acp_irq_handler(int irq, void *dev_id) 377 377 { 378 + struct amd_sdw_manager *amd_manager; 378 379 struct snd_sof_dev *sdev = dev_id; 379 380 const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata); 381 + struct acp_dev_data *adata = sdev->pdata->hw_pdata; 380 382 unsigned int base = desc->dsp_intr_base; 381 383 unsigned int val; 384 + int irq_flag = 0; 382 385 383 386 val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET); 384 387 if (val & ACP_DSP_TO_HOST_IRQ) { ··· 390 387 return IRQ_WAKE_THREAD; 391 388 } 392 389 393 - return IRQ_NONE; 390 + val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat); 391 + if (val & ACP_SDW0_IRQ_MASK) { 392 + amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev); 393 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat, ACP_SDW0_IRQ_MASK); 394 + if (amd_manager) 395 + schedule_work(&amd_manager->amd_sdw_irq_thread); 396 + irq_flag = 1; 397 + } 398 + 399 + if (val & ACP_ERROR_IRQ_MASK) { 400 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat, ACP_ERROR_IRQ_MASK); 401 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + ACP_SW0_I2S_ERROR_REASON, 0); 402 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + ACP_SW1_I2S_ERROR_REASON, 0); 403 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + ACP_ERROR_STATUS, 0); 404 + irq_flag = 1; 405 + } 406 + 407 + if (desc->ext_intr_stat1) { 408 + val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat1); 409 + if (val & ACP_SDW1_IRQ_MASK) { 410 + amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev); 411 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat1, 412 + ACP_SDW1_IRQ_MASK); 413 + if (amd_manager) 414 + schedule_work(&amd_manager->amd_sdw_irq_thread); 415 + irq_flag = 1; 416 + } 417 + } 418 + if (irq_flag) 419 + return IRQ_HANDLED; 420 + else 421 + return IRQ_NONE; 394 422 } 395 423 396 424 static int acp_power_on(struct snd_sof_dev *sdev) ··· 477 443 if (desc->ext_intr_enb) 478 444 snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_enb, 0x01); 479 445 446 + if (desc->ext_intr_cntl) 447 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_cntl, ACP_ERROR_IRQ_MASK); 480 448 return ret; 481 449 } 482 450
+5
sound/soc/sof/amd/acp.h
··· 93 93 #define PROBE_STATUS_BIT BIT(31) 94 94 95 95 #define ACP_FIRMWARE_SIGNATURE 0x100 96 + #define ACP_ERROR_IRQ_MASK BIT(29) 97 + #define ACP_SDW0_IRQ_MASK BIT(21) 98 + #define ACP_SDW1_IRQ_MASK BIT(2) 96 99 #define ACP_DEFAULT_SRAM_LENGTH 0x00080000 97 100 #define ACP_SRAM_PAGE_COUNT 128 98 101 ··· 187 184 unsigned int host_bridge_id; 188 185 u32 pgfsm_base; 189 186 u32 ext_intr_enb; 187 + u32 ext_intr_cntl; 190 188 u32 ext_intr_stat; 189 + u32 ext_intr_stat1; 191 190 u32 dsp_intr_base; 192 191 u32 sram_pte_offset; 193 192 u32 hw_semaphore_offset;