| From 5636d2f842c7bd7800002868ead3d6b809d385a0 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com> |
| Date: Thu, 22 Jan 2015 18:58:46 +0900 |
| Subject: drm/radeon: Restore GART table contents after pinning it in VRAM v3 |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com> |
| |
| commit 5636d2f842c7bd7800002868ead3d6b809d385a0 upstream. |
| |
| The GART table BO has to be moved out of VRAM for suspend/resume. Any |
| updates to the GART table during that time were silently dropped without |
| this change. This caused GPU lockups on resume in some cases, see the bug |
| reports referenced below. |
| |
| This might also make GPU reset more robust in some cases, as we no longer |
| rely on the GART table in VRAM being preserved across the GPU |
| lockup/reset. |
| |
| v2: Add logic to radeon_gart_table_vram_pin directly instead of |
| reinstating radeon_gart_restore |
| v3: Move code after assignment of rdev->gart.table_addr so that the GART |
| TLB flush can work as intended, add code comment explaining why we're |
| doing this |
| |
| Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85204 |
| Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=86267 |
| Reviewed-by: Christian König <christian.koenig@amd.com> |
| Signed-off-by: Michel Dänzer <michel.daenzer@amd.com> |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/radeon/radeon_gart.c | 13 +++++++++++++ |
| 1 file changed, 13 insertions(+) |
| |
| --- a/drivers/gpu/drm/radeon/radeon_gart.c |
| +++ b/drivers/gpu/drm/radeon/radeon_gart.c |
| @@ -165,6 +165,19 @@ int radeon_gart_table_vram_pin(struct ra |
| radeon_bo_unpin(rdev->gart.robj); |
| radeon_bo_unreserve(rdev->gart.robj); |
| rdev->gart.table_addr = gpu_addr; |
| + |
| + if (!r) { |
| + int i; |
| + |
| + /* We might have dropped some GART table updates while it wasn't |
| + * mapped, restore all entries |
| + */ |
| + for (i = 0; i < rdev->gart.num_gpu_pages; i++) |
| + radeon_gart_set_page(rdev, i, rdev->gart.pages_entry[i]); |
| + mb(); |
| + radeon_gart_tlb_flush(rdev); |
| + } |
| + |
| return r; |
| } |
| |