Commit ebd288cb authored by Matt Roper's avatar Matt Roper Committed by Rodrigo Vivi
Browse files

drm/xe: Move VRAM from GT to tile



On platforms with VRAM, the VRAM is associated with the tile, not the
GT.

v2:
 - Unsquash the GGTT handling back into its own patch.
 - Fix kunit test build
v3:
 - Tweak the "FIXME" comment to clarify that this function will be
   completely gone by the end of the series.  (Lucas)
v4:
 - Move a few changes that were supposed to be part of the GGTT patch
   back to that commit.  (Gustavo)
v5:
 - Kerneldoc parameter name fix.

Cc: Gustavo Sousa <gustavo.sousa@intel.com>
Reviewed-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Acked-by: default avatarGustavo Sousa <gustavo.sousa@intel.com>
Link: https://lore.kernel.org/r/20230601215244.678611-11-matthew.d.roper@intel.com


Signed-off-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent ad703e06
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -115,9 +115,9 @@ static void ccs_test_run_gt(struct xe_device *xe, struct xe_gt *gt,
	int ret;

	/* TODO: Sanity check */
	vram_bit = XE_BO_CREATE_VRAM0_BIT << gt->info.vram_id;
	vram_bit = XE_BO_CREATE_VRAM0_BIT << gt_to_tile(gt)->id;
	kunit_info(test, "Testing gt id %u vram id %u\n", gt->info.id,
		   gt->info.vram_id);
		   gt_to_tile(gt)->id);

	bo = xe_bo_create_locked(xe, NULL, NULL, SZ_1M, ttm_bo_type_device,
				 vram_bit);
@@ -179,7 +179,7 @@ static int evict_test_run_gt(struct xe_device *xe, struct xe_gt *gt, struct kuni
	int err, i;

	kunit_info(test, "Testing device %s gt id %u vram id %u\n",
		   dev_name(xe->drm.dev), gt->info.id, gt->info.vram_id);
		   dev_name(xe->drm.dev), gt->info.id, gt_to_tile(gt)->id);

	for (i = 0; i < 2; ++i) {
		xe_vm_lock(vm, &ww, 0, false);
+22 −22
Original line number Diff line number Diff line
@@ -71,25 +71,25 @@ static bool xe_bo_is_user(struct xe_bo *bo)
	return bo->flags & XE_BO_CREATE_USER_BIT;
}

static struct xe_gt *
mem_type_to_gt(struct xe_device *xe, u32 mem_type)
static struct xe_tile *
mem_type_to_tile(struct xe_device *xe, u32 mem_type)
{
	XE_BUG_ON(mem_type != XE_PL_STOLEN && !mem_type_is_vram(mem_type));

	return xe_device_get_gt(xe, mem_type == XE_PL_STOLEN ? 0 : (mem_type - XE_PL_VRAM0));
	return &xe->tiles[mem_type == XE_PL_STOLEN ? 0 : (mem_type - XE_PL_VRAM0)];
}

/**
 * xe_bo_to_gt() - Get a GT from a BO's memory location
 * xe_bo_to_tile() - Get a tile from a BO's memory location
 * @bo: The buffer object
 *
 * Get a GT from a BO's memory location, should be called on BOs in VRAM only.
 * Get a tile from a BO's memory location, should be called on BOs in VRAM only.
 *
 * Return: xe_gt object which is closest to the BO
 * Return: xe_tile object which is closest to the BO
 */
struct xe_gt *xe_bo_to_gt(struct xe_bo *bo)
struct xe_tile *xe_bo_to_tile(struct xe_bo *bo)
{
	return mem_type_to_gt(xe_bo_device(bo), bo->ttm.resource->mem_type);
	return mem_type_to_tile(xe_bo_device(bo), bo->ttm.resource->mem_type);
}

