summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorChengzhe Liu <ChengZhe.Liu@amd.com>2021-07-20 15:18:12 +0800
committerAlex Deucher <alexander.deucher@amd.com>2021-07-23 10:09:40 -0400
commit1bece222eabeb3d8b10c5f2dadb03b6fb780b050 (patch)
tree9504670a7f981c878e732e03ea2dc8fd1c2c6806 /drivers/gpu/drm/amd
parent5810323ba692895b045e3f1b3e107605c3717dab (diff)
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>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c21
3 files changed, 26 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 909e52fb76cd..d3a4299b1f30 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -5329,6 +5329,10 @@ int amdgpu_device_baco_exit(struct drm_device *dev)
adev->nbio.funcs->enable_doorbell_interrupt)
adev->nbio.funcs->enable_doorbell_interrupt(adev, true);
+ if (amdgpu_passthrough(adev) &&
+ adev->nbio.funcs->clear_doorbell_interrupt)
+ adev->nbio.funcs->clear_doorbell_interrupt(adev);
+
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
index 45295dce5c3e..843052205bd5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
@@ -95,6 +95,7 @@ struct amdgpu_nbio_funcs {
void (*program_aspm)(struct amdgpu_device *adev);
void (*apply_lc_spc_mode_wa)(struct amdgpu_device *adev);
void (*apply_l1_link_width_reconfig_wa)(struct amdgpu_device *adev);
+ void (*clear_doorbell_interrupt)(struct amdgpu_device *adev);
};
struct amdgpu_nbio {
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
index 7b79eeaa88aa..b184b656b9b6 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
@@ -508,6 +508,26 @@ static void nbio_v2_3_apply_l1_link_width_reconfig_wa(struct amdgpu_device *adev
WREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL, reg_data);
}
+static void nbio_v2_3_clear_doorbell_interrupt(struct amdgpu_device *adev)
+{
+ uint32_t reg, reg_data;
+
+ if (adev->asic_type != CHIP_SIENNA_CICHLID)
+ return;
+
+ reg = RREG32_SOC15(NBIO, 0, mmBIF_RB_CNTL);
+
+ /* Clear Interrupt Status
+ */
+ if ((reg & BIF_RB_CNTL__RB_ENABLE_MASK) == 0) {
+ reg = RREG32_SOC15(NBIO, 0, mmBIF_DOORBELL_INT_CNTL);
+ if (reg & BIF_DOORBELL_INT_CNTL__DOORBELL_INTERRUPT_STATUS_MASK) {
+ reg_data = 1 << BIF_DOORBELL_INT_CNTL__DOORBELL_INTERRUPT_CLEAR__SHIFT;
+ WREG32_SOC15(NBIO, 0, mmBIF_DOORBELL_INT_CNTL, reg_data);
+ }
+ }
+}
+
const struct amdgpu_nbio_funcs nbio_v2_3_funcs = {
.get_hdp_flush_req_offset = nbio_v2_3_get_hdp_flush_req_offset,
.get_hdp_flush_done_offset = nbio_v2_3_get_hdp_flush_done_offset,
@@ -531,4 +551,5 @@ const struct amdgpu_nbio_funcs nbio_v2_3_funcs = {
.program_aspm = nbio_v2_3_program_aspm,
.apply_lc_spc_mode_wa = nbio_v2_3_apply_lc_spc_mode_wa,
.apply_l1_link_width_reconfig_wa = nbio_v2_3_apply_l1_link_width_reconfig_wa,
+ .clear_doorbell_interrupt = nbio_v2_3_clear_doorbell_interrupt,
};