drm/amdgpu: Add xcc specific functions
authorLijo Lazar <lijo.lazar@amd.com>
Wed, 16 Nov 2022 05:17:18 +0000 (10:47 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 9 Jun 2023 13:49:12 +0000 (09:49 -0400)
Add more XCC specific functions and use them from IP block functions.
RLC, CP functions are further split to have xcc specific versions.

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c

index 93420c7..93a0baa 100644 (file)
@@ -955,52 +955,64 @@ static void gfx_v9_4_3_xcc_init_gds_vmid(struct amdgpu_device *adev, int xcc_id)
        }
 }
 
-static void gfx_v9_4_3_constants_init(struct amdgpu_device *adev)
+static void gfx_v9_4_3_xcc_constants_init(struct amdgpu_device *adev,
+                                         int xcc_id)
 {
        u32 tmp;
-       int i, j, num_xcc;
-
-       num_xcc = NUM_XCC(adev->gfx.xcc_mask);
-
-       gfx_v9_4_3_get_cu_info(adev, &adev->gfx.cu_info);
-       adev->gfx.config.db_debug2 = RREG32_SOC15(GC, GET_INST(GC, 0), regDB_DEBUG2);
+       int i;
 
        /* XXX SH_MEM regs */
        /* where to put LDS, scratch, GPUVM in FSA64 space */
        mutex_lock(&adev->srbm_mutex);
        for (i = 0; i < adev->vm_manager.id_mgr[AMDGPU_GFXHUB(0)].num_ids; i++) {
-               for (j = 0; j < num_xcc; j++) {
-                       soc15_grbm_select(adev, 0, 0, 0, i, GET_INST(GC, j));
-                       /* CP and shaders */
-                       if (i == 0) {
-                               tmp = REG_SET_FIELD(0, SH_MEM_CONFIG, ALIGNMENT_MODE,
-                                                   SH_MEM_ALIGNMENT_MODE_UNALIGNED);
-                               tmp = REG_SET_FIELD(tmp, SH_MEM_CONFIG, RETRY_DISABLE,
-                                                   !!adev->gmc.noretry);
-                               WREG32_SOC15_RLC(GC, GET_INST(GC, j), regSH_MEM_CONFIG, tmp);
-                               WREG32_SOC15_RLC(GC, GET_INST(GC, j), regSH_MEM_BASES, 0);
-                       } else {
-                               tmp = REG_SET_FIELD(0, SH_MEM_CONFIG, ALIGNMENT_MODE,
-                                                   SH_MEM_ALIGNMENT_MODE_UNALIGNED);
-                               tmp = REG_SET_FIELD(tmp, SH_MEM_CONFIG, RETRY_DISABLE,
-                                                   !!adev->gmc.noretry);
-                               WREG32_SOC15_RLC(GC, GET_INST(GC, j), regSH_MEM_CONFIG, tmp);
-                               tmp = REG_SET_FIELD(0, SH_MEM_BASES, PRIVATE_BASE,
-                                       (adev->gmc.private_aperture_start >> 48));
-                               tmp = REG_SET_FIELD(tmp, SH_MEM_BASES, SHARED_BASE,
-                                       (adev->gmc.shared_aperture_start >> 48));
-                               WREG32_SOC15_RLC(GC, GET_INST(GC, j), regSH_MEM_BASES, tmp);
-                       }
+               soc15_grbm_select(adev, 0, 0, 0, i, GET_INST(GC, xcc_id));
+               /* CP and shaders */
+               if (i == 0) {
+                       tmp = REG_SET_FIELD(0, SH_MEM_CONFIG, ALIGNMENT_MODE,
+                                           SH_MEM_ALIGNMENT_MODE_UNALIGNED);
+                       tmp = REG_SET_FIELD(tmp, SH_MEM_CONFIG, RETRY_DISABLE,
+                                           !!adev->gmc.noretry);
+                       WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id),
+                                        regSH_MEM_CONFIG, tmp);
+                       WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id),
+                                        regSH_MEM_BASES, 0);
+               } else {
+                       tmp = REG_SET_FIELD(0, SH_MEM_CONFIG, ALIGNMENT_MODE,
+                                           SH_MEM_ALIGNMENT_MODE_UNALIGNED);
+                       tmp = REG_SET_FIELD(tmp, SH_MEM_CONFIG, RETRY_DISABLE,
+                                           !!adev->gmc.noretry);
+                       WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id),
+                                        regSH_MEM_CONFIG, tmp);
+                       tmp = REG_SET_FIELD(0, SH_MEM_BASES, PRIVATE_BASE,
+                                           (adev->gmc.private_aperture_start >>
+                                            48));
+                       tmp = REG_SET_FIELD(tmp, SH_MEM_BASES, SHARED_BASE,
+                                           (adev->gmc.shared_aperture_start >>
+                                            48));
+                       WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id),
+                                        regSH_MEM_BASES, tmp);
                }
        }
        soc15_grbm_select(adev, 0, 0, 0, 0, GET_INST(GC, 0));
 
        mutex_unlock(&adev->srbm_mutex);
 
