diff options
author | Jerome Glisse <jglisse@redhat.com> | 2013-06-06 17:51:21 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-06-12 08:16:29 -0400 |
commit | 089920f21db0108fb105ecfd81de4c92d88f06d0 (patch) | |
tree | 2bdece83b9d396767ff6795b110af36a2dd0c388 /drivers/gpu/drm/radeon/radeon_device.c | |
parent | 3813f5ca9ab7a00e80a17aab34f155453c66c78a (diff) |
drm/radeon: fix write back suspend regression with uvd v2
UVD ring can't use scratch thus it does need writeback buffer to keep
a valid address or radeon_ring_backup will trigger a kernel fault.
It's ok to not unpin the write back buffer on suspend as it leave in
gtt and thus does not need eviction.
v2: Fix the uvd case.
Reported and tracked by Wojtek <wojtask9@wp.pl>
Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_device.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 189973836cff..b0dc0b6cb4e0 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -244,16 +244,6 @@ void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg) | |||
244 | */ | 244 | */ |
245 | void radeon_wb_disable(struct radeon_device *rdev) | 245 | void radeon_wb_disable(struct radeon_device *rdev) |
246 | { | 246 | { |
247 | int r; | ||
248 | |||
249 | if (rdev->wb.wb_obj) { | ||
250 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); | ||
251 | if (unlikely(r != 0)) | ||
252 | return; | ||
253 | radeon_bo_kunmap(rdev->wb.wb_obj); | ||
254 | radeon_bo_unpin(rdev->wb.wb_obj); | ||
255 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
256 | } | ||
257 | rdev->wb.enabled = false; | 247 | rdev->wb.enabled = false; |
258 | } | 248 | } |
259 | 249 | ||
@@ -269,6 +259,11 @@ void radeon_wb_fini(struct radeon_device *rdev) | |||
269 | { | 259 | { |
270 | radeon_wb_disable(rdev); | 260 | radeon_wb_disable(rdev); |
271 | if (rdev->wb.wb_obj) { | 261 | if (rdev->wb.wb_obj) { |
262 | if (!radeon_bo_reserve(rdev->wb.wb_obj, false)) { | ||
263 | radeon_bo_kunmap(rdev->wb.wb_obj); | ||
264 | radeon_bo_unpin(rdev->wb.wb_obj); | ||
265 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
266 | } | ||
272 | radeon_bo_unref(&rdev->wb.wb_obj); | 267 | radeon_bo_unref(&rdev->wb.wb_obj); |
273 | rdev->wb.wb = NULL; | 268 | rdev->wb.wb = NULL; |
274 | rdev->wb.wb_obj = NULL; | 269 | rdev->wb.wb_obj = NULL; |
@@ -295,26 +290,26 @@ int radeon_wb_init(struct radeon_device *rdev) | |||
295 | dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); | 290 | dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); |
296 | return r; | 291 | return r; |
297 | } | 292 | } |
298 | } | 293 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); |
299 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); | 294 | if (unlikely(r != 0)) { |
300 | if (unlikely(r != 0)) { | 295 | radeon_wb_fini(rdev); |
301 | radeon_wb_fini(rdev); | 296 | return r; |
302 | return r; | 297 | } |
303 | } | 298 | r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, |
304 | r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, | 299 | &rdev->wb.gpu_addr); |
305 | &rdev->wb.gpu_addr); | 300 | if (r) { |
306 | if (r) { | 301 | radeon_bo_unreserve(rdev->wb.wb_obj); |
302 | dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); | ||
303 | radeon_wb_fini(rdev); | ||
304 | return r; | ||
305 | } | ||
306 | r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); | ||
307 | radeon_bo_unreserve(rdev->wb.wb_obj); | 307 | radeon_bo_unreserve(rdev->wb.wb_obj); |
308 | dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); | 308 | if (r) { |
309 | radeon_wb_fini(rdev); | 309 | dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); |
310 | return r; | 310 | radeon_wb_fini(rdev); |
311 | } | 311 | return r; |
312 | r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); | 312 | } |
313 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
314 | if (r) { | ||
315 | dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); | ||
316 | radeon_wb_fini(rdev); | ||
317 | return r; | ||
318 | } | 313 | } |
319 | 314 | ||
320 | /* clear wb memory */ | 315 | /* clear wb memory */ |