aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/1465-drm-amdgpu-Add-support-for-resuming-SDMA-queues-w-o-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/1465-drm-amdgpu-Add-support-for-resuming-SDMA-queues-w-o-.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/1465-drm-amdgpu-Add-support-for-resuming-SDMA-queues-w-o-.patch120
1 files changed, 120 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/1465-drm-amdgpu-Add-support-for-resuming-SDMA-queues-w-o-.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/1465-drm-amdgpu-Add-support-for-resuming-SDMA-queues-w-o-.patch
new file mode 100644
index 00000000..dc733821
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/1465-drm-amdgpu-Add-support-for-resuming-SDMA-queues-w-o-.patch
@@ -0,0 +1,120 @@
+From 11ad77a401121948f441d1559cf9695361a7fab5 Mon Sep 17 00:00:00 2001
+From: Felix Kuehling <Felix.Kuehling@amd.com>
+Date: Thu, 30 Jun 2016 16:41:32 -0400
+Subject: [PATCH 1465/4131] drm/amdgpu: Add support for resuming SDMA queues
+ w/o HWS
+
+Save wptr in hqd_sdma_destroy, restore it in hqd_sdma_load. Also
+read updated wptr from user mode when resuming an SDMA queue.
+
+Change-Id: Iea14fd8a3b4563c52c789d42fbad6d56a51684f7
+Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 25 ++++++++++++++++++++--
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 26 ++++++++++++++++++++---
+ 2 files changed, 46 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+index a67c20a..3e42eaa 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+@@ -498,8 +498,26 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
+ }
+
+ WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, m->sdma_rlc_doorbell);
+- WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0);
+- WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0);
++ WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, m->sdma_rlc_rb_rptr);
++
++ if (mm && mm == current->mm)
++ wptr_valid = !get_user(data, wptr);
++ else if (mm) {
++ struct vm_area_struct *vma;
++
++ vma = find_vma(mm, (unsigned long)wptr);
++ if (vma && vma->vm_start <= (unsigned long)wptr &&
++ vma->vm_ops && vma->vm_ops->access)
++ wptr_valid = (sizeof(data) == vma->vm_ops->access(
++ vma, (unsigned long)wptr,
++ &data, sizeof(data), 0));
++ }
++ if (wptr_valid)
++ WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, data);
++ else
++ WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR,
++ m->sdma_rlc_rb_rptr);
++
+ WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR, m->sdma_rlc_virtual_addr);
+ WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, m->sdma_rlc_rb_base);
+ WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI, m->sdma_rlc_rb_base_hi);
+@@ -765,6 +783,7 @@ static int kgd_wave_control_execute(struct kgd_dev *kgd,
+ {
+ struct amdgpu_device *adev = get_amdgpu_device(kgd);
+ uint32_t data;
++ bool wptr_valid = false;
+
+ mutex_lock(&adev->grbm_idx_mutex);
+
+@@ -841,6 +860,8 @@ static int alloc_memory_of_scratch(struct kgd_dev *kgd,
+ WREG32(mmSH_HIDDEN_PRIVATE_BASE_VMID, va);
+ unlock_srbm(kgd);
+
++ m->sdma_rlc_rb_rptr = RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR);
++
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+index 7d71727..ad92de6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+@@ -466,7 +466,7 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
+ uint32_t sdma_base_addr;
+ uint32_t temp, timeout = 2000;
+ uint32_t data;
+-
++ bool wptr_valid = false;
+
+ m = get_sdma_mqd(mqd);
+ sdma_base_addr = get_sdma_base_addr(m);
+@@ -495,8 +495,26 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
+ }
+
+ WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, m->sdmax_rlcx_doorbell);
+- WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0);
+- WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0);
++ WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, m->sdmax_rlcx_rb_rptr);
++
++ if (mm && mm == current->mm)
++ wptr_valid = !get_user(data, wptr);
++ else if (mm) {
++ struct vm_area_struct *vma;
++
++ vma = find_vma(mm, (unsigned long)wptr);
++ if (vma && vma->vm_start <= (unsigned long)wptr &&
++ vma->vm_ops && vma->vm_ops->access)
++ wptr_valid = (sizeof(data) == vma->vm_ops->access(
++ vma, (unsigned long)wptr,
++ &data, sizeof(data), 0));
++ }
++ if (wptr_valid)
++ WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, data);
++ else
++ WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR,
++ m->sdmax_rlcx_rb_rptr);
++
+ WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR, m->sdmax_rlcx_virtual_addr);
+ WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, m->sdmax_rlcx_rb_base);
+ WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI, m->sdmax_rlcx_rb_base_hi);
+@@ -711,6 +729,8 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
+ RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL) |
+ SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK);
+
++ m->sdmax_rlcx_rb_rptr = RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR);
++
+ return 0;
+ }
+
+--
+2.7.4
+