aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0431-drm-amdgpu-save-and-restore-UVD-context-with-suspend.patch
diff options
context:
space:
mode:
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.patch173
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
+