Commit b8ca8fef authored by Akeem G Abodunrin's avatar Akeem G Abodunrin Committed by Matthew Auld
Browse files

drm/i915/stolen: don't treat small BAR as an error



On client platforms with reduced LMEM BAR, we should be able to continue
with driver load with reduced io_size. Instead of using the BAR size to
determine the how large stolen should be, we should instead use the
ADDR_RANGE register to figure this out(at least on platforms like DG2).
For simplicity we don't attempt to support partially mappable stolen.

v2: rearrange the io_mapping_init_wc slightly, since the stolen setup
might result in reduced io_size.

Signed-off-by: default avatarAkeem G Abodunrin <akeem.g.abodunrin@intel.com>
Co-developed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Signed-off-by: default avatarMatthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: default avatarNirmoy Das <nirmoy.das@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220315181425.576828-2-matthew.auld@intel.com
parent 56eda725
Loading
Loading
Loading
Loading
+43 −19
Original line number Diff line number Diff line
@@ -12,6 +12,8 @@

#include "gem/i915_gem_lmem.h"
#include "gem/i915_gem_region.h"
#include "gt/intel_gt.h"
#include "gt/intel_region_lmem.h"
#include "i915_drv.h"
#include "i915_gem_stolen.h"
#include "i915_reg.h"
@@ -492,7 +494,7 @@ static int i915_gem_init_stolen(struct intel_memory_region *mem)

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

	/* It is possible for the reserved area to end before the end of stolen
	 * memory, so just consider the start. */
@@ -750,11 +752,6 @@ static int init_stolen_lmem(struct intel_memory_region *mem)
	if (GEM_WARN_ON(resource_size(&mem->region) == 0))
		return -ENODEV;

	if (!io_mapping_init_wc(&mem->iomap,
				mem->io_start,
				mem->io_size))
		return -EIO;

	/*
	 * TODO: For stolen lmem we mostly just care about populating the dsm
	 * related bits and setting up the drm_mm allocator for the range.
@@ -762,17 +759,25 @@ static int init_stolen_lmem(struct intel_memory_region *mem)
	 */
	err = i915_gem_init_stolen(mem);
	if (err)
		goto err_fini;
		return err;

	if (mem->io_size && !io_mapping_init_wc(&mem->iomap,
						mem->io_start,
						mem->io_size)) {
		err = -EIO;
		goto err_cleanup;
	}

	return 0;

err_fini:
	io_mapping_fini(&mem->iomap);
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;
@@ -790,25 +795,43 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type,
{
	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;
	resource_size_t io_start;
	resource_size_t lmem_size;
	u64 lmem_base;

	lmem_base = intel_uncore_read64(uncore, GEN12_DSMBASE);
	if (GEM_WARN_ON(lmem_base >= pci_resource_len(pdev, 2)))
	if (WARN_ON_ONCE(instance))
		return ERR_PTR(-ENODEV);

	/* Use DSM base address instead for stolen memory */
	dsm_base = intel_uncore_read64(uncore, GEN12_DSMBASE);
	if (IS_DG1(uncore->i915)) {
		lmem_size = pci_resource_len(pdev, 2);
		if (WARN_ON(lmem_size < dsm_base))
			return ERR_PTR(-ENODEV);
	} else {
		resource_size_t lmem_range;

	lmem_size = pci_resource_len(pdev, 2) - lmem_base;
	io_start = pci_resource_start(pdev, 2) + lmem_base;
		lmem_range = intel_gt_read_register(&i915->gt0, XEHPSDV_TILE0_ADDR_RANGE) & 0xFFFF;
		lmem_size = lmem_range >> XEHPSDV_TILE_LMEM_RANGE_SHIFT;
		lmem_size *= SZ_1G;
	}

	dsm_size = lmem_size - dsm_base;
	if (pci_resource_len(pdev, 2) < lmem_size) {
		io_start = 0;
		io_size = 0;
	} else {
		io_start = pci_resource_start(pdev, 2) + 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, lmem_base, lmem_size,
	mem = intel_memory_region_create(i915, dsm_base, dsm_size,
					 min_page_size,
					 io_start, lmem_size,
					 io_start, io_size,
					 type, instance,
					 &i915_region_stolen_lmem_ops);
	if (IS_ERR(mem))
@@ -822,6 +845,7 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type,

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

	intel_memory_region_set_name(mem, "stolen-local");

+3 −0
Original line number Diff line number Diff line
@@ -8464,6 +8464,9 @@ enum skl_power_gate {
#define   SGGI_DIS			REG_BIT(15)
#define   SGR_DIS			REG_BIT(13)

#define XEHPSDV_TILE0_ADDR_RANGE	_MMIO(0x4900)
#define   XEHPSDV_TILE_LMEM_RANGE_SHIFT  8

#define XEHPSDV_FLAT_CCS_BASE_ADDR	_MMIO(0x4910)
#define   XEHPSDV_CCS_BASE_SHIFT	8