/*
 * SPDX-License-Identifier: MIT
 *
 * Copyright © 2008-2012 Intel Corporation
 */

#include <linux/errno.h>
#include <linux/mutex.h>

#include <drm/drm_mm.h>
#include <drm/i915_drm.h>

#include "gem/i915_gem_lmem.h"
#include "gem/i915_gem_region.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_mcr.h"
#include "gt/intel_gt_regs.h"
#include "gt/intel_region_lmem.h"
#include "i915_drv.h"
#include "i915_gem_stolen.h"
#include "i915_pci.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "i915_vgpu.h"
#include "intel_mchbar_regs.h"
#include "intel_pci_config.h"

/*
 * The BIOS typically reserves some of the system's memory for the exclusive
 * use of the integrated graphics. This memory is no longer available for
 * use by the OS and so the user finds that his system has less memory
 * available than he put in. We refer to this memory as stolen.
 *
 * The BIOS will allocate its framebuffer from the stolen memory. Our
 * goal is try to reuse that object for our own fbcon which must always
 * be available for panics. Anything else we can reuse the stolen memory
 * for is a boon.
 */

int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *i915,
					 struct drm_mm_node *node, u64 size,
					 unsigned alignment, u64 start, u64 end)
{
	int ret;

	if (!drm_mm_initialized(&i915->mm.stolen))
		return -ENODEV;

	/* WaSkipStolenMemoryFirstPage:bdw+ */
	if (GRAPHICS_VER(i915) >= 8 && start < 4096)
		start = 4096;

	mutex_lock(&i915->mm.stolen_lock);
	ret = drm_mm_insert_node_in_range(&i915->mm.stolen, node,
					  size, alignment, 0,
					  start, end, DRM_MM_INSERT_BEST);
	mutex_unlock(&i915->mm.stolen_lock);

	return ret;
}

int i915_gem_stolen_insert_node(struct drm_i915_private *i915,
				struct drm_mm_node *node, u64 size,
				unsigned alignment)
{
	return i915_gem_stolen_insert_node_in_range(i915, node,
						    size, alignment,
						    I915_GEM_STOLEN_BIAS,
						    U64_MAX);
}

void i915_gem_stolen_remove_node(struct drm_i915_private *i915,
				 struct drm_mm_node *node)
{
	mutex_lock(&i915->mm.stolen_lock);
	drm_mm_remove_node(node);
	mutex_unlock(&i915->mm.stolen_lock);
}

static bool valid_stolen_size(struct drm_i915_private *i915, struct resource *dsm)
{
	return (dsm->start != 0 || HAS_LMEMBAR_SMEM_STOLEN(i915)) && dsm->end > dsm->start;
}

static int adjust_stolen(struct drm_i915_private *i915,
			 struct resource *dsm)
{
	struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
	struct intel_uncore *uncore = ggtt->vm.gt->uncore;

	if (!valid_stolen_size(i915, dsm))
		return -EINVAL;

	/*
	 * Make sure we don't clobber the GTT if it's within stolen memory
	 *
	 * TODO: We have yet too encounter the case where the GTT wasn't at the
	 * end of stolen. With that assumption we could simplify this.
	 */
	if (GRAPHICS_VER(i915) <= 4 &&
	    !IS_G33(i915) && !IS_PINEVIEW(i915) && !IS_G4X(i915)) {
		struct resource stolen[2] = {*dsm, *dsm};
		struct resource ggtt_res;
		resource_size_t ggtt_start;

		ggtt_start = intel_uncore_read(uncore, PGTBL_CTL);
		if (GRAPHICS_VER(i915) == 4)
			ggtt_start = (ggtt_start & PGTBL_ADDRESS_LO_MASK) |
				     (ggtt_start & PGTBL_ADDRESS_HI_MASK) << 28;
		else
			ggtt_start &= PGTBL_ADDRESS_LO_MASK;

		ggtt_res = DEFINE_RES_MEM(ggtt_start, ggtt_total_entries(ggtt) * 4);

		if (ggtt_res.start >= stolen[0].start && ggtt_res.start < stolen[0].end)
			stolen[0].end = ggtt_res.start;
		if (ggtt_res.end > stolen[1].start && ggtt_res.end <= stolen[1].end)
			stolen[1].start = ggtt_res.end;

		/* Pick the larger of the two chunks */
		if (resource_size(&stolen[0]) > resource_size(&stolen[1]))
			*dsm = stolen[0];
		else
			*dsm = stolen[1];

		if (stolen[0].start != stolen[1].start ||
		    stolen[0].end != stolen[1].end) {
			drm_dbg(&i915->drm,
				"GTT within stolen memory at %pR\n",
				&ggtt_res);
			drm_dbg(&i915->drm, "Stolen memory adjusted to %pR\n",
				dsm);
		}
	}

