The retry CAM can filter interrupts which occur repeatedly,
such as page fault interrupts when retry faults are enabled.
This makes processing those interrupts much more efficient,
because the CPU won't have to deal with processing the same
interrupt repeatedly.

Enable the doorbell for the retry CAM.

Also change the doorbell range to actually enable the
doorbell for the retry CAM.

Signed-off-by: Timur Kristóf <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/ih_v6_0.c   | 25 +++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c |  2 +-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c 
b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c
index 4470df45b7ea..d6554add485c 100644
--- a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c
@@ -307,6 +307,16 @@ static int ih_v6_0_enable_ring(struct amdgpu_device *adev,
        return 0;
 }
 
+static uint32_t ih_v6_0_setup_retry_doorbell(u32 doorbell_index)
+{
+       u32 val = 0;
+
+       val = REG_SET_FIELD(val, IH_DOORBELL_RPTR, OFFSET, doorbell_index);
+       val = REG_SET_FIELD(val, IH_DOORBELL_RPTR, ENABLE, 1);
+
+       return val;
+}
+
 /**
  * ih_v6_0_irq_init - init and enable the interrupt ring
  *
@@ -392,6 +402,21 @@ static int ih_v6_0_irq_init(struct amdgpu_device *adev)
 
        pci_set_master(adev->pdev);
 
+       if (!(adev->flags & AMD_IS_APU)) {
+               /* Allocate the doorbell for IH Retry CAM */
+               adev->irq.retry_cam_doorbell_index = (adev->doorbell_index.ih + 
2) << 1;
+               WREG32_SOC15(OSSSYS, 0, regIH_DOORBELL_RETRY_CAM,
+                            
ih_v6_0_setup_retry_doorbell(adev->irq.retry_cam_doorbell_index));
+
+               /* Enable IH Retry CAM */
+               tmp = RREG32_SOC15(OSSSYS, 0, regIH_RETRY_INT_CAM_CNTL);
+               tmp = REG_SET_FIELD(tmp, IH_RETRY_INT_CAM_CNTL, ENABLE, 1);
+               tmp = REG_SET_FIELD(tmp, IH_RETRY_INT_CAM_CNTL, CAM_SIZE, 0xF);
+               WREG32_SOC15(OSSSYS, 0, regIH_RETRY_INT_CAM_CNTL, tmp);
+
+               adev->irq.retry_cam_enabled = true;
+       }
+
        /* enable interrupts */
        ret = ih_v6_0_toggle_interrupts(adev, true);
        if (ret)
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c 
b/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c
index f89e5f40e1a5..a66e3073aed8 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c
@@ -199,7 +199,7 @@ static void nbio_v4_3_ih_doorbell_range(struct 
amdgpu_device *adev,
                ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
                                                  S2A_DOORBELL_ENTRY_1_CTRL,
                                                  S2A_DOORBELL_PORT1_RANGE_SIZE,
-                                                 2);
+                                                 8);
                ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
                                                  S2A_DOORBELL_ENTRY_1_CTRL,
                                                  
S2A_DOORBELL_PORT1_AWADDR_31_28_VALUE,
-- 
2.55.0

Reply via email to