diff options
author | Leo Liu <leo.liu@amd.com> | 2016-04-01 10:36:06 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-04-04 17:00:50 -0400 |
commit | 3f99dd814a6fdf9e06562f210b8e7702db9e9158 (patch) | |
tree | 5f214a9b1aef6fe465051197259427fd91a4f461 | |
parent | 749b48faaf64d1081d7216068ff3da92c230bad0 (diff) |
drm/amdgpu: save and restore UVD context with suspend and resume
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>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 7 |
5 files changed, 35 insertions, 26 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c4a21c6428f5..62a778012fe0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1591,6 +1591,7 @@ struct amdgpu_uvd { | |||
1591 | struct amdgpu_bo *vcpu_bo; | 1591 | struct amdgpu_bo *vcpu_bo; |
1592 | void *cpu_addr; | 1592 | void *cpu_addr; |
1593 | uint64_t gpu_addr; | 1593 | uint64_t gpu_addr; |
1594 | void *saved_bo; | ||
1594 | atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; | 1595 | atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; |
1595 | struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; | 1596 | struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; |
1596 | struct delayed_work idle_work; | 1597 | 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 c1a581044417..4b8ca3515fbc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
@@ -241,32 +241,34 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) | |||
241 | 241 | ||
242 | int amdgpu_uvd_suspend(struct amdgpu_device *adev) | 242 | int amdgpu_uvd_suspend(struct amdgpu_device *adev) |
243 | { | 243 | { |
244 | struct amdgpu_ring *ring = &adev->uvd.ring; | 244 | unsigned size; |
245 | int i, r; | 245 | void *ptr; |
246 | const struct common_firmware_header *hdr; | ||
247 | int i; | ||
246 | 248 | ||
247 | if (adev->uvd.vcpu_bo == NULL) | 249 | if (adev->uvd.vcpu_bo == NULL) |
248 | return 0; | 250 | return 0; |
249 | 251 | ||
250 | for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { | 252 | for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) |
251 | uint32_t handle = atomic_read(&adev->uvd.handles[i]); | 253 | if (atomic_read(&adev->uvd.handles[i])) |
252 | if (handle != 0) { | 254 | break; |
253 | struct fence *fence; | ||
254 | 255 | ||
255 | amdgpu_uvd_note_usage(adev); | 256 | if (i == AMDGPU_MAX_UVD_HANDLES) |
257 | return 0; | ||
256 | 258 | ||
257 | r = amdgpu_uvd_get_destroy_msg(ring, handle, false, &fence); | 259 | hdr = (const struct common_firmware_header *)adev->uvd.fw->data; |
258 | if (r) { | ||
259 | DRM_ERROR("Error destroying UVD (%d)!\n", r); | ||
260 | continue; | ||
261 | } | ||
262 | 260 | ||
263 | fence_wait(fence, false); | 261 | size = amdgpu_bo_size(adev->uvd.vcpu_bo); |
264 | fence_put(fence); | 262 | size -= le32_to_cpu(hdr->ucode_size_bytes); |
265 | 263 | ||
266 | adev->uvd.filp[i] = NULL; | 264 | ptr = adev->uvd.cpu_addr; |
267 | atomic_set(&adev->uvd.handles[i], 0); | 265 | ptr += le32_to_cpu(hdr->ucode_size_bytes); |
268 | } | 266 | |
269 | } | 267 | adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); |
268 | if (!adev->uvd.saved_bo) | ||
269 | return -ENOMEM; | ||
270 | |||
271 | memcpy(adev->uvd.saved_bo, ptr, size); | ||
270 | 272 | ||
271 | return 0; | 273 | return 0; |
272 | } | 274 | } |
@@ -291,7 +293,12 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) | |||
291 | ptr = adev->uvd.cpu_addr; | 293 | ptr = adev->uvd.cpu_addr; |
292 | ptr += le32_to_cpu(hdr->ucode_size_bytes); | 294 | ptr += le32_to_cpu(hdr->ucode_size_bytes); |
293 | 295 | ||
294 | memset(ptr, 0, size); | 296 | if (adev->uvd.saved_bo != NULL) { |
297 | memcpy(ptr, adev->uvd.saved_bo, size); | ||
298 | kfree(adev->uvd.saved_bo); | ||
299 | adev->uvd.saved_bo = NULL; | ||
300 | } else | ||
301 | memset(ptr, 0, size); | ||
295 | 302 | ||
296 | return 0; | 303 | return 0; |
297 | } | 304 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index c606ccb38d8b..cb463753115b 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) | |||
224 | int r; | 224 | int r; |
225 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 225 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
226 | 226 | ||
227 | r = amdgpu_uvd_suspend(adev); | 227 | r = uvd_v4_2_hw_fini(adev); |
228 | if (r) | 228 | if (r) |
229 | return r; | 229 | return r; |
230 | 230 | ||
231 | r = uvd_v4_2_hw_fini(adev); | 231 | r = amdgpu_uvd_suspend(adev); |
232 | if (r) | 232 | if (r) |
233 | return r; | 233 | return r; |
234 | 234 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index e3c852d9d79a..16476d80f475 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) | |||
220 | int r; | 220 | int r; |
221 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 221 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
222 | 222 | ||
223 | r = amdgpu_uvd_suspend(adev); | 223 | r = uvd_v5_0_hw_fini(adev); |
224 | if (r) | 224 | if (r) |
225 | return r; | 225 | return r; |
226 | 226 | ||
227 | r = uvd_v5_0_hw_fini(adev); | 227 | r = amdgpu_uvd_suspend(adev); |
228 | if (r) | 228 | if (r) |
229 | return r; | 229 | return r; |
230 | 230 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 3375e614ac67..d49379145ef2 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) | |||
214 | int r; | 214 | int r; |
215 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 215 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
216 | 216 | ||
217 | r = uvd_v6_0_hw_fini(adev); | ||
218 | if (r) | ||
219 | return r; | ||
220 | |||
217 | /* Skip this for APU for now */ | 221 | /* Skip this for APU for now */ |
218 | if (!(adev->flags & AMD_IS_APU)) { | 222 | if (!(adev->flags & AMD_IS_APU)) { |
219 | r = amdgpu_uvd_suspend(adev); | 223 | r = amdgpu_uvd_suspend(adev); |
220 | if (r) | 224 | if (r) |
221 | return r; | 225 | return r; |
222 | } | 226 | } |
223 | r = uvd_v6_0_hw_fini(adev); | ||
224 | if (r) | ||
225 | return r; | ||
226 | 227 | ||
227 | return r; | 228 | return r; |
228 | } | 229 | } |