	if (!valid_stolen_size(i915, dsm))
		return -EINVAL;

	return 0;
}

static int request_smem_stolen(struct drm_i915_private *i915,
			       struct resource *dsm)
{
	struct resource *r;

	/*
	 * With stolen lmem, we don't need to request system memory for the
	 * address range since it's local to the gpu.
	 *
	 * Starting MTL, in IGFX devices the stolen memory is exposed via
	 * LMEMBAR and shall be considered similar to stolen lmem.
	 */
	if (HAS_LMEM(i915) || HAS_LMEMBAR_SMEM_STOLEN(i915))
		return 0;

	/*
	 * Verify that nothing else uses this physical address. Stolen
	 * memory should be reserved by the BIOS and hidden from the
	 * kernel. So if the region is already marked as busy, something
	 * is seriously wrong.
	 */
	r = devm_request_mem_region(i915->drm.dev, dsm->start,
				    resource_size(dsm),
				    "Graphics Stolen Memory");
	if (r == NULL) {
		/*
		 * One more attempt but this time requesting region from
		 * start + 1, as we have seen that this resolves the region
		 * conflict with the PCI Bus.
		 * This is a BIOS w/a: Some BIOS wrap stolen in the root
		 * PCI bus, but have an off-by-one error. Hence retry the
		 * reservation starting from 1 instead of 0.
		 * There's also BIOS with off-by-one on the other end.
		 */
		r = devm_request_mem_region(i915->drm.dev, dsm->start + 1,
					    resource_size(dsm) - 2,
					    "Graphics Stolen Memory");
		/*
		 * GEN3 firmware likes to smash pci bridges into the stolen
		 * range. Apparently this works.
		 */
		if (!r && GRAPHICS_VER(i915) != 3) {
			drm_err(&i915->drm,
				"conflict detected with stolen region: %pR\n",
				dsm);

			return -EBUSY;
		}
	}

	return 0;
}

static void i915_gem_cleanup_stolen(struct drm_i915_private *i915)
{
	if (!drm_mm_initialized(&i915->mm.stolen))
		return;

	drm_mm_takedown(&i915->mm.stolen);
}

static void g4x_get_stolen_reserved(struct drm_i915_private *i915,
				    struct intel_uncore *uncore,
				    resource_size_t *base,
				    resource_size_t *size)
{
	u32 reg_val = intel_uncore_read(uncore,
					IS_GM45(i915) ?
					CTG_STOLEN_RESERVED :
					ELK_STOLEN_RESERVED);
	resource_size_t stolen_top = i915->dsm.stolen.end + 1;

	drm_dbg(&i915->drm, "%s_STOLEN_RESERVED = %08x\n",
		IS_GM45(i915) ? "CTG" : "ELK", reg_val);

	if ((reg_val & G4X_STOLEN_RESERVED_ENABLE) == 0)
		return;

	/*
	 * Whether ILK really reuses the ELK register for this is unclear.
	 * Let's see if we catch anyone with this supposedly enabled on ILK.
	 */
	drm_WARN(&i915->drm, GRAPHICS_VER(i915) == 5,
		 "ILK stolen reserved found? 0x%08x\n",
		 reg_val);

	if (!(reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK))
		return;

	*base = (reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK) << 16;
	drm_WARN_ON(&i915->drm,
		    (reg_val & G4X_STOLEN_RESERVED_ADDR1_MASK) < *base);

	*size = stolen_top - *base;
}

