Commit ee60e29f authored by Christian König's avatar Christian König Committed by Alex Deucher
Browse files

drm/radeon: rework VMID handling



Move binding onto the ring, simplifying handling a bit.

Signed-off-by: default avatarChristian König <deathsimple@vodafone.de>
Reviewed-by: default avatarJerome Glisse <jglisse@redhat.com>
parent 9b40e5d8
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -1497,14 +1497,6 @@ void cayman_vm_fini(struct radeon_device *rdev)
{
}

int cayman_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id)
{
	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (id << 2), 0);
	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (id << 2), vm->last_pfn);
	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (id << 2), vm->pt_gpu_addr >> 12);
	return 0;
}

#define R600_PTE_VALID     (1 << 0)
#define R600_PTE_SYSTEM    (1 << 1)
#define R600_PTE_SNOOPED   (1 << 2)
@@ -1540,10 +1532,20 @@ void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm,
void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ib *ib)
{
	struct radeon_ring *ring = &rdev->ring[ib->ring];
	struct radeon_vm *vm = ib->vm;

	if (!ib->vm || ib->vm->id == -1)
	if (vm == NULL)
		return;

	radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (vm->id << 2), 0));
	radeon_ring_write(ring, 0);

	radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (vm->id << 2), 0));
	radeon_ring_write(ring, vm->last_pfn);

	radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0));
	radeon_ring_write(ring, vm->pt_gpu_addr >> 12);

	/* flush hdp cache */
	radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
	radeon_ring_write(ring, 0x1);
+26 −4
Original line number Diff line number Diff line
@@ -253,6 +253,22 @@ static inline struct radeon_fence *radeon_fence_later(struct radeon_fence *a,
	}
}

static inline bool radeon_fence_is_earlier(struct radeon_fence *a,
					   struct radeon_fence *b)
{
	if (!a) {
		return false;
	}

	if (!b) {
		return true;
	}

	BUG_ON(a->ring != b->ring);

	return a->seq < b->seq;
}

/*
 * Tiling registers
 */
