From 5ba7f950d16871a673a2da8b8e0e9a4bd56c4c61 Mon Sep 17 00:00:00 2001 From: Flora Cui Date: Fri, 19 Aug 2016 13:43:01 +0800 Subject: [PATCH 0768/4131] drm/amdgpu: reserve buffer in visible vram & gtt for direct gma Change-Id: I6ef5315bf8550ed82fd197cc5363b6de8356c882 Signed-off-by: Flora Cui Reviewed-by: Hawking Zhang Conflicts: drivers/gpu/drm/amd/amdgpu/amdgpu.h --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 10 ++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 83 +++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index a8a27ac..b7db1d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1390,6 +1390,15 @@ typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t); typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t); typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t); +struct amdgpu_direct_gma { + /* reserved in visible vram*/ + struct amdgpu_bo *dgma_bo; + atomic64_t vram_usage; + /* reserved in gart */ + struct ttm_mem_reg gart_mem; + atomic64_t gart_usage; +}; + #define AMDGPU_RESET_MAGIC_NUM 64 struct amdgpu_device { struct device *dev; @@ -1432,6 +1441,7 @@ struct amdgpu_device { uint8_t *bios; uint32_t bios_size; struct amdgpu_bo *stolen_vga_memory; + struct amdgpu_direct_gma direct_gma; uint32_t bios_scratch_reg_offset; uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH]; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 9e15cc3..8196fff 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1190,6 +1190,86 @@ static struct ttm_bo_driver amdgpu_bo_driver = { .access_memory = &amdgpu_ttm_access_memory }; +#define AMDGPU_DIRECT_GMA_SIZE_MAX 96 +static int amdgpu_direct_gma_init(struct amdgpu_device *adev) +{ + struct ttm_mem_type_manager *man = &adev->mman.bdev.man[TTM_PL_TT]; + struct ttm_mem_reg *mem = &adev->direct_gma.gart_mem; + struct amdgpu_bo *abo; + struct ttm_buffer_object gtt_bo; + struct ttm_place place = { + .fpfn = 0, + .lpfn = 0, + .flags = TTM_PL_FLAG_TOPDOWN + }; + unsigned long size; + int r; + + amdgpu_direct_gma_size = min(amdgpu_direct_gma_size, AMDGPU_DIRECT_GMA_SIZE_MAX); + if (amdgpu_direct_gma_size == 0) + return 0; + + size = (unsigned long)amdgpu_direct_gma_size << 20; + /* reserve in visible vram */ + r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | AMDGPU_GEM_CREATE_TOP_DOWN, + NULL, NULL, 0, &abo); + if (unlikely(r)) + goto error_out; + + r = amdgpu_bo_reserve(abo, false); + if (unlikely(r)) + goto error_free; + + r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM, NULL); + amdgpu_bo_unreserve(abo); + if (unlikely(r)) + goto error_free; + + adev->direct_gma.dgma_bo = abo; + + /* reserve in gtt */ + mem->size = size; + mem->mem_type = TTM_PL_TT; + mem->num_pages = size >> PAGE_SHIFT; + mem->page_alignment = PAGE_SIZE; + r = (*man->func->get_node)(man, >t_bo, &place, mem); + if (unlikely(r)) + goto error_free; + + adev->gart_pin_size += size; + DRM_INFO("%dMB VRAM/GTT reserved for Direct GMA\n", amdgpu_direct_gma_size); + return 0; + +error_free: + amdgpu_bo_unref(&abo); + +error_out: + amdgpu_direct_gma_size = 0; + memset(&adev->direct_gma, 0, sizeof(adev->direct_gma)); + DRM_ERROR("Fail to enable Direct GMA\n"); + return r; +} + +static void amdgpu_direct_gma_fini(struct amdgpu_device *adev) +{ + struct ttm_mem_type_manager *man = &adev->mman.bdev.man[TTM_PL_TT]; + int r; + + if (amdgpu_direct_gma_size == 0) + return; + + r = amdgpu_bo_reserve(adev->direct_gma.dgma_bo, false); + if (r == 0) { + amdgpu_bo_unpin(adev->direct_gma.dgma_bo); + amdgpu_bo_unreserve(adev->direct_gma.dgma_bo); + } + amdgpu_bo_unref(&adev->direct_gma.dgma_bo); + + (*man->func->put_node)(man, &adev->direct_gma.gart_mem); + adev->gart_pin_size -= (u64)amdgpu_direct_gma_size << 20; +} + int amdgpu_ttm_init(struct amdgpu_device *adev) { uint64_t gtt_size; @@ -1250,6 +1330,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) DRM_INFO("amdgpu: %uM of GTT memory ready.\n", (unsigned)(gtt_size / (1024 * 1024))); + amdgpu_direct_gma_init(adev); + adev->gds.mem.total_size = adev->gds.mem.total_size << AMDGPU_GDS_SHIFT; adev->gds.mem.gfx_partition_size = adev->gds.mem.gfx_partition_size << AMDGPU_GDS_SHIFT; adev->gds.mem.cs_partition_size = adev->gds.mem.cs_partition_size << AMDGPU_GDS_SHIFT; @@ -1312,6 +1394,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev) } amdgpu_bo_unref(&adev->stolen_vga_memory); } + amdgpu_direct_gma_fini(adev); ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_VRAM); ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_TT); if (adev->gds.mem.total_size) -- 2.7.4