static void gen6_get_stolen_reserved(struct drm_i915_private *i915,
				     struct intel_uncore *uncore,
				     resource_size_t *base,
				     resource_size_t *size)
{
	u32 reg_val = intel_uncore_read(uncore, GEN6_STOLEN_RESERVED);

	drm_dbg(&i915->drm, "GEN6_STOLEN_RESERVED = %08x\n", reg_val);

	if (!(reg_val & GEN6_STOLEN_RESERVED_ENABLE))
		return;

	*base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;

	switch (reg_val & GEN6_STOLEN_RESERVED_SIZE_MASK) {
	case GEN6_STOLEN_RESERVED_1M:
		*size = 1024 * 1024;
		break;
	case GEN6_STOLEN_RESERVED_512K:
		*size = 512 * 1024;
		break;
	case GEN6_STOLEN_RESERVED_256K:
		*size = 256 * 1024;
		break;
	case GEN6_STOLEN_RESERVED_128K:
		*size = 128 * 1024;
		break;
	default:
		*size = 1024 * 1024;
		MISSING_CASE(reg_val & GEN6_STOLEN_RESERVED_SIZE_MASK);
	}
}

static void vlv_get_stolen_reserved(struct drm_i915_private *i915,
				    struct intel_uncore *uncore,
				    resource_size_t *base,
				    resource_size_t *size)
{
	u32 reg_val = intel_uncore_read(uncore, GEN6_STOLEN_RESERVED);
	resource_size_t stolen_top = i915->dsm.stolen.end + 1;

	drm_dbg(&i915->drm, "GEN6_STOLEN_RESERVED = %08x\n", reg_val);

	if (!(reg_val & GEN6_STOLEN_RESERVED_ENABLE))
		return;

	switch (reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK) {
	default:
		MISSING_CASE(reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK);
		fallthrough;
	case GEN7_STOLEN_RESERVED_1M:
		*size = 1024 * 1024;
		break;
	}

	/*
	 * On vlv, the ADDR_MASK portion is left as 0 and HW deduces the
	 * reserved location as (top - size).
	 */
	*base = stolen_top - *size;
}

static void gen7_get_stolen_reserved(struct drm_i915_private *i915,
				     struct intel_uncore *uncore,
				     resource_size_t *base,
				     resource_size_t *size)
{
	u32 reg_val = intel_uncore_read(uncore, GEN6_STOLEN_RESERVED);

	drm_dbg(&i915->drm, "GEN6_STOLEN_RESERVED = %08x\n", reg_val);

	if (!(reg_val & GEN6_STOLEN_RESERVED_ENABLE))
		return;

	*base = reg_val & GEN7_STOLEN_RESERVED_ADDR_MASK;

	switch (reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK) {
	case GEN7_STOLEN_RESERVED_1M:
		*size = 1024 * 1024;
		break;
	case GEN7_STOLEN_RESERVED_256K:
		*size = 256 * 1024;
		break;
	default:
		*size = 1024 * 1024;
		MISSING_CASE(reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK);
	}
}

static void chv_get_stolen_reserved(struct drm_i915_private *i915,
				    struct intel_uncore *uncore,
				    resource_size_t *base,
				    resource_size_t *size)
{
	u32 reg_val = intel_uncore_read(uncore, GEN6_STOLEN_RESERVED);

	drm_dbg(&i915->drm, "GEN6_STOLEN_RESERVED = %08x\n", reg_val);

	if (!(reg_val & GEN6_STOLEN_RESERVED_ENABLE))
		return;

	*base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;

	switch (reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK) {
	case GEN8_STOLEN_RESERVED_1M:
		*size = 1024 * 1024;
		break;
	case GEN8_STOLEN_RESERVED_2M:
		*size = 2 * 1024 * 1024;
		break;
	case GEN8_STOLEN_RESERVED_4M:
		*size = 4 * 1024 * 1024;
		break;
	case GEN8_STOLEN_RESERVED_8M:
		*size = 8 * 1024 * 1024;
		break;
	default:
		*size = 8 * 1024 * 1024;
		MISSING_CASE(reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK);
	}
}

static void bdw_get_stolen_reserved(struct drm_i915_private *i915,
				    struct intel_uncore *uncore,
				    resource_size_t *base,
				    resource_size_t *size)
{
	u32 reg_val = intel_uncore_read(uncore, GEN6_STOLEN_RESERVED);
	resource_size_t stolen_top = i915->dsm.stolen.end + 1;

	drm_dbg(&i915->drm, "GEN6_STOLEN_RESERVED = %08x\n", reg_val);

	if (!(reg_val & GEN6_STOLEN_RESERVED_ENABLE))
		return;

	if (!(reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK))
		return;

	*base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
	*size = stolen_top - *base;
}

