| From 210b3b3c7563df391bd81d49c51af303b928de4a Mon Sep 17 00:00:00 2001 |
| From: Xiaojie Yuan <xiaojie.yuan@amd.com> |
| Date: Wed, 20 Nov 2019 14:02:22 +0800 |
| Subject: drm/amdgpu/gfx10: re-init clear state buffer after gpu reset |
| |
| From: Xiaojie Yuan <xiaojie.yuan@amd.com> |
| |
| commit 210b3b3c7563df391bd81d49c51af303b928de4a upstream. |
| |
| This patch fixes 2nd baco reset failure with gfxoff enabled on navi1x. |
| |
| clear state buffer (resides in vram) is corrupted after 1st baco reset, |
| upon gfxoff exit, CPF gets garbage header in CSIB and hangs. |
| |
| Signed-off-by: Xiaojie Yuan <xiaojie.yuan@amd.com> |
| Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 43 ++++++++++++++++++++++++++++----- |
| 1 file changed, 37 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c |
| +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c |
| @@ -1785,27 +1785,52 @@ static void gfx_v10_0_enable_gui_idle_in |
| WREG32_SOC15(GC, 0, mmCP_INT_CNTL_RING0, tmp); |
| } |
| |
| -static void gfx_v10_0_init_csb(struct amdgpu_device *adev) |
| +static int gfx_v10_0_init_csb(struct amdgpu_device *adev) |
| { |
| + int r; |
| + |
| + if (adev->in_gpu_reset) { |
| + r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false); |
| + if (r) |
| + return r; |
| + |
| + r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, |
| + (void **)&adev->gfx.rlc.cs_ptr); |
| + if (!r) { |
| + adev->gfx.rlc.funcs->get_csb_buffer(adev, |
| + adev->gfx.rlc.cs_ptr); |
| + amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj); |
| + } |
| + |
| + amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); |
| + if (r) |
| + return r; |
| + } |
| + |
| /* csib */ |
| WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_HI, |
| adev->gfx.rlc.clear_state_gpu_addr >> 32); |
| WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_LO, |
| adev->gfx.rlc.clear_state_gpu_addr & 0xfffffffc); |
| WREG32_SOC15(GC, 0, mmRLC_CSIB_LENGTH, adev->gfx.rlc.clear_state_size); |
| + |
| + return 0; |
| } |
| |
| -static void gfx_v10_0_init_pg(struct amdgpu_device *adev) |
| +static int gfx_v10_0_init_pg(struct amdgpu_device *adev) |
| { |
| int i; |
| + int r; |
| |
| - gfx_v10_0_init_csb(adev); |
| + r = gfx_v10_0_init_csb(adev); |
| + if (r) |
| + return r; |
| |
| for (i = 0; i < adev->num_vmhubs; i++) |
| amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0); |
| |
| /* TODO: init power gating */ |
| - return; |
| + return 0; |
| } |
| |
| void gfx_v10_0_rlc_stop(struct amdgpu_device *adev) |
| @@ -1907,7 +1932,10 @@ static int gfx_v10_0_rlc_resume(struct a |
| r = gfx_v10_0_wait_for_rlc_autoload_complete(adev); |
| if (r) |
| return r; |
| - gfx_v10_0_init_pg(adev); |
| + |
| + r = gfx_v10_0_init_pg(adev); |
| + if (r) |
| + return r; |
| |
| /* enable RLC SRM */ |
| gfx_v10_0_rlc_enable_srm(adev); |
| @@ -1933,7 +1961,10 @@ static int gfx_v10_0_rlc_resume(struct a |
| return r; |
| } |
| |
| - gfx_v10_0_init_pg(adev); |
| + r = gfx_v10_0_init_pg(adev); |
| + if (r) |
| + return r; |
| + |
| adev->gfx.rlc.funcs->start(adev); |
| |
| if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) { |