-       for (i = 0; i < num_xcc; i++) {
-               gfx_v9_4_3_xcc_init_compute_vmid(adev, i);
-               gfx_v9_4_3_xcc_init_gds_vmid(adev, i);
-       }
+       gfx_v9_4_3_xcc_init_compute_vmid(adev, xcc_id);
+       gfx_v9_4_3_xcc_init_gds_vmid(adev, xcc_id);
+}
+
+static void gfx_v9_4_3_constants_init(struct amdgpu_device *adev)
+{
+       int i, num_xcc;
+
+       num_xcc = NUM_XCC(adev->gfx.xcc_mask);
+
+       gfx_v9_4_3_get_cu_info(adev, &adev->gfx.cu_info);
+       adev->gfx.config.db_debug2 =
+               RREG32_SOC15(GC, GET_INST(GC, 0), regDB_DEBUG2);
+
+       for (i = 0; i < num_xcc; i++)
+               gfx_v9_4_3_xcc_constants_init(adev, i);
 }
 
 static void
@@ -1167,16 +1179,31 @@ static void gfx_v9_4_3_xcc_enable_gui_idle_interrupt(struct amdgpu_device *adev,
        WREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_INT_CNTL_RING0, tmp);
 }
 
+static void gfx_v9_4_3_xcc_rlc_stop(struct amdgpu_device *adev, int xcc_id)
+{
+       WREG32_FIELD15_PREREG(GC, GET_INST(GC, xcc_id), RLC_CNTL,
+                             RLC_ENABLE_F32, 0);
+       gfx_v9_4_3_xcc_enable_gui_idle_interrupt(adev, false, xcc_id);
+       gfx_v9_4_3_xcc_wait_for_rlc_serdes(adev, xcc_id);
+}
+
 static void gfx_v9_4_3_rlc_stop(struct amdgpu_device *adev)
 {
        int i, num_xcc;
 
        num_xcc = NUM_XCC(adev->gfx.xcc_mask);
-       for (i = 0; i < num_xcc; i++) {
-               WREG32_FIELD15_PREREG(GC, GET_INST(GC, i), RLC_CNTL, RLC_ENABLE_F32, 0);
-               gfx_v9_4_3_xcc_enable_gui_idle_interrupt(adev, false, i);
-               gfx_v9_4_3_xcc_wait_for_rlc_serdes(adev, i);
-       }
+       for (i = 0; i < num_xcc; i++)
+               gfx_v9_4_3_xcc_rlc_stop(adev, i);
+}
+
+static void gfx_v9_4_3_xcc_rlc_reset(struct amdgpu_device *adev, int xcc_id)
+{
+       WREG32_FIELD15_PREREG(GC, GET_INST(GC, xcc_id), GRBM_SOFT_RESET,
+                             SOFT_RESET_RLC, 1);
+       udelay(50);
+       WREG32_FIELD15_PREREG(GC, GET_INST(GC, xcc_id), GRBM_SOFT_RESET,
+                             SOFT_RESET_RLC, 0);
+       udelay(50);
 }
 
 static void gfx_v9_4_3_rlc_reset(struct amdgpu_device *adev)
