From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> Check how many extra GT tiles are available on the system and setup register access for all of them. We can detect how may GT tiles are available by reading a register on the root tile. The same register returns the tile ID on all tiles. Bspec: 33407 Original-author: Abdiel Janulgue Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> Cc: Matthew Auld <matthew.auld@xxxxxxxxx> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@xxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Cc: Paulo Zanoni <paulo.r.zanoni@xxxxxxxxx> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@xxxxxxxxx> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@xxxxxxxxx> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@xxxxxxxxx> --- drivers/gpu/drm/i915/gt/intel_gt.c | 66 +++++++++++++++++++++++- drivers/gpu/drm/i915/i915_drv.h | 3 ++ drivers/gpu/drm/i915/i915_pci.c | 1 + drivers/gpu/drm/i915/i915_reg.h | 4 ++ drivers/gpu/drm/i915/intel_device_info.h | 1 + 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index 6528d21e68eb..d7efaef9ade7 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -943,6 +943,17 @@ tile_setup(struct intel_gt *gt, unsigned int id, phys_addr_t phys_addr) if (ret) return ret; + /* Which tile am I? default to zero on single tile systems */ + if (HAS_REMOTE_TILES(i915)) { + u32 instance = + __raw_uncore_read32(gt->uncore, XEHPSDV_MTCFG_ADDR) & + TILE_NUMBER; + + if (GEM_WARN_ON(instance != id)) + return -ENXIO; + } + + gt->info.id = id; gt->phys_addr = phys_addr; return 0; @@ -958,11 +969,25 @@ static void tile_cleanup(struct intel_gt *gt) } } +static unsigned int tile_count(struct drm_i915_private *i915) +{ + u32 mtcfg; + + /* + * We use raw MMIO reads at this point since the + * MMIO vfuncs are not setup yet + */ + mtcfg = __raw_uncore_read32(&i915->uncore, XEHPSDV_MTCFG_ADDR); + return REG_FIELD_GET(TILE_COUNT, mtcfg) + 1; +} + int intel_probe_gts(struct drm_i915_private *i915) { struct pci_dev *pdev = to_pci_dev(i915->drm.dev); + struct intel_gt *gt; phys_addr_t phys_addr; unsigned int mmio_bar; + unsigned int i, tiles; int ret; mmio_bar = GRAPHICS_VER(i915) == 2 ? 1 : 0; @@ -975,8 +1000,47 @@ int intel_probe_gts(struct drm_i915_private *i915) i915->gts[0] = &i915->gt; - /* TODO: add more tiles */ + if (!HAS_REMOTE_TILES(i915)) + return 0; + + /* Setup other tiles */ + tiles = tile_count(i915); + drm_dbg(&i915->drm, "Tile count: %u\n", tiles); + + if (GEM_WARN_ON(tiles > I915_MAX_TILES)) + return -EINVAL; + + /* For multi-tile platforms, size of GTTMMADR is 16MB per tile */ + if (GEM_WARN_ON(pci_resource_len(pdev, 0) / tiles != SZ_16M)) + return -EINVAL; + + for (i = 1; i < tiles; i++) { + gt = kzalloc(sizeof(*gt), GFP_KERNEL); + if (!gt) { + ret = -ENOMEM; + goto err; + } + + ret = tile_setup(gt, i, phys_addr + SZ_16M * i); + if (ret) + goto err; + + i915->gts[i] = gt; + } + + i915->remote_tiles = tiles - 1; + return 0; + +err: + drm_err(&i915->drm, "Failed to initialize tile %u! (%d)\n", i, ret); + + for_each_gt(i915, i, gt) { + tile_cleanup(gt); + i915->gts[i] = NULL; + } + + return ret; } int intel_gt_tiles_init(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3a26a21ffb3a..342c42e5aa96 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -865,6 +865,8 @@ struct drm_i915_private { */ resource_size_t stolen_usable_size; /* Total size minus reserved ranges */ + unsigned int remote_tiles; + struct intel_uncore uncore; struct intel_uncore_mmio_debug mmio_debug; @@ -1724,6 +1726,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i)) #define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM) +#define HAS_REMOTE_TILES(dev_priv) (INTEL_INFO(dev_priv)->has_remote_tiles) #define HAS_GT_UC(dev_priv) (INTEL_INFO(dev_priv)->has_gt_uc) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 169837de395d..95870c2e366e 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -1015,6 +1015,7 @@ static const struct intel_device_info xehpsdv_info = { DGFX_FEATURES, PLATFORM(INTEL_XEHPSDV), .display = { }, + .has_remote_tiles = 1, .pipe_mask = 0, .platform_engine_mask = BIT(RCS0) | BIT(BCS0) | diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a897f4abea0c..5d13c19e14aa 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -12477,6 +12477,10 @@ enum skl_power_gate { #define GEN12_GLOBAL_MOCS(i) _MMIO(0x4000 + (i) * 4) /* Global MOCS regs */ +#define XEHPSDV_MTCFG_ADDR _MMIO(0x101800) +#define TILE_COUNT REG_GENMASK(15, 8) +#define TILE_NUMBER REG_GENMASK(7, 0) + #define GEN12_GSMBASE _MMIO(0x108100) #define GEN12_DSMBASE _MMIO(0x1080C0) diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index 8e6f48d1eb7b..3992b414e21d 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -136,6 +136,7 @@ enum intel_ppgtt_type { func(has_pxp); \ func(has_rc6); \ func(has_rc6p); \ + func(has_remote_tiles); \ func(has_rps); \ func(has_runtime_pm); \ func(has_snoop); \ -- 2.33.0