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.3-59-g8ed1b 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.3-59-g8ed1b 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 ++-------- include/uapi/drm/amdgpu_drm.h | 7 ++----- 2 files changed, 4 insertions(+), 13 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; diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 9e771fb858b4..77bc5740fd7c 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -73,15 +73,12 @@ #define AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED (1 << 0) /* Flag that CPU access will not work, this VRAM domain is invisible */ #define AMDGPU_GEM_CREATE_NO_CPU_ACCESS (1 << 1) -/* Flag that un-cached attributes should be used for GTT */ -#define AMDGPU_GEM_CREATE_CPU_GTT_UC (1 << 2) /* Flag that USWC attributes should be used for GTT */ -#define AMDGPU_GEM_CREATE_CPU_GTT_WC (1 << 3) +#define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2) /* Flag mask for GTT domain_flags */ #define AMDGPU_GEM_CREATE_CPU_GTT_MASK \ - (AMDGPU_GEM_CREATE_CPU_GTT_WC | \ - AMDGPU_GEM_CREATE_CPU_GTT_UC | \ + (AMDGPU_GEM_CREATE_CPU_GTT_USWC | \ AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | \ AMDGPU_GEM_CREATE_NO_CPU_ACCESS) -- cgit v1.2.3-59-g8ed1b From 271c81256612b162a9ae0f8c0f0a055a7523cea5 Mon Sep 17 00:00:00 2001 From: Christian König 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_gem.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 5fd0bc73b302..8dd843da799f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -316,7 +316,8 @@ int amdgpu_mode_dumb_mmap(struct drm_file *filp, return -ENOENT; } robj = gem_to_amdgpu_bo(gobj); - if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm)) { + if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm) || + (robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) { drm_gem_object_unreference_unlocked(gobj); return -EPERM; } 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.3-59-g8ed1b From fbd76d59efe061c89d4ba14eef3a2cac1e3056c2 Mon Sep 17 00:00:00 2001 From: Marek Olšák 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_fb.c | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 43 +------------- drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 92 ++++------------------------- drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 93 ++++-------------------------- drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 91 ++++------------------------- include/uapi/drm/amdgpu_drm.h | 40 +++++++------ 6 files changed, 58 insertions(+), 304 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index ef611986b2b6..73b7aad5a872 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -32,6 +32,7 @@ #include #include #include "amdgpu.h" +#include "cikd.h" #include @@ -135,7 +136,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, rbo = gem_to_amdgpu_bo(gobj); if (fb_tiled) - tiling_flags = AMDGPU_TILING_MACRO; + tiling_flags = AMDGPU_TILING_SET(ARRAY_MODE, GRPH_ARRAY_2D_TILED_THIN1); ret = amdgpu_bo_reserve(rbo, false); if (unlikely(ret != 0)) 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; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index d412291ed70e..37b96236fe2c 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -2008,61 +2008,6 @@ static void dce_v10_0_grph_enable(struct drm_crtc *crtc, bool enable) WREG32(mmGRPH_ENABLE + amdgpu_crtc->crtc_offset, 0); } -static void dce_v10_0_tiling_fields(uint64_t tiling_flags, unsigned *bankw, - unsigned *bankh, unsigned *mtaspect, - unsigned *tile_split) -{ - *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; - *tile_split = (tiling_flags >> AMDGPU_TILING_EG_TILE_SPLIT_SHIFT) & AMDGPU_TILING_EG_TILE_SPLIT_MASK; - switch (*bankw) { - default: - case 1: - *bankw = ADDR_SURF_BANK_WIDTH_1; - break; - case 2: - *bankw = ADDR_SURF_BANK_WIDTH_2; - break; - case 4: - *bankw = ADDR_SURF_BANK_WIDTH_4; - break; - case 8: - *bankw = ADDR_SURF_BANK_WIDTH_8; - break; - } - switch (*bankh) { - default: - case 1: - *bankh = ADDR_SURF_BANK_HEIGHT_1; - break; - case 2: - *bankh = ADDR_SURF_BANK_HEIGHT_2; - break; - case 4: - *bankh = ADDR_SURF_BANK_HEIGHT_4; - break; - case 8: - *bankh = ADDR_SURF_BANK_HEIGHT_8; - break; - } - switch (*mtaspect) { - default: - case 1: - *mtaspect = ADDR_SURF_MACRO_ASPECT_1; - break; - case 2: - *mtaspect = ADDR_SURF_MACRO_ASPECT_2; - break; - case 4: - *mtaspect = ADDR_SURF_MACRO_ASPECT_4; - break; - case 8: - *mtaspect = ADDR_SURF_MACRO_ASPECT_8; - break; - } -} - static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y, int atomic) @@ -2076,10 +2021,8 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, struct amdgpu_bo *rbo; uint64_t fb_location, tiling_flags; uint32_t fb_format, fb_pitch_pixels; - unsigned bankw, bankh, mtaspect, tile_split; u32 fb_swap = REG_SET_FIELD(0, GRPH_SWAP_CNTL, GRPH_ENDIAN_SWAP, ENDIAN_NONE); - /* XXX change to VI */ - u32 pipe_config = (adev->gfx.config.tile_mode_array[10] >> 6) & 0x1f; + u32 pipe_config; u32 tmp, viewport_w, viewport_h; int r; bool bypass_lut = false; @@ -2121,6 +2064,8 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, amdgpu_bo_get_tiling_flags(rbo, &tiling_flags); amdgpu_bo_unreserve(rbo); + pipe_config = AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG); + switch (target_fb->pixel_format) { case DRM_FORMAT_C8: fb_format = REG_SET_FIELD(0, GRPH_CONTROL, GRPH_DEPTH, 0); @@ -2198,27 +2143,15 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, return -EINVAL; } - if (tiling_flags & AMDGPU_TILING_MACRO) { - unsigned tileb, index, num_banks, tile_split_bytes; - - dce_v10_0_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); - /* Set NUM_BANKS. */ - /* Calculate the macrotile mode index. */ - tile_split_bytes = 64 << tile_split; - tileb = 8 * 8 * target_fb->bits_per_pixel / 8; - tileb = min(tile_split_bytes, tileb); + if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == ARRAY_2D_TILED_THIN1) { + unsigned bankw, bankh, mtaspect, tile_split, num_banks; - for (index = 0; tileb > 64; index++) { - tileb >>= 1; - } - - if (index >= 16) { - DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n", - target_fb->bits_per_pixel, tile_split); - return -EINVAL; - } + bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH); + bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT); + mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT); + tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT); + num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS); - num_banks = (adev->gfx.config.macrotile_mode_array[index] >> 6) & 0x3; fb_format = REG_SET_FIELD(fb_format, GRPH_CONTROL, GRPH_NUM_BANKS, num_banks); fb_format = REG_SET_FIELD(fb_format, GRPH_CONTROL, GRPH_ARRAY_MODE, ARRAY_2D_TILED_THIN1); @@ -2230,14 +2163,11 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, mtaspect); fb_format = REG_SET_FIELD(fb_format, GRPH_CONTROL, GRPH_MICRO_TILE_MODE, ADDR_SURF_MICRO_TILING_DISPLAY); - } else if (tiling_flags & AMDGPU_TILING_MICRO) { + } else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == ARRAY_1D_TILED_THIN1) { fb_format = REG_SET_FIELD(fb_format, GRPH_CONTROL, GRPH_ARRAY_MODE, ARRAY_1D_TILED_THIN1); } - /* Read the pipe config from the 2D TILED SCANOUT mode. - * It should be the same for the other modes too, but not all - * modes set the pipe config field. */ fb_format = REG_SET_FIELD(fb_format, GRPH_CONTROL, GRPH_PIPE_CONFIG, pipe_config); diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 55fef15a4fcf..04a5d4cd75b6 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -2006,61 +2006,6 @@ static void dce_v11_0_grph_enable(struct drm_crtc *crtc, bool enable) WREG32(mmGRPH_ENABLE + amdgpu_crtc->crtc_offset, 0); } -static void dce_v11_0_tiling_fields(uint64_t tiling_flags, unsigned *bankw, - unsigned *bankh, unsigned *mtaspect, - unsigned *tile_split) -{ - *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; - *tile_split = (tiling_flags >> AMDGPU_TILING_EG_TILE_SPLIT_SHIFT) & AMDGPU_TILING_EG_TILE_SPLIT_MASK; - switch (*bankw) { - default: - case 1: - *bankw = ADDR_SURF_BANK_WIDTH_1; - break; - case 2: - *bankw = ADDR_SURF_BANK_WIDTH_2; - break; - case 4: - *bankw = ADDR_SURF_BANK_WIDTH_4; - break; - case 8: - *bankw = ADDR_SURF_BANK_WIDTH_8; - break; - } - switch (*bankh) { - default: - case 1: - *bankh = ADDR_SURF_BANK_HEIGHT_1; - break; - case 2: - *bankh = ADDR_SURF_BANK_HEIGHT_2; - break; - case 4: - *bankh = ADDR_SURF_BANK_HEIGHT_4; - break; - case 8: - *bankh = ADDR_SURF_BANK_HEIGHT_8; - break; - } - switch (*mtaspect) { - default: - case 1: - *mtaspect = ADDR_SURF_MACRO_ASPECT_1; - break; - case 2: - *mtaspect = ADDR_SURF_MACRO_ASPECT_2; - break; - case 4: - *mtaspect = ADDR_SURF_MACRO_ASPECT_4; - break; - case 8: - *mtaspect = ADDR_SURF_MACRO_ASPECT_8; - break; - } -} - static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y, int atomic) @@ -2074,10 +2019,8 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc, struct amdgpu_bo *rbo; uint64_t fb_location, tiling_flags; uint32_t fb_format, fb_pitch_pixels; - unsigned bankw, bankh, mtaspect, tile_split; u32 fb_swap = REG_SET_FIELD(0, GRPH_SWAP_CNTL, GRPH_ENDIAN_SWAP, ENDIAN_NONE); - /* XXX change to VI */ - u32 pipe_config = (adev->gfx.config.tile_mode_array[10] >> 6) & 0x1f; + u32 pipe_config; u32 tmp, viewport_w, viewport_h; int r; bool bypass_lut = false; @@ -2119,6 +2062,8 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc, amdgpu_bo_get_tiling_flags(rbo, &tiling_flags); amdgpu_bo_unreserve(rbo); + pipe_config = AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG); + switch (target_fb->pixel_format) { case DRM_FORMAT_C8: fb_format = REG_SET_FIELD(0, GRPH_CONTROL, GRPH_DEPTH, 0); @@ -2196,28 +2141,15 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc, return -EINVAL; } - if (tiling_flags & AMDGPU_TILING_MACRO) { - unsigned tileb, index, num_banks, tile_split_bytes; - - dce_v11_0_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); - /* Set NUM_BANKS. */ - /* Calculate the macrotile mode index. */ - tile_split_bytes = 64 << tile_split; - tileb = 8 * 8 * target_fb->bits_per_pixel / 8; - tileb = min(tile_split_bytes, tileb); + if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == ARRAY_2D_TILED_THIN1) { + unsigned bankw, bankh, mtaspect, tile_split, num_banks; - for (index = 0; tileb > 64; index++) { - tileb >>= 1; - } - - if (index >= 16) { - DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n", - target_fb->bits_per_pixel, tile_split); - return -EINVAL; - } + bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH); + bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT); + mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT); + tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT); + num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS); - /* XXX fix me for VI */ - num_banks = (adev->gfx.config.macrotile_mode_array[index] >> 6) & 0x3; fb_format = REG_SET_FIELD(fb_format, GRPH_CONTROL, GRPH_NUM_BANKS, num_banks); fb_format = REG_SET_FIELD(fb_format, GRPH_CONTROL, GRPH_ARRAY_MODE, ARRAY_2D_TILED_THIN1); @@ -2229,14 +2161,11 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc, mtaspect); fb_format = REG_SET_FIELD(fb_format, GRPH_CONTROL, GRPH_MICRO_TILE_MODE, ADDR_SURF_MICRO_TILING_DISPLAY); - } else if (tiling_flags & AMDGPU_TILING_MICRO) { + } else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == ARRAY_1D_TILED_THIN1) { fb_format = REG_SET_FIELD(fb_format, GRPH_CONTROL, GRPH_ARRAY_MODE, ARRAY_1D_TILED_THIN1); } - /* Read the pipe config from the 2D TILED SCANOUT mode. - * It should be the same for the other modes too, but not all - * modes set the pipe config field. */ fb_format = REG_SET_FIELD(fb_format, GRPH_CONTROL, GRPH_PIPE_CONFIG, pipe_config); diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index c1bc6935c88e..9f2ff8d374f3 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -1976,61 +1976,6 @@ static void dce_v8_0_grph_enable(struct drm_crtc *crtc, bool enable) WREG32(mmGRPH_ENABLE + amdgpu_crtc->crtc_offset, 0); } -static void dce_v8_0_tiling_fields(uint64_t tiling_flags, unsigned *bankw, - unsigned *bankh, unsigned *mtaspect, - unsigned *tile_split) -{ - *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; - *tile_split = (tiling_flags >> AMDGPU_TILING_EG_TILE_SPLIT_SHIFT) & AMDGPU_TILING_EG_TILE_SPLIT_MASK; - switch (*bankw) { - default: - case 1: - *bankw = ADDR_SURF_BANK_WIDTH_1; - break; - case 2: - *bankw = ADDR_SURF_BANK_WIDTH_2; - break; - case 4: - *bankw = ADDR_SURF_BANK_WIDTH_4; - break; - case 8: - *bankw = ADDR_SURF_BANK_WIDTH_8; - break; - } - switch (*bankh) { - default: - case 1: - *bankh = ADDR_SURF_BANK_HEIGHT_1; - break; - case 2: - *bankh = ADDR_SURF_BANK_HEIGHT_2; - break; - case 4: - *bankh = ADDR_SURF_BANK_HEIGHT_4; - break; - case 8: - *bankh = ADDR_SURF_BANK_HEIGHT_8; - break; - } - switch (*mtaspect) { - default: - case 1: - *mtaspect = ADDR_SURF_MACRO_TILE_ASPECT_1; - break; - case 2: - *mtaspect = ADDR_SURF_MACRO_TILE_ASPECT_2; - break; - case 4: - *mtaspect = ADDR_SURF_MACRO_TILE_ASPECT_4; - break; - case 8: - *mtaspect = ADDR_SURF_MACRO_TILE_ASPECT_8; - break; - } -} - static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y, int atomic) @@ -2044,9 +1989,8 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc, struct amdgpu_bo *rbo; uint64_t fb_location, tiling_flags; uint32_t fb_format, fb_pitch_pixels; - unsigned bankw, bankh, mtaspect, tile_split; u32 fb_swap = (GRPH_ENDIAN_NONE << GRPH_SWAP_CNTL__GRPH_ENDIAN_SWAP__SHIFT); - u32 pipe_config = (adev->gfx.config.tile_mode_array[10] >> 6) & 0x1f; + u32 pipe_config; u32 tmp, viewport_w, viewport_h; int r; bool bypass_lut = false; @@ -2088,6 +2032,8 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc, amdgpu_bo_get_tiling_flags(rbo, &tiling_flags); amdgpu_bo_unreserve(rbo); + pipe_config = AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG); + switch (target_fb->pixel_format) { case DRM_FORMAT_C8: fb_format = ((GRPH_DEPTH_8BPP << GRPH_CONTROL__GRPH_DEPTH__SHIFT) | @@ -2158,27 +2104,15 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc, return -EINVAL; } - if (tiling_flags & AMDGPU_TILING_MACRO) { - unsigned tileb, index, num_banks, tile_split_bytes; - - dce_v8_0_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); - /* Set NUM_BANKS. */ - /* Calculate the macrotile mode index. */ - tile_split_bytes = 64 << tile_split; - tileb = 8 * 8 * target_fb->bits_per_pixel / 8; - tileb = min(tile_split_bytes, tileb); + if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == ARRAY_2D_TILED_THIN1) { + unsigned bankw, bankh, mtaspect, tile_split, num_banks; - for (index = 0; tileb > 64; index++) { - tileb >>= 1; - } - - if (index >= 16) { - DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n", - target_fb->bits_per_pixel, tile_split); - return -EINVAL; - } + bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH); + bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT); + mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT); + tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT); + num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS); - num_banks = (adev->gfx.config.macrotile_mode_array[index] >> 6) & 0x3; fb_format |= (num_banks << GRPH_CONTROL__GRPH_NUM_BANKS__SHIFT); fb_format |= (GRPH_ARRAY_2D_TILED_THIN1 << GRPH_CONTROL__GRPH_ARRAY_MODE__SHIFT); fb_format |= (tile_split << GRPH_CONTROL__GRPH_TILE_SPLIT__SHIFT); @@ -2186,13 +2120,10 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc, fb_format |= (bankh << GRPH_CONTROL__GRPH_BANK_HEIGHT__SHIFT); fb_format |= (mtaspect << GRPH_CONTROL__GRPH_MACRO_TILE_ASPECT__SHIFT); fb_format |= (DISPLAY_MICRO_TILING << GRPH_CONTROL__GRPH_MICRO_TILE_MODE__SHIFT); - } else if (tiling_flags & AMDGPU_TILING_MICRO) { + } else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == ARRAY_1D_TILED_THIN1) { fb_format |= (GRPH_ARRAY_1D_TILED_THIN1 << GRPH_CONTROL__GRPH_ARRAY_MODE__SHIFT); } - /* Read the pipe config from the 2D TILED SCANOUT mode. - * It should be the same for the other modes too, but not all - * modes set the pipe config field. */ fb_format |= (pipe_config << GRPH_CONTROL__GRPH_PIPE_CONFIG__SHIFT); dce_v8_0_vga_enable(crtc, false); diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 46580e950036..d9b9b6f8de2b 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -199,24 +199,28 @@ struct drm_amdgpu_gem_userptr { uint32_t handle; }; -#define AMDGPU_TILING_MACRO 0x1 -#define AMDGPU_TILING_MICRO 0x2 -#define AMDGPU_TILING_SWAP_16BIT 0x4 -#define AMDGPU_TILING_R600_NO_SCANOUT AMDGPU_TILING_SWAP_16BIT -#define AMDGPU_TILING_SWAP_32BIT 0x8 -/* this object requires a surface when mapped - i.e. front buffer */ -#define AMDGPU_TILING_SURFACE 0x10 -#define AMDGPU_TILING_MICRO_SQUARE 0x20 -#define AMDGPU_TILING_EG_BANKW_SHIFT 8 -#define AMDGPU_TILING_EG_BANKW_MASK 0xf -#define AMDGPU_TILING_EG_BANKH_SHIFT 12 -#define AMDGPU_TILING_EG_BANKH_MASK 0xf -#define AMDGPU_TILING_EG_MACRO_TILE_ASPECT_SHIFT 16 -#define AMDGPU_TILING_EG_MACRO_TILE_ASPECT_MASK 0xf -#define AMDGPU_TILING_EG_TILE_SPLIT_SHIFT 24 -#define AMDGPU_TILING_EG_TILE_SPLIT_MASK 0xf -#define AMDGPU_TILING_EG_STENCIL_TILE_SPLIT_SHIFT 28 -#define AMDGPU_TILING_EG_STENCIL_TILE_SPLIT_MASK 0xf +/* same meaning as the GB_TILE_MODE and GL_MACRO_TILE_MODE fields */ +#define AMDGPU_TILING_ARRAY_MODE_SHIFT 0 +#define AMDGPU_TILING_ARRAY_MODE_MASK 0xf +#define AMDGPU_TILING_PIPE_CONFIG_SHIFT 4 +#define AMDGPU_TILING_PIPE_CONFIG_MASK 0x1f +#define AMDGPU_TILING_TILE_SPLIT_SHIFT 9 +#define AMDGPU_TILING_TILE_SPLIT_MASK 0x7 +#define AMDGPU_TILING_MICRO_TILE_MODE_SHIFT 12 +#define AMDGPU_TILING_MICRO_TILE_MODE_MASK 0x7 +#define AMDGPU_TILING_BANK_WIDTH_SHIFT 15 +#define AMDGPU_TILING_BANK_WIDTH_MASK 0x3 +#define AMDGPU_TILING_BANK_HEIGHT_SHIFT 17 +#define AMDGPU_TILING_BANK_HEIGHT_MASK 0x3 +#define AMDGPU_TILING_MACRO_TILE_ASPECT_SHIFT 19 +#define AMDGPU_TILING_MACRO_TILE_ASPECT_MASK 0x3 +#define AMDGPU_TILING_NUM_BANKS_SHIFT 21 +#define AMDGPU_TILING_NUM_BANKS_MASK 0x3 + +#define AMDGPU_TILING_SET(field, value) \ + (((value) & AMDGPU_TILING_##field##_MASK) << AMDGPU_TILING_##field##_SHIFT) +#define AMDGPU_TILING_GET(value, field) \ + (((value) >> AMDGPU_TILING_##field##_SHIFT) & AMDGPU_TILING_##field##_MASK) #define AMDGPU_GEM_METADATA_OP_SET_METADATA 1 #define AMDGPU_GEM_METADATA_OP_GET_METADATA 2 -- cgit v1.2.3-59-g8ed1b From 5fb1941d0ce70d8ce56b12edcb1a1f2ba07629dd Mon Sep 17 00:00:00 2001 From: Christian König 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.3-59-g8ed1b 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.h | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 176 +++++++++++++++++++--------- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 9 +- drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 2 +- 8 files changed, 136 insertions(+), 64 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 80f0bea52e33..8eb5c5529304 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -43,6 +43,7 @@ #include #include +#include #include "amd_shared.h" #include "amdgpu_family.h" @@ -542,12 +543,14 @@ struct amdgpu_bo_va { struct amdgpu_bo *bo; }; +#define AMDGPU_GEM_DOMAIN_MAX 0x3 + struct amdgpu_bo { /* Protected by gem.mutex */ struct list_head list; /* Protected by tbo.reserved */ u32 initial_domain; - struct ttm_place placements[4]; + struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1]; struct ttm_placement placement; struct ttm_buffer_object tbo; struct ttm_bo_kmap_obj kmap; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index f22c0671c3eb..b16b9256883e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -159,7 +159,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc, goto cleanup; } - r = amdgpu_bo_pin_restricted(new_rbo, AMDGPU_GEM_DOMAIN_VRAM, 0, &base); + r = amdgpu_bo_pin_restricted(new_rbo, AMDGPU_GEM_DOMAIN_VRAM, 0, 0, &base); if (unlikely(r != 0)) { amdgpu_bo_unreserve(new_rbo); r = -EINVAL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index 73b7aad5a872..c1645d21f8e2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -150,7 +150,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, } - ret = amdgpu_bo_pin_restricted(rbo, AMDGPU_GEM_DOMAIN_VRAM, 0, NULL); + ret = amdgpu_bo_pin_restricted(rbo, AMDGPU_GEM_DOMAIN_VRAM, 0, 0, NULL); if (ret) { amdgpu_bo_unreserve(rbo); goto out_unref; 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) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index b1e0a03c1d78..675bdc30e41d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -130,13 +130,20 @@ int amdgpu_bo_create(struct amdgpu_device *adev, bool kernel, u32 domain, u64 flags, struct sg_table *sg, struct amdgpu_bo **bo_ptr); +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); int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr); void amdgpu_bo_kunmap(struct amdgpu_bo *bo); struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo); void amdgpu_bo_unref(struct amdgpu_bo **bo); int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain, u64 *gpu_addr); int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, - u64 max_offset, u64 *gpu_addr); + u64 min_offset, u64 max_offset, + u64 *gpu_addr); int amdgpu_bo_unpin(struct amdgpu_bo *bo); int amdgpu_bo_evict_vram(struct amdgpu_device *adev); void amdgpu_bo_force_delete(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index da9a4b9a1f6c..926c8e0789b0 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -2553,7 +2553,7 @@ static int dce_v10_0_crtc_cursor_set(struct drm_crtc *crtc, if (unlikely(ret != 0)) goto fail; ret = amdgpu_bo_pin_restricted(robj, AMDGPU_GEM_DOMAIN_VRAM, - 0, &gpu_addr); + 0, 0, &gpu_addr); amdgpu_bo_unreserve(robj); if (ret) goto fail; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index edd9d17ba82a..bc60fd1844f3 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -2552,7 +2552,7 @@ static int dce_v11_0_crtc_cursor_set(struct drm_crtc *crtc, if (unlikely(ret != 0)) goto fail; ret = amdgpu_bo_pin_restricted(robj, AMDGPU_GEM_DOMAIN_VRAM, - 0, &gpu_addr); + 0, 0, &gpu_addr); amdgpu_bo_unreserve(robj); if (ret) goto fail; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 1d291f1d5b79..9e8b9f1fad18 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -2496,7 +2496,7 @@ static int dce_v8_0_crtc_cursor_set(struct drm_crtc *crtc, if (unlikely(ret != 0)) goto fail; ret = amdgpu_bo_pin_restricted(robj, AMDGPU_GEM_DOMAIN_VRAM, - 0, &gpu_addr); + 0, 0, &gpu_addr); amdgpu_bo_unreserve(robj); if (ret) goto fail; -- cgit v1.2.3-59-g8ed1b From e176fe176d3a02d9409e0f36502799083ae13e1b Mon Sep 17 00:00:00 2001 From: Christian König 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.h | 2 -- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 -- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 2 -- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 40 +++--------------------------- 5 files changed, 4 insertions(+), 43 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 6c8c24ba463d..4300e3d4b1cd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1558,8 +1558,6 @@ struct amdgpu_dpm { struct amdgpu_pm { struct mutex mutex; - /* write locked while reprogramming mclk */ - struct rw_semaphore mclk_lock; u32 current_sclk; u32 current_mclk; u32 default_sclk; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 175dc67130c3..36be03ce76c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1401,7 +1401,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, mutex_init(&adev->gfx.gpu_clock_mutex); mutex_init(&adev->srbm_mutex); mutex_init(&adev->grbm_idx_mutex); - init_rwsem(&adev->pm.mclk_lock); init_rwsem(&adev->exclusive_lock); mutex_init(&adev->mn_lock); hash_init(adev->mn_hash); 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; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 89782543f854..605a9e42f943 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -581,7 +581,6 @@ force: } mutex_lock(&adev->ddev->struct_mutex); - down_write(&adev->pm.mclk_lock); mutex_lock(&adev->ring_lock); /* update whether vce is active */ @@ -629,7 +628,6 @@ force: done: mutex_unlock(&adev->ring_lock); - up_write(&adev->pm.mclk_lock); mutex_unlock(&adev->ddev->struct_mutex); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 729e0bb3070f..d3706a498293 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -966,52 +966,20 @@ void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size) man->size = size >> PAGE_SHIFT; } -static struct vm_operations_struct amdgpu_ttm_vm_ops; -static const struct vm_operations_struct *ttm_vm_ops = NULL; - -static int amdgpu_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct ttm_buffer_object *bo; - struct amdgpu_device *adev; - int r; - - bo = (struct ttm_buffer_object *)vma->vm_private_data; - if (bo == NULL) { - return VM_FAULT_NOPAGE; - } - adev = amdgpu_get_adev(bo->bdev); - down_read(&adev->pm.mclk_lock); - r = ttm_vm_ops->fault(vma, vmf); - up_read(&adev->pm.mclk_lock); - return r; -} - int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma) { struct drm_file *file_priv; struct amdgpu_device *adev; - int r; - if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) { + if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) return -EINVAL; - } file_priv = filp->private_data; adev = file_priv->minor->dev->dev_private; - if (adev == NULL) { + if (adev == NULL) return -EINVAL; - } - r = ttm_bo_mmap(filp, vma, &adev->mman.bdev); - if (unlikely(r != 0)) { - return r; - } - if (unlikely(ttm_vm_ops == NULL)) { - ttm_vm_ops = vma->vm_ops; - amdgpu_ttm_vm_ops = *ttm_vm_ops; - amdgpu_ttm_vm_ops.fault = &amdgpu_ttm_fault; - } - vma->vm_ops = &amdgpu_ttm_vm_ops; - return 0; + + return ttm_bo_mmap(filp, vma, &adev->mman.bdev); } int amdgpu_copy_buffer(struct amdgpu_ring *ring, -- cgit v1.2.3-59-g8ed1b