@@ -1184,10 +1211,19 @@ static void gfx_v9_4_3_rlc_reset(struct amdgpu_device *adev)
        int i, num_xcc;
 
        num_xcc = NUM_XCC(adev->gfx.xcc_mask);
-       for (i = 0; i < num_xcc; i++) {
-               WREG32_FIELD15_PREREG(GC, GET_INST(GC, i), GRBM_SOFT_RESET, SOFT_RESET_RLC, 1);
-               udelay(50);
-               WREG32_FIELD15_PREREG(GC, GET_INST(GC, i), GRBM_SOFT_RESET, SOFT_RESET_RLC, 0);
+       for (i = 0; i < num_xcc; i++)
+               gfx_v9_4_3_xcc_rlc_reset(adev, i);
+}
+
+static void gfx_v9_4_3_xcc_rlc_start(struct amdgpu_device *adev, int xcc_id)
+{
+       WREG32_FIELD15_PREREG(GC, GET_INST(GC, xcc_id), RLC_CNTL,
+                             RLC_ENABLE_F32, 1);
+       udelay(50);
+
+       /* carrizo do enable cp interrupt after cp inited */
+       if (!(adev->flags & AMD_IS_APU)) {
+               gfx_v9_4_3_xcc_enable_gui_idle_interrupt(adev, true, xcc_id);
                udelay(50);
        }
 }
@@ -1201,15 +1237,7 @@ static void gfx_v9_4_3_rlc_start(struct amdgpu_device *adev)
 
        num_xcc = NUM_XCC(adev->gfx.xcc_mask);
        for (i = 0; i < num_xcc; i++) {
-               WREG32_FIELD15_PREREG(GC, GET_INST(GC, i), RLC_CNTL, RLC_ENABLE_F32, 1);
-               udelay(50);
-
-               /* carrizo do enable cp interrupt after cp inited */
-               if (!(adev->flags & AMD_IS_APU)) {
-                       gfx_v9_4_3_xcc_enable_gui_idle_interrupt(adev, true, i);
-                       udelay(50);
-               }
-
+               gfx_v9_4_3_xcc_rlc_start(adev, i);
 #ifdef AMDGPU_RLC_DEBUG_RETRY
                /* RLC_GPM_GENERAL_6 : RLC Ucode version */
                rlc_ucode_ver = RREG32_SOC15(GC, GET_INST(GC, i), regRLC_GPM_GENERAL_6);
@@ -1260,28 +1288,39 @@ static int gfx_v9_4_3_xcc_rlc_load_microcode(struct amdgpu_device *adev,
        return 0;
 }
 
-static int gfx_v9_4_3_rlc_resume(struct amdgpu_device *adev)
+static int gfx_v9_4_3_xcc_rlc_resume(struct amdgpu_device *adev, int xcc_id)
 {
-       int r, i, num_xcc;
+       int r;
 
-       adev->gfx.rlc.funcs->stop(adev);
+       gfx_v9_4_3_xcc_rlc_stop(adev, xcc_id);
 
-       num_xcc = NUM_XCC(adev->gfx.xcc_mask);
-       for (i = 0; i < num_xcc; i++) {
-               /* disable CG */
-               WREG32_SOC15(GC, GET_INST(GC, i), regRLC_CGCG_CGLS_CTRL, 0);
+       /* disable CG */
+       WREG32_SOC15(GC, GET_INST(GC, xcc_id), regRLC_CGCG_CGLS_CTRL, 0);
 
-               gfx_v9_4_3_xcc_init_pg(adev, i);
+       gfx_v9_4_3_xcc_init_pg(adev, xcc_id);
 
-               if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
-                       /* legacy rlc firmware loading */
-                       r = gfx_v9_4_3_xcc_rlc_load_microcode(adev, i);
-                       if (r)
-                               return r;
-               }
+       if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
+               /* legacy rlc firmware loading */
+               r = gfx_v9_4_3_xcc_rlc_load_microcode(adev, xcc_id);
+               if (r)
+                       return r;
        }
 
-       adev->gfx.rlc.funcs->start(adev);
+       gfx_v9_4_3_xcc_rlc_start(adev, xcc_id);
+
+       return 0;
+}
+
+static int gfx_v9_4_3_rlc_resume(struct amdgpu_device *adev)
+{
+       int r, i, num_xcc;
+
+       num_xcc = NUM_XCC(adev->gfx.xcc_mask);
+       for (i = 0; i < num_xcc; i++) {
+               r = gfx_v9_4_3_xcc_rlc_resume(adev, i);
+               if (r)
+                       return r;
+       }
 
        return 0;
 }
