diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0431-drm-amdgpu-save-and-restore-UVD-context-with-suspend.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0431-drm-amdgpu-save-and-restore-UVD-context-with-suspend.patch | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0431-drm-amdgpu-save-and-restore-UVD-context-with-suspend.patch b/common/recipes-kernel/linux/files/0431-drm-amdgpu-save-and-restore-UVD-context-with-suspend.patch new file mode 100644 index 00000000..ffbc8849 --- /dev/null +++ b/common/recipes-kernel/linux/files/0431-drm-amdgpu-save-and-restore-UVD-context-with-suspend.patch @@ -0,0 +1,173 @@ +From 880a8ad9990c8cb09e5f991eca25105164245e28 Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Fri, 1 Apr 2016 10:36:06 -0400 +Subject: [PATCH 0431/1110] drm/amdgpu: save and restore UVD context with + suspend and resume +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +and revert fix following it accordingly + +Revert "drm/amdgpu: stop trying to suspend UVD sessions v2" +Revert "drm/amdgpu: fix the UVD suspend sequence order" + +Signed-off-by: Leo Liu <leo.liu@amd.com> +Reviewed-by: Christian König <christian.koenig@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Kalyan Alle <kalyan.alle@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + + drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 48 ++++++++++++++++++--------------- + drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 4 +-- + drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 4 +-- + drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 7 ++--- + 5 files changed, 36 insertions(+), 28 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index 3ff6b3e..16cdddb 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -1595,6 +1595,7 @@ struct amdgpu_uvd { + struct amdgpu_bo *vcpu_bo; + void *cpu_addr; + uint64_t gpu_addr; ++ void *saved_bo; + unsigned fw_version; + atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; + struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +index 324bb32..69547c3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +@@ -243,32 +243,33 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) + + int amdgpu_uvd_suspend(struct amdgpu_device *adev) + { +- struct amdgpu_ring *ring = &adev->uvd.ring; +- int i, r; ++ unsigned size; ++ void *ptr; ++ const struct common_firmware_header *hdr; ++ int i; + + if (adev->uvd.vcpu_bo == NULL) + return 0; + +- for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { +- uint32_t handle = atomic_read(&adev->uvd.handles[i]); +- if (handle != 0) { +- struct fence *fence; +- +- amdgpu_uvd_note_usage(adev); +- +- r = amdgpu_uvd_get_destroy_msg(ring, handle, false, &fence); +- if (r) { +- DRM_ERROR("Error destroying UVD (%d)!\n", r); +- continue; +- } ++ for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) ++ if (atomic_read(&adev->uvd.handles[i])) ++ break; ++ ++ if (i == AMDGPU_MAX_UVD_HANDLES) ++ return 0; ++ hdr = (const struct common_firmware_header *)adev->uvd.fw->data; + +- fence_wait(fence, false); +- fence_put(fence); ++ size = amdgpu_bo_size(adev->uvd.vcpu_bo); ++ size -= le32_to_cpu(hdr->ucode_size_bytes); + +- adev->uvd.filp[i] = NULL; +- atomic_set(&adev->uvd.handles[i], 0); +- } +- } ++ ptr = adev->uvd.cpu_addr; ++ ptr += le32_to_cpu(hdr->ucode_size_bytes); ++ ++ adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); ++ if (!adev->uvd.saved_bo) ++ return -ENOMEM; ++ ++ memcpy(adev->uvd.saved_bo, ptr, size); + + return 0; + } +@@ -295,7 +296,12 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) + ptr = adev->uvd.cpu_addr; + ptr += le32_to_cpu(hdr->ucode_size_bytes); + +- memset(ptr, 0, size); ++ if (adev->uvd.saved_bo != NULL) { ++ memcpy(ptr, adev->uvd.saved_bo, size); ++ kfree(adev->uvd.saved_bo); ++ adev->uvd.saved_bo = NULL; ++ } else ++ memset(ptr, 0, size); + + return 0; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +index c606ccb..cb46375 100644 +--- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c ++++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +@@ -224,11 +224,11 @@ static int uvd_v4_2_suspend(void *handle) + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +- r = amdgpu_uvd_suspend(adev); ++ r = uvd_v4_2_hw_fini(adev); + if (r) + return r; + +- r = uvd_v4_2_hw_fini(adev); ++ r = amdgpu_uvd_suspend(adev); + if (r) + return r; + +diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +index e3c852d..16476d8 100644 +--- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +@@ -220,11 +220,11 @@ static int uvd_v5_0_suspend(void *handle) + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +- r = amdgpu_uvd_suspend(adev); ++ r = uvd_v5_0_hw_fini(adev); + if (r) + return r; + +- r = uvd_v5_0_hw_fini(adev); ++ r = amdgpu_uvd_suspend(adev); + if (r) + return r; + +diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +index 3375e61..d493791 100644 +--- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +@@ -214,15 +214,16 @@ static int uvd_v6_0_suspend(void *handle) + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + ++ r = uvd_v6_0_hw_fini(adev); ++ if (r) ++ return r; ++ + /* Skip this for APU for now */ + if (!(adev->flags & AMD_IS_APU)) { + r = amdgpu_uvd_suspend(adev); + if (r) + return r; + } +- r = uvd_v6_0_hw_fini(adev); +- if (r) +- return r; + + return r; + } +-- +2.7.4 + |