static void icl_get_stolen_reserved(struct drm_i915_private *i915,
				    struct intel_uncore *uncore,
				    resource_size_t *base,
				    resource_size_t *size)
{
	u64 reg_val = intel_uncore_read64(uncore, GEN6_STOLEN_RESERVED);

	drm_dbg(&i915->drm, "GEN6_STOLEN_RESERVED = 0x%016llx\n", reg_val);

	/* Wa_14019821291 */
	if (MEDIA_VER_FULL(i915) == IP_VER(13, 0)) {
		/*
		 * This workaround is primarily implemented by the BIOS.  We
		 * just need to figure out whether the BIOS has applied the
		 * workaround (meaning the programmed address falls within
		 * the DSM) and, if so, reserve that part of the DSM to
		 * prevent accidental reuse.  The DSM location should be just
		 * below the WOPCM.
		 */
		u64 gscpsmi_base = intel_uncore_read64_2x32(uncore,
							    MTL_GSCPSMI_BASEADDR_LSB,
							    MTL_GSCPSMI_BASEADDR_MSB);
		if (gscpsmi_base >= i915->dsm.stolen.start &&
		    gscpsmi_base < i915->dsm.stolen.end) {
			*base = gscpsmi_base;
			*size = i915->dsm.stolen.end - gscpsmi_base;
			return;
		}
	}

	switch (reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK) {
	case GEN8_STOLEN_RESERVED_1M:
		*size = 1024 * 1024;
		break;
	case GEN8_STOLEN_RESERVED_2M:
		*size = 2 * 1024 * 1024;
		break;
	case GEN8_STOLEN_RESERVED_4M:
		*size = 4 * 1024 * 1024;
		break;
	case GEN8_STOLEN_RESERVED_8M:
		*size = 8 * 1024 * 1024;
		break;
	default:
		*size = 8 * 1024 * 1024;
		MISSING_CASE(reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK);
	}

	if (HAS_LMEMBAR_SMEM_STOLEN(i915))
		/* the base is initialized to stolen top so subtract size to get base */
		*base -= *size;
	else
		*base = reg_val & GEN11_STOLEN_RESERVED_ADDR_MASK;
}

/*
 * Initialize i915->dsm.reserved to contain the reserved space within the Data
 * Stolen Memory. This is a range on the top of DSM that is reserved, not to
 * be used by driver, so must be excluded from the region passed to the
 * allocator later. In the spec this is also called as WOPCM.
 *
 * Our expectation is that the reserved space is at the top of the stolen
 * region, as it has been the case for every platform, and *never* at the
 * bottom, so the calculation here can be simplified.
 */
static int init_reserved_stolen(struct drm_i915_private *i915)
{
	struct intel_uncore *uncore = &i915->uncore;
	resource_size_t reserved_base, stolen_top;
	resource_size_t reserved_size;
	int ret = 0;

	stolen_top = i915->dsm.stolen.end + 1;
	reserved_base = stolen_top;
	reserved_size = 0;

	if (GRAPHICS_VER(i915) >= 11) {
		icl_get_stolen_reserved(i915, uncore,
					&reserved_base, &reserved_size);
	} else if (GRAPHICS_VER(i915) >= 8) {
		if (IS_LP(i915))
			chv_get_stolen_reserved(i915, uncore,
						&reserved_base, &reserved_size);
		else
			bdw_get_stolen_reserved(i915, uncore,
						&reserved_base, &reserved_size);
	} else if (GRAPHICS_VER(i915) >= 7) {
		if (IS_VALLEYVIEW(i915))
			vlv_get_stolen_reserved(i915, uncore,
						&reserved_base, &reserved_size);
		else
			gen7_get_stolen_reserved(i915, uncore,
						 &reserved_base, &reserved_size);
	} else if (GRAPHICS_VER(i915) >= 6) {
		gen6_get_stolen_reserved(i915, uncore,
					 &reserved_base, &reserved_size);
	} else if (GRAPHICS_VER(i915) >= 5 || IS_G4X(i915)) {
		g4x_get_stolen_reserved(i915, uncore,
					&reserved_base, &reserved_size);
	}

	/* No reserved stolen */
	if (reserved_base == stolen_top)
		goto bail_out;

	if (!reserved_base) {
		drm_err(&i915->drm,
			"inconsistent reservation %pa + %pa; ignoring\n",
			&reserved_base, &reserved_size);
		ret = -EINVAL;
		goto bail_out;
	}

	i915->dsm.reserved = DEFINE_RES_MEM(reserved_base, reserved_size);

	if (!resource_contains(&i915->dsm.stolen, &i915->dsm.reserved)) {
		drm_err(&i915->drm,
			"Stolen reserved area %pR outside stolen memory %pR\n",
			&i915->dsm.reserved, &i915->dsm.stolen);
		ret = -EINVAL;
		goto bail_out;
	}

	return 0;

bail_out:
	i915->dsm.reserved = DEFINE_RES_MEM(reserved_base, 0);

	return ret;
}