@@ -1845,47 +1884,58 @@ done:
        return r;
 }
 
-static int gfx_v9_4_3_cp_resume(struct amdgpu_device *adev)
+static int gfx_v9_4_3_xcc_cp_resume(struct amdgpu_device *adev, int xcc_id)
 {
-       int r, i, j, num_xcc;
        struct amdgpu_ring *ring;
+       int r, j;
 
-       num_xcc = NUM_XCC(adev->gfx.xcc_mask);
-       for (i = 0; i < num_xcc; i++) {
-               gfx_v9_4_3_xcc_enable_gui_idle_interrupt(adev, false, i);
+       gfx_v9_4_3_xcc_enable_gui_idle_interrupt(adev, false, xcc_id);
 
-               if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
-                       gfx_v9_4_3_xcc_disable_gpa_mode(adev, i);
+       if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
+               gfx_v9_4_3_xcc_disable_gpa_mode(adev, xcc_id);
 
-                       r = gfx_v9_4_3_xcc_cp_compute_load_microcode(adev, i);
-                       if (r)
-                               return r;
-               }
+               r = gfx_v9_4_3_xcc_cp_compute_load_microcode(adev, xcc_id);
+               if (r)
+                       return r;
+       }
 
-               if (adev->gfx.partition_mode ==
-                   AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE)
-                       gfx_v9_4_3_switch_compute_partition(
-                               adev, amdgpu_user_partt_mode);
+       if (adev->gfx.partition_mode == AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE)
+               gfx_v9_4_3_switch_compute_partition(adev,
+                                                   amdgpu_user_partt_mode);
 
-               /* set the virtual and physical id based on partition_mode */
-               gfx_v9_4_3_xcc_program_xcc_id(adev, i);
+       /* set the virtual and physical id based on partition_mode */
+       gfx_v9_4_3_xcc_program_xcc_id(adev, xcc_id);
 
-               r = gfx_v9_4_3_xcc_kiq_resume(adev, i);
-               if (r)
-                       return r;
+       r = gfx_v9_4_3_xcc_kiq_resume(adev, xcc_id);
+       if (r)
+               return r;
+
+       r = gfx_v9_4_3_xcc_kcq_resume(adev, xcc_id);
+       if (r)
+               return r;
 
-               r = gfx_v9_4_3_xcc_kcq_resume(adev, i);
+       for (j = 0; j < adev->gfx.num_compute_rings; j++) {
+               ring = &adev->gfx.compute_ring
+                               [j + xcc_id * adev->gfx.num_compute_rings];
+               r = amdgpu_ring_test_helper(ring);
                if (r)
                        return r;
+       }
 
