diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3969-drm-amdgpu-Fix-KIQ-hang-on-bare-metal-for-device-unb.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3969-drm-amdgpu-Fix-KIQ-hang-on-bare-metal-for-device-unb.patch | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3969-drm-amdgpu-Fix-KIQ-hang-on-bare-metal-for-device-unb.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3969-drm-amdgpu-Fix-KIQ-hang-on-bare-metal-for-device-unb.patch new file mode 100644 index 00000000..d910c49c --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3969-drm-amdgpu-Fix-KIQ-hang-on-bare-metal-for-device-unb.patch @@ -0,0 +1,102 @@ +From 3a3eee6943218baa08f2b8da49249c4f76f09467 Mon Sep 17 00:00:00 2001 +From: Andrey Grodzovsky <andrey.grodzovsky@amd.com> +Date: Wed, 28 Mar 2018 08:01:53 -0400 +Subject: [PATCH 3969/4131] drm/amdgpu: Fix KIQ hang on bare metal for device + unbind/bind back v2. + +Problem: When unbind and then bind back the device KIQ hangs on Vega +after mapping KCQs request. + +Fix: Adding deinitialzie code from CAIL during HW fini solves the +hang. + +v2: use srbm_mutex around soc15_grbm_select() + +Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 54 ++++++++++++++++++++++++++++++++++- + 1 file changed, 53 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +index 1de3da3..2ea409c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +@@ -2757,6 +2757,45 @@ static int gfx_v9_0_kiq_init_register(struct amdgpu_ring *ring) + return 0; + } + ++static int gfx_v9_0_kiq_fini_register(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ int j; ++ ++ /* disable the queue if it's active */ ++ if (RREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE) & 1) { ++ ++ WREG32_SOC15(GC, 0, mmCP_HQD_DEQUEUE_REQUEST, 1); ++ ++ for (j = 0; j < adev->usec_timeout; j++) { ++ if (!(RREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE) & 1)) ++ break; ++ udelay(1); ++ } ++ ++ if (adev->usec_timeout == AMDGPU_MAX_USEC_TIMEOUT) { ++ DRM_DEBUG("KIQ dequeue request failed.\n"); ++ ++ WREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE, 0); ++ } ++ ++ /* Manual disable if dequeue request times out */ ++ WREG32_SOC15(GC, 0, mmCP_HQD_DEQUEUE_REQUEST, ++ 0); ++ } ++ ++ WREG32_SOC15(GC, 0, mmCP_HQD_IQ_TIMER, 0); ++ WREG32_SOC15(GC, 0, mmCP_HQD_IB_CONTROL, 0); ++ WREG32_SOC15(GC, 0, mmCP_HQD_PERSISTENT_STATE, 0); ++ WREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL, 0x40000000); ++ WREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL, 0); ++ WREG32_SOC15(GC, 0, mmCP_HQD_PQ_RPTR, 0); ++ WREG32_SOC15(GC, 0, mmCP_HQD_PQ_WPTR_HI, 0); ++ WREG32_SOC15(GC, 0, mmCP_HQD_PQ_WPTR_LO, 0); ++ ++ return 0; ++} ++ + static int gfx_v9_0_kiq_init_queue(struct amdgpu_ring *ring) + { + struct amdgpu_device *adev = ring->adev; +@@ -3010,7 +3049,6 @@ static int gfx_v9_0_kcq_disable(struct amdgpu_ring *kiq_ring,struct amdgpu_ring + return r; + } + +- + static int gfx_v9_0_hw_fini(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; +@@ -3033,6 +3071,20 @@ static int gfx_v9_0_hw_fini(void *handle) + WREG32_FIELD15(GC, 0, CP_PQ_WPTR_POLL_CNTL, EN, 0); + return 0; + } ++ ++ /* Use deinitialize sequence from CAIL when unbinding device from driver, ++ * otherwise KIQ is hanging when binding back ++ */ ++ if (!adev->in_gpu_reset && !adev->gfx.in_suspend) { ++ mutex_lock(&adev->srbm_mutex); ++ soc15_grbm_select(adev, adev->gfx.kiq.ring.me, ++ adev->gfx.kiq.ring.pipe, ++ adev->gfx.kiq.ring.queue, 0); ++ gfx_v9_0_kiq_fini_register(&adev->gfx.kiq.ring); ++ soc15_grbm_select(adev, 0, 0, 0, 0); ++ mutex_unlock(&adev->srbm_mutex); ++ } ++ + gfx_v9_0_cp_enable(adev, false); + gfx_v9_0_rlc_stop(adev); + +-- +2.7.4 + |