Need to handle the interrupt enables for all pipes.

Signed-off-by: Alex Deucher <alexander.deuc...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 130 ++++++++++++++++++++-----
 1 file changed, 106 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index af98fd0f32a7..4e761d166ef5 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -1496,26 +1496,68 @@ static void gfx_v12_0_constants_init(struct 
amdgpu_device *adev)
        gfx_v12_0_init_compute_vmid(adev);
 }
 
+static u32 gfx_v12_0_get_cpg_int_cntl(struct amdgpu_device *adev,
+                                     int me, int pipe)
+{
+       if (me != 0)
+               return 0;
+
+       switch (pipe) {
+       case 0:
+               return SOC15_REG_OFFSET(GC, 0, regCP_INT_CNTL_RING0);
+       default:
+               return 0;
+       }
+}
+
+static u32 gfx_v12_0_get_cpc_int_cntl(struct amdgpu_device *adev,
+                                     int me, int pipe)
+{
+       /*
+        * amdgpu controls only the first MEC. That's why this function only
+        * handles the setting of interrupts for this specific MEC. All other
+        * pipes' interrupts are set by amdkfd.
+        */
+       if (me != 1)
+               return 0;
+
+       switch (pipe) {
+       case 0:
+               return SOC15_REG_OFFSET(GC, 0, regCP_ME1_PIPE0_INT_CNTL);
+       case 1:
+               return SOC15_REG_OFFSET(GC, 0, regCP_ME1_PIPE1_INT_CNTL);
+       default:
+               return 0;
+       }
+}
+
 static void gfx_v12_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,
-                                               bool enable)
+                                              bool enable)
 {
-       u32 tmp;
+       u32 tmp, cp_int_cntl_reg;
+       int i, j;
 
        if (amdgpu_sriov_vf(adev))
                return;
 
-       tmp = RREG32_SOC15(GC, 0, regCP_INT_CNTL_RING0);
-
-       tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE,
-                           enable ? 1 : 0);
-       tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CNTX_EMPTY_INT_ENABLE,
-                           enable ? 1 : 0);
-       tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CMP_BUSY_INT_ENABLE,
-                           enable ? 1 : 0);
-       tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, GFX_IDLE_INT_ENABLE,
-                           enable ? 1 : 0);
-
-       WREG32_SOC15(GC, 0, regCP_INT_CNTL_RING0, tmp);
+       for (i = 0; i < adev->gfx.me.num_me; i++) {
+               for (i = 0; i < adev->gfx.me.num_pipe_per_me; i++) {
+                       cp_int_cntl_reg = gfx_v12_0_get_cpg_int_cntl(adev, i, 
j);
+
+                       if (cp_int_cntl_reg) {
+                               tmp = RREG32_SOC15_IP(GC, cp_int_cntl_reg);
+                               tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, 
CNTX_BUSY_INT_ENABLE,
+                                                   enable ? 1 : 0);
+                               tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, 
CNTX_EMPTY_INT_ENABLE,
+                                                   enable ? 1 : 0);
+                               tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, 
CMP_BUSY_INT_ENABLE,
+                                                   enable ? 1 : 0);
+                               tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, 
GFX_IDLE_INT_ENABLE,
+                                                   enable ? 1 : 0);
+                               WREG32_SOC15_IP(GC, cp_int_cntl_reg, tmp);
+                       }
+               }
+       }
 }
 
 static int gfx_v12_0_init_csb(struct amdgpu_device *adev)
