aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2015-05-07 09:19:25 -0400
committerAlex Deucher <alexander.deucher@amd.com>2015-08-28 15:04:18 -0400
commit8f8202f771c182a7244caa5880f50def1bedd713 (patch)
tree43de86a0005b0f38dbb7a7563d2bd7da99bfc21c /drivers/gpu/drm/amd/amdgpu
parente61235db62c5e68e56e59bea62b88f9f3d7a3cf5 (diff)
drm/amdgpu: stop trying to suspend UVD sessions v2
Saving the current UVD state on suspend and restoring it on resume just doesn't work reliable. Just close cleanup all sessions on suspend. Ported from radeon commit "12e49feadff6d7b7ebbe852b36943a71524d8d34". v2: rebased Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> (v1)
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c42
2 files changed, 19 insertions, 24 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 719506808b4a..9fefcd9c1af1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1666,7 +1666,6 @@ struct amdgpu_uvd {
1666 struct amdgpu_bo *vcpu_bo; 1666 struct amdgpu_bo *vcpu_bo;
1667 void *cpu_addr; 1667 void *cpu_addr;
1668 uint64_t gpu_addr; 1668 uint64_t gpu_addr;
1669 void *saved_bo;
1670 atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; 1669 atomic_t handles[AMDGPU_MAX_UVD_HANDLES];
1671 struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; 1670 struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES];
1672 struct delayed_work idle_work; 1671 struct delayed_work idle_work;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index b87355ccfb1d..3ad4a83c418f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -221,31 +221,32 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
221 221
222int amdgpu_uvd_suspend(struct amdgpu_device *adev) 222int amdgpu_uvd_suspend(struct amdgpu_device *adev)
223{ 223{
224 unsigned size; 224 struct amdgpu_ring *ring = &adev->uvd.ring;
225 void *ptr; 225 int i, r;
226 const struct common_firmware_header *hdr;
227 int i;
228 226
229 if (adev->uvd.vcpu_bo == NULL) 227 if (adev->uvd.vcpu_bo == NULL)
230 return 0; 228 return 0;
231 229
232 for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) 230 for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) {
233 if (atomic_read(&adev->uvd.handles[i])) 231 uint32_t handle = atomic_read(&adev->uvd.handles[i]);
234 break; 232 if (handle != 0) {
235 233 struct fence *fence;
236 if (i == AMDGPU_MAX_UVD_HANDLES)
237 return 0;
238 234
239 hdr = (const struct common_firmware_header *)adev->uvd.fw->data; 235 amdgpu_uvd_note_usage(adev);
240 236
241 size = amdgpu_bo_size(adev->uvd.vcpu_bo); 237 r = amdgpu_uvd_get_destroy_msg(ring, handle, &fence);
242 size -= le32_to_cpu(hdr->ucode_size_bytes); 238 if (r) {
239 DRM_ERROR("Error destroying UVD (%d)!\n", r);
240 continue;
241 }
243 242
244 ptr = adev->uvd.cpu_addr; 243 fence_wait(fence, false);
245 ptr += le32_to_cpu(hdr->ucode_size_bytes); 244 fence_put(fence);
246 245
247 adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); 246 adev->uvd.filp[i] = NULL;
248 memcpy(adev->uvd.saved_bo, ptr, size); 247 atomic_set(&adev->uvd.handles[i], 0);
248 }
249 }
249 250
250 return 0; 251 return 0;
251} 252}
@@ -270,12 +271,7 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
270 ptr = adev->uvd.cpu_addr; 271 ptr = adev->uvd.cpu_addr;
271 ptr += le32_to_cpu(hdr->ucode_size_bytes); 272 ptr += le32_to_cpu(hdr->ucode_size_bytes);
272 273
273 if (adev->uvd.saved_bo != NULL) { 274 memset(ptr, 0, size);
274 memcpy(ptr, adev->uvd.saved_bo, size);
275 kfree(adev->uvd.saved_bo);
276 adev->uvd.saved_bo = NULL;
277 } else
278 memset(ptr, 0, size);
279 275
280 return 0; 276 return 0;
281} 277}