-               for (j = 0; j < adev->gfx.num_compute_rings; j++) {
-                       ring = &adev->gfx.compute_ring[j + i * adev->gfx.num_compute_rings];
-                       r = amdgpu_ring_test_helper(ring);
-                       if (r)
-                               return r;
-               }
+       gfx_v9_4_3_xcc_enable_gui_idle_interrupt(adev, true, xcc_id);
+
+       return 0;
+}
+
+static int gfx_v9_4_3_cp_resume(struct amdgpu_device *adev)
+{
+       int r, i, num_xcc;
 
-               gfx_v9_4_3_xcc_enable_gui_idle_interrupt(adev, true, i);
+       num_xcc = NUM_XCC(adev->gfx.xcc_mask);
+       for (i = 0; i < num_xcc; i++) {
+               r = gfx_v9_4_3_xcc_cp_resume(adev, i);
+               if (r)
+                       return r;
        }
 
        return 0;
@@ -1897,6 +1947,37 @@ static void gfx_v9_4_3_xcc_cp_enable(struct amdgpu_device *adev, bool enable,
        gfx_v9_4_3_xcc_cp_compute_enable(adev, enable, xcc_id);
 }
 
+static void gfx_v9_4_3_xcc_fini(struct amdgpu_device *adev, int xcc_id)
+{
+       if (amdgpu_gfx_disable_kcq(adev, xcc_id))
+               DRM_ERROR("XCD %d KCQ disable failed\n", xcc_id);
+
+       /* Use deinitialize sequence from CAIL when unbinding device
+        * from driver, otherwise KIQ is hanging when binding back
+        */
+       if (!amdgpu_in_reset(adev) && !adev->in_suspend) {
+               mutex_lock(&adev->srbm_mutex);
+               soc15_grbm_select(adev, adev->gfx.kiq[xcc_id].ring.me,
+                                 adev->gfx.kiq[xcc_id].ring.pipe,
+                                 adev->gfx.kiq[xcc_id].ring.queue, 0,
+                                 GET_INST(GC, xcc_id));
+               gfx_v9_4_3_xcc_kiq_fini_register(&adev->gfx.kiq[xcc_id].ring,
+                                                xcc_id);
+               soc15_grbm_select(adev, 0, 0, 0, 0, GET_INST(GC, xcc_id));
+               mutex_unlock(&adev->srbm_mutex);
+       }
+
+       gfx_v9_4_3_xcc_cp_enable(adev, false, xcc_id);
+
+       /* Skip suspend with A+A reset */
+       if (adev->gmc.xgmi.connected_to_cpu && amdgpu_in_reset(adev)) {
+               dev_dbg(adev->dev, "Device in reset. Skipping RLC halt\n");
+               return;
+       }
+
+       gfx_v9_4_3_xcc_rlc_stop(adev, xcc_id);
+}
+
 static int gfx_v9_4_3_hw_init(void *handle)
 {
        int r;
@@ -1927,33 +2008,9 @@ static int gfx_v9_4_3_hw_fini(void *handle)
 
        num_xcc = NUM_XCC(adev->gfx.xcc_mask);
        for (i = 0; i < num_xcc; i++) {
-               if (amdgpu_gfx_disable_kcq(adev, i))
-                       DRM_ERROR("XCD %d KCQ disable failed\n", i);
-
-               /* Use deinitialize sequence from CAIL when unbinding device
-                * from driver, otherwise KIQ is hanging when binding back
-                */
-               if (!amdgpu_in_reset(adev) && !adev->in_suspend) {
-                       mutex_lock(&adev->srbm_mutex);
-                       soc15_grbm_select(adev, adev->gfx.kiq[i].ring.me,
-                                       adev->gfx.kiq[i].ring.pipe,
-                                       adev->gfx.kiq[i].ring.queue, 0, GET_INST(GC, i));
-                       gfx_v9_4_3_xcc_kiq_fini_register(&adev->gfx.kiq[i].ring,
-                                                        i);
-                       soc15_grbm_select(adev, 0, 0, 0, 0, GET_INST(GC, i));
-                       mutex_unlock(&adev->srbm_mutex);
-               }
-
-               gfx_v9_4_3_xcc_cp_enable(adev, false, i);
-       }
-
-       /* Skip suspend with A+A reset */
-       if (adev->gmc.xgmi.connected_to_cpu && amdgpu_in_reset(adev)) {
-               dev_dbg(adev->dev, "Device in reset. Skipping RLC halt\n");
-               return 0;
+               gfx_v9_4_3_xcc_fini(adev, i);
        }
 
-       adev->gfx.rlc.funcs->stop(adev);
        return 0;
 }