aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2020-09-23 09:49:48 +1000
committerDave Airlie <airlied@redhat.com>2020-09-23 09:52:24 +1000
commit6ea6be77086f23d4b346c9946dae24593befda2e (patch)
treedc3926a543ed2b8270aa111d97ee603970560eda /drivers/gpu/drm/radeon
parentMerge tag 'amd-drm-next-5.10-2020-09-18' of git://people.freedesktop.org/~agd5f/linux into drm-next (diff)
parentdrm/vc4: hvs: Pull the state of all the CRTCs prior to PV muxing (diff)
downloadlinux-dev-6ea6be77086f23d4b346c9946dae24593befda2e.tar.xz
linux-dev-6ea6be77086f23d4b346c9946dae24593befda2e.zip
Merge tag 'drm-misc-next-2020-09-21' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.10: UAPI Changes: Cross-subsystem Changes: - virtio: Merged a PR for patches that will affect drm/virtio Core Changes: - dev: More devm_drm convertions and removal of drm_dev_init - atomic: Split out drm_atomic_helper_calc_timestamping_constants of drm_atomic_helper_update_legacy_modeset_state - ttm: More rework Driver Changes: - i915: selftests improvements - panfrost: support for Amlogic SoC - vc4: one fix - tree-wide: conversions to devm_drm_dev_alloc, - ast: simplifications of the atomic modesetting code - panfrost: multiple fixes - vc4: multiple fixes Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <maxime@cerno.tech> Link: https://patchwork.freedesktop.org/patch/msgid/20200921152956.2gxnsdgxmwhvjyut@gilmour.lan
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h8
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_mn.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c44
-rw-r--r--drivers/gpu/drm/radeon/radeon_prime.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c226
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c2
8 files changed, 188 insertions, 106 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index cc4f58d16589..a6d8de01194a 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -2815,10 +2815,12 @@ extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enabl
extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain);
extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
-extern int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
+extern int radeon_ttm_tt_set_userptr(struct radeon_device *rdev,
+ struct ttm_tt *ttm, uint64_t addr,
uint32_t flags);
-extern bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm);
-extern bool radeon_ttm_tt_is_readonly(struct ttm_tt *ttm);
+extern bool radeon_ttm_tt_has_userptr(struct radeon_device *rdev, struct ttm_tt *ttm);
+extern bool radeon_ttm_tt_is_readonly(struct radeon_device *rdev, struct ttm_tt *ttm);
+bool radeon_ttm_tt_is_bound(struct ttm_bo_device *bdev, struct ttm_tt *ttm);
extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base);
extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
extern int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon);
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 33ae1b883268..21ce2f9502c0 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -160,7 +160,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
p->relocs[i].allowed_domains = domain;
}
- if (radeon_ttm_tt_has_userptr(p->relocs[i].robj->tbo.ttm)) {
+ if (radeon_ttm_tt_has_userptr(p->rdev, p->relocs[i].robj->tbo.ttm)) {
uint32_t domain = p->relocs[i].preferred_domains;
if (!(domain & RADEON_GEM_DOMAIN_GTT)) {
DRM_ERROR("Only RADEON_GEM_DOMAIN_GTT is "
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index 7f5dfe04789e..e5c4271e64ed 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -331,7 +331,7 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data,
goto handle_lockup;
bo = gem_to_radeon_bo(gobj);
- r = radeon_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags);
+ r = radeon_ttm_tt_set_userptr(rdev, bo->tbo.ttm, args->addr, args->flags);
if (r)
goto release_object;
@@ -420,7 +420,7 @@ int radeon_mode_dumb_mmap(struct drm_file *filp,
return -ENOENT;
}
robj = gem_to_radeon_bo(gobj);
- if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) {
+ if (radeon_ttm_tt_has_userptr(robj->rdev, robj->tbo.ttm)) {
drm_gem_object_put(gobj);
return -EPERM;
}
@@ -721,7 +721,7 @@ int radeon_gem_op_ioctl(struct drm_device *dev, void *data,
robj = gem_to_radeon_bo(gobj);
r = -EPERM;
- if (radeon_ttm_tt_has_userptr(robj->tbo.ttm))
+ if (radeon_ttm_tt_has_userptr(robj->rdev, robj->tbo.ttm))
goto out;
r = radeon_bo_reserve(robj, false);
diff --git a/drivers/gpu/drm/radeon/radeon_mn.c b/drivers/gpu/drm/radeon/radeon_mn.c
index f93829f08a4d..97b9b6dd6dd3 100644
--- a/drivers/gpu/drm/radeon/radeon_mn.c
+++ b/drivers/gpu/drm/radeon/radeon_mn.c
@@ -53,7 +53,7 @@ static bool radeon_mn_invalidate(struct mmu_interval_notifier *mn,
struct ttm_operation_ctx ctx = { false, false };
long r;
- if (!bo->tbo.ttm || bo->tbo.ttm->state != tt_bound)
+ if (!bo->tbo.ttm || !radeon_ttm_tt_is_bound(bo->tbo.bdev, bo->tbo.ttm))
return true;
if (!mmu_notifier_range_blockable(range))
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index bb7582afd803..316e35d3f8a9 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -112,58 +112,58 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
rbo->rdev->mc.visible_vram_size < rbo->rdev->mc.real_vram_size) {
rbo->placements[c].fpfn =
rbo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
+ rbo->placements[c].mem_type = TTM_PL_VRAM;
rbo->placements[c++].flags = TTM_PL_FLAG_WC |
- TTM_PL_FLAG_UNCACHED |
- TTM_PL_FLAG_VRAM;
+ TTM_PL_FLAG_UNCACHED;
}
rbo->placements[c].fpfn = 0;
+ rbo->placements[c].mem_type = TTM_PL_VRAM;
rbo->placements[c++].flags = TTM_PL_FLAG_WC |
- TTM_PL_FLAG_UNCACHED |
- TTM_PL_FLAG_VRAM;
+ TTM_PL_FLAG_UNCACHED;
}
if (domain & RADEON_GEM_DOMAIN_GTT) {
if (rbo->flags & RADEON_GEM_GTT_UC) {
rbo->placements[c].fpfn = 0;
- rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED |
- TTM_PL_FLAG_TT;
+ rbo->placements[c].mem_type = TTM_PL_TT;
+ rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED;
} else if ((rbo->flags & RADEON_GEM_GTT_WC) ||
(rbo->rdev->flags & RADEON_IS_AGP)) {
rbo->placements[c].fpfn = 0;
+ rbo->placements[c].mem_type = TTM_PL_TT;
rbo->placements[c++].flags = TTM_PL_FLAG_WC |
- TTM_PL_FLAG_UNCACHED |
- 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;
+ rbo->placements[c].mem_type = TTM_PL_TT;
+ rbo->placements[c++].flags = TTM_PL_FLAG_CACHED;
}
}
if (domain & RADEON_GEM_DOMAIN_CPU) {
if (rbo->flags & RADEON_GEM_GTT_UC) {
rbo->placements[c].fpfn = 0;
- rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED |
- TTM_PL_FLAG_SYSTEM;
+ rbo->placements[c].mem_type = TTM_PL_SYSTEM;
+ rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED;
} else if ((rbo->flags & RADEON_GEM_GTT_WC) ||
rbo->rdev->flags & RADEON_IS_AGP) {
rbo->placements[c].fpfn = 0;
+ rbo->placements[c].mem_type = TTM_PL_SYSTEM;
rbo->placements[c++].flags = TTM_PL_FLAG_WC |
- TTM_PL_FLAG_UNCACHED |
- 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;
+ rbo->placements[c].mem_type = TTM_PL_SYSTEM;
+ rbo->placements[c++].flags = TTM_PL_FLAG_CACHED;
}
}
if (!c) {
rbo->placements[c].fpfn = 0;
- rbo->placements[c++].flags = TTM_PL_MASK_CACHING |
- TTM_PL_FLAG_SYSTEM;
+ rbo->placements[c].mem_type = TTM_PL_SYSTEM;
+ rbo->placements[c++].flags = TTM_PL_MASK_CACHING;
}
rbo->placement.num_placement = c;
@@ -171,7 +171,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
for (i = 0; i < c; ++i) {
if ((rbo->flags & RADEON_GEM_CPU_ACCESS) &&
- (rbo->placements[i].flags & TTM_PL_FLAG_VRAM) &&
+ (rbo->placements[i].mem_type == TTM_PL_VRAM) &&
!rbo->placements[i].fpfn)
rbo->placements[i].lpfn =
rbo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
@@ -331,7 +331,7 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset,
struct ttm_operation_ctx ctx = { false, false };
int r, i;
- if (radeon_ttm_tt_has_userptr(bo->tbo.ttm))
+ if (radeon_ttm_tt_has_userptr(bo->rdev, bo->tbo.ttm))
return -EPERM;
if (bo->pin_count) {
@@ -360,7 +360,7 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset,
radeon_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) &&
+ if ((bo->placements[i].mem_type == TTM_PL_VRAM) &&
!(bo->flags & RADEON_GEM_NO_CPU_ACCESS) &&
(!max_offset || max_offset > bo->rdev->mc.visible_vram_size))
bo->placements[i].lpfn =
@@ -824,7 +824,7 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT;
for (i = 0; i < rbo->placement.num_placement; i++) {
/* Force into visible VRAM */
- if ((rbo->placements[i].flags & TTM_PL_FLAG_VRAM) &&
+ if ((rbo->placements[i].mem_type == TTM_PL_VRAM) &&
(!rbo->placements[i].lpfn || rbo->placements[i].lpfn > lpfn))
rbo->placements[i].lpfn = lpfn;
}
diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c
index b906e8fbd5f3..b9de0e51c0be 100644
--- a/drivers/gpu/drm/radeon/radeon_prime.c
+++ b/drivers/gpu/drm/radeon/radeon_prime.c
@@ -36,7 +36,7 @@ struct sg_table *radeon_gem_prime_get_sg_table(struct drm_gem_object *obj)
struct radeon_bo *bo = gem_to_radeon_bo(obj);
int npages = bo->tbo.num_pages;
- return drm_prime_pages_to_sg(bo->tbo.ttm->pages, npages);
+ return drm_prime_pages_to_sg(obj->dev, bo->tbo.ttm->pages, npages);
}
void *radeon_gem_prime_vmap(struct drm_gem_object *obj)
@@ -121,7 +121,7 @@ struct dma_buf *radeon_gem_prime_export(struct drm_gem_object *gobj,
int flags)
{
struct radeon_bo *bo = gem_to_radeon_bo(gobj);
- if (radeon_ttm_tt_has_userptr(bo->tbo.ttm))
+ if (radeon_ttm_tt_has_userptr(bo->rdev, bo->tbo.ttm))
return ERR_PTR(-EPERM);
return drm_gem_prime_export(gobj, flags);
}
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 74ad50c7491c..36150b7f31a9 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -56,6 +56,10 @@
static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
static void radeon_ttm_debugfs_fini(struct radeon_device *rdev);
+static int radeon_ttm_tt_bind(struct ttm_bo_device *bdev,
+ struct ttm_tt *ttm,
+ struct ttm_resource *bo_mem);
+
struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
{
struct radeon_mman *mman;
@@ -69,17 +73,13 @@ struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
static int radeon_ttm_init_vram(struct radeon_device *rdev)
{
return ttm_range_man_init(&rdev->mman.bdev, TTM_PL_VRAM,
- TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC,
- TTM_PL_FLAG_WC, false,
- rdev->mc.real_vram_size >> PAGE_SHIFT);
+ false, rdev->mc.real_vram_size >> PAGE_SHIFT);
}
static int radeon_ttm_init_gtt(struct radeon_device *rdev)
{
return ttm_range_man_init(&rdev->mman.bdev, TTM_PL_TT,
- TTM_PL_MASK_CACHING,
- TTM_PL_FLAG_CACHED, true,
- rdev->mc.gtt_size >> PAGE_SHIFT);
+ true, rdev->mc.gtt_size >> PAGE_SHIFT);
}
static void radeon_evict_flags(struct ttm_buffer_object *bo,
@@ -88,7 +88,8 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo,
static const struct ttm_place placements = {
.fpfn = 0,
.lpfn = 0,
- .flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM
+ .mem_type = TTM_PL_SYSTEM,
+ .flags = TTM_PL_MASK_CACHING
};
struct radeon_bo *rbo;
@@ -119,7 +120,7 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo,
RADEON_GEM_DOMAIN_GTT);
rbo->placement.num_busy_placement = 0;
for (i = 0; i < rbo->placement.num_placement; i++) {
- if (rbo->placements[i].flags & TTM_PL_FLAG_VRAM) {
+ if (rbo->placements[i].mem_type == TTM_PL_VRAM) {
if (rbo->placements[i].fpfn < fpfn)
rbo->placements[i].fpfn = fpfn;
} else {
@@ -141,23 +142,14 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo,
static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp)
{
struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo);
+ struct radeon_device *rdev = radeon_get_rdev(bo->bdev);
- if (radeon_ttm_tt_has_userptr(bo->ttm))
+ if (radeon_ttm_tt_has_userptr(rdev, bo->ttm))
return -EPERM;
return drm_vma_node_verify_access(&rbo->tbo.base.vma_node,
filp->private_data);
}
-static void radeon_move_null(struct ttm_buffer_object *bo,
- struct ttm_resource *new_mem)
-{
- struct ttm_resource *old_mem = &bo->mem;
-
- BUG_ON(old_mem->mm_node != NULL);
- *old_mem = *new_mem;
- new_mem->mm_node = NULL;
-}
-
static int radeon_move_blit(struct ttm_buffer_object *bo,
bool evict, bool no_wait_gpu,
struct ttm_resource *new_mem,
@@ -208,7 +200,7 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
if (IS_ERR(fence))
return PTR_ERR(fence);
- r = ttm_bo_move_accel_cleanup(bo, &fence->base, evict, new_mem);
+ r = ttm_bo_move_accel_cleanup(bo, &fence->base, evict, false, new_mem);
radeon_fence_unref(&fence);
return r;
}
@@ -233,7 +225,8 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo,
placement.busy_placement = &placements;
placements.fpfn = 0;
placements.lpfn = 0;
- placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
+ placements.mem_type = TTM_PL_TT;
+ placements.flags = TTM_PL_MASK_CACHING;
r = ttm_bo_mem_space(bo, &placement, &tmp_mem, &ctx);
if (unlikely(r)) {
return r;
@@ -244,7 +237,12 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo,
goto out_cleanup;
}
- r = ttm_tt_bind(bo->ttm, &tmp_mem, &ctx);
+ r = ttm_tt_populate(bo->bdev, bo->ttm, &ctx);
+ if (unlikely(r)) {
+ goto out_cleanup;
+ }
+
+ r = radeon_ttm_tt_bind(bo->bdev, bo->ttm, &tmp_mem);
if (unlikely(r)) {
goto out_cleanup;
}
@@ -278,7 +276,8 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo,
placement.busy_placement = &placements;
placements.fpfn = 0;
placements.lpfn = 0;
- placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
+ placements.mem_type = TTM_PL_TT;
+ placements.flags = TTM_PL_MASK_CACHING;
r = ttm_bo_mem_space(bo, &placement, &tmp_mem, &ctx);
if (unlikely(r)) {
return r;
@@ -316,7 +315,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict,
rdev = radeon_get_rdev(bo->bdev);
if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {
- radeon_move_null(bo, new_mem);
+ ttm_bo_move_null(bo, new_mem);
return 0;
}
if ((old_mem->mem_type == TTM_PL_TT &&
@@ -324,7 +323,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict,
(old_mem->mem_type == TTM_PL_SYSTEM &&
new_mem->mem_type == TTM_PL_TT)) {
/* bind is enough */
- radeon_move_null(bo, new_mem);
+ ttm_bo_move_null(bo, new_mem);
return 0;
}
if (!rdev->ring[radeon_copy_ring_index(rdev)].ready ||
@@ -372,8 +371,8 @@ static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_reso
#if IS_ENABLED(CONFIG_AGP)
if (rdev->flags & RADEON_IS_AGP) {
/* RADEON_IS_AGP is set only if AGP is active */
- mem->bus.offset = mem->start << PAGE_SHIFT;
- mem->bus.base = rdev->mc.agp_base;
+ mem->bus.offset = (mem->start << PAGE_SHIFT) +
+ rdev->mc.agp_base;
mem->bus.is_iomem = !rdev->ddev->agp->cant_use_aperture;
}
#endif
@@ -383,7 +382,7 @@ static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_reso
/* check if it's visible */
if ((mem->bus.offset + bus_size) > rdev->mc.visible_vram_size)
return -EINVAL;
- mem->bus.base = rdev->mc.aper_base;
+ mem->bus.offset += rdev->mc.aper_base;
mem->bus.is_iomem = true;
#ifdef __alpha__
/*
@@ -392,12 +391,10 @@ static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_reso
*/
if (mem->placement & TTM_PL_FLAG_WC)
mem->bus.addr =
- ioremap_wc(mem->bus.base + mem->bus.offset,
- bus_size);
+ ioremap_wc(mem->bus.offset, bus_size);
else
mem->bus.addr =
- ioremap(mem->bus.base + mem->bus.offset,
- bus_size);
+ ioremap(mem->bus.offset, bus_size);
if (!mem->bus.addr)
return -ENOMEM;
@@ -407,7 +404,7 @@ static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_reso
* It then can be used to build PTEs for VRAM
* access, as done in ttm_bo_vm_fault().
*/
- mem->bus.base = (mem->bus.base & 0x0ffffffffUL) +
+ mem->bus.offset = (mem->bus.offset & 0x0ffffffffUL) +
rdev->ddev->hose->dense_mem_base;
#endif
break;
@@ -427,12 +424,13 @@ struct radeon_ttm_tt {
uint64_t userptr;
struct mm_struct *usermm;
uint32_t userflags;
+ bool bound;
};
/* prepare the sg table with the user pages */
-static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
+static int radeon_ttm_tt_pin_userptr(struct ttm_bo_device *bdev, struct ttm_tt *ttm)
{
- struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
+ struct radeon_device *rdev = radeon_get_rdev(bdev);
struct radeon_ttm_tt *gtt = (void *)ttm;
unsigned pinned = 0;
int r;
@@ -491,9 +489,9 @@ release_pages:
return r;
}
-static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
+static void radeon_ttm_tt_unpin_userptr(struct ttm_bo_device *bdev, struct ttm_tt *ttm)
{
- struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
+ struct radeon_device *rdev = radeon_get_rdev(bdev);
struct radeon_ttm_tt *gtt = (void *)ttm;
struct sg_page_iter sg_iter;
@@ -520,17 +518,28 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
sg_free_table(ttm->sg);
}
-static int radeon_ttm_backend_bind(struct ttm_tt *ttm,
+static bool radeon_ttm_backend_is_bound(struct ttm_tt *ttm)
+{
+ struct radeon_ttm_tt *gtt = (void*)ttm;
+
+ return (gtt->bound);
+}
+
+static int radeon_ttm_backend_bind(struct ttm_bo_device *bdev,
+ struct ttm_tt *ttm,
struct ttm_resource *bo_mem)
{
struct radeon_ttm_tt *gtt = (void*)ttm;
- struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
+ struct radeon_device *rdev = radeon_get_rdev(bdev);
uint32_t flags = RADEON_GART_PAGE_VALID | RADEON_GART_PAGE_READ |
RADEON_GART_PAGE_WRITE;
int r;
+ if (gtt->bound)
+ return 0;
+
if (gtt->userptr) {
- radeon_ttm_tt_pin_userptr(ttm);
+ radeon_ttm_tt_pin_userptr(bdev, ttm);
flags &= ~RADEON_GART_PAGE_WRITE;
}
@@ -548,34 +557,36 @@ static int radeon_ttm_backend_bind(struct ttm_tt *ttm,
ttm->num_pages, (unsigned)gtt->offset);
return r;
}
+ gtt->bound = true;
return 0;
}
-static void radeon_ttm_backend_unbind(struct ttm_tt *ttm)
+static void radeon_ttm_backend_unbind(struct ttm_bo_device *bdev, struct ttm_tt *ttm)
{
struct radeon_ttm_tt *gtt = (void *)ttm;
- struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
+ struct radeon_device *rdev = radeon_get_rdev(bdev);
+
+ if (!gtt->bound)
+ return;
radeon_gart_unbind(rdev, gtt->offset, ttm->num_pages);
if (gtt->userptr)
- radeon_ttm_tt_unpin_userptr(ttm);
+ radeon_ttm_tt_unpin_userptr(bdev, ttm);
+ gtt->bound = false;
}
-static void radeon_ttm_backend_destroy(struct ttm_tt *ttm)
+static void radeon_ttm_backend_destroy(struct ttm_bo_device *bdev, struct ttm_tt *ttm)
{
struct radeon_ttm_tt *gtt = (void *)ttm;
+ radeon_ttm_backend_unbind(bdev, ttm);
+ ttm_tt_destroy_common(bdev, ttm);
+
ttm_dma_tt_fini(&gtt->ttm);
kfree(gtt);
}
-static struct ttm_backend_func radeon_backend_func = {
- .bind = &radeon_ttm_backend_bind,
- .unbind = &radeon_ttm_backend_unbind,
- .destroy = &radeon_ttm_backend_destroy,
-};
-
static struct ttm_tt *radeon_ttm_tt_create(struct ttm_buffer_object *bo,
uint32_t page_flags)
{
@@ -594,7 +605,6 @@ static struct ttm_tt *radeon_ttm_tt_create(struct ttm_buffer_object *bo,
if (gtt == NULL) {
return NULL;
}
- gtt->ttm.ttm.func = &radeon_backend_func;
if (ttm_dma_tt_init(&gtt->ttm, bo, page_flags)) {
kfree(gtt);
return NULL;
@@ -602,18 +612,25 @@ static struct ttm_tt *radeon_ttm_tt_create(struct ttm_buffer_object *bo,
return &gtt->ttm.ttm;
}
-static struct radeon_ttm_tt *radeon_ttm_tt_to_gtt(struct ttm_tt *ttm)
+static struct radeon_ttm_tt *radeon_ttm_tt_to_gtt(struct radeon_device *rdev,
+ struct ttm_tt *ttm)
{
- if (!ttm || ttm->func != &radeon_backend_func)
+#if IS_ENABLED(CONFIG_AGP)
+ if (rdev->flags & RADEON_IS_AGP)
return NULL;
- return (struct radeon_ttm_tt *)ttm;
+#endif
+
+ if (!ttm)
+ return NULL;
+ return container_of(ttm, struct radeon_ttm_tt, ttm.ttm);
}
-static int radeon_ttm_tt_populate(struct ttm_tt *ttm,
- struct ttm_operation_ctx *ctx)
+static int radeon_ttm_tt_populate(struct ttm_bo_device *bdev,
+ struct ttm_tt *ttm,
+ struct ttm_operation_ctx *ctx)
{
- struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(ttm);
- struct radeon_device *rdev;
+ struct radeon_device *rdev = radeon_get_rdev(bdev);
+ struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(rdev, ttm);
bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
if (gtt && gtt->userptr) {
@@ -622,21 +639,20 @@ static int radeon_ttm_tt_populate(struct ttm_tt *ttm,
return -ENOMEM;
ttm->page_flags |= TTM_PAGE_FLAG_SG;
- ttm->state = tt_unbound;
+ ttm_tt_set_populated(ttm);
return 0;
}
if (slave && ttm->sg) {
drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
gtt->ttm.dma_address, ttm->num_pages);
- ttm->state = tt_unbound;
+ ttm_tt_set_populated(ttm);
return 0;
}
- rdev = radeon_get_rdev(ttm->bdev);
#if IS_ENABLED(CONFIG_AGP)
if (rdev->flags & RADEON_IS_AGP) {
- return ttm_agp_tt_populate(ttm, ctx);
+ return ttm_pool_populate(ttm, ctx);
}
#endif
@@ -649,10 +665,10 @@ static int radeon_ttm_tt_populate(struct ttm_tt *ttm,
return ttm_populate_and_map_pages(rdev->dev, &gtt->ttm, ctx);
}
-static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm)
+static void radeon_ttm_tt_unpopulate(struct ttm_bo_device *bdev, struct ttm_tt *ttm)
{
- struct radeon_device *rdev;
- struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(ttm);
+ struct radeon_device *rdev = radeon_get_rdev(bdev);
+ struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(rdev, ttm);
bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
if (gtt && gtt->userptr) {
@@ -664,10 +680,9 @@ static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm)
if (slave)
return;
- rdev = radeon_get_rdev(ttm->bdev);
#if IS_ENABLED(CONFIG_AGP)
if (rdev->flags & RADEON_IS_AGP) {
- ttm_agp_tt_unpopulate(ttm);
+ ttm_pool_unpopulate(ttm);
return;
}
#endif
@@ -682,10 +697,11 @@ static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm)
ttm_unmap_and_unpopulate_pages(rdev->dev, &gtt->ttm);
}
-int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
+int radeon_ttm_tt_set_userptr(struct radeon_device *rdev,
+ struct ttm_tt *ttm, uint64_t addr,
uint32_t flags)
{
- struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(ttm);
+ struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(rdev, ttm);
if (gtt == NULL)
return -EINVAL;
@@ -696,9 +712,69 @@ int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
return 0;
}
-bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm)
+bool radeon_ttm_tt_is_bound(struct ttm_bo_device *bdev,
+ struct ttm_tt *ttm)
+{
+#if IS_ENABLED(CONFIG_AGP)
+ struct radeon_device *rdev = radeon_get_rdev(bdev);
+ if (rdev->flags & RADEON_IS_AGP)
+ return ttm_agp_is_bound(ttm);
+#endif
+ return radeon_ttm_backend_is_bound(ttm);
+}
+
+static int radeon_ttm_tt_bind(struct ttm_bo_device *bdev,
+ struct ttm_tt *ttm,
+ struct ttm_resource *bo_mem)
+{
+#if IS_ENABLED(CONFIG_AGP)
+ struct radeon_device *rdev = radeon_get_rdev(bdev);
+#endif
+
+ if (!bo_mem)
+ return -EINVAL;
+#if IS_ENABLED(CONFIG_AGP)
+ if (rdev->flags & RADEON_IS_AGP)
+ return ttm_agp_bind(ttm, bo_mem);
+#endif
+
+ return radeon_ttm_backend_bind(bdev, ttm, bo_mem);
+}
+
+static void radeon_ttm_tt_unbind(struct ttm_bo_device *bdev,
+ struct ttm_tt *ttm)
+{
+#if IS_ENABLED(CONFIG_AGP)
+ struct radeon_device *rdev = radeon_get_rdev(bdev);
+
+ if (rdev->flags & RADEON_IS_AGP) {
+ ttm_agp_unbind(ttm);
+ return;
+ }
+#endif
+ radeon_ttm_backend_unbind(bdev, ttm);
+}
+
+static void radeon_ttm_tt_destroy(struct ttm_bo_device *bdev,
+ struct ttm_tt *ttm)
+{
+#if IS_ENABLED(CONFIG_AGP)
+ struct radeon_device *rdev = radeon_get_rdev(bdev);
+
+ if (rdev->flags & RADEON_IS_AGP) {
+ ttm_agp_unbind(ttm);
+ ttm_tt_destroy_common(bdev, ttm);
+ ttm_agp_destroy(ttm);
+ return;
+ }
+#endif
+ radeon_ttm_backend_destroy(bdev, ttm);
+}
+
+bool radeon_ttm_tt_has_userptr(struct radeon_device *rdev,
+ struct ttm_tt *ttm)
{
- struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(ttm);
+ struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(rdev, ttm);
if (gtt == NULL)
return false;
@@ -706,9 +782,10 @@ bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm)
return !!gtt->userptr;
}
-bool radeon_ttm_tt_is_readonly(struct ttm_tt *ttm)
+bool radeon_ttm_tt_is_readonly(struct radeon_device *rdev,
+ struct ttm_tt *ttm)
{
- struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(ttm);
+ struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(rdev, ttm);
if (gtt == NULL)
return false;
@@ -720,6 +797,9 @@ static struct ttm_bo_driver radeon_bo_driver = {
.ttm_tt_create = &radeon_ttm_tt_create,
.ttm_tt_populate = &radeon_ttm_tt_populate,
.ttm_tt_unpopulate = &radeon_ttm_tt_unpopulate,
+ .ttm_tt_bind = &radeon_ttm_tt_bind,
+ .ttm_tt_unbind = &radeon_ttm_tt_unbind,
+ .ttm_tt_destroy = &radeon_ttm_tt_destroy,
.eviction_valuable = ttm_bo_eviction_valuable,
.evict_flags = &radeon_evict_flags,
.move = &radeon_bo_move,
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index 71e2c3785ab9..ebad27c91a0d 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -942,7 +942,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
bo_va->flags &= ~RADEON_VM_PAGE_VALID;
bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM;
bo_va->flags &= ~RADEON_VM_PAGE_SNOOPED;
- if (bo_va->bo && radeon_ttm_tt_is_readonly(bo_va->bo->tbo.ttm))
+ if (bo_va->bo && radeon_ttm_tt_is_readonly(rdev, bo_va->bo->tbo.ttm))
bo_va->flags &= ~RADEON_VM_PAGE_WRITEABLE;
if (mem) {