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

drm/amdgpu: Clear doorbell interrupt status for Sienna Cichlid

On Sienna Cichlid, in pass-through mode, if we unload the driver in BACO
mode(RTPM), then the kernel would receive thousands of interrupts.
That's because there is doorbell monitor interrupt on BIF, so KVM keeps
injecting interrupts to the guest VM. So we should clear the doorbell
interrupt status after BACO exit.

v2: Modify coding style and commit message

Signed-off-by: Chengzhe Liu <ChengZhe.Liu@amd.com>
Reviewed-by: Luben Tuikov <luben.tuikov@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Chengzhe Liu and committed by
Alex Deucher
1bece222 5810323b

+26
+4
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 5329 5329 adev->nbio.funcs->enable_doorbell_interrupt) 5330 5330 adev->nbio.funcs->enable_doorbell_interrupt(adev, true); 5331 5331 5332 + if (amdgpu_passthrough(adev) && 5333 + adev->nbio.funcs->clear_doorbell_interrupt) 5334 + adev->nbio.funcs->clear_doorbell_interrupt(adev); 5335 + 5332 5336 return 0; 5333 5337 } 5334 5338
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
··· 95 95 void (*program_aspm)(struct amdgpu_device *adev); 96 96 void (*apply_lc_spc_mode_wa)(struct amdgpu_device *adev); 97 97 void (*apply_l1_link_width_reconfig_wa)(struct amdgpu_device *adev); 98 + void (*clear_doorbell_interrupt)(struct amdgpu_device *adev); 98 99 }; 99 100 100 101 struct amdgpu_nbio {
+21
drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
··· 508 508 WREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL, reg_data); 509 509 } 510 510 511 + static void nbio_v2_3_clear_doorbell_interrupt(struct amdgpu_device *adev) 512 + { 513 + uint32_t reg, reg_data; 514 + 515 + if (adev->asic_type != CHIP_SIENNA_CICHLID) 516 + return; 517 + 518 + reg = RREG32_SOC15(NBIO, 0, mmBIF_RB_CNTL); 519 + 520 + /* Clear Interrupt Status 521 + */ 522 + if ((reg & BIF_RB_CNTL__RB_ENABLE_MASK) == 0) { 523 + reg = RREG32_SOC15(NBIO, 0, mmBIF_DOORBELL_INT_CNTL); 524 + if (reg & BIF_DOORBELL_INT_CNTL__DOORBELL_INTERRUPT_STATUS_MASK) { 525 + reg_data = 1 << BIF_DOORBELL_INT_CNTL__DOORBELL_INTERRUPT_CLEAR__SHIFT; 526 + WREG32_SOC15(NBIO, 0, mmBIF_DOORBELL_INT_CNTL, reg_data); 527 + } 528 + } 529 + } 530 + 511 531 const struct amdgpu_nbio_funcs nbio_v2_3_funcs = { 512 532 .get_hdp_flush_req_offset = nbio_v2_3_get_hdp_flush_req_offset, 513 533 .get_hdp_flush_done_offset = nbio_v2_3_get_hdp_flush_done_offset, ··· 551 531 .program_aspm = nbio_v2_3_program_aspm, 552 532 .apply_lc_spc_mode_wa = nbio_v2_3_apply_lc_spc_mode_wa, 553 533 .apply_l1_link_width_reconfig_wa = nbio_v2_3_apply_l1_link_width_reconfig_wa, 534 + .clear_doorbell_interrupt = nbio_v2_3_clear_doorbell_interrupt, 554 535 };