diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_ttm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ttm.c | 122 |
1 files changed, 84 insertions, 38 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index d031b6863082..e9918d88f5b0 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <ttm/ttm_bo_driver.h> | 33 | #include <ttm/ttm_bo_driver.h> |
34 | #include <ttm/ttm_placement.h> | 34 | #include <ttm/ttm_placement.h> |
35 | #include <ttm/ttm_module.h> | 35 | #include <ttm/ttm_module.h> |
36 | #include <ttm/ttm_page_alloc.h> | ||
36 | #include <drm/drmP.h> | 37 | #include <drm/drmP.h> |
37 | #include <drm/radeon_drm.h> | 38 | #include <drm/radeon_drm.h> |
38 | #include <linux/seq_file.h> | 39 | #include <linux/seq_file.h> |
@@ -162,34 +163,21 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
162 | (unsigned)type); | 163 | (unsigned)type); |
163 | return -EINVAL; | 164 | return -EINVAL; |
164 | } | 165 | } |
165 | man->io_offset = rdev->mc.agp_base; | ||
166 | man->io_size = rdev->mc.gtt_size; | ||
167 | man->io_addr = NULL; | ||
168 | if (!rdev->ddev->agp->cant_use_aperture) | 166 | if (!rdev->ddev->agp->cant_use_aperture) |
169 | man->flags = TTM_MEMTYPE_FLAG_NEEDS_IOREMAP | | 167 | man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; |
170 | TTM_MEMTYPE_FLAG_MAPPABLE; | ||
171 | man->available_caching = TTM_PL_FLAG_UNCACHED | | 168 | man->available_caching = TTM_PL_FLAG_UNCACHED | |
172 | TTM_PL_FLAG_WC; | 169 | TTM_PL_FLAG_WC; |
173 | man->default_caching = TTM_PL_FLAG_WC; | 170 | man->default_caching = TTM_PL_FLAG_WC; |
174 | } else | ||
175 | #endif | ||
176 | { | ||
177 | man->io_offset = 0; | ||
178 | man->io_size = 0; | ||
179 | man->io_addr = NULL; | ||
180 | } | 171 | } |
172 | #endif | ||
181 | break; | 173 | break; |
182 | case TTM_PL_VRAM: | 174 | case TTM_PL_VRAM: |
183 | /* "On-card" video ram */ | 175 | /* "On-card" video ram */ |
184 | man->gpu_offset = rdev->mc.vram_start; | 176 | man->gpu_offset = rdev->mc.vram_start; |
185 | man->flags = TTM_MEMTYPE_FLAG_FIXED | | 177 | man->flags = TTM_MEMTYPE_FLAG_FIXED | |
186 | TTM_MEMTYPE_FLAG_NEEDS_IOREMAP | | ||
187 | TTM_MEMTYPE_FLAG_MAPPABLE; | 178 | TTM_MEMTYPE_FLAG_MAPPABLE; |
188 | man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; | 179 | man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; |
189 | man->default_caching = TTM_PL_FLAG_WC; | 180 | man->default_caching = TTM_PL_FLAG_WC; |
190 | man->io_addr = NULL; | ||
191 | man->io_offset = rdev->mc.aper_base; | ||
192 | man->io_size = rdev->mc.aper_size; | ||
193 | break; | 181 | break; |
194 | default: | 182 | default: |
195 | DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); | 183 | DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); |
@@ -244,9 +232,9 @@ static void radeon_move_null(struct ttm_buffer_object *bo, | |||
244 | } | 232 | } |
245 | 233 | ||
246 | static int radeon_move_blit(struct ttm_buffer_object *bo, | 234 | static int radeon_move_blit(struct ttm_buffer_object *bo, |
247 | bool evict, int no_wait, | 235 | bool evict, int no_wait_reserve, bool no_wait_gpu, |
248 | struct ttm_mem_reg *new_mem, | 236 | struct ttm_mem_reg *new_mem, |
249 | struct ttm_mem_reg *old_mem) | 237 | struct ttm_mem_reg *old_mem) |
250 | { | 238 | { |
251 | struct radeon_device *rdev; | 239 | struct radeon_device *rdev; |
252 | uint64_t old_start, new_start; | 240 | uint64_t old_start, new_start; |
@@ -290,13 +278,14 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
290 | r = radeon_copy(rdev, old_start, new_start, new_mem->num_pages, fence); | 278 | r = radeon_copy(rdev, old_start, new_start, new_mem->num_pages, fence); |
291 | /* FIXME: handle copy error */ | 279 | /* FIXME: handle copy error */ |
292 | r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL, | 280 | r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL, |
293 | evict, no_wait, new_mem); | 281 | evict, no_wait_reserve, no_wait_gpu, new_mem); |
294 | radeon_fence_unref(&fence); | 282 | radeon_fence_unref(&fence); |
295 | return r; | 283 | return r; |
296 | } | 284 | } |
297 | 285 | ||
298 | static int radeon_move_vram_ram(struct ttm_buffer_object *bo, | 286 | static int radeon_move_vram_ram(struct ttm_buffer_object *bo, |
299 | bool evict, bool interruptible, bool no_wait, | 287 | bool evict, bool interruptible, |
288 | bool no_wait_reserve, bool no_wait_gpu, | ||
300 | struct ttm_mem_reg *new_mem) | 289 | struct ttm_mem_reg *new_mem) |
301 | { | 290 | { |
302 | struct radeon_device *rdev; | 291 | struct radeon_device *rdev; |
@@ -317,7 +306,7 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, | |||
317 | placement.busy_placement = &placements; | 306 | placement.busy_placement = &placements; |
318 | placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; | 307 | placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; |
319 | r = ttm_bo_mem_space(bo, &placement, &tmp_mem, | 308 | r = ttm_bo_mem_space(bo, &placement, &tmp_mem, |
320 | interruptible, no_wait); | 309 | interruptible, no_wait_reserve, no_wait_gpu); |
321 | if (unlikely(r)) { | 310 | if (unlikely(r)) { |
322 | return r; | 311 | return r; |
323 | } | 312 | } |
@@ -331,11 +320,11 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, | |||
331 | if (unlikely(r)) { | 320 | if (unlikely(r)) { |
332 | goto out_cleanup; | 321 | goto out_cleanup; |
333 | } | 322 | } |
334 | r = radeon_move_blit(bo, true, no_wait, &tmp_mem, old_mem); | 323 | r = radeon_move_blit(bo, true, no_wait_reserve, no_wait_gpu, &tmp_mem, old_mem); |
335 | if (unlikely(r)) { | 324 | if (unlikely(r)) { |
336 | goto out_cleanup; | 325 | goto out_cleanup; |
337 | } | 326 | } |
338 | r = ttm_bo_move_ttm(bo, true, no_wait, new_mem); | 327 | r = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, new_mem); |
339 | out_cleanup: | 328 | out_cleanup: |
340 | if (tmp_mem.mm_node) { | 329 | if (tmp_mem.mm_node) { |
341 | struct ttm_bo_global *glob = rdev->mman.bdev.glob; | 330 | struct ttm_bo_global *glob = rdev->mman.bdev.glob; |
@@ -349,7 +338,8 @@ out_cleanup: | |||
349 | } | 338 | } |
350 | 339 | ||
351 | static int radeon_move_ram_vram(struct ttm_buffer_object *bo, | 340 | static int radeon_move_ram_vram(struct ttm_buffer_object *bo, |
352 | bool evict, bool interruptible, bool no_wait, | 341 | bool evict, bool interruptible, |
342 | bool no_wait_reserve, bool no_wait_gpu, | ||
353 | struct ttm_mem_reg *new_mem) | 343 | struct ttm_mem_reg *new_mem) |
354 | { | 344 | { |
355 | struct radeon_device *rdev; | 345 | struct radeon_device *rdev; |
@@ -369,15 +359,15 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo, | |||
369 | placement.num_busy_placement = 1; | 359 | placement.num_busy_placement = 1; |
370 | placement.busy_placement = &placements; | 360 | placement.busy_placement = &placements; |
371 | placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; | 361 | placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; |
372 | r = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, no_wait); | 362 | r = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, no_wait_reserve, no_wait_gpu); |
373 | if (unlikely(r)) { | 363 | if (unlikely(r)) { |
374 | return r; | 364 | return r; |
375 | } | 365 | } |
376 | r = ttm_bo_move_ttm(bo, true, no_wait, &tmp_mem); | 366 | r = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, &tmp_mem); |
377 | if (unlikely(r)) { | 367 | if (unlikely(r)) { |
378 | goto out_cleanup; | 368 | goto out_cleanup; |
379 | } | 369 | } |
380 | r = radeon_move_blit(bo, true, no_wait, new_mem, old_mem); | 370 | r = radeon_move_blit(bo, true, no_wait_reserve, no_wait_gpu, new_mem, old_mem); |
381 | if (unlikely(r)) { | 371 | if (unlikely(r)) { |
382 | goto out_cleanup; | 372 | goto out_cleanup; |
383 | } | 373 | } |
@@ -394,8 +384,9 @@ out_cleanup: | |||
394 | } | 384 | } |
395 | 385 | ||
396 | static int radeon_bo_move(struct ttm_buffer_object *bo, | 386 | static int radeon_bo_move(struct ttm_buffer_object *bo, |
397 | bool evict, bool interruptible, bool no_wait, | 387 | bool evict, bool interruptible, |
398 | struct ttm_mem_reg *new_mem) | 388 | bool no_wait_reserve, bool no_wait_gpu, |
389 | struct ttm_mem_reg *new_mem) | ||
399 | { | 390 | { |
400 | struct radeon_device *rdev; | 391 | struct radeon_device *rdev; |
401 | struct ttm_mem_reg *old_mem = &bo->mem; | 392 | struct ttm_mem_reg *old_mem = &bo->mem; |
@@ -422,23 +413,66 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, | |||
422 | if (old_mem->mem_type == TTM_PL_VRAM && | 413 | if (old_mem->mem_type == TTM_PL_VRAM && |
423 | new_mem->mem_type == TTM_PL_SYSTEM) { | 414 | new_mem->mem_type == TTM_PL_SYSTEM) { |
424 | r = radeon_move_vram_ram(bo, evict, interruptible, | 415 | r = radeon_move_vram_ram(bo, evict, interruptible, |
425 | no_wait, new_mem); | 416 | no_wait_reserve, no_wait_gpu, new_mem); |
426 | } else if (old_mem->mem_type == TTM_PL_SYSTEM && | 417 | } else if (old_mem->mem_type == TTM_PL_SYSTEM && |
427 | new_mem->mem_type == TTM_PL_VRAM) { | 418 | new_mem->mem_type == TTM_PL_VRAM) { |
428 | r = radeon_move_ram_vram(bo, evict, interruptible, | 419 | r = radeon_move_ram_vram(bo, evict, interruptible, |
429 | no_wait, new_mem); | 420 | no_wait_reserve, no_wait_gpu, new_mem); |
430 | } else { | 421 | } else { |
431 | r = radeon_move_blit(bo, evict, no_wait, new_mem, old_mem); | 422 | r = radeon_move_blit(bo, evict, no_wait_reserve, no_wait_gpu, new_mem, old_mem); |
432 | } | 423 | } |
433 | 424 | ||
434 | if (r) { | 425 | if (r) { |
435 | memcpy: | 426 | memcpy: |
436 | r = ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); | 427 | r = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); |
437 | } | 428 | } |
438 | |||
439 | return r; | 429 | return r; |
440 | } | 430 | } |
441 | 431 | ||
432 | static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) | ||
433 | { | ||
434 | struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; | ||
435 | struct radeon_device *rdev = radeon_get_rdev(bdev); | ||
436 | |||
437 | mem->bus.addr = NULL; | ||
438 | mem->bus.offset = 0; | ||
439 | mem->bus.size = mem->num_pages << PAGE_SHIFT; | ||
440 | mem->bus.base = 0; | ||
441 | mem->bus.is_iomem = false; | ||
442 | if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) | ||
443 | return -EINVAL; | ||
444 | switch (mem->mem_type) { | ||
445 | case TTM_PL_SYSTEM: | ||
446 | /* system memory */ | ||
447 | return 0; | ||
448 | case TTM_PL_TT: | ||
449 | #if __OS_HAS_AGP | ||
450 | if (rdev->flags & RADEON_IS_AGP) { | ||
451 | /* RADEON_IS_AGP is set only if AGP is active */ | ||
452 | mem->bus.offset = mem->mm_node->start << PAGE_SHIFT; | ||
453 | mem->bus.base = rdev->mc.agp_base; | ||
454 | mem->bus.is_iomem = !rdev->ddev->agp->cant_use_aperture; | ||
455 | } | ||
456 | #endif | ||
457 | break; | ||
458 | case TTM_PL_VRAM: | ||
459 | mem->bus.offset = mem->mm_node->start << PAGE_SHIFT; | ||
460 | /* check if it's visible */ | ||
461 | if ((mem->bus.offset + mem->bus.size) > rdev->mc.visible_vram_size) | ||
462 | return -EINVAL; | ||
463 | mem->bus.base = rdev->mc.aper_base; | ||
464 | mem->bus.is_iomem = true; | ||
465 | break; | ||
466 | default: | ||
467 | return -EINVAL; | ||
468 | } | ||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | static void radeon_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) | ||
473 | { | ||
474 | } | ||
475 | |||
442 | static int radeon_sync_obj_wait(void *sync_obj, void *sync_arg, | 476 | static int radeon_sync_obj_wait(void *sync_obj, void *sync_arg, |
443 | bool lazy, bool interruptible) | 477 | bool lazy, bool interruptible) |
444 | { | 478 | { |
@@ -479,6 +513,8 @@ static struct ttm_bo_driver radeon_bo_driver = { | |||
479 | .sync_obj_ref = &radeon_sync_obj_ref, | 513 | .sync_obj_ref = &radeon_sync_obj_ref, |
480 | .move_notify = &radeon_bo_move_notify, | 514 | .move_notify = &radeon_bo_move_notify, |
481 | .fault_reserve_notify = &radeon_bo_fault_reserve_notify, | 515 | .fault_reserve_notify = &radeon_bo_fault_reserve_notify, |
516 | .io_mem_reserve = &radeon_ttm_io_mem_reserve, | ||
517 | .io_mem_free = &radeon_ttm_io_mem_free, | ||
482 | }; | 518 | }; |
483 | 519 | ||
484 | int radeon_ttm_init(struct radeon_device *rdev) | 520 | int radeon_ttm_init(struct radeon_device *rdev) |
@@ -571,13 +607,17 @@ static const struct vm_operations_struct *ttm_vm_ops = NULL; | |||
571 | static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 607 | static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
572 | { | 608 | { |
573 | struct ttm_buffer_object *bo; | 609 | struct ttm_buffer_object *bo; |
610 | struct radeon_device *rdev; | ||
574 | int r; | 611 | int r; |
575 | 612 | ||
576 | bo = (struct ttm_buffer_object *)vma->vm_private_data; | 613 | bo = (struct ttm_buffer_object *)vma->vm_private_data; |
577 | if (bo == NULL) { | 614 | if (bo == NULL) { |
578 | return VM_FAULT_NOPAGE; | 615 | return VM_FAULT_NOPAGE; |
579 | } | 616 | } |
617 | rdev = radeon_get_rdev(bo->bdev); | ||
618 | mutex_lock(&rdev->vram_mutex); | ||
580 | r = ttm_vm_ops->fault(vma, vmf); | 619 | r = ttm_vm_ops->fault(vma, vmf); |
620 | mutex_unlock(&rdev->vram_mutex); | ||
581 | return r; | 621 | return r; |
582 | } | 622 | } |
583 | 623 | ||
@@ -745,8 +785,8 @@ static int radeon_mm_dump_table(struct seq_file *m, void *data) | |||
745 | static int radeon_ttm_debugfs_init(struct radeon_device *rdev) | 785 | static int radeon_ttm_debugfs_init(struct radeon_device *rdev) |
746 | { | 786 | { |
747 | #if defined(CONFIG_DEBUG_FS) | 787 | #if defined(CONFIG_DEBUG_FS) |
748 | static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES]; | 788 | static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES+1]; |
749 | static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES][32]; | 789 | static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES+1][32]; |
750 | unsigned i; | 790 | unsigned i; |
751 | 791 | ||
752 | for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) { | 792 | for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) { |
@@ -763,7 +803,13 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev) | |||
763 | radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_TT].manager; | 803 | radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_TT].manager; |
764 | 804 | ||
765 | } | 805 | } |
766 | return radeon_debugfs_add_files(rdev, radeon_mem_types_list, RADEON_DEBUGFS_MEM_TYPES); | 806 | /* Add ttm page pool to debugfs */ |
807 | sprintf(radeon_mem_types_names[i], "ttm_page_pool"); | ||
808 | radeon_mem_types_list[i].name = radeon_mem_types_names[i]; | ||
809 | radeon_mem_types_list[i].show = &ttm_page_alloc_debugfs; | ||
810 | radeon_mem_types_list[i].driver_features = 0; | ||
811 | radeon_mem_types_list[i].data = NULL; | ||
812 | return radeon_debugfs_add_files(rdev, radeon_mem_types_list, RADEON_DEBUGFS_MEM_TYPES+1); | ||
767 | 813 | ||
768 | #endif | 814 | #endif |
769 | return 0; | 815 | return 0; |