static int i915_gem_init_stolen(struct intel_memory_region *mem)
{
	struct drm_i915_private *i915 = mem->i915;

	mutex_init(&i915->mm.stolen_lock);

	if (intel_vgpu_active(i915)) {
		drm_notice(&i915->drm,
			   "%s, disabling use of stolen memory\n",
			   "iGVT-g active");
		return -ENOSPC;
	}

	if (i915_vtd_active(i915) && GRAPHICS_VER(i915) < 8) {
		drm_notice(&i915->drm,
			   "%s, disabling use of stolen memory\n",
			   "DMAR active");
		return -ENOSPC;
	}

	if (adjust_stolen(i915, &mem->region))
		return -ENOSPC;

	if (request_smem_stolen(i915, &mem->region))
		return -ENOSPC;

	i915->dsm.stolen = mem->region;

	if (init_reserved_stolen(i915))
		return -ENOSPC;

	/* Exclude the reserved region from driver use */
	mem->region.end = i915->dsm.reserved.start - 1;
	mem->io_size = min(mem->io_size, resource_size(&mem->region));

	i915->dsm.usable_size = resource_size(&mem->region);

	drm_dbg(&i915->drm,
		"Memory reserved for graphics device: %lluK, usable: %lluK\n",
		(u64)resource_size(&i915->dsm.stolen) >> 10,
		(u64)i915->dsm.usable_size >> 10);

	if (i915->dsm.usable_size == 0)
		return -ENOSPC;

	/* Basic memrange allocator for stolen space. */
	drm_mm_init(&i915->mm.stolen, 0, i915->dsm.usable_size);

	/*
	 * Access to stolen lmem beyond certain size for MTL A0 stepping
	 * would crash the machine. Disable stolen lmem for userspace access
	 * by setting usable_size to zero.
	 */
	if (IS_METEORLAKE(i915) && INTEL_REVID(i915) == 0x0)
		i915->dsm.usable_size = 0;

	return 0;
}

static void dbg_poison(struct i915_ggtt *ggtt,
		       dma_addr_t addr, resource_size_t size,
		       u8 x)
{
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
	if (!drm_mm_node_allocated(&ggtt->error_capture))
		return;

	if (ggtt->vm.bind_async_flags & I915_VMA_GLOBAL_BIND)
		return; /* beware stop_machine() inversion */

	GEM_BUG_ON(!IS_ALIGNED(size, PAGE_SIZE));

	mutex_lock(&ggtt->error_mutex);
	while (size) {
		void __iomem *s;

		ggtt->vm.insert_page(&ggtt->vm, addr,
				     ggtt->error_capture.start,
				     i915_gem_get_pat_index(ggtt->vm.i915,
							    I915_CACHE_NONE),
				     0);
		mb();

		s = io_mapping_map_wc(&ggtt->iomap,
				      ggtt->error_capture.start,
				      PAGE_SIZE);
		memset_io(s, x, PAGE_SIZE);
		io_mapping_unmap(s);

		addr += PAGE_SIZE;
		size -= PAGE_SIZE;
	}
	mb();
	ggtt->vm.clear_range(&ggtt->vm, ggtt->error_capture.start, PAGE_SIZE);
	mutex_unlock(&ggtt->error_mutex);
#endif
}

