diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index 707f85825996..1f51897acc5b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -68,9 +68,75 @@ */ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) { - return amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE, - AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.robj, - &adev->gart.table_addr, &adev->gart.ptr); + int r; + + if (adev->gart.robj == NULL) { + r = amdgpu_bo_create(adev, adev->gart.table_size, + PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, + NULL, NULL, 0, &adev->gart.robj); + if (r) { + return r; + } + } + return 0; +} + +/** + * amdgpu_gart_table_vram_pin - pin gart page table in vram + * + * @adev: amdgpu_device pointer + * + * Pin the GART page table in vram so it will not be moved + * by the memory manager (pcie r4xx, r5xx+). These asics require the + * gart table to be in video memory. + * Returns 0 for success, error for failure. + */ +int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev) +{ + uint64_t gpu_addr; + int r; + + r = amdgpu_bo_reserve(adev->gart.robj, false); + if (unlikely(r != 0)) + return r; + r = amdgpu_bo_pin(adev->gart.robj, + AMDGPU_GEM_DOMAIN_VRAM, &gpu_addr); + if (r) { + amdgpu_bo_unreserve(adev->gart.robj); + return r; + } + r = amdgpu_bo_kmap(adev->gart.robj, &adev->gart.ptr); + if (r) + amdgpu_bo_unpin(adev->gart.robj); + amdgpu_bo_unreserve(adev->gart.robj); + adev->gart.table_addr = gpu_addr; + return r; +} + +/** + * amdgpu_gart_table_vram_unpin - unpin gart page table in vram + * + * @adev: amdgpu_device pointer + * + * Unpin the GART page table in vram (pcie r4xx, r5xx+). + * These asics require the gart table to be in video memory. + */ +void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev) +{ + int r; + + if (adev->gart.robj == NULL) { + return; + } + r = amdgpu_bo_reserve(adev->gart.robj, true); + if (likely(r == 0)) { + amdgpu_bo_kunmap(adev->gart.robj); + amdgpu_bo_unpin(adev->gart.robj); + amdgpu_bo_unreserve(adev->gart.robj); + adev->gart.ptr = NULL; + } } /** @@ -84,9 +150,10 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) */ void amdgpu_gart_table_vram_free(struct amdgpu_device *adev) { - amdgpu_bo_free_kernel(&adev->gart.robj, - &adev->gart.table_addr, - &adev->gart.ptr); + if (adev->gart.robj == NULL) { + return; + } + amdgpu_bo_unref(&adev->gart.robj); } /* |