@@ -4584,15 +4626,42 @@ static int gfx_v12_0_eop_irq(struct amdgpu_device *adev,
 
 static int gfx_v12_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
                                              struct amdgpu_irq_src *source,
-                                             unsigned type,
+                                             unsigned int type,
                                              enum amdgpu_interrupt_state state)
 {
+       u32 cp_int_cntl_reg, cp_int_cntl;
+       int i, j;
+
        switch (state) {
        case AMDGPU_IRQ_STATE_DISABLE:
        case AMDGPU_IRQ_STATE_ENABLE:
-               WREG32_FIELD15_PREREG(GC, 0, CP_INT_CNTL_RING0,
-                                     PRIV_REG_INT_ENABLE,
-                                     state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
+               for (i = 0; i < adev->gfx.me.num_me; i++) {
+                       for (i = 0; i < adev->gfx.me.num_pipe_per_me; i++) {
+                               cp_int_cntl_reg = 
gfx_v12_0_get_cpg_int_cntl(adev, i, j);
+
+                               if (cp_int_cntl_reg) {
+                                       cp_int_cntl = RREG32_SOC15_IP(GC, 
cp_int_cntl_reg);
+                                       cp_int_cntl = 
REG_SET_FIELD(cp_int_cntl, CP_INT_CNTL_RING0,
+                                                                   
PRIV_REG_INT_ENABLE,
+                                                                   state == 
AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
+                                       WREG32_SOC15_IP(GC, cp_int_cntl_reg, 
cp_int_cntl);
+                               }
+                       }
+               }
+               for (i = 0; i < adev->gfx.mec.num_mec; i++) {
+                       for (i = 0; i < adev->gfx.mec.num_pipe_per_mec; i++) {
+                               /* MECs start at 1 */
+                               cp_int_cntl_reg = 
gfx_v12_0_get_cpc_int_cntl(adev, i + 1, j);
+
+                               if (cp_int_cntl_reg) {
+                                       cp_int_cntl = RREG32_SOC15_IP(GC, 
cp_int_cntl_reg);
+                                       cp_int_cntl = 
REG_SET_FIELD(cp_int_cntl, CP_ME1_PIPE0_INT_CNTL,
+                                                                   
PRIV_REG_INT_ENABLE,
+                                                                   state == 
AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
+                                       WREG32_SOC15_IP(GC, cp_int_cntl_reg, 
cp_int_cntl);
+                               }
+                       }
+               }
                break;
        default:
                break;
@@ -4603,15 +4672,28 @@ static int gfx_v12_0_set_priv_reg_fault_state(struct 
amdgpu_device *adev,
 
 static int gfx_v12_0_set_priv_inst_fault_state(struct amdgpu_device *adev,
                                               struct amdgpu_irq_src *source,
-                                              unsigned type,
+                                              unsigned int type,
                                               enum amdgpu_interrupt_state 
state)
 {
+       u32 cp_int_cntl_reg, cp_int_cntl;
+       int i, j;
+
        switch (state) {
        case AMDGPU_IRQ_STATE_DISABLE:
        case AMDGPU_IRQ_STATE_ENABLE:
-               WREG32_FIELD15_PREREG(GC, 0, CP_INT_CNTL_RING0,
-                              PRIV_INSTR_INT_ENABLE,
-                              state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
+               for (i = 0; i < adev->gfx.me.num_me; i++) {
+                       for (i = 0; i < adev->gfx.me.num_pipe_per_me; i++) {
+                               cp_int_cntl_reg = 
gfx_v12_0_get_cpg_int_cntl(adev, i, j);
+
+                               if (cp_int_cntl_reg) {
+                                       cp_int_cntl = RREG32_SOC15_IP(GC, 
cp_int_cntl_reg);
+                                       cp_int_cntl = 
REG_SET_FIELD(cp_int_cntl, CP_INT_CNTL_RING0,
+                                                                   
PRIV_INSTR_INT_ENABLE,
+                                                                   state == 
AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
+                                       WREG32_SOC15_IP(GC, cp_int_cntl_reg, 
cp_int_cntl);
+                               }
+                       }
+               }
                break;
        default:
                break;
@@ -4635,8 +4717,8 @@ static void gfx_v12_0_handle_priv_fault(struct 
amdgpu_device *adev,
        case 0:
                for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
                        ring = &adev->gfx.gfx_ring[i];
-                       /* we only enabled 1 gfx queue per pipe for now */
-                       if (ring->me == me_id && ring->pipe == pipe_id)
+                       if (ring->me == me_id && ring->pipe == pipe_id &&
+                           ring->queue == queue_id)
                                drm_sched_fault(&ring->sched);
                }
                break;
-- 
2.45.2

Reply via email to