summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-19 12:29:43 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-19 12:29:43 -0700
commit31cc088a4f5d83481c6f5041bd6eb06115b974af (patch)
treec08195d0f8de69e87e2e1f271130433e1c555ce0 /drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
parentdd4542d2823ac55cb86450960423f55e818aa182 (diff)
parent8ee795625665208589a97972b01790bb04ea83e3 (diff)
Merge tag 'drm-next-2019-07-19' of git://anongit.freedesktop.org/drm/drm
Pull drm fixes from Daniel Vetter: "Dave is back in shape, but now family got it so I'm doing the pull. Two things worthy of note: - nouveau feature pull was way too late, Dave&me decided to not take that, so Ben spun up a pull with just the fixes. - after some chatting with the arm display maintainers we decided to change a bit how that's maintained, for more oversight/review and cross vendor collab. More details below: nouveau: - bugfixes - TU116 enabling (minor iteration) :w amdgpu: - large pile of fixes for new hw support this release (navi, vega20) - audio hotplug fix - bunch of corner cases and small fixes all over for amdgpu/kfd komeda: - back out some new properties (from this merge window) that needs more pondering. bochs: - fb pitch setup core: - a new panel quirk - misc fixes" * tag 'drm-next-2019-07-19' of git://anongit.freedesktop.org/drm/drm: (73 commits) drm/nouveau/secboot/gp102-: remove WAR for SEC2 RTOS start bug drm/nouveau/flcn/gp102-: improve implementation of bind_context() on SEC2/GSP drm/nouveau: fix memory leak in nouveau_conn_reset() drm/nouveau/dmem: missing mutex_lock in error path drm/nouveau/hwmon: return EINVAL if the GPU is powered down for sensors reads drm/nouveau: fix bogus GPL-2 license header drm/nouveau: fix bogus GPL-2 license header drm/nouveau/i2c: Enable i2c pads & busses during preinit drm/nouveau/disp/tu102-: wire up scdc parameter setter drm/nouveau/core: recognise TU116 chipset drm/nouveau/kms: disallow dual-link harder if hdmi connection detected drm/nouveau/disp/nv50-: fix center/aspect-corrected scaling drm/nouveau/disp/nv50-: force scaler for any non-default LVDS/eDP modes drm/nouveau/mcp89/mmu: Use mcp77_mmu_new instead of g84_mmu_new on MCP89. drm/amd/display: init res_pool dccg_ref, dchub_ref with xtalin_freq drm/amdgpu/pm: remove check for pp funcs in freq sysfs handlers drm/amd/display: Force uclk to max for every state drm/amdkfd: Remove GWS from process during uninit drm/amd/amdgpu: Fix offset for vmid selection in debugfs interface drm/amd/powerplay: update vega20 driver if to fit latest SMU firmware ...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 5c05644b9b96..e51b48ac48eb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -391,6 +391,7 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
src_node_start = amdgpu_mm_node_addr(src->bo, ++src_mm,
src->mem);
src_node_size = (src_mm->size << PAGE_SHIFT);
+ src_page_offset = 0;
} else {
src_node_start += cur_size;
src_page_offset = src_node_start & (PAGE_SIZE - 1);
@@ -400,6 +401,7 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
dst_node_start = amdgpu_mm_node_addr(dst->bo, ++dst_mm,
dst->mem);
dst_node_size = (dst_mm->size << PAGE_SHIFT);
+ dst_page_offset = 0;
} else {
dst_node_start += cur_size;
dst_page_offset = dst_node_start & (PAGE_SIZE - 1);
@@ -487,6 +489,7 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict,
placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
r = ttm_bo_mem_space(bo, &placement, &tmp_mem, ctx);
if (unlikely(r)) {
+ pr_err("Failed to find GTT space for blit from VRAM\n");
return r;
}
@@ -545,6 +548,7 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict,
placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
r = ttm_bo_mem_space(bo, &placement, &tmp_mem, ctx);
if (unlikely(r)) {
+ pr_err("Failed to find GTT space for blit to VRAM\n");
return r;
}
@@ -565,6 +569,30 @@ out_cleanup:
}
/**
+ * amdgpu_mem_visible - Check that memory can be accessed by ttm_bo_move_memcpy
+ *
+ * Called by amdgpu_bo_move()
+ */
+static bool amdgpu_mem_visible(struct amdgpu_device *adev,
+ struct ttm_mem_reg *mem)
+{
+ struct drm_mm_node *nodes = mem->mm_node;
+
+ if (mem->mem_type == TTM_PL_SYSTEM ||
+ mem->mem_type == TTM_PL_TT)
+ return true;
+ if (mem->mem_type != TTM_PL_VRAM)
+ return false;
+
+ /* ttm_mem_reg_ioremap only supports contiguous memory */
+ if (nodes->size != mem->num_pages)
+ return false;
+
+ return ((nodes->start + nodes->size) << PAGE_SHIFT)
+ <= adev->gmc.visible_vram_size;
+}
+
+/**
* amdgpu_bo_move - Move a buffer object to a new memory location
*
* Called by ttm_bo_handle_move_mem()
@@ -608,8 +636,10 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
return 0;
}
- if (!adev->mman.buffer_funcs_enabled)
+ if (!adev->mman.buffer_funcs_enabled) {
+ r = -ENODEV;
goto memcpy;
+ }
if (old_mem->mem_type == TTM_PL_VRAM &&
new_mem->mem_type == TTM_PL_SYSTEM) {
@@ -624,10 +654,16 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
if (r) {
memcpy:
- r = ttm_bo_move_memcpy(bo, ctx, new_mem);
- if (r) {
+ /* Check that all memory is CPU accessible */
+ if (!amdgpu_mem_visible(adev, old_mem) ||
+ !amdgpu_mem_visible(adev, new_mem)) {
+ pr_err("Move buffer fallback to memcpy unavailable\n");
return r;
}
+
+ r = ttm_bo_move_memcpy(bo, ctx, new_mem);
+ if (r)
+ return r;
}
if (bo->type == ttm_bo_type_device &&
@@ -2059,9 +2095,9 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
mm_node = bo->tbo.mem.mm_node;
num_loops = 0;
while (num_pages) {
- uint32_t byte_count = mm_node->size << PAGE_SHIFT;
+ uint64_t byte_count = mm_node->size << PAGE_SHIFT;
- num_loops += DIV_ROUND_UP(byte_count, max_bytes);
+ num_loops += DIV_ROUND_UP_ULL(byte_count, max_bytes);
num_pages -= mm_node->size;
++mm_node;
}
@@ -2087,12 +2123,13 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
mm_node = bo->tbo.mem.mm_node;
while (num_pages) {
- uint32_t byte_count = mm_node->size << PAGE_SHIFT;
+ uint64_t byte_count = mm_node->size << PAGE_SHIFT;
uint64_t dst_addr;
dst_addr = amdgpu_mm_node_addr(&bo->tbo, mm_node, &bo->tbo.mem);
while (byte_count) {
- uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
+ uint32_t cur_size_in_bytes = min_t(uint64_t, byte_count,
+ max_bytes);
amdgpu_emit_fill_buffer(adev, &job->ibs[0], src_data,
dst_addr, cur_size_in_bytes);