diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 151 | 
1 files changed, 89 insertions, 62 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 6d08cde8443c..3526efa8960e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -191,14 +191,21 @@ int amdgpu_bo_create_reserved(struct amdgpu_device *adev,  			      u32 domain, struct amdgpu_bo **bo_ptr,  			      u64 *gpu_addr, void **cpu_addr)  { +	struct amdgpu_bo_param bp;  	bool free = false;  	int r; +	memset(&bp, 0, sizeof(bp)); +	bp.size = size; +	bp.byte_align = align; +	bp.domain = domain; +	bp.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | +		AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; +	bp.type = ttm_bo_type_kernel; +	bp.resv = NULL; +  	if (!*bo_ptr) { -		r = amdgpu_bo_create(adev, size, align, domain, -				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | -				     AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, -				     ttm_bo_type_kernel, NULL, bo_ptr); +		r = amdgpu_bo_create(adev, &bp, bo_ptr);  		if (r) {  			dev_err(adev->dev, "(%d) failed to allocate kernel bo\n",  				r); @@ -341,27 +348,25 @@ fail:  	return false;  } -static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size, -			       int byte_align, u32 domain, -			       u64 flags, enum ttm_bo_type type, -			       struct reservation_object *resv, +static int amdgpu_bo_do_create(struct amdgpu_device *adev, +			       struct amdgpu_bo_param *bp,  			       struct amdgpu_bo **bo_ptr)  {  	struct ttm_operation_ctx ctx = { -		.interruptible = (type != ttm_bo_type_kernel), +		.interruptible = (bp->type != ttm_bo_type_kernel),  		.no_wait_gpu = false, -		.resv = resv, +		.resv = bp->resv,  		.flags = TTM_OPT_FLAG_ALLOW_RES_EVICT  	};  	struct amdgpu_bo *bo; -	unsigned long page_align; +	unsigned long page_align, size = bp->size;  	size_t acc_size;  	int r; -	page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; +	page_align = roundup(bp->byte_align, PAGE_SIZE) >> PAGE_SHIFT;  	size = ALIGN(size, PAGE_SIZE); -	if (!amdgpu_bo_validate_size(adev, size, domain)) +	if (!amdgpu_bo_validate_size(adev, size, bp->domain))  		return -ENOMEM;  	*bo_ptr = NULL; @@ -375,18 +380,14 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size,  	drm_gem_private_object_init(adev->ddev, &bo->gem_base, size);  	INIT_LIST_HEAD(&bo->shadow_list);  	INIT_LIST_HEAD(&bo->va); -	bo->preferred_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM | -					 AMDGPU_GEM_DOMAIN_GTT | -					 AMDGPU_GEM_DOMAIN_CPU | -					 AMDGPU_GEM_DOMAIN_GDS | -					 AMDGPU_GEM_DOMAIN_GWS | -					 AMDGPU_GEM_DOMAIN_OA); +	bo->preferred_domains = bp->preferred_domain ? bp->preferred_domain : +		bp->domain;  	bo->allowed_domains = bo->preferred_domains; -	if (type != ttm_bo_type_kernel && +	if (bp->type != ttm_bo_type_kernel &&  	    bo->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)  		bo->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT; -	bo->flags = flags; +	bo->flags = bp->flags;  #ifdef CONFIG_X86_32  	/* XXX: Write-combined CPU mappings of GTT seem broken on 32-bit @@ -417,11 +418,13 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size,  #endif  	bo->tbo.bdev = &adev->mman.bdev; -	amdgpu_ttm_placement_from_domain(bo, domain); +	amdgpu_ttm_placement_from_domain(bo, bp->domain); +	if (bp->type == ttm_bo_type_kernel) +		bo->tbo.priority = 1; -	r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type, +	r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, bp->type,  				 &bo->placement, page_align, &ctx, acc_size, -				 NULL, resv, &amdgpu_ttm_bo_destroy); +				 NULL, bp->resv, &amdgpu_ttm_bo_destroy);  	if (unlikely(r != 0))  		return r; @@ -433,10 +436,7 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size,  	else  		amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved, 0); -	if (type == ttm_bo_type_kernel) -		bo->tbo.priority = 1; - -	if (flags & AMDGPU_GEM_CREATE_VRAM_CLEARED && +	if (bp->flags & AMDGPU_GEM_CREATE_VRAM_CLEARED &&  	    bo->tbo.mem.placement & TTM_PL_FLAG_VRAM) {  		struct dma_fence *fence; @@ -449,20 +449,20 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size,  		bo->tbo.moving = dma_fence_get(fence);  		dma_fence_put(fence);  	} -	if (!resv) +	if (!bp->resv)  		amdgpu_bo_unreserve(bo);  	*bo_ptr = bo;  	trace_amdgpu_bo_create(bo);  	/* Treat CPU_ACCESS_REQUIRED only as a hint if given by UMD */ -	if (type == ttm_bo_type_device) +	if (bp->type == ttm_bo_type_device)  		bo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;  	return 0;  fail_unreserve: -	if (!resv) +	if (!bp->resv)  		ww_mutex_unlock(&bo->tbo.resv->lock);  	amdgpu_bo_unref(&bo);  	return r; @@ -472,16 +472,22 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,  				   unsigned long size, int byte_align,  				   struct amdgpu_bo *bo)  { +	struct amdgpu_bo_param bp;  	int r;  	if (bo->shadow)  		return 0; -	r = amdgpu_bo_do_create(adev, size, byte_align, AMDGPU_GEM_DOMAIN_GTT, -				AMDGPU_GEM_CREATE_CPU_GTT_USWC | -				AMDGPU_GEM_CREATE_SHADOW, -				ttm_bo_type_kernel, -				bo->tbo.resv, &bo->shadow); +	memset(&bp, 0, sizeof(bp)); +	bp.size = size; +	bp.byte_align = byte_align; +	bp.domain = AMDGPU_GEM_DOMAIN_GTT; +	bp.flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC | +		AMDGPU_GEM_CREATE_SHADOW; +	bp.type = ttm_bo_type_kernel; +	bp.resv = bo->tbo.resv; + +	r = amdgpu_bo_do_create(adev, &bp, &bo->shadow);  	if (!r) {  		bo->shadow->parent = amdgpu_bo_ref(bo);  		mutex_lock(&adev->shadow_list_lock); @@ -492,28 +498,26 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,  	return r;  } -int amdgpu_bo_create(struct amdgpu_device *adev, unsigned long size, -		     int byte_align, u32 domain, -		     u64 flags, enum ttm_bo_type type, -		     struct reservation_object *resv, +int amdgpu_bo_create(struct amdgpu_device *adev, +		     struct amdgpu_bo_param *bp,  		     struct amdgpu_bo **bo_ptr)  { -	uint64_t parent_flags = flags & ~AMDGPU_GEM_CREATE_SHADOW; +	u64 flags = bp->flags;  	int r; -	r = amdgpu_bo_do_create(adev, size, byte_align, domain, -				parent_flags, type, resv, bo_ptr); +	bp->flags = bp->flags & ~AMDGPU_GEM_CREATE_SHADOW; +	r = amdgpu_bo_do_create(adev, bp, bo_ptr);  	if (r)  		return r;  	if ((flags & AMDGPU_GEM_CREATE_SHADOW) && amdgpu_need_backup(adev)) { -		if (!resv) +		if (!bp->resv)  			WARN_ON(reservation_object_lock((*bo_ptr)->tbo.resv,  							NULL)); -		r = amdgpu_bo_create_shadow(adev, size, byte_align, (*bo_ptr)); +		r = amdgpu_bo_create_shadow(adev, bp->size, bp->byte_align, (*bo_ptr)); -		if (!resv) +		if (!bp->resv)  			reservation_object_unlock((*bo_ptr)->tbo.resv);  		if (r) @@ -689,8 +693,17 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,  		return -EINVAL;  	/* A shared bo cannot be migrated to VRAM */ -	if (bo->prime_shared_count && (domain == AMDGPU_GEM_DOMAIN_VRAM)) -		return -EINVAL; +	if (bo->prime_shared_count) { +		if (domain & AMDGPU_GEM_DOMAIN_GTT) +			domain = AMDGPU_GEM_DOMAIN_GTT; +		else +			return -EINVAL; +	} + +	/* This assumes only APU display buffers are pinned with (VRAM|GTT). +	 * See function amdgpu_display_supported_domains() +	 */ +	domain = amdgpu_bo_get_preferred_pin_domain(adev, domain);  	if (bo->pin_count) {  		uint32_t mem_type = bo->tbo.mem.mem_type; @@ -749,8 +762,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,  	domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);  	if (domain == AMDGPU_GEM_DOMAIN_VRAM) {  		adev->vram_pin_size += amdgpu_bo_size(bo); -		if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) -			adev->invisible_pin_size += amdgpu_bo_size(bo); +		adev->invisible_pin_size += amdgpu_vram_mgr_bo_invisible_size(bo);  	} else if (domain == AMDGPU_GEM_DOMAIN_GTT) {  		adev->gart_pin_size += amdgpu_bo_size(bo);  	} @@ -777,25 +789,22 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo)  	bo->pin_count--;  	if (bo->pin_count)  		return 0; -	for (i = 0; i < bo->placement.num_placement; i++) { -		bo->placements[i].lpfn = 0; -		bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; -	} -	r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); -	if (unlikely(r)) { -		dev_err(adev->dev, "%p validate failed for unpin\n", bo); -		goto error; -	}  	if (bo->tbo.mem.mem_type == TTM_PL_VRAM) {  		adev->vram_pin_size -= amdgpu_bo_size(bo); -		if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) -			adev->invisible_pin_size -= amdgpu_bo_size(bo); +		adev->invisible_pin_size -= amdgpu_vram_mgr_bo_invisible_size(bo);  	} else if (bo->tbo.mem.mem_type == TTM_PL_TT) {  		adev->gart_pin_size -= amdgpu_bo_size(bo);  	} -error: +	for (i = 0; i < bo->placement.num_placement; i++) { +		bo->placements[i].lpfn = 0; +		bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; +	} +	r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); +	if (unlikely(r)) +		dev_err(adev->dev, "%p validate failed for unpin\n", bo); +  	return r;  } @@ -838,6 +847,13 @@ int amdgpu_bo_init(struct amdgpu_device *adev)  	return amdgpu_ttm_init(adev);  } +int amdgpu_bo_late_init(struct amdgpu_device *adev) +{ +	amdgpu_ttm_late_init(adev); + +	return 0; +} +  void amdgpu_bo_fini(struct amdgpu_device *adev)  {  	amdgpu_ttm_fini(adev); @@ -1042,3 +1058,14 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)  	return bo->tbo.offset;  } + +uint32_t amdgpu_bo_get_preferred_pin_domain(struct amdgpu_device *adev, +					    uint32_t domain) +{ +	if (domain == (AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT)) { +		domain = AMDGPU_GEM_DOMAIN_VRAM; +		if (adev->gmc.real_vram_size <= AMDGPU_SG_THRESHOLD) +			domain = AMDGPU_GEM_DOMAIN_GTT; +	} +	return domain; +}  |