static struct sg_table *
i915_pages_create_for_stolen(struct drm_device *dev,
			     resource_size_t offset, resource_size_t size)
{
	struct drm_i915_private *i915 = to_i915(dev);
	struct sg_table *st;
	struct scatterlist *sg;

	GEM_BUG_ON(range_overflows(offset, size, resource_size(&i915->dsm.stolen)));

	/* We hide that we have no struct page backing our stolen object
	 * by wrapping the contiguous physical allocation with a fake
	 * dma mapping in a single scatterlist.
	 */

	st = kmalloc(sizeof(*st), GFP_KERNEL);
	if (st == NULL)
		return ERR_PTR(-ENOMEM);

	if (sg_alloc_table(st, 1, GFP_KERNEL)) {
		kfree(st);
		return ERR_PTR(-ENOMEM);
	}

	sg = st->sgl;
	sg->offset = 0;
	sg->length = size;

	sg_dma_address(sg) = (dma_addr_t)i915->dsm.stolen.start + offset;
	sg_dma_len(sg) = size;

	return st;
}

static int i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj)
{
	struct drm_i915_private *i915 = to_i915(obj->base.dev);
	struct sg_table *pages =
		i915_pages_create_for_stolen(obj->base.dev,
					     obj->stolen->start,
					     obj->stolen->size);
	if (IS_ERR(pages))
		return PTR_ERR(pages);

	dbg_poison(to_gt(i915)->ggtt,
		   sg_dma_address(pages->sgl),
		   sg_dma_len(pages->sgl),
		   POISON_INUSE);

	__i915_gem_object_set_pages(obj, pages);

	return 0;
}

static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj,
					     struct sg_table *pages)
{
	struct drm_i915_private *i915 = to_i915(obj->base.dev);
	/* Should only be called from i915_gem_object_release_stolen() */

	dbg_poison(to_gt(i915)->ggtt,
		   sg_dma_address(pages->sgl),
		   sg_dma_len(pages->sgl),
		   POISON_FREE);

	sg_free_table(pages);
	kfree(pages);
}

static void
i915_gem_object_release_stolen(struct drm_i915_gem_object *obj)
{
	struct drm_i915_private *i915 = to_i915(obj->base.dev);
	struct drm_mm_node *stolen = fetch_and_zero(&obj->stolen);

	GEM_BUG_ON(!stolen);
	i915_gem_stolen_remove_node(i915, stolen);
	kfree(stolen);

	i915_gem_object_release_memory_region(obj);
}

static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
	.name = "i915_gem_object_stolen",
	.get_pages = i915_gem_object_get_pages_stolen,
	.put_pages = i915_gem_object_put_pages_stolen,
	.release = i915_gem_object_release_stolen,
};

static int __i915_gem_object_create_stolen(struct intel_memory_region *mem,
					   struct drm_i915_gem_object *obj,
					   struct drm_mm_node *stolen)
{
	static struct lock_class_key lock_class;
	unsigned int cache_level;
	unsigned int flags;
	int err;

	/*
	 * Stolen objects are always physically contiguous since we just
	 * allocate one big block underneath using the drm_mm range allocator.
	 */
	flags = I915_BO_ALLOC_CONTIGUOUS;

	drm_gem_private_object_init(&mem->i915->drm, &obj->base, stolen->size);
	i915_gem_object_init(obj, &i915_gem_object_stolen_ops, &lock_class, flags);

