drm/amdgpu: add helper to toggle ih ring interrupts for vega10
authorHawking Zhang <Hawking.Zhang@amd.com>
Tue, 1 Dec 2020 14:54:47 +0000 (22:54 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 23 Dec 2020 20:03:50 +0000 (15:03 -0500)
vega10_ih_toggle_ring_interrupts will be used to
enable/disable an ih ring interrupts for vega10/12,
RAVEN series and RENOIR APUs

Signed-off-by: Hawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Acked-by: Felix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: Dennis Li <Dennis.Li@amd.com>
Reviewed-by: Feifei Xu <Feifei.Xu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/vega10_ih.c

index 42e7897..fa4c490 100644 (file)
@@ -213,6 +213,51 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
        }
 }
 
+/**
+ * vega10_ih_toggle_ring_interrupts - toggle the interrupt ring buffer
+ *
+ * @adev: amdgpu_device pointer
+ * @ih: amdgpu_ih_ring pointet
+ * @enable: true - enable the interrupts, false - disable the interrupts
+ *
+ * Toggle the interrupt ring buffer (VEGA10)
+ */
+static int vega10_ih_toggle_ring_interrupts(struct amdgpu_device *adev,
+                                           struct amdgpu_ih_ring *ih,
+                                           bool enable)
+{
+       struct amdgpu_ih_regs *ih_regs;
+       uint32_t tmp;
+
+       ih_regs = &ih->ih_regs;
+
+       tmp = RREG32(ih_regs->ih_rb_cntl);
+       tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0));
+       /* enable_intr field is only valid in ring0 */
+       if (ih == &adev->irq.ih)
+               tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
+       if (amdgpu_sriov_vf(adev)) {
+               if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
+                       dev_err(adev->dev, "PSP program IH_RB_CNTL failed!\n");
+                       return -ETIMEDOUT;
+               }
+       } else {
+               WREG32(ih_regs->ih_rb_cntl, tmp);
+       }
+
+       if (enable) {
+               ih->enabled = true;
+       } else {
+               /* set rptr, wptr to 0 */
+               WREG32(ih_regs->ih_rb_rptr, 0);
+               WREG32(ih_regs->ih_rb_wptr, 0);
+               ih->enabled = false;
+               ih->rptr = 0;
+       }
+
+       return 0;
+}
+
 static uint32_t vega10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl)
 {
        int rb_bufsz = order_base_2(ih->ring_size / 4);