int radeon_gem_object_create(struct radeon_device *rdev, int size, int alignment, int initial_domain, bool discardable, bool kernel, bool interruptible, struct drm_gem_object **obj) { struct drm_gem_object *gobj; struct radeon_object *robj; int r; *obj = NULL; gobj = drm_gem_object_alloc(rdev->ddev, size); if (!gobj) { return -ENOMEM; } if (alignment < PAGE_SIZE) { alignment = PAGE_SIZE; } r = radeon_object_create(rdev, gobj, size, kernel, initial_domain, interruptible, &robj); if (r) { DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n", size, initial_domain, alignment); mutex_lock(&rdev->ddev->struct_mutex); drm_gem_object_unreference(gobj); mutex_unlock(&rdev->ddev->struct_mutex); return r; } gobj->driver_private = robj; *obj = gobj; return 0; }
int radeon_ttm_init(struct radeon_device *rdev) { int r; r = radeon_ttm_global_init(rdev); if (r) { return r; } r = ttm_bo_device_init(&rdev->mman.bdev, rdev->mman.bo_global_ref.ref.object, &radeon_bo_driver, DRM_FILE_PAGE_OFFSET, rdev->need_dma32); if (r) { DRM_ERROR("failed initializing buffer object driver(%d).\n", r); return r; } r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, 0, ((rdev->mc.real_vram_size) >> PAGE_SHIFT)); if (r) { DRM_ERROR("Failed initializing VRAM heap.\n"); return r; } r = radeon_object_create(rdev, NULL, 256 * 1024, true, RADEON_GEM_DOMAIN_VRAM, false, &rdev->stollen_vga_memory); if (r) { return r; } r = radeon_object_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL); if (r) { radeon_object_unref(&rdev->stollen_vga_memory); return r; } DRM_INFO("radeon: %uM of VRAM memory ready\n", (unsigned)rdev->mc.real_vram_size / (1024 * 1024)); r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0, ((rdev->mc.gtt_size) >> PAGE_SHIFT)); if (r) { DRM_ERROR("Failed initializing GTT heap.\n"); return r; } DRM_INFO("radeon: %uM of GTT memory ready.\n", (unsigned)(rdev->mc.gtt_size / (1024 * 1024))); if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; } r = radeon_ttm_debugfs_init(rdev); if (r) { DRM_ERROR("Failed to init debugfs\n"); return r; } return 0; }
void radeon_test_moves(struct radeon_device *rdev) { struct radeon_object *vram_obj = NULL; struct radeon_object **gtt_obj = NULL; struct radeon_fence *fence = NULL; uint64_t gtt_addr, vram_addr; unsigned i, n, size; int r; size = 1024 * 1024; n = ((u32)(rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE - rdev->cp.ring_size)) / size; gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); if (!gtt_obj) { DRM_ERROR("Failed to allocate %d pointers\n", n); r = 1; goto out_cleanup; } r = radeon_object_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM, false, &vram_obj); if (r) { DRM_ERROR("Failed to create VRAM object\n"); goto out_cleanup; } r = radeon_object_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr); if (r) { DRM_ERROR("Failed to pin VRAM object\n"); goto out_cleanup; } for (i = 0; i < n; i++) { void *gtt_map, *vram_map; void **gtt_start, **gtt_end; void **vram_start, **vram_end; r = radeon_object_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_GTT, false, gtt_obj + i); if (r) { DRM_ERROR("Failed to create GTT object %d\n", i); goto out_cleanup; } r = radeon_object_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, >t_addr); if (r) { DRM_ERROR("Failed to pin GTT object %d\n", i); goto out_cleanup; } r = radeon_object_kmap(gtt_obj[i], >t_map); if (r) { DRM_ERROR("Failed to map GTT object %d\n", i); goto out_cleanup; } for (gtt_start = gtt_map, gtt_end = gtt_map + size; gtt_start < gtt_end; gtt_start++) *gtt_start = gtt_start; radeon_object_kunmap(gtt_obj[i]); r = radeon_fence_create(rdev, &fence); if (r) { DRM_ERROR("Failed to create GTT->VRAM fence %d\n", i); goto out_cleanup; } r = radeon_copy(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, fence); if (r) { DRM_ERROR("Failed GTT->VRAM copy %d\n", i); goto out_cleanup; } r = radeon_fence_wait(fence, false); if (r) { DRM_ERROR("Failed to wait for GTT->VRAM fence %d\n", i); goto out_cleanup; } radeon_fence_unref(&fence); r = radeon_object_kmap(vram_obj, &vram_map); if (r) { DRM_ERROR("Failed to map VRAM object after copy %d\n", i); goto out_cleanup; } for (gtt_start = gtt_map, gtt_end = gtt_map + size, vram_start = vram_map, vram_end = vram_map + size; vram_start < vram_end; gtt_start++, vram_start++) { if (*vram_start != gtt_start) { DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, " "expected 0x%p (GTT map 0x%p-0x%p)\n", i, *vram_start, gtt_start, gtt_map, gtt_end); radeon_object_kunmap(vram_obj); goto out_cleanup; } *vram_start = vram_start; } radeon_object_kunmap(vram_obj); r = radeon_fence_create(rdev, &fence); if (r) { DRM_ERROR("Failed to create VRAM->GTT fence %d\n", i); goto out_cleanup; } r = radeon_copy(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, fence); if (r) { DRM_ERROR("Failed VRAM->GTT copy %d\n", i); goto out_cleanup; } r = radeon_fence_wait(fence, false); if (r) { DRM_ERROR("Failed to wait for VRAM->GTT fence %d\n", i); goto out_cleanup; } radeon_fence_unref(&fence); r = radeon_object_kmap(gtt_obj[i], >t_map); if (r) { DRM_ERROR("Failed to map GTT object after copy %d\n", i); goto out_cleanup; } for (gtt_start = gtt_map, gtt_end = gtt_map + size, vram_start = vram_map, vram_end = vram_map + size; gtt_start < gtt_end; gtt_start++, vram_start++) { if (*gtt_start != vram_start) { DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, " "expected 0x%p (VRAM map 0x%p-0x%p)\n", i, *gtt_start, vram_start, vram_map, vram_end); radeon_object_kunmap(gtt_obj[i]); goto out_cleanup; } } radeon_object_kunmap(gtt_obj[i]); DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n", gtt_addr - rdev->mc.gtt_location); } out_cleanup: if (vram_obj) { radeon_object_unpin(vram_obj); radeon_object_unref(&vram_obj); } if (gtt_obj) { for (i = 0; i < n; i++) { if (gtt_obj[i]) { radeon_object_unpin(gtt_obj[i]); radeon_object_unref(>t_obj[i]); } } kfree(gtt_obj); } if (fence) { radeon_fence_unref(&fence); } if (r) { printk(KERN_WARNING "Error while testing BO move.\n"); } }