From d38ceaf99ed015f2a0b9af3499791bd3a3daae21 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 20 Apr 2015 16:55:21 -0400 Subject: drm/amdgpu: add core driver (v4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds the non-asic specific core driver code. v2: remove extra kconfig option v3: implement minor fixes from Fengguang Wu v4: fix cast in amdgpu_ucode.c Acked-by: Christian König Acked-by: Jammy Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 646 +++++++++++++++++++++++++++++ 1 file changed, 646 insertions(+) create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c new file mode 100644 index 000000000000..b51582714c21 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -0,0 +1,646 @@ +/* + * Copyright 2009 Jerome Glisse. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + */ +/* + * Authors: + * Jerome Glisse + * Thomas Hellstrom + * Dave Airlie + */ +#include +#include +#include +#include +#include "amdgpu.h" +#include "amdgpu_trace.h" + + +int amdgpu_ttm_init(struct amdgpu_device *adev); +void amdgpu_ttm_fini(struct amdgpu_device *adev); + +static u64 amdgpu_get_vis_part_size(struct amdgpu_device *adev, + struct ttm_mem_reg * mem) +{ + u64 ret = 0; + if (mem->start << PAGE_SHIFT < adev->mc.visible_vram_size) { + ret = (u64)((mem->start << PAGE_SHIFT) + mem->size) > + adev->mc.visible_vram_size ? + adev->mc.visible_vram_size - (mem->start << PAGE_SHIFT): + mem->size; + } + return ret; +} + +static void amdgpu_update_memory_usage(struct amdgpu_device *adev, + struct ttm_mem_reg *old_mem, + struct ttm_mem_reg *new_mem) +{ + u64 vis_size; + if (!adev) + return; + + if (new_mem) { + switch (new_mem->mem_type) { + case TTM_PL_TT: + atomic64_add(new_mem->size, &adev->gtt_usage); + break; + case TTM_PL_VRAM: + atomic64_add(new_mem->size, &adev->vram_usage); + vis_size = amdgpu_get_vis_part_size(adev, new_mem); + atomic64_add(vis_size, &adev->vram_vis_usage); + break; + } + } + + if (old_mem) { + switch (old_mem->mem_type) { + case TTM_PL_TT: + atomic64_sub(old_mem->size, &adev->gtt_usage); + break; + case TTM_PL_VRAM: + atomic64_sub(old_mem->size, &adev->vram_usage); + vis_size = amdgpu_get_vis_part_size(adev, old_mem); + atomic64_sub(vis_size, &adev->vram_vis_usage); + break; + } + } +} + +static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) +{ + struct amdgpu_bo *bo; + + bo = container_of(tbo, struct amdgpu_bo, tbo); + + amdgpu_update_memory_usage(bo->adev, &bo->tbo.mem, NULL); + amdgpu_mn_unregister(bo); + + mutex_lock(&bo->adev->gem.mutex); + list_del_init(&bo->list); + mutex_unlock(&bo->adev->gem.mutex); + drm_gem_object_release(&bo->gem_base); + kfree(bo->metadata); + kfree(bo); +} + +bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo) +{ + if (bo->destroy == &amdgpu_ttm_bo_destroy) + return true; + return false; +} + +void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain) +{ + u32 c = 0, i; + rbo->placement.placement = rbo->placements; + rbo->placement.busy_placement = rbo->placements; + + if (domain & AMDGPU_GEM_DOMAIN_VRAM) { + if (rbo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS && + rbo->adev->mc.visible_vram_size < rbo->adev->mc.real_vram_size) { + rbo->placements[c].fpfn = + rbo->adev->mc.visible_vram_size >> PAGE_SHIFT; + rbo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | + TTM_PL_FLAG_VRAM; + } + rbo->placements[c].fpfn = 0; + rbo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | + TTM_PL_FLAG_VRAM; + } + + if (domain & AMDGPU_GEM_DOMAIN_GTT) { + if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_UC) { + rbo->placements[c].fpfn = 0; + rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_TT; + } else if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_WC) { + rbo->placements[c].fpfn = 0; + rbo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT | + TTM_PL_FLAG_UNCACHED; + } else { + rbo->placements[c].fpfn = 0; + rbo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_TT; + } + } + + if (domain & AMDGPU_GEM_DOMAIN_CPU) { + if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_UC) { + rbo->placements[c].fpfn = 0; + rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_SYSTEM; + } else if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_WC) { + rbo->placements[c].fpfn = 0; + rbo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_SYSTEM | + TTM_PL_FLAG_UNCACHED; + } else { + rbo->placements[c].fpfn = 0; + rbo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM; + } + } + + if (domain & AMDGPU_GEM_DOMAIN_GDS) { + rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | + AMDGPU_PL_FLAG_GDS; + } + if (domain & AMDGPU_GEM_DOMAIN_GWS) { + rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | + AMDGPU_PL_FLAG_GWS; + } + if (domain & AMDGPU_GEM_DOMAIN_OA) { + rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | + AMDGPU_PL_FLAG_OA; + } + + if (!c) { + rbo->placements[c].fpfn = 0; + rbo->placements[c++].flags = TTM_PL_MASK_CACHING | + TTM_PL_FLAG_SYSTEM; + } + rbo->placement.num_placement = c; + rbo->placement.num_busy_placement = c; + + for (i = 0; i < c; i++) { + if ((rbo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && + (rbo->placements[i].flags & TTM_PL_FLAG_VRAM) && + !rbo->placements[i].fpfn) + rbo->placements[i].lpfn = + rbo->adev->mc.visible_vram_size >> PAGE_SHIFT; + else + rbo->placements[i].lpfn = 0; + } + + if (rbo->tbo.mem.size > 512 * 1024) { + for (i = 0; i < c; i++) { + rbo->placements[i].flags |= TTM_PL_FLAG_TOPDOWN; + } + } +} + +int amdgpu_bo_create(struct amdgpu_device *adev, + unsigned long size, int byte_align, bool kernel, u32 domain, u64 flags, + struct sg_table *sg, struct amdgpu_bo **bo_ptr) +{ + struct amdgpu_bo *bo; + enum ttm_bo_type type; + unsigned long page_align; + size_t acc_size; + int r; + + /* VI has a hw bug where VM PTEs have to be allocated in groups of 8. + * do this as a temporary workaround + */ + if (!(domain & (AMDGPU_GEM_DOMAIN_GDS | AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA))) { + if (adev->asic_type >= CHIP_TOPAZ) { + if (byte_align & 0x7fff) + byte_align = ALIGN(byte_align, 0x8000); + if (size & 0x7fff) + size = ALIGN(size, 0x8000); + } + } + + page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + size = ALIGN(size, PAGE_SIZE); + + if (kernel) { + type = ttm_bo_type_kernel; + } else if (sg) { + type = ttm_bo_type_sg; + } else { + type = ttm_bo_type_device; + } + *bo_ptr = NULL; + + acc_size = ttm_bo_dma_acc_size(&adev->mman.bdev, size, + sizeof(struct amdgpu_bo)); + + bo = kzalloc(sizeof(struct amdgpu_bo), GFP_KERNEL); + if (bo == NULL) + return -ENOMEM; + r = drm_gem_object_init(adev->ddev, &bo->gem_base, size); + if (unlikely(r)) { + kfree(bo); + return r; + } + bo->adev = adev; + INIT_LIST_HEAD(&bo->list); + INIT_LIST_HEAD(&bo->va); + bo->initial_domain = 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->flags = flags; + amdgpu_ttm_placement_from_domain(bo, domain); + /* Kernel allocation are uninterruptible */ + down_read(&adev->pm.mclk_lock); + r = ttm_bo_init(&adev->mman.bdev, &bo->tbo, size, type, + &bo->placement, page_align, !kernel, NULL, + acc_size, sg, NULL, &amdgpu_ttm_bo_destroy); + up_read(&adev->pm.mclk_lock); + if (unlikely(r != 0)) { + return r; + } + *bo_ptr = bo; + + trace_amdgpu_bo_create(bo); + + return 0; +} + +int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) +{ + bool is_iomem; + int r; + + if (bo->kptr) { + if (ptr) { + *ptr = bo->kptr; + } + return 0; + } + r = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap); + if (r) { + return r; + } + bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); + if (ptr) { + *ptr = bo->kptr; + } + return 0; +} + +void amdgpu_bo_kunmap(struct amdgpu_bo *bo) +{ + if (bo->kptr == NULL) + return; + bo->kptr = NULL; + ttm_bo_kunmap(&bo->kmap); +} + +struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo) +{ + if (bo == NULL) + return NULL; + + ttm_bo_reference(&bo->tbo); + return bo; +} + +void amdgpu_bo_unref(struct amdgpu_bo **bo) +{ + struct ttm_buffer_object *tbo; + + if ((*bo) == NULL) + return; + + tbo = &((*bo)->tbo); + ttm_bo_unref(&tbo); + if (tbo == NULL) + *bo = NULL; +} + +int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, u64 max_offset, + u64 *gpu_addr) +{ + int r, i; + + if (amdgpu_ttm_tt_has_userptr(bo->tbo.ttm)) + return -EPERM; + + if (bo->pin_count) { + bo->pin_count++; + if (gpu_addr) + *gpu_addr = amdgpu_bo_gpu_offset(bo); + + if (max_offset != 0) { + u64 domain_start; + + if (domain == AMDGPU_GEM_DOMAIN_VRAM) + domain_start = bo->adev->mc.vram_start; + else + domain_start = bo->adev->mc.gtt_start; + WARN_ON_ONCE(max_offset < + (amdgpu_bo_gpu_offset(bo) - domain_start)); + } + + return 0; + } + amdgpu_ttm_placement_from_domain(bo, domain); + for (i = 0; i < bo->placement.num_placement; i++) { + /* force to pin into visible video ram */ + if ((bo->placements[i].flags & TTM_PL_FLAG_VRAM) && + !(bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) && + (!max_offset || max_offset > bo->adev->mc.visible_vram_size)) + bo->placements[i].lpfn = + bo->adev->mc.visible_vram_size >> PAGE_SHIFT; + else + bo->placements[i].lpfn = max_offset >> PAGE_SHIFT; + + bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; + } + + r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); + if (likely(r == 0)) { + bo->pin_count = 1; + if (gpu_addr != NULL) + *gpu_addr = amdgpu_bo_gpu_offset(bo); + if (domain == AMDGPU_GEM_DOMAIN_VRAM) + bo->adev->vram_pin_size += amdgpu_bo_size(bo); + else + bo->adev->gart_pin_size += amdgpu_bo_size(bo); + } else { + dev_err(bo->adev->dev, "%p pin failed\n", bo); + } + return r; +} + +int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain, u64 *gpu_addr) +{ + return amdgpu_bo_pin_restricted(bo, domain, 0, gpu_addr); +} + +int amdgpu_bo_unpin(struct amdgpu_bo *bo) +{ + int r, i; + + if (!bo->pin_count) { + dev_warn(bo->adev->dev, "%p unpin not necessary\n", bo); + return 0; + } + 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, false, false); + if (likely(r == 0)) { + if (bo->tbo.mem.mem_type == TTM_PL_VRAM) + bo->adev->vram_pin_size -= amdgpu_bo_size(bo); + else + bo->adev->gart_pin_size -= amdgpu_bo_size(bo); + } else { + dev_err(bo->adev->dev, "%p validate failed for unpin\n", bo); + } + return r; +} + +int amdgpu_bo_evict_vram(struct amdgpu_device *adev) +{ + /* late 2.6.33 fix IGP hibernate - we need pm ops to do this correct */ + if (0 && (adev->flags & AMDGPU_IS_APU)) { + /* Useless to evict on IGP chips */ + return 0; + } + return ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_VRAM); +} + +void amdgpu_bo_force_delete(struct amdgpu_device *adev) +{ + struct amdgpu_bo *bo, *n; + + if (list_empty(&adev->gem.objects)) { + return; + } + dev_err(adev->dev, "Userspace still has active objects !\n"); + list_for_each_entry_safe(bo, n, &adev->gem.objects, list) { + mutex_lock(&adev->ddev->struct_mutex); + dev_err(adev->dev, "%p %p %lu %lu force free\n", + &bo->gem_base, bo, (unsigned long)bo->gem_base.size, + *((unsigned long *)&bo->gem_base.refcount)); + mutex_lock(&bo->adev->gem.mutex); + list_del_init(&bo->list); + mutex_unlock(&bo->adev->gem.mutex); + /* this should unref the ttm bo */ + drm_gem_object_unreference(&bo->gem_base); + mutex_unlock(&adev->ddev->struct_mutex); + } +} + +int amdgpu_bo_init(struct amdgpu_device *adev) +{ + /* Add an MTRR for the VRAM */ + adev->mc.vram_mtrr = arch_phys_wc_add(adev->mc.aper_base, + adev->mc.aper_size); + DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n", + adev->mc.mc_vram_size >> 20, + (unsigned long long)adev->mc.aper_size >> 20); + DRM_INFO("RAM width %dbits DDR\n", + adev->mc.vram_width); + return amdgpu_ttm_init(adev); +} + +void amdgpu_bo_fini(struct amdgpu_device *adev) +{ + amdgpu_ttm_fini(adev); + arch_phys_wc_del(adev->mc.vram_mtrr); +} + +int amdgpu_bo_fbdev_mmap(struct amdgpu_bo *bo, + struct vm_area_struct *vma) +{ + return ttm_fbdev_mmap(vma, &bo->tbo); +} + +int amdgpu_bo_set_tiling_flags(struct amdgpu_bo *bo, u64 tiling_flags) +{ + unsigned bankw, bankh, mtaspect, tilesplit, stilesplit; + + bankw = (tiling_flags >> AMDGPU_TILING_EG_BANKW_SHIFT) & AMDGPU_TILING_EG_BANKW_MASK; + bankh = (tiling_flags >> AMDGPU_TILING_EG_BANKH_SHIFT) & AMDGPU_TILING_EG_BANKH_MASK; + mtaspect = (tiling_flags >> AMDGPU_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & AMDGPU_TILING_EG_MACRO_TILE_ASPECT_MASK; + tilesplit = (tiling_flags >> AMDGPU_TILING_EG_TILE_SPLIT_SHIFT) & AMDGPU_TILING_EG_TILE_SPLIT_MASK; + stilesplit = (tiling_flags >> AMDGPU_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & AMDGPU_TILING_EG_STENCIL_TILE_SPLIT_MASK; + switch (bankw) { + case 0: + case 1: + case 2: + case 4: + case 8: + break; + default: + return -EINVAL; + } + switch (bankh) { + case 0: + case 1: + case 2: + case 4: + case 8: + break; + default: + return -EINVAL; + } + switch (mtaspect) { + case 0: + case 1: + case 2: + case 4: + case 8: + break; + default: + return -EINVAL; + } + if (tilesplit > 6) { + return -EINVAL; + } + if (stilesplit > 6) { + return -EINVAL; + } + + bo->tiling_flags = tiling_flags; + return 0; +} + +void amdgpu_bo_get_tiling_flags(struct amdgpu_bo *bo, u64 *tiling_flags) +{ + lockdep_assert_held(&bo->tbo.resv->lock.base); + + if (tiling_flags) + *tiling_flags = bo->tiling_flags; +} + +int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata, + uint32_t metadata_size, uint64_t flags) +{ + void *buffer; + + if (!metadata_size) { + if (bo->metadata_size) { + kfree(bo->metadata); + bo->metadata_size = 0; + } + return 0; + } + + if (metadata == NULL) + return -EINVAL; + + buffer = kzalloc(metadata_size, GFP_KERNEL); + if (buffer == NULL) + return -ENOMEM; + + memcpy(buffer, metadata, metadata_size); + + kfree(bo->metadata); + bo->metadata_flags = flags; + bo->metadata = buffer; + bo->metadata_size = metadata_size; + + return 0; +} + +int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, + size_t buffer_size, uint32_t *metadata_size, + uint64_t *flags) +{ + if (!buffer && !metadata_size) + return -EINVAL; + + if (buffer) { + if (buffer_size < bo->metadata_size) + return -EINVAL; + + if (bo->metadata_size) + memcpy(buffer, bo->metadata, bo->metadata_size); + } + + if (metadata_size) + *metadata_size = bo->metadata_size; + if (flags) + *flags = bo->metadata_flags; + + return 0; +} + +void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, + struct ttm_mem_reg *new_mem) +{ + struct amdgpu_bo *rbo; + + if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) + return; + + rbo = container_of(bo, struct amdgpu_bo, tbo); + amdgpu_vm_bo_invalidate(rbo->adev, rbo); + + /* update statistics */ + if (!new_mem) + return; + + /* move_notify is called before move happens */ + amdgpu_update_memory_usage(rbo->adev, &bo->mem, new_mem); +} + +int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) +{ + struct amdgpu_device *adev; + struct amdgpu_bo *rbo; + unsigned long offset, size; + int r; + + if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) + return 0; + rbo = container_of(bo, struct amdgpu_bo, tbo); + adev = rbo->adev; + if (bo->mem.mem_type == TTM_PL_VRAM) { + size = bo->mem.num_pages << PAGE_SHIFT; + offset = bo->mem.start << PAGE_SHIFT; + if ((offset + size) > adev->mc.visible_vram_size) { + /* hurrah the memory is not visible ! */ + amdgpu_ttm_placement_from_domain(rbo, AMDGPU_GEM_DOMAIN_VRAM); + rbo->placements[0].lpfn = adev->mc.visible_vram_size >> PAGE_SHIFT; + r = ttm_bo_validate(bo, &rbo->placement, false, false); + if (unlikely(r != 0)) + return r; + offset = bo->mem.start << PAGE_SHIFT; + /* this should not happen */ + if ((offset + size) > adev->mc.visible_vram_size) + return -EINVAL; + } + } + return 0; +} + +/** + * amdgpu_bo_fence - add fence to buffer object + * + * @bo: buffer object in question + * @fence: fence to add + * @shared: true if fence should be added shared + * + */ +void amdgpu_bo_fence(struct amdgpu_bo *bo, struct amdgpu_fence *fence, + bool shared) +{ + struct reservation_object *resv = bo->tbo.resv; + + if (shared) + reservation_object_add_shared_fence(resv, &fence->base); + else + reservation_object_add_excl_fence(resv, &fence->base); +} -- cgit v1.2.2 From 2d8bd23a057234ce8e540a3a08f4e67abcc551a8 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 22 Apr 2015 14:00:49 -0400 Subject: drm/amdgpu: drop ttm two ended allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amdgpu_bo_create() calls amdgpu_ttm_placement_from_domain() before ttm_bo_init() is called. amdgpu_ttm_placement_from_domain() uses the ttm bo size to determine when to select top down allocation but since the ttm bo is not initialized yet the check is always false. It only took affect when buffers were validated later. It also seemed to regress suspend and resume on some systems possibly due to it not taking affect in amdgpu_bo_create(). amdgpu_bo_create() and amdgpu_ttm_placement_from_domain() need to be reworked substantially for this to be optimally effective. Re-enable it at that point. Ported from radeon commit: a239118a24b3bf9089751068e431dfb63dc4168b Signed-off-by: Alex Deucher Reviewed-by: Michel Dänzer Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index b51582714c21..f5e17f95e812 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -189,12 +189,6 @@ void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain) else rbo->placements[i].lpfn = 0; } - - if (rbo->tbo.mem.size > 512 * 1024) { - for (i = 0; i < c; i++) { - rbo->placements[i].flags |= TTM_PL_FLAG_TOPDOWN; - } - } } int amdgpu_bo_create(struct amdgpu_device *adev, -- cgit v1.2.2 From 886712881da15b7f455c43a4ce4121f20035c0fa Mon Sep 17 00:00:00 2001 From: Jammy Zhou Date: Wed, 6 May 2015 18:44:29 +0800 Subject: drm/amdgpu: remove AMDGPU_GEM_CREATE_CPU_GTT_UC This flag isn't used by user mode drivers, remove it to avoid confusion. And rename GTT_WC to GTT_USWC to make it clear. Signed-off-by: Jammy Zhou Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index f5e17f95e812..992b7f5843bc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -132,10 +132,7 @@ void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain) } if (domain & AMDGPU_GEM_DOMAIN_GTT) { - if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_UC) { - rbo->placements[c].fpfn = 0; - rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_TT; - } else if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_WC) { + if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) { rbo->placements[c].fpfn = 0; rbo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT | TTM_PL_FLAG_UNCACHED; @@ -146,10 +143,7 @@ void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain) } if (domain & AMDGPU_GEM_DOMAIN_CPU) { - if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_UC) { - rbo->placements[c].fpfn = 0; - rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_SYSTEM; - } else if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_WC) { + if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) { rbo->placements[c].fpfn = 0; rbo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_UNCACHED; -- cgit v1.2.2 From 271c81256612b162a9ae0f8c0f0a055a7523cea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 13 May 2015 14:30:53 +0200 Subject: drm/amdgpu: enforce AMDGPU_GEM_CREATE_NO_CPU_ACCESS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deny user and kernel mapping if we said we never want to do so. Signed-off-by: Christian König Reviewed-by: Jammy Zhou Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 992b7f5843bc..a721f5044557 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -263,6 +263,9 @@ int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) bool is_iomem; int r; + if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) + return -EPERM; + if (bo->kptr) { if (ptr) { *ptr = bo->kptr; -- cgit v1.2.2 From fbd76d59efe061c89d4ba14eef3a2cac1e3056c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 14 May 2015 23:48:26 +0200 Subject: drm/amdgpu: rework tiling flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marek Olšák Reviewed-by: Alex Deucher Acked-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 43 +----------------------------- 1 file changed, 1 insertion(+), 42 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index a721f5044557..b545f614628c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -459,49 +459,8 @@ int amdgpu_bo_fbdev_mmap(struct amdgpu_bo *bo, int amdgpu_bo_set_tiling_flags(struct amdgpu_bo *bo, u64 tiling_flags) { - unsigned bankw, bankh, mtaspect, tilesplit, stilesplit; - - bankw = (tiling_flags >> AMDGPU_TILING_EG_BANKW_SHIFT) & AMDGPU_TILING_EG_BANKW_MASK; - bankh = (tiling_flags >> AMDGPU_TILING_EG_BANKH_SHIFT) & AMDGPU_TILING_EG_BANKH_MASK; - mtaspect = (tiling_flags >> AMDGPU_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & AMDGPU_TILING_EG_MACRO_TILE_ASPECT_MASK; - tilesplit = (tiling_flags >> AMDGPU_TILING_EG_TILE_SPLIT_SHIFT) & AMDGPU_TILING_EG_TILE_SPLIT_MASK; - stilesplit = (tiling_flags >> AMDGPU_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & AMDGPU_TILING_EG_STENCIL_TILE_SPLIT_MASK; - switch (bankw) { - case 0: - case 1: - case 2: - case 4: - case 8: - break; - default: + if (AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT) > 6) return -EINVAL; - } - switch (bankh) { - case 0: - case 1: - case 2: - case 4: - case 8: - break; - default: - return -EINVAL; - } - switch (mtaspect) { - case 0: - case 1: - case 2: - case 4: - case 8: - break; - default: - return -EINVAL; - } - if (tilesplit > 6) { - return -EINVAL; - } - if (stilesplit > 6) { - return -EINVAL; - } bo->tiling_flags = tiling_flags; return 0; -- cgit v1.2.2 From 5fb1941d0ce70d8ce56b12edcb1a1f2ba07629dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 21 May 2015 17:03:46 +0200 Subject: drm/amdgpu: port fault_reserve_notify changes from radeon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 55 +++++++++++++++++++----------- 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index b545f614628c..dcc6af97f59d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -549,30 +549,45 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) { struct amdgpu_device *adev; - struct amdgpu_bo *rbo; - unsigned long offset, size; - int r; + struct amdgpu_bo *abo; + unsigned long offset, size, lpfn; + int i, r; if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) return 0; - rbo = container_of(bo, struct amdgpu_bo, tbo); - adev = rbo->adev; - if (bo->mem.mem_type == TTM_PL_VRAM) { - size = bo->mem.num_pages << PAGE_SHIFT; - offset = bo->mem.start << PAGE_SHIFT; - if ((offset + size) > adev->mc.visible_vram_size) { - /* hurrah the memory is not visible ! */ - amdgpu_ttm_placement_from_domain(rbo, AMDGPU_GEM_DOMAIN_VRAM); - rbo->placements[0].lpfn = adev->mc.visible_vram_size >> PAGE_SHIFT; - r = ttm_bo_validate(bo, &rbo->placement, false, false); - if (unlikely(r != 0)) - return r; - offset = bo->mem.start << PAGE_SHIFT; - /* this should not happen */ - if ((offset + size) > adev->mc.visible_vram_size) - return -EINVAL; - } + + abo = container_of(bo, struct amdgpu_bo, tbo); + adev = abo->adev; + if (bo->mem.mem_type != TTM_PL_VRAM) + return 0; + + size = bo->mem.num_pages << PAGE_SHIFT; + offset = bo->mem.start << PAGE_SHIFT; + if ((offset + size) <= adev->mc.visible_vram_size) + return 0; + + /* hurrah the memory is not visible ! */ + amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM); + lpfn = adev->mc.visible_vram_size >> PAGE_SHIFT; + for (i = 0; i < abo->placement.num_placement; i++) { + /* Force into visible VRAM */ + if ((abo->placements[i].flags & TTM_PL_FLAG_VRAM) && + (!abo->placements[i].lpfn || abo->placements[i].lpfn > lpfn)) + abo->placements[i].lpfn = lpfn; + } + r = ttm_bo_validate(bo, &abo->placement, false, false); + if (unlikely(r == -ENOMEM)) { + amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT); + return ttm_bo_validate(bo, &abo->placement, false, false); + } else if (unlikely(r != 0)) { + return r; } + + offset = bo->mem.start << PAGE_SHIFT; + /* this should never happen */ + if ((offset + size) > adev->mc.visible_vram_size) + return -EINVAL; + return 0; } -- cgit v1.2.2 From 7e5a547f64af66fd906f266f0e8c9bde213d025c Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Fri, 24 Apr 2015 17:37:30 +0800 Subject: drm/amdgpu: implement the allocation range (v3) Pass a ttm_placement pointer to amdgpu_bo_create_restricted add min_offset to amdgpu_bo_pin_restricted. This makes it easier to allocate memory with address restrictions. With this patch we can also enable 2-ended allocation again. v2: fix rebase conflicts v3: memset placements before using Reviewed-by: Jammy Zhou Signed-off-by: Chunming Zhou Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 176 +++++++++++++++++++---------- 1 file changed, 119 insertions(+), 57 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index dcc6af97f59d..62cabfb5dff8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -41,13 +41,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev); void amdgpu_ttm_fini(struct amdgpu_device *adev); static u64 amdgpu_get_vis_part_size(struct amdgpu_device *adev, - struct ttm_mem_reg * mem) + struct ttm_mem_reg *mem) { u64 ret = 0; if (mem->start << PAGE_SHIFT < adev->mc.visible_vram_size) { ret = (u64)((mem->start << PAGE_SHIFT) + mem->size) > adev->mc.visible_vram_size ? - adev->mc.visible_vram_size - (mem->start << PAGE_SHIFT): + adev->mc.visible_vram_size - (mem->start << PAGE_SHIFT) : mem->size; } return ret; @@ -112,82 +112,111 @@ bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo) return false; } -void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain) +static void amdgpu_ttm_placement_init(struct amdgpu_device *adev, + struct ttm_placement *placement, + struct ttm_place *placements, + u32 domain, u64 flags) { u32 c = 0, i; - rbo->placement.placement = rbo->placements; - rbo->placement.busy_placement = rbo->placements; + + placement->placement = placements; + placement->busy_placement = placements; if (domain & AMDGPU_GEM_DOMAIN_VRAM) { - if (rbo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS && - rbo->adev->mc.visible_vram_size < rbo->adev->mc.real_vram_size) { - rbo->placements[c].fpfn = - rbo->adev->mc.visible_vram_size >> PAGE_SHIFT; - rbo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | - TTM_PL_FLAG_VRAM; + if (flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS && + adev->mc.visible_vram_size < adev->mc.real_vram_size) { + placements[c].fpfn = + adev->mc.visible_vram_size >> PAGE_SHIFT; + placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | + TTM_PL_FLAG_VRAM; } - rbo->placements[c].fpfn = 0; - rbo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | - TTM_PL_FLAG_VRAM; + placements[c].fpfn = 0; + placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | + TTM_PL_FLAG_VRAM; } if (domain & AMDGPU_GEM_DOMAIN_GTT) { - if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) { - rbo->placements[c].fpfn = 0; - rbo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT | - TTM_PL_FLAG_UNCACHED; + if (flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) { + placements[c].fpfn = 0; + placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT | + TTM_PL_FLAG_UNCACHED; } else { - rbo->placements[c].fpfn = 0; - rbo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_TT; + placements[c].fpfn = 0; + placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_TT; } } if (domain & AMDGPU_GEM_DOMAIN_CPU) { - if (rbo->flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) { - rbo->placements[c].fpfn = 0; - rbo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_SYSTEM | - TTM_PL_FLAG_UNCACHED; + if (flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) { + placements[c].fpfn = 0; + placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_SYSTEM | + TTM_PL_FLAG_UNCACHED; } else { - rbo->placements[c].fpfn = 0; - rbo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM; + placements[c].fpfn = 0; + placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM; } } if (domain & AMDGPU_GEM_DOMAIN_GDS) { - rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | - AMDGPU_PL_FLAG_GDS; + placements[c].fpfn = 0; + placements[c++].flags = TTM_PL_FLAG_UNCACHED | + AMDGPU_PL_FLAG_GDS; } if (domain & AMDGPU_GEM_DOMAIN_GWS) { - rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | - AMDGPU_PL_FLAG_GWS; + placements[c].fpfn = 0; + placements[c++].flags = TTM_PL_FLAG_UNCACHED | + AMDGPU_PL_FLAG_GWS; } if (domain & AMDGPU_GEM_DOMAIN_OA) { - rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | - AMDGPU_PL_FLAG_OA; + placements[c].fpfn = 0; + placements[c++].flags = TTM_PL_FLAG_UNCACHED | + AMDGPU_PL_FLAG_OA; } if (!c) { - rbo->placements[c].fpfn = 0; - rbo->placements[c++].flags = TTM_PL_MASK_CACHING | - TTM_PL_FLAG_SYSTEM; + placements[c].fpfn = 0; + placements[c++].flags = TTM_PL_MASK_CACHING | + TTM_PL_FLAG_SYSTEM; } - rbo->placement.num_placement = c; - rbo->placement.num_busy_placement = c; + placement->num_placement = c; + placement->num_busy_placement = c; for (i = 0; i < c; i++) { - if ((rbo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && - (rbo->placements[i].flags & TTM_PL_FLAG_VRAM) && - !rbo->placements[i].fpfn) - rbo->placements[i].lpfn = - rbo->adev->mc.visible_vram_size >> PAGE_SHIFT; + if ((flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && + (placements[i].flags & TTM_PL_FLAG_VRAM) && + !placements[i].fpfn) + placements[i].lpfn = + adev->mc.visible_vram_size >> PAGE_SHIFT; else - rbo->placements[i].lpfn = 0; + placements[i].lpfn = 0; } } -int amdgpu_bo_create(struct amdgpu_device *adev, - unsigned long size, int byte_align, bool kernel, u32 domain, u64 flags, - struct sg_table *sg, struct amdgpu_bo **bo_ptr) +void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain) +{ + amdgpu_ttm_placement_init(rbo->adev, &rbo->placement, + rbo->placements, domain, rbo->flags); +} + +static void amdgpu_fill_placement_to_bo(struct amdgpu_bo *bo, + struct ttm_placement *placement) +{ + BUG_ON(placement->num_placement > (AMDGPU_GEM_DOMAIN_MAX + 1)); + + memcpy(bo->placements, placement->placement, + placement->num_placement * sizeof(struct ttm_place)); + bo->placement.num_placement = placement->num_placement; + bo->placement.num_busy_placement = placement->num_busy_placement; + bo->placement.placement = bo->placements; + bo->placement.busy_placement = bo->placements; +} + +int amdgpu_bo_create_restricted(struct amdgpu_device *adev, + unsigned long size, int byte_align, + bool kernel, u32 domain, u64 flags, + struct sg_table *sg, + struct ttm_placement *placement, + struct amdgpu_bo **bo_ptr) { struct amdgpu_bo *bo; enum ttm_bo_type type; @@ -241,7 +270,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev, AMDGPU_GEM_DOMAIN_OA); bo->flags = flags; - amdgpu_ttm_placement_from_domain(bo, domain); + amdgpu_fill_placement_to_bo(bo, placement); /* Kernel allocation are uninterruptible */ down_read(&adev->pm.mclk_lock); r = ttm_bo_init(&adev->mman.bdev, &bo->tbo, size, type, @@ -258,6 +287,27 @@ int amdgpu_bo_create(struct amdgpu_device *adev, return 0; } +int amdgpu_bo_create(struct amdgpu_device *adev, + unsigned long size, int byte_align, + bool kernel, u32 domain, u64 flags, + struct sg_table *sg, struct amdgpu_bo **bo_ptr) +{ + struct ttm_placement placement = {0}; + struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1]; + + memset(&placements, 0, + (AMDGPU_GEM_DOMAIN_MAX + 1) * sizeof(struct ttm_place)); + + amdgpu_ttm_placement_init(adev, &placement, + placements, domain, flags); + + return amdgpu_bo_create_restricted(adev, size, byte_align, + kernel, domain, flags, + sg, + &placement, + bo_ptr); +} + int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) { bool is_iomem; @@ -313,14 +363,19 @@ void amdgpu_bo_unref(struct amdgpu_bo **bo) *bo = NULL; } -int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, u64 max_offset, +int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, + u64 min_offset, u64 max_offset, u64 *gpu_addr) { int r, i; + unsigned fpfn, lpfn; if (amdgpu_ttm_tt_has_userptr(bo->tbo.ttm)) return -EPERM; + if (WARN_ON_ONCE(min_offset > max_offset)) + return -EINVAL; + if (bo->pin_count) { bo->pin_count++; if (gpu_addr) @@ -328,7 +383,6 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, u64 max_offset, if (max_offset != 0) { u64 domain_start; - if (domain == AMDGPU_GEM_DOMAIN_VRAM) domain_start = bo->adev->mc.vram_start; else @@ -343,13 +397,21 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, u64 max_offset, for (i = 0; i < bo->placement.num_placement; i++) { /* force to pin into visible video ram */ if ((bo->placements[i].flags & TTM_PL_FLAG_VRAM) && - !(bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) && - (!max_offset || max_offset > bo->adev->mc.visible_vram_size)) - bo->placements[i].lpfn = - bo->adev->mc.visible_vram_size >> PAGE_SHIFT; - else - bo->placements[i].lpfn = max_offset >> PAGE_SHIFT; - + !(bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) && + (!max_offset || max_offset > bo->adev->mc.visible_vram_size)) { + if (WARN_ON_ONCE(min_offset > + bo->adev->mc.visible_vram_size)) + return -EINVAL; + fpfn = min_offset >> PAGE_SHIFT; + lpfn = bo->adev->mc.visible_vram_size >> PAGE_SHIFT; + } else { + fpfn = min_offset >> PAGE_SHIFT; + lpfn = max_offset >> PAGE_SHIFT; + } + if (fpfn > bo->placements[i].fpfn) + bo->placements[i].fpfn = fpfn; + if (lpfn && lpfn < bo->placements[i].lpfn) + bo->placements[i].lpfn = lpfn; bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; } @@ -370,7 +432,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, u64 max_offset, int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain, u64 *gpu_addr) { - return amdgpu_bo_pin_restricted(bo, domain, 0, gpu_addr); + return amdgpu_bo_pin_restricted(bo, domain, 0, 0, gpu_addr); } int amdgpu_bo_unpin(struct amdgpu_bo *bo) -- cgit v1.2.2 From e176fe176d3a02d9409e0f36502799083ae13e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 27 May 2015 10:22:47 +0200 Subject: drm/amdgpu: remove mclk_lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not needed any more. Signed-off-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 62cabfb5dff8..7d801e016e31 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -272,11 +272,9 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev, bo->flags = flags; amdgpu_fill_placement_to_bo(bo, placement); /* Kernel allocation are uninterruptible */ - down_read(&adev->pm.mclk_lock); r = ttm_bo_init(&adev->mman.bdev, &bo->tbo, size, type, &bo->placement, page_align, !kernel, NULL, acc_size, sg, NULL, &amdgpu_ttm_bo_destroy); - up_read(&adev->pm.mclk_lock); if (unlikely(r != 0)) { return r; } -- cgit v1.2.2