@@ -527,7 +527,7 @@ static intel_engine_mask_t init_engine_mask(struct intel_gt *gt)
u16 vdbox_mask;
u16 vebox_mask;
- info->engine_mask = INTEL_INFO(i915)->platform_engine_mask;
+ GEM_BUG_ON(!info->engine_mask);
if (GRAPHICS_VER(i915) < 11)
return info->engine_mask;
@@ -912,7 +912,7 @@ u32 intel_gt_read_register_fw(struct intel_gt *gt, i915_reg_t reg)
return intel_uncore_read_fw(gt->uncore, reg);
}
-static int
+int
intel_gt_tile_setup(struct intel_gt *gt, unsigned int id, phys_addr_t phys_addr)
{
struct drm_i915_private *i915 = gt->i915;
@@ -921,6 +921,11 @@ intel_gt_tile_setup(struct intel_gt *gt, unsigned int id, phys_addr_t phys_addr)
int ret;
if (id) {
+ /* For multi-tile platforms BAR0 must have at least 16MB per tile */
+ if (GEM_WARN_ON(pci_resource_len(to_pci_dev(i915->drm.dev), 0) <
+ (id + 1) * SZ_16M))
+ return -EINVAL;
+
uncore = kzalloc(sizeof(*uncore), GFP_KERNEL);
if (!uncore)
return -ENOMEM;
@@ -943,6 +948,16 @@ intel_gt_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->phys_addr = phys_addr;
return 0;
@@ -959,25 +974,87 @@ intel_gt_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_gt_probe_all(struct drm_i915_private *i915)
{
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+ const struct intel_gt_definition *gtdef;
+ 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;
phys_addr = pci_resource_start(pdev, mmio_bar);
/* We always have at least one primary GT on any device */
- ret = intel_gt_tile_setup(&i915->gt, 0, phys_addr);
+ gt = &i915->gt;
+ gt->name = "Primary GT";
+ gt->info.engine_mask = INTEL_INFO(i915)->platform_engine_mask;
+
+ drm_dbg(&i915->drm, "Setting up %s %u\n", gt->name, gt->info.id);
+ ret = intel_gt_tile_setup(gt, 0, phys_addr);
if (ret)
return ret;
i915->gts[0] = &i915->gt;
- /* TODO: add more tiles */
+ tiles = tile_count(i915);
+ drm_dbg(&i915->drm, "Tile count: %u\n", tiles);
+
+ for (gtdef = INTEL_INFO(i915)->extra_gts, i = 1;
+ gtdef && i < tiles;
+ gtdef++, i++) {
+ if (GEM_WARN_ON(i >= I915_MAX_GTS)) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ gt = kzalloc(sizeof(*gt), GFP_KERNEL);
+ if (!gt) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ gt->i915 = i915;
+ gt->name = gtdef->name;
+ gt->type = gtdef->type;
+ gt->info.engine_mask = gtdef->engine_mask;
+ gt->info.id = i;
+
+ drm_dbg(&i915->drm, "Setting up %s %u\n", gt->name, gt->info.id);
+ ret = intel_gt_tile_setup(gt, i, phys_addr + gtdef->mapping_base);
+ if (ret)
+ goto err;
+
+ i915->gts[i] = gt;
+ }
+
+ i915->remote_tiles = tiles - 1;
+
return 0;
+
+err:
+ drm_err(&i915->drm, "Failed to initialize %s %u! (%d)\n", gtdef->name, i, ret);
+
+ for_each_gt(i915, i, gt) {
+ intel_gt_tile_cleanup(gt);
+ i915->gts[i] = NULL;
+ }
+
+ return ret;
}
void intel_gt_release_all(struct drm_i915_private *i915)
@@ -50,6 +50,8 @@ void intel_gt_driver_late_release(struct intel_gt *gt);
int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout);
+int intel_gt_tile_setup(struct intel_gt *gt, unsigned int id, phys_addr_t phys_addr);
+
void intel_gt_check_and_clear_faults(struct intel_gt *gt);
void intel_gt_clear_error_registers(struct intel_gt *gt,
intel_engine_mask_t engine_mask);
@@ -90,7 +92,7 @@ void intel_gt_release_all(struct drm_i915_private *i915);
#define for_each_gt(i915__, id__, gt__) \
for ((id__) = 0; \
- (id__) < I915_MAX_TILES; \
+ (id__) < I915_MAX_GTS; \
(id__)++) \
for_each_if(((gt__) = (i915__)->gts[(id__)]))
@@ -68,6 +68,9 @@ enum intel_submission_method {
struct intel_gt {
struct drm_i915_private *i915;
+ const char *name;
+ enum intel_gt_type type;
+
struct intel_uncore *uncore;
struct i915_ggtt *ggtt;
@@ -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;
@@ -1196,8 +1198,8 @@ struct drm_i915_private {
/*
* i915->gts[0] == &i915->gt
*/
-#define I915_MAX_TILES 4
- struct intel_gt *gts[I915_MAX_TILES];
+#define I915_MAX_GTS 4
+ struct intel_gt *gts[I915_MAX_GTS];
struct {
struct i915_gem_contexts {
@@ -1723,6 +1725,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)
@@ -29,6 +29,7 @@
#include "i915_drv.h"
#include "i915_pci.h"
+#include "gt/intel_gt.h"
#define PLATFORM(x) .platform = (x)
#define GEN(x) \
@@ -1008,6 +1009,37 @@ static const struct intel_device_info adl_p_info = {
.media_ver = 12, \
.media_rel = 50
+#define XE_HP_SDV_ENGINES \
+ BIT(BCS0) | \
+ BIT(VECS0) | BIT(VECS1) | BIT(VECS2) | BIT(VECS3) | \
+ BIT(VCS0) | BIT(VCS1) | BIT(VCS2) | BIT(VCS3) | \
+ BIT(VCS4) | BIT(VCS5) | BIT(VCS6) | BIT(VCS7)
+
+static const struct intel_gt_definition xehp_sdv_gts[] = {
+ {
+ .type = GT_TILE,
+ .name = "Remote Tile GT",
+ .mapping_base = SZ_16M,
+ .engine_mask = XE_HP_SDV_ENGINES,
+
+ },
+ {
+ .type = GT_TILE,
+ .name = "Remote Tile GT",
+ .mapping_base = SZ_16M * 2,
+ .engine_mask = XE_HP_SDV_ENGINES,
+
+ },
+ {
+ .type = GT_TILE,
+ .name = "Remote Tile GT",
+ .mapping_base = SZ_16M * 3,
+ .engine_mask = XE_HP_SDV_ENGINES,
+
+ },
+ {}
+};
+
__maybe_unused
static const struct intel_device_info xehpsdv_info = {
XE_HP_FEATURES,
@@ -1015,12 +1047,10 @@ static const struct intel_device_info xehpsdv_info = {
DGFX_FEATURES,
PLATFORM(INTEL_XEHPSDV),
.display = { },
+ .extra_gts = xehp_sdv_gts,
+ .has_remote_tiles = 1,
.pipe_mask = 0,
- .platform_engine_mask =
- BIT(RCS0) | BIT(BCS0) |
- BIT(VECS0) | BIT(VECS1) | BIT(VECS2) | BIT(VECS3) |
- BIT(VCS0) | BIT(VCS1) | BIT(VCS2) | BIT(VCS3) |
- BIT(VCS4) | BIT(VCS5) | BIT(VCS6) | BIT(VCS7),
+ .platform_engine_mask = XE_HP_SDV_ENGINES,
.require_force_probe = 1,
};
@@ -12466,6 +12466,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)
@@ -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); \
@@ -166,6 +167,18 @@ enum intel_ppgtt_type {
func(overlay_needs_physical); \
func(supports_tv);
+enum intel_gt_type {
+ GT_PRIMARY,
+ GT_TILE,
+};
+
+struct intel_gt_definition {
+ enum intel_gt_type type;
+ char *name;
+ u32 mapping_base;
+ intel_engine_mask_t engine_mask;
+};
+
struct intel_device_info {
u8 graphics_ver;
u8 graphics_rel;
@@ -185,6 +198,8 @@ struct intel_device_info {
u32 memory_regions; /* regions supported by the HW */
+ const struct intel_gt_definition *extra_gts;
+
u32 display_mmio_offset;
u8 gt; /* GT number, 0 if undefined */