aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4613-drm-amdgpu-fix-calltrace-during-kmd-unload-v3.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4613-drm-amdgpu-fix-calltrace-during-kmd-unload-v3.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4613-drm-amdgpu-fix-calltrace-during-kmd-unload-v3.patch324
1 files changed, 324 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4613-drm-amdgpu-fix-calltrace-during-kmd-unload-v3.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4613-drm-amdgpu-fix-calltrace-during-kmd-unload-v3.patch
new file mode 100644
index 00000000..b47602b8
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4613-drm-amdgpu-fix-calltrace-during-kmd-unload-v3.patch
@@ -0,0 +1,324 @@
+From 52f19708950e75cdb45af6c578c2b811eeb4084b Mon Sep 17 00:00:00 2001
+From: Monk Liu <Monk.Liu@amd.com>
+Date: Tue, 26 Nov 2019 19:42:25 +0800
+Subject: [PATCH 4613/4736] drm/amdgpu: fix calltrace during kmd unload(v3)
+
+issue:
+kernel would report a warning from a double unpin
+during the driver unloading on the CSB bo
+
+why:
+we unpin it during hw_fini, and there will be another
+unpin in sw_fini on CSB bo.
+
+fix:
+actually we don't need to pin/unpin it during
+hw_init/fini since it is created with kernel pinned,
+we only need to fullfill the CSB again during hw_init
+to prevent CSB/VRAM lost after S3
+
+v2:
+get_csb in init_rlc so hw_init() will make CSIB content
+back even after reset or s3
+
+v3:
+use bo_create_kernel instead of bo_create_reserved for CSB
+otherwise the bo_free_kernel() on CSB is not aligned and
+would lead to its internal reserve pending there forever
+
+take care of gfx7/8 as well
+
+Signed-off-by: Monk Liu <Monk.Liu@amd.com>
+Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
+Reviewed-by: Xiaojie Yuan <xiaojie.yuan@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c | 10 +----
+ drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 58 +------------------------
+ drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 2 +
+ drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 40 +----------------
+ drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 40 +----------------
+ 5 files changed, 6 insertions(+), 144 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c
+index c8793e6cc3c5..6373bfb47d55 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c
+@@ -124,13 +124,12 @@ int amdgpu_gfx_rlc_init_sr(struct amdgpu_device *adev, u32 dws)
+ */
+ int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev)
+ {
+- volatile u32 *dst_ptr;
+ u32 dws;
+ int r;
+
+ /* allocate clear state block */
+ adev->gfx.rlc.clear_state_size = dws = adev->gfx.rlc.funcs->get_csb_size(adev);
+- r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
++ r = amdgpu_bo_create_kernel(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.clear_state_obj,
+ &adev->gfx.rlc.clear_state_gpu_addr,
+@@ -141,13 +140,6 @@ int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev)
+ return r;
+ }
+
+- /* set up the cs buffer */
+- dst_ptr = adev->gfx.rlc.cs_ptr;
+- adev->gfx.rlc.funcs->get_csb_buffer(adev, dst_ptr);
+- amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj);
+- amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
+- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
+-
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+index cd4982d70889..914d4b2f8401 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+@@ -987,39 +987,6 @@ static int gfx_v10_0_rlc_init(struct amdgpu_device *adev)
+ return 0;
+ }
+
+-static int gfx_v10_0_csb_vram_pin(struct amdgpu_device *adev)
+-{
+- int r;
+-
+- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
+- if (unlikely(r != 0))
+- return r;
+-
+- r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
+- AMDGPU_GEM_DOMAIN_VRAM);
+- if (!r)
+- adev->gfx.rlc.clear_state_gpu_addr =
+- amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);
+-
+- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
+-
+- return r;
+-}
+-
+-static void gfx_v10_0_csb_vram_unpin(struct amdgpu_device *adev)
+-{
+- int r;
+-
+- if (!adev->gfx.rlc.clear_state_obj)
+- return;
+-
+- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
+- if (likely(r == 0)) {
+- amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
+- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
+- }
+-}
+-
+ static void gfx_v10_0_mec_fini(struct amdgpu_device *adev)
+ {
+ amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
+@@ -1788,25 +1755,7 @@ static void gfx_v10_0_enable_gui_idle_interrupt(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;
+- }
++ adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
+
+ /* csib */
+ WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_HI,
+@@ -3777,10 +3726,6 @@ static int gfx_v10_0_hw_init(void *handle)
+ int r;
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+- r = gfx_v10_0_csb_vram_pin(adev);
+- if (r)
+- return r;
+-
+ if (!amdgpu_emu_mode)
+ gfx_v10_0_init_golden_registers(adev);
+
+@@ -3868,7 +3813,6 @@ static int gfx_v10_0_hw_fini(void *handle)
+ }
+ gfx_v10_0_cp_enable(adev, false);
+ gfx_v10_0_enable_gui_idle_interrupt(adev, false);
+- gfx_v10_0_csb_vram_unpin(adev);
+
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+index b8c2e9d9c711..0dabd0d0889c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+@@ -4543,6 +4543,8 @@ static int gfx_v7_0_hw_init(void *handle)
+
+ gfx_v7_0_constants_init(adev);
+
++ /* init CSB */
++ adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
+ /* init rlc */
+ r = adev->gfx.rlc.funcs->resume(adev);
+ if (r)
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+index 1f4f7c05e269..387e95319594 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+@@ -1317,39 +1317,6 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
+ return 0;
+ }
+
+-static int gfx_v8_0_csb_vram_pin(struct amdgpu_device *adev)
+-{
+- int r;
+-
+- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
+- if (unlikely(r != 0))
+- return r;
+-
+- r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
+- AMDGPU_GEM_DOMAIN_VRAM);
+- if (!r)
+- adev->gfx.rlc.clear_state_gpu_addr =
+- amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);
+-
+- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
+-
+- return r;
+-}
+-
+-static void gfx_v8_0_csb_vram_unpin(struct amdgpu_device *adev)
+-{
+- int r;
+-
+- if (!adev->gfx.rlc.clear_state_obj)
+- return;
+-
+- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
+- if (likely(r == 0)) {
+- amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
+- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
+- }
+-}
+-
+ static void gfx_v8_0_mec_fini(struct amdgpu_device *adev)
+ {
+ amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
+@@ -3903,6 +3870,7 @@ static void gfx_v8_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,
+
+ static void gfx_v8_0_init_csb(struct amdgpu_device *adev)
+ {
++ adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
+ /* csib */
+ WREG32(mmRLC_CSIB_ADDR_HI,
+ adev->gfx.rlc.clear_state_gpu_addr >> 32);
+@@ -4822,10 +4790,6 @@ static int gfx_v8_0_hw_init(void *handle)
+ gfx_v8_0_init_golden_registers(adev);
+ gfx_v8_0_constants_init(adev);
+
+- r = gfx_v8_0_csb_vram_pin(adev);
+- if (r)
+- return r;
+-
+ r = adev->gfx.rlc.funcs->resume(adev);
+ if (r)
+ return r;
+@@ -4943,8 +4907,6 @@ static int gfx_v8_0_hw_fini(void *handle)
+ pr_err("rlc is busy, skip halt rlc\n");
+ amdgpu_gfx_rlc_exit_safe_mode(adev);
+
+- gfx_v8_0_csb_vram_unpin(adev);
+-
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+index 8f9861361a9d..e644d5ea56b9 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+@@ -1681,39 +1681,6 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
+ return 0;
+ }
+
+-static int gfx_v9_0_csb_vram_pin(struct amdgpu_device *adev)
+-{
+- int r;
+-
+- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
+- if (unlikely(r != 0))
+- return r;
+-
+- r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
+- AMDGPU_GEM_DOMAIN_VRAM);
+- if (!r)
+- adev->gfx.rlc.clear_state_gpu_addr =
+- amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);
+-
+- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
+-
+- return r;
+-}
+-
+-static void gfx_v9_0_csb_vram_unpin(struct amdgpu_device *adev)
+-{
+- int r;
+-
+- if (!adev->gfx.rlc.clear_state_obj)
+- return;
+-
+- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
+- if (likely(r == 0)) {
+- amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
+- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
+- }
+-}
+-
+ static void gfx_v9_0_mec_fini(struct amdgpu_device *adev)
+ {
+ amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
+@@ -2408,6 +2375,7 @@ static void gfx_v9_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,
+
+ static void gfx_v9_0_init_csb(struct amdgpu_device *adev)
+ {
++ adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
+ /* csib */
+ WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmRLC_CSIB_ADDR_HI),
+ adev->gfx.rlc.clear_state_gpu_addr >> 32);
+@@ -3699,10 +3667,6 @@ static int gfx_v9_0_hw_init(void *handle)
+
+ gfx_v9_0_constants_init(adev);
+
+- r = gfx_v9_0_csb_vram_pin(adev);
+- if (r)
+- return r;
+-
+ r = adev->gfx.rlc.funcs->resume(adev);
+ if (r)
+ return r;
+@@ -3784,8 +3748,6 @@ static int gfx_v9_0_hw_fini(void *handle)
+ gfx_v9_0_cp_enable(adev, false);
+ adev->gfx.rlc.funcs->stop(adev);
+
+- gfx_v9_0_csb_vram_unpin(adev);
+-
+ return 0;
+ }
+
+--
+2.17.1
+