From 44b5cf2e0f7952856f48b9be56b9eb2f688d70f0 Mon Sep 17 00:00:00 2001 From: Lijo Lazar Date: Wed, 16 Nov 2022 10:47:18 +0530 Subject: [PATCH] drm/amdgpu: Add xcc specific functions 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 Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 295 +++++++++++++++++++------------- 1 file changed, 176 insertions(+), 119 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c index 93420c7..93a0baa 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c @@ -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; } -- 2.7.4