diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gart.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_gart.c | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 84146d5901aa..5450fa95a47e 100644 --- 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 radeon_device *rdev) | |||
| 165 | radeon_bo_unpin(rdev->gart.robj); | 165 | radeon_bo_unpin(rdev->gart.robj); |
| 166 | radeon_bo_unreserve(rdev->gart.robj); | 166 | radeon_bo_unreserve(rdev->gart.robj); |
| 167 | rdev->gart.table_addr = gpu_addr; | 167 | rdev->gart.table_addr = gpu_addr; |
| 168 | |||
| 169 | if (!r) { | ||
| 170 | int i; | ||
| 171 | |||
| 172 | /* We might have dropped some GART table updates while it wasn't | ||
| 173 | * mapped, restore all entries | ||
| 174 | */ | ||
| 175 | for (i = 0; i < rdev->gart.num_gpu_pages; i++) | ||
| 176 | radeon_gart_set_page(rdev, i, rdev->gart.pages_entry[i]); | ||
| 177 | mb(); | ||
| 178 | radeon_gart_tlb_flush(rdev); | ||
| 179 | } | ||
| 180 | |||
| 168 | return r; | 181 | return r; |
| 169 | } | 182 | } |
| 170 | 183 | ||
| @@ -228,7 +241,6 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
| 228 | unsigned t; | 241 | unsigned t; |
| 229 | unsigned p; | 242 | unsigned p; |
| 230 | int i, j; | 243 | int i, j; |
| 231 | u64 page_base; | ||
| 232 | 244 | ||
| 233 | if (!rdev->gart.ready) { | 245 | if (!rdev->gart.ready) { |
| 234 | WARN(1, "trying to unbind memory from uninitialized GART !\n"); | 246 | WARN(1, "trying to unbind memory from uninitialized GART !\n"); |
| @@ -239,14 +251,12 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
| 239 | for (i = 0; i < pages; i++, p++) { | 251 | for (i = 0; i < pages; i++, p++) { |
| 240 | if (rdev->gart.pages[p]) { | 252 | if (rdev->gart.pages[p]) { |
| 241 | rdev->gart.pages[p] = NULL; | 253 | rdev->gart.pages[p] = NULL; |
| 242 | rdev->gart.pages_addr[p] = rdev->dummy_page.addr; | ||
| 243 | page_base = rdev->gart.pages_addr[p]; | ||
| 244 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 254 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
| 255 | rdev->gart.pages_entry[t] = rdev->dummy_page.entry; | ||
| 245 | if (rdev->gart.ptr) { | 256 | if (rdev->gart.ptr) { |
| 246 | radeon_gart_set_page(rdev, t, page_base, | 257 | radeon_gart_set_page(rdev, t, |
| 247 | RADEON_GART_PAGE_DUMMY); | 258 | rdev->dummy_page.entry); |
| 248 | } | 259 | } |
| 249 | page_base += RADEON_GPU_PAGE_SIZE; | ||
| 250 | } | 260 | } |
| 251 | } | 261 | } |
| 252 | } | 262 | } |
| @@ -274,7 +284,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
| 274 | { | 284 | { |
| 275 | unsigned t; | 285 | unsigned t; |
| 276 | unsigned p; | 286 | unsigned p; |
| 277 | uint64_t page_base; | 287 | uint64_t page_base, page_entry; |
| 278 | int i, j; | 288 | int i, j; |
| 279 | 289 | ||
| 280 | if (!rdev->gart.ready) { | 290 | if (!rdev->gart.ready) { |
| @@ -285,14 +295,15 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
| 285 | p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); | 295 | p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); |
| 286 | 296 | ||
| 287 | for (i = 0; i < pages; i++, p++) { | 297 | for (i = 0; i < pages; i++, p++) { |
| 288 | rdev->gart.pages_addr[p] = dma_addr[i]; | ||
| 289 | rdev->gart.pages[p] = pagelist[i]; | 298 | rdev->gart.pages[p] = pagelist[i]; |
| 290 | if (rdev->gart.ptr) { | 299 | page_base = dma_addr[i]; |
| 291 | page_base = rdev->gart.pages_addr[p]; | 300 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
| 292 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 301 | page_entry = radeon_gart_get_page_entry(page_base, flags); |
| 293 | radeon_gart_set_page(rdev, t, page_base, flags); | 302 | rdev->gart.pages_entry[t] = page_entry; |
| 294 | page_base += RADEON_GPU_PAGE_SIZE; | 303 | if (rdev->gart.ptr) { |
| 304 | radeon_gart_set_page(rdev, t, page_entry); | ||
| 295 | } | 305 | } |
| 306 | page_base += RADEON_GPU_PAGE_SIZE; | ||
| 296 | } | 307 | } |
| 297 | } | 308 | } |
| 298 | mb(); | 309 | mb(); |
| @@ -334,16 +345,15 @@ int radeon_gart_init(struct radeon_device *rdev) | |||
| 334 | radeon_gart_fini(rdev); | 345 | radeon_gart_fini(rdev); |
| 335 | return -ENOMEM; | 346 | return -ENOMEM; |
| 336 | } | 347 | } |
| 337 | rdev->gart.pages_addr = vzalloc(sizeof(dma_addr_t) * | 348 | rdev->gart.pages_entry = vmalloc(sizeof(uint64_t) * |
| 338 | rdev->gart.num_cpu_pages); | 349 | rdev->gart.num_gpu_pages); |
| 339 | if (rdev->gart.pages_addr == NULL) { | 350 | if (rdev->gart.pages_entry == NULL) { |
| 340 | radeon_gart_fini(rdev); | 351 | radeon_gart_fini(rdev); |
| 341 | return -ENOMEM; | 352 | return -ENOMEM; |
| 342 | } | 353 | } |
| 343 | /* set GART entry to point to the dummy page by default */ | 354 | /* set GART entry to point to the dummy page by default */ |
| 344 | for (i = 0; i < rdev->gart.num_cpu_pages; i++) { | 355 | for (i = 0; i < rdev->gart.num_gpu_pages; i++) |
| 345 | rdev->gart.pages_addr[i] = rdev->dummy_page.addr; | 356 | rdev->gart.pages_entry[i] = rdev->dummy_page.entry; |
| 346 | } | ||
| 347 | return 0; | 357 | return 0; |
| 348 | } | 358 | } |
| 349 | 359 | ||
| @@ -356,15 +366,15 @@ int radeon_gart_init(struct radeon_device *rdev) | |||
| 356 | */ | 366 | */ |
| 357 | void radeon_gart_fini(struct radeon_device *rdev) | 367 | void radeon_gart_fini(struct radeon_device *rdev) |
| 358 | { | 368 | { |
| 359 | if (rdev->gart.pages && rdev->gart.pages_addr && rdev->gart.ready) { | 369 | if (rdev->gart.ready) { |
| 360 | /* unbind pages */ | 370 | /* unbind pages */ |
| 361 | radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); | 371 | radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); |
| 362 | } | 372 | } |
| 363 | rdev->gart.ready = false; | 373 | rdev->gart.ready = false; |
| 364 | vfree(rdev->gart.pages); | 374 | vfree(rdev->gart.pages); |
| 365 | vfree(rdev->gart.pages_addr); | 375 | vfree(rdev->gart.pages_entry); |
| 366 | rdev->gart.pages = NULL; | 376 | rdev->gart.pages = NULL; |
| 367 | rdev->gart.pages_addr = NULL; | 377 | rdev->gart.pages_entry = NULL; |
| 368 | 378 | ||
| 369 | radeon_dummy_page_fini(rdev); | 379 | radeon_dummy_page_fini(rdev); |
| 370 | } | 380 | } |
