diff options
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-.patch | 120 |
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 + |