	obj->stolen = stolen;
	obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
	cache_level = HAS_LLC(mem->i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
	i915_gem_object_set_cache_coherency(obj, cache_level);

	if (WARN_ON(!i915_gem_object_trylock(obj, NULL)))
		return -EBUSY;

	i915_gem_object_init_memory_region(obj, mem);

	err = i915_gem_object_pin_pages(obj);
	if (err)
		i915_gem_object_release_memory_region(obj);
	i915_gem_object_unlock(obj);

	return err;
}

static int _i915_gem_object_stolen_init(struct intel_memory_region *mem,
					struct drm_i915_gem_object *obj,
					resource_size_t offset,
					resource_size_t size,
					resource_size_t page_size,
					unsigned int flags)
{
	struct drm_i915_private *i915 = mem->i915;
	struct drm_mm_node *stolen;
	int ret;

	if (!drm_mm_initialized(&i915->mm.stolen))
		return -ENODEV;

	if (size == 0)
		return -EINVAL;

	/*
	 * With discrete devices, where we lack a mappable aperture there is no
	 * possible way to ever access this memory on the CPU side.
	 */
	if (mem->type == INTEL_MEMORY_STOLEN_LOCAL && !mem->io_size &&
	    !(flags & I915_BO_ALLOC_GPU_ONLY))
		return -ENOSPC;

	stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
	if (!stolen)
		return -ENOMEM;

	if (offset != I915_BO_INVALID_OFFSET) {
		drm_dbg(&i915->drm,
			"creating preallocated stolen object: stolen_offset=%pa, size=%pa\n",
			&offset, &size);

		stolen->start = offset;
		stolen->size = size;
		mutex_lock(&i915->mm.stolen_lock);
		ret = drm_mm_reserve_node(&i915->mm.stolen, stolen);
		mutex_unlock(&i915->mm.stolen_lock);
	} else {
		ret = i915_gem_stolen_insert_node(i915, stolen, size,
						  mem->min_page_size);
	}
	if (ret)
		goto err_free;

	ret = __i915_gem_object_create_stolen(mem, obj, stolen);
	if (ret)
		goto err_remove;

	return 0;

err_remove:
	i915_gem_stolen_remove_node(i915, stolen);
err_free:
	kfree(stolen);
	return ret;
}

struct drm_i915_gem_object *
i915_gem_object_create_stolen(struct drm_i915_private *i915,
			      resource_size_t size)
{
	return i915_gem_object_create_region(i915->mm.stolen_region, size, 0, 0);
}

static int init_stolen_smem(struct intel_memory_region *mem)
{
	int err;

	/*
	 * Initialise stolen early so that we may reserve preallocated
	 * objects for the BIOS to KMS transition.
	 */
	err = i915_gem_init_stolen(mem);
	if (err)
		drm_dbg(&mem->i915->drm, "Skip stolen region: failed to setup\n");

	return 0;
}

static int release_stolen_smem(struct intel_memory_region *mem)
{
	i915_gem_cleanup_stolen(mem->i915);
	return 0;
}

static const struct intel_memory_region_ops i915_region_stolen_smem_ops = {
	.init = init_stolen_smem,
	.release = release_stolen_smem,
	.init_object = _i915_gem_object_stolen_init,
};

static int init_stolen_lmem(struct intel_memory_region *mem)
{
	struct drm_i915_private *i915 = mem->i915;
	int err;

	if (GEM_WARN_ON(resource_size(&mem->region) == 0))
		return 0;

	err = i915_gem_init_stolen(mem);
	if (err) {
		drm_dbg(&mem->i915->drm, "Skip stolen region: failed to setup\n");
		return 0;
	}

	if (mem->io_size &&
	    !io_mapping_init_wc(&mem->iomap, mem->io_start, mem->io_size))
		goto err_cleanup;

	drm_dbg(&i915->drm, "Stolen Local memory IO start: %pa\n",
		&mem->io_start);
	drm_dbg(&i915->drm, "Stolen Local DSM base: %pa\n", &mem->region.start);

	return 0;

err_cleanup:
	i915_gem_cleanup_stolen(mem->i915);
	return err;
}

static int release_stolen_lmem(struct intel_memory_region *mem)
{
	if (mem->io_size)
		io_mapping_fini(&mem->iomap);
	i915_gem_cleanup_stolen(mem->i915);
	return 0;
}

static const struct intel_memory_region_ops i915_region_stolen_lmem_ops = {
	.init = init_stolen_lmem,
	.release = release_stolen_lmem,
	.init_object = _i915_gem_object_stolen_init,
};

static int mtl_get_gms_size(struct intel_uncore *uncore)
{
	u16 ggc, gms;

	ggc = intel_uncore_read16(uncore, GGC);

	/* check GGMS, should be fixed 0x3 (8MB) */
	if ((ggc & GGMS_MASK) != GGMS_MASK)
		return -EIO;

	/* return valid GMS value, -EIO if invalid */
	gms = REG_FIELD_GET(GMS_MASK, ggc);
	switch (gms) {
	case 0x0 ... 0x04:
		return gms * 32;
	case 0xf0 ... 0xfe:
		return (gms - 0xf0 + 1) * 4;
	default:
		MISSING_CASE(gms);
		return -EIO;
	}
}

struct intel_memory_region *
i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type,
			   u16 instance)
{
	struct intel_uncore *uncore = &i915->uncore;
	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
	resource_size_t dsm_size, dsm_base, lmem_size;
	struct intel_memory_region *mem;
	resource_size_t io_start, io_size;
	resource_size_t min_page_size;
	int ret;

	if (WARN_ON_ONCE(instance))
		return ERR_PTR(-ENODEV);

	if (!i915_pci_resource_valid(pdev, GEN12_LMEM_BAR))
		return ERR_PTR(-ENXIO);

	if (HAS_LMEMBAR_SMEM_STOLEN(i915) || IS_DG1(i915)) {
		lmem_size = pci_resource_len(pdev, GEN12_LMEM_BAR);
	} else {
		resource_size_t lmem_range;

		lmem_range = intel_gt_mcr_read_any(to_gt(i915), XEHP_TILE0_ADDR_RANGE) & 0xFFFF;
		lmem_size = lmem_range >> XEHP_TILE_LMEM_RANGE_SHIFT;
		lmem_size *= SZ_1G;
	}

	if (HAS_LMEMBAR_SMEM_STOLEN(i915)) {
		/*
		 * MTL dsm size is in GGC register.
		 * Also MTL uses offset to GSMBASE in ptes, so i915
		 * uses dsm_base = 8MBs to setup stolen region, since
		 * DSMBASE = GSMBASE + 8MB.
		 */
		ret = mtl_get_gms_size(uncore);
		if (ret < 0) {
			drm_err(&i915->drm, "invalid MTL GGC register setting\n");
			return ERR_PTR(ret);
		}

		dsm_base = SZ_8M;
		dsm_size = (resource_size_t)(ret * SZ_1M);

		GEM_BUG_ON(pci_resource_len(pdev, GEN12_LMEM_BAR) != SZ_256M);
		GEM_BUG_ON((dsm_base + dsm_size) > lmem_size);
	} else {
		/* Use DSM base address instead for stolen memory */
		dsm_base = intel_uncore_read64(uncore, GEN12_DSMBASE) & GEN12_BDSM_MASK;
		if (WARN_ON(lmem_size < dsm_base))
			return ERR_PTR(-ENODEV);
		dsm_size = ALIGN_DOWN(lmem_size - dsm_base, SZ_1M);
	}

	if (pci_resource_len(pdev, GEN12_LMEM_BAR) < lmem_size) {
		io_start = 0;
		io_size = 0;
	} else {
		io_start = pci_resource_start(pdev, GEN12_LMEM_BAR) + dsm_base;
		io_size = dsm_size;
	}

	min_page_size = HAS_64K_PAGES(i915) ? I915_GTT_PAGE_SIZE_64K :
						I915_GTT_PAGE_SIZE_4K;

	mem = intel_memory_region_create(i915, dsm_base, dsm_size,
					 min_page_size,
					 io_start, io_size,
					 type, instance,
					 &i915_region_stolen_lmem_ops);
	if (IS_ERR(mem))
		return mem;

	intel_memory_region_set_name(mem, "stolen-local");

	mem->private = true;

	return mem;
}