@@ -628,10 +644,13 @@ struct radeon_ring {
/*
 * VM
 */

#define RADEON_NUM_VM	16

struct radeon_vm {
	struct list_head		list;
	struct list_head		va;
	int				id;
	unsigned			id;
	unsigned			last_pfn;
	u64				pt_gpu_addr;
	u64				*pt;
@@ -646,7 +665,7 @@ struct radeon_vm {
struct radeon_vm_manager {
	struct mutex			lock;
	struct list_head		lru_vm;
	uint32_t			use_bitmap;
	struct radeon_fence		*active[RADEON_NUM_VM];
	struct radeon_sa_manager	sa_manager;
	uint32_t			max_pfn;
	/* number of VMIDs */
@@ -1117,7 +1136,6 @@ struct radeon_asic {
	struct {
		int (*init)(struct radeon_device *rdev);
		void (*fini)(struct radeon_device *rdev);
		int (*bind)(struct radeon_device *rdev, struct radeon_vm *vm, int id);
		uint32_t (*page_flags)(struct radeon_device *rdev,
				       struct radeon_vm *vm,
				       uint32_t flags);
@@ -1734,7 +1752,6 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
#define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p))
#define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev))
#define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev))
#define radeon_asic_vm_bind(rdev, v, id) (rdev)->asic->vm.bind((rdev), (v), (id))
#define radeon_asic_vm_page_flags(rdev, v, flags) (rdev)->asic->vm.page_flags((rdev), (v), (flags))
#define radeon_asic_vm_set_page(rdev, v, pfn, addr, flags) (rdev)->asic->vm.set_page((rdev), (v), (pfn), (addr), (flags))
#define radeon_ring_start(rdev, r, cp) (rdev)->asic->ring[(r)].ring_start((rdev), (cp))
@@ -1817,6 +1834,11 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm);
void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm);
int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm);
void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm);
struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
				       struct radeon_vm *vm, int ring);
void radeon_vm_fence(struct radeon_device *rdev,
		     struct radeon_vm *vm,
		     struct radeon_fence *fence);
int radeon_vm_bo_update_pte(struct radeon_device *rdev,
			    struct radeon_vm *vm,
			    struct radeon_bo *bo,
+3 −6
Original line number Diff line number Diff line
@@ -1375,7 +1375,6 @@ static struct radeon_asic cayman_asic = {
	.vm = {
		.init = &cayman_vm_init,
		.fini = &cayman_vm_fini,
		.bind = &cayman_vm_bind,
		.page_flags = &cayman_vm_page_flags,
		.set_page = &cayman_vm_set_page,
	},
@@ -1480,7 +1479,6 @@ static struct radeon_asic trinity_asic = {
	.vm = {
		.init = &cayman_vm_init,
		.fini = &cayman_vm_fini,
		.bind = &cayman_vm_bind,
		.page_flags = &cayman_vm_page_flags,
		.set_page = &cayman_vm_set_page,
	},
@@ -1585,7 +1583,6 @@ static struct radeon_asic si_asic = {
	.vm = {
		.init = &si_vm_init,
		.fini = &si_vm_fini,
		.bind = &si_vm_bind,
		.page_flags = &cayman_vm_page_flags,
		.set_page = &cayman_vm_set_page,
	},
@@ -1599,7 +1596,7 @@ static struct radeon_asic si_asic = {
			.ring_test = &r600_ring_test,
			.ib_test = &r600_ib_test,
			.is_lockup = &si_gpu_is_lockup,
			.vm_flush = &cayman_vm_flush,
			.vm_flush = &si_vm_flush,
		},
		[CAYMAN_RING_TYPE_CP1_INDEX] = {
			.ib_execute = &si_ring_ib_execute,
@@ -1610,7 +1607,7 @@ static struct radeon_asic si_asic = {
			.ring_test = &r600_ring_test,
			.ib_test = &r600_ib_test,
			.is_lockup = &si_gpu_is_lockup,
			.vm_flush = &cayman_vm_flush,
			.vm_flush = &si_vm_flush,
		},
		[CAYMAN_RING_TYPE_CP2_INDEX] = {
			.ib_execute = &si_ring_ib_execute,
@@ -1621,7 +1618,7 @@ static struct radeon_asic si_asic = {
			.ring_test = &r600_ring_test,
			.ib_test = &r600_ib_test,
			.is_lockup = &si_gpu_is_lockup,
			.vm_flush = &cayman_vm_flush,
			.vm_flush = &si_vm_flush,
		}
	},
	.irq = {
+1 −3
Original line number Diff line number Diff line
@@ -440,7 +440,6 @@ int cayman_asic_reset(struct radeon_device *rdev);
void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
int cayman_vm_init(struct radeon_device *rdev);
void cayman_vm_fini(struct radeon_device *rdev);
int cayman_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id);
void cayman_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm);
void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ib *ib);
uint32_t cayman_vm_page_flags(struct radeon_device *rdev,
@@ -470,8 +469,7 @@ int si_irq_set(struct radeon_device *rdev);
int si_irq_process(struct radeon_device *rdev);
int si_vm_init(struct radeon_device *rdev);
void si_vm_fini(struct radeon_device *rdev);
int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id);
void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm);
void si_vm_flush(struct radeon_device *rdev, struct radeon_ib *ib);
int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
uint64_t si_get_gpu_clock(struct radeon_device *rdev);

+4 −5
Original line number Diff line number Diff line
@@ -485,6 +485,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
	}
	radeon_cs_sync_rings(parser);
	radeon_cs_sync_to(parser, vm->last_flush);
	radeon_cs_sync_to(parser, radeon_vm_grab_id(rdev, vm, parser->ring));

	if ((rdev->family >= CHIP_TAHITI) &&
	    (parser->chunk_const_ib_idx != -1)) {
@@ -493,13 +494,11 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
		r = radeon_ib_schedule(rdev, &parser->ib, NULL);
	}

out:
	if (!r) {
		if (vm->fence) {
			radeon_fence_unref(&vm->fence);
		}
		vm->fence = radeon_fence_ref(parser->ib.fence);
		radeon_vm_fence(rdev, vm, parser->ib.fence);
	}

out:
	mutex_unlock(&vm->mutex);
	mutex_unlock(&rdev->vm_manager.lock);
	return r;
Loading