]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drm/amdgpu: Clear doorbell interrupt status for Sienna Cichlid
authorChengzhe Liu <ChengZhe.Liu@amd.com>
Tue, 20 Jul 2021 07:18:12 +0000 (15:18 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 23 Jul 2021 14:09:40 +0000 (10:09 -0400)
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>
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c

index 909e52fb76cdb5f4541571aa76a654de9ac6b7b1..d3a4299b1f30b68c36899ae7a0998e1486b444bc 100644 (file)
@@ -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;
 }
 
index 45295dce5c3ec10eeb12f2b831e5baf2303847c4..843052205bd5a719c77c31561bc6e5bb3d8a16cd 100644 (file)
@@ -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 {
index 7b79eeaa88aa65fee7002a8b9cb56a218e3e3709..b184b656b9b6b93b92b9e8ee6d17b3a53cdb9df3 100644 (file)
@@ -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,
 };