static void try_add_system(struct xe_bo *bo, struct ttm_place *places,
@@ -109,9 +109,9 @@ static void try_add_system(struct xe_bo *bo, struct ttm_place *places,
static void add_vram(struct xe_device *xe, struct xe_bo *bo,
		     struct ttm_place *places, u32 bo_flags, u32 mem_type, u32 *c)
{
	struct xe_gt *gt = mem_type_to_gt(xe, mem_type);
	struct xe_tile *tile = mem_type_to_tile(xe, mem_type);

	XE_BUG_ON(!gt->mem.vram.size);
	XE_BUG_ON(!tile->mem.vram.size);

	places[*c] = (struct ttm_place) {
		.mem_type = mem_type,
@@ -362,7 +362,7 @@ static int xe_ttm_io_mem_reserve(struct ttm_device *bdev,
				 struct ttm_resource *mem)
{
	struct xe_device *xe = ttm_to_xe_device(bdev);
	struct xe_gt *gt;
	struct xe_tile *tile;

	switch (mem->mem_type) {
	case XE_PL_SYSTEM:
@@ -370,15 +370,15 @@ static int xe_ttm_io_mem_reserve(struct ttm_device *bdev,
		return 0;
	case XE_PL_VRAM0:
	case XE_PL_VRAM1:
		gt = mem_type_to_gt(xe, mem->mem_type);
		tile = mem_type_to_tile(xe, mem->mem_type);
		mem->bus.offset = mem->start << PAGE_SHIFT;

		if (gt->mem.vram.mapping &&
		if (tile->mem.vram.mapping &&
		    mem->placement & TTM_PL_FLAG_CONTIGUOUS)
			mem->bus.addr = (u8 *)gt->mem.vram.mapping +
			mem->bus.addr = (u8 *)tile->mem.vram.mapping +
				mem->bus.offset;

		mem->bus.offset += gt->mem.vram.io_start;
		mem->bus.offset += tile->mem.vram.io_start;
		mem->bus.is_iomem = true;

#if  !defined(CONFIG_X86)
@@ -638,9 +638,9 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
	if (bo->gt)
		gt = bo->gt;
	else if (resource_is_vram(new_mem))
		gt = mem_type_to_gt(xe, new_mem->mem_type);
		gt = &mem_type_to_tile(xe, new_mem->mem_type)->primary_gt;
	else if (resource_is_vram(old_mem))
		gt = mem_type_to_gt(xe, old_mem->mem_type);
		gt = &mem_type_to_tile(xe, old_mem->mem_type)->primary_gt;

	XE_BUG_ON(!gt);
	XE_BUG_ON(!gt->migrate);
@@ -664,7 +664,7 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,

			/* Create a new VMAP once kernel BO back in VRAM */
			if (!ret && resource_is_vram(new_mem)) {
				void *new_addr = gt->mem.vram.mapping +
				void *new_addr = gt_to_tile(gt)->mem.vram.mapping +
					(new_mem->start << PAGE_SHIFT);

				if (XE_WARN_ON(new_mem->start == XE_BO_INVALID_OFFSET)) {
@@ -836,14 +836,14 @@ static unsigned long xe_ttm_io_mem_pfn(struct ttm_buffer_object *ttm_bo,
{
	struct xe_device *xe = ttm_to_xe_device(ttm_bo->bdev);
	struct xe_bo *bo = ttm_to_xe_bo(ttm_bo);
	struct xe_gt *gt = mem_type_to_gt(xe, ttm_bo->resource->mem_type);
	struct xe_tile *tile = mem_type_to_tile(xe, ttm_bo->resource->mem_type);
	struct xe_res_cursor cursor;

	if (ttm_bo->resource->mem_type == XE_PL_STOLEN)
		return xe_ttm_stolen_io_offset(bo, page_offset << PAGE_SHIFT) >> PAGE_SHIFT;

	xe_res_first(ttm_bo->resource, (u64)page_offset << PAGE_SHIFT, 0, &cursor);
	return (gt->mem.vram.io_start + cursor.start) >> PAGE_SHIFT;
	return (tile->mem.vram.io_start + cursor.start) >> PAGE_SHIFT;
}

static void __xe_bo_vunmap(struct xe_bo *bo);
@@ -1344,12 +1344,12 @@ struct xe_bo *xe_bo_create_from_data(struct xe_device *xe, struct xe_gt *gt,
uint64_t vram_region_gpu_offset(struct ttm_resource *res)
{
	struct xe_device *xe = ttm_to_xe_device(res->bo->bdev);
	struct xe_gt *gt = mem_type_to_gt(xe, res->mem_type);
	struct xe_tile *tile = mem_type_to_tile(xe, res->mem_type);

	if (res->mem_type == XE_PL_STOLEN)
		return xe_ttm_stolen_gpu_offset(xe);

	return xe->mem.vram.base + gt->mem.vram.base;
	return xe->mem.vram.base + tile->mem.vram.base;
}

/**
+2 −2
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@
/* -- */
#define XE_BO_CREATE_STOLEN_BIT		BIT(4)
#define XE_BO_CREATE_VRAM_IF_DGFX(gt) \
	(IS_DGFX(gt_to_xe(gt)) ? XE_BO_CREATE_VRAM0_BIT << gt->info.vram_id : \
	(IS_DGFX(gt_to_xe(gt)) ? XE_BO_CREATE_VRAM0_BIT << gt_to_tile(gt)->id : \
	 XE_BO_CREATE_SYSTEM_BIT)
#define XE_BO_CREATE_GGTT_BIT		BIT(5)
#define XE_BO_CREATE_IGNORE_MIN_PAGE_SIZE_BIT BIT(6)
@@ -108,7 +108,7 @@ struct xe_bo *xe_bo_create_from_data(struct xe_device *xe, struct xe_gt *gt,
int xe_bo_placement_for_flags(struct xe_device *xe, struct xe_bo *bo,
			      u32 bo_flags);

struct xe_gt *xe_bo_to_gt(struct xe_bo *bo);
struct xe_tile *xe_bo_to_tile(struct xe_bo *bo);

static inline struct xe_bo *ttm_to_xe_bo(const struct ttm_buffer_object *bo)
{
+0 −4
Original line number Diff line number Diff line
@@ -285,10 +285,6 @@ int xe_device_probe(struct xe_device *xe)
		err = xe_tile_init_noalloc(tile);
		if (err)
			goto err_irq_shutdown;

		err = xe_gt_init_noalloc(&tile->primary_gt);
		if (err)
			goto err_irq_shutdown;
	}

	/* Allocate and map stolen after potential VRAM resize */
+30 −0
Original line number Diff line number Diff line
@@ -96,6 +96,36 @@ struct xe_tile {

	/** @mem: memory management info for tile */
	struct {
		/**
		 * @vram: VRAM info for tile.
		 *
		 * Although VRAM is associated with a specific tile, it can
		 * still be accessed by all tiles' GTs.
		 */
		struct {
			/** @io_start: IO start address of this VRAM instance */
			resource_size_t io_start;
			/**
			 * @io_size: IO size of this VRAM instance
			 *
			 * This represents how much of this VRAM we can access
			 * via the CPU through the VRAM BAR. This can be smaller
			 * than @size, in which case only part of VRAM is CPU
			 * accessible (typically the first 256M). This
			 * configuration is known as small-bar.
			 */
			resource_size_t io_size;
			/** @base: offset of VRAM starting base */
			resource_size_t base;
			/** @size: size of VRAM. */
			resource_size_t size;
			/** @mapping: pointer to VRAM mappable space */
			void *__iomem mapping;
		} vram;

		/** @vram_mgr: VRAM TTM manager */
		struct xe_ttm_vram_mgr *vram_mgr;

		/** @ggtt: Global graphics translation table */
		struct xe_ggtt *ggtt;
	} mem;
Loading