struct intel_memory_region*
i915_gem_stolen_smem_setup(struct drm_i915_private *i915, u16 type,
			   u16 instance)
{
	struct intel_memory_region *mem;

	mem = intel_memory_region_create(i915,
					 intel_graphics_stolen_res.start,
					 resource_size(&intel_graphics_stolen_res),
					 PAGE_SIZE, 0, 0, type, instance,
					 &i915_region_stolen_smem_ops);
	if (IS_ERR(mem))
		return mem;

	intel_memory_region_set_name(mem, "stolen-system");

	mem->private = true;

	return mem;
}

bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj)
{
	return obj->ops == &i915_gem_object_stolen_ops;
}

bool i915_gem_stolen_initialized(const struct drm_i915_private *i915)
{
	return drm_mm_initialized(&i915->mm.stolen);
}

u64 i915_gem_stolen_area_address(const struct drm_i915_private *i915)
{
	return i915->dsm.stolen.start;
}

u64 i915_gem_stolen_area_size(const struct drm_i915_private *i915)
{
	return resource_size(&i915->dsm.stolen);
}

u64 i915_gem_stolen_node_address(const struct drm_i915_private *i915,
				 const struct drm_mm_node *node)
{
	return i915->dsm.stolen.start + i915_gem_stolen_node_offset(node);
}

bool i915_gem_stolen_node_allocated(const struct drm_mm_node *node)
{
	return drm_mm_node_allocated(node);
}

u64 i915_gem_stolen_node_offset(const struct drm_mm_node *node)
{
	return node->start;
}

u64 i915_gem_stolen_node_size(const struct drm_mm_node *node)
{
	return node->size;
}
