drm/xe: Move register MMIO into xe_tile
authorMatt Roper <matthew.d.roper@intel.com>
Thu, 1 Jun 2023 21:52:19 +0000 (14:52 -0700)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Tue, 19 Dec 2023 23:34:11 +0000 (18:34 -0500)
Each tile has its own register region in the BAR, containing instances
of all registers for the platform.  In contrast, the multiple GTs within
a tile share the same MMIO space; there's just a small subset of
registers (the GSI registers) which have multiple copies at different
offsets (0x0 for primary GT, 0x380000 for media GT).  Move the register
MMIO region size/pointers to the tile structure, leaving just the GSI
offset information in the GT structure.

Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://lore.kernel.org/r/20230601215244.678611-7-matthew.d.roper@intel.com
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_device_types.h
drivers/gpu/drm/xe/xe_ggtt.c
drivers/gpu/drm/xe/xe_gt_types.h
drivers/gpu/drm/xe/xe_mmio.c
drivers/gpu/drm/xe/xe_mmio.h

index b76344a9c33b039414e01f525081c33257fc44cb..107a947a7361812840ecf961cddff5b2cff28f2f 100644 (file)
@@ -75,6 +75,22 @@ struct xe_tile {
        struct xe_gt primary_gt;
 
        /* TODO: Add media GT here */
+
+       /**
+        * @mmio: MMIO info for a tile.
+        *
+        * Each tile has its own 16MB space in BAR0, laid out as:
+        * * 0-4MB: registers
+        * * 4MB-8MB: reserved
+        * * 8MB-16MB: global GTT
+        */
+       struct {
+               /** @size: size of tile's MMIO space */
+               size_t size;
+
+               /** @regs: pointer to tile's MMIO space (starting with registers) */
+               void *regs;
+       } mmio;
 };
 
 /**
index 4eefb2b3166ce5b88ae4e6f404ef6b32b841b753..cd8ada94e688e4d2e1076d311224281c82aa59d4 100644 (file)
@@ -93,6 +93,7 @@ static void ggtt_fini_noalloc(struct drm_device *drm, void *arg)
 int xe_ggtt_init_noalloc(struct xe_gt *gt, struct xe_ggtt *ggtt)
 {
        struct xe_device *xe = gt_to_xe(gt);
+       struct xe_tile *tile = gt_to_tile(gt);
        struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
        unsigned int gsm_size;
 
@@ -106,7 +107,7 @@ int xe_ggtt_init_noalloc(struct xe_gt *gt, struct xe_ggtt *ggtt)
                return -ENOMEM;
        }
 
-       ggtt->gsm = gt->mmio.regs + SZ_8M;
+       ggtt->gsm = tile->mmio.regs + SZ_8M;
        ggtt->size = (gsm_size / 8) * (u64) XE_PAGE_SIZE;
 
        if (IS_DGFX(xe) && xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K)
index 11605a99ad665608055cb330cf50f7f123905673..81e6ab0c77e09374d8bfd03ce51374abfa1997cb 100644 (file)
@@ -124,14 +124,11 @@ struct xe_gt {
        } info;
 
        /**
-        * @mmio: mmio info for GT, can be subset of the global device mmio
-        * space
+        * @mmio: mmio info for GT.  All GTs within a tile share the same
+        * register space, but have their own copy of GSI registers at a
+        * specific offset, as well as their own forcewake handling.
         */
        struct {
-               /** @size: size of MMIO space on GT */
-               size_t size;
-               /** @regs: pointer to MMIO space on GT */
-               void *regs;
                /** @fw: force wake for GT */
                struct xe_force_wake fw;
                /**
index 79f902d2faea2c6da18a10ccc16fdee5ed1e2d73..b27103080ca96fbffe326681be8753fa237f6214 100644 (file)
@@ -346,6 +346,7 @@ static void xe_mmio_probe_tiles(struct xe_device *xe)
 
        if (xe->info.tile_count > 1) {
                const int mmio_bar = 0;
+               struct xe_tile *tile;
                size_t size;
                void *regs;
 
@@ -359,11 +360,11 @@ static void xe_mmio_probe_tiles(struct xe_device *xe)
                size = xe->mmio.size / adj_tile_count;
                regs = xe->mmio.regs;
 
-               for_each_gt(gt, xe, id) {
-                       if (id && !xe_gt_is_media_type(gt))
-                               regs += size;
-                       gt->mmio.size = size;
-                       gt->mmio.regs = regs;
+               for_each_tile(tile, xe, id) {
+                       tile->mmio.size = size;
+                       tile->mmio.regs = regs;
+
+                       regs += size;
                }
        }
 }
@@ -379,15 +380,16 @@ static void mmio_fini(struct drm_device *drm, void *arg)
 
 int xe_mmio_init(struct xe_device *xe)
 {
+       struct xe_tile *root_tile = xe_device_get_root_tile(xe);
        struct xe_gt *gt = xe_device_get_gt(xe, 0);
        const int mmio_bar = 0;
        int err;
 
        /*
-        * Map the entire BAR, which includes registers (0-4MB), reserved space
-        * (4MB-8MB), and GGTT (8MB-16MB). Other parts of the driver (GTs,
-        * GGTTs) will derive the pointers they need from the mapping in the
-        * device structure.
+        * Map the first 16MB of th BAR, which includes the registers (0-4MB),
+        * reserved space (4MB-8MB), and GGTT (8MB-16MB) for a single tile.
+        * This will get remapped later if we determine that we're running
+        * on a multi-tile system.
         */
        xe->mmio.size = SZ_16M;
        xe->mmio.regs = pci_iomap(to_pci_dev(xe->drm.dev), mmio_bar,
@@ -401,9 +403,9 @@ int xe_mmio_init(struct xe_device *xe)
        if (err)
                return err;
 
-       /* 1 GT for now, 1 to 1 mapping, may change on multi-GT devices */
-       gt->mmio.size = xe->mmio.size;
-       gt->mmio.regs = xe->mmio.regs;
+       /* Setup first tile; other tiles (if present) will be setup later. */
+       root_tile->mmio.size = xe->mmio.size;
+       root_tile->mmio.regs = xe->mmio.regs;
 
        /*
         * The boot firmware initializes local memory and assesses its health.
index da91729a3854294c08da9216b4b5b4a26874ba52..0ba7aa790f0b3cc4bce0f792222b58c6a99ff35e 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/io-64-nonatomic-lo-hi.h>
 
 #include "regs/xe_reg_defs.h"
+#include "xe_device_types.h"
 #include "xe_gt_types.h"
 
 struct drm_device;
@@ -22,27 +23,33 @@ int xe_mmio_init(struct xe_device *xe);
 
 static inline u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg)
 {
+       struct xe_tile *tile = gt_to_tile(gt);
+
        if (reg.addr < gt->mmio.adj_limit)
                reg.addr += gt->mmio.adj_offset;
 
-       return readb(gt->mmio.regs + reg.addr);
+       return readb(tile->mmio.regs + reg.addr);
 }
 
 static inline void xe_mmio_write32(struct xe_gt *gt,
                                   struct xe_reg reg, u32 val)
 {
+       struct xe_tile *tile = gt_to_tile(gt);
+
        if (reg.addr < gt->mmio.adj_limit)
                reg.addr += gt->mmio.adj_offset;
 
-       writel(val, gt->mmio.regs + reg.addr);
+       writel(val, tile->mmio.regs + reg.addr);
 }
 
 static inline u32 xe_mmio_read32(struct xe_gt *gt, struct xe_reg reg)
 {
+       struct xe_tile *tile = gt_to_tile(gt);
+
        if (reg.addr < gt->mmio.adj_limit)
                reg.addr += gt->mmio.adj_offset;
 
-       return readl(gt->mmio.regs + reg.addr);
+       return readl(tile->mmio.regs + reg.addr);
 }
 
 static inline u32 xe_mmio_rmw32(struct xe_gt *gt, struct xe_reg reg, u32 clr,
@@ -60,18 +67,22 @@ static inline u32 xe_mmio_rmw32(struct xe_gt *gt, struct xe_reg reg, u32 clr,
 static inline void xe_mmio_write64(struct xe_gt *gt,
                                   struct xe_reg reg, u64 val)
 {
+       struct xe_tile *tile = gt_to_tile(gt);
+
        if (reg.addr < gt->mmio.adj_limit)
                reg.addr += gt->mmio.adj_offset;
 
-       writeq(val, gt->mmio.regs + reg.addr);
+       writeq(val, tile->mmio.regs + reg.addr);
 }
 
 static inline u64 xe_mmio_read64(struct xe_gt *gt, struct xe_reg reg)
 {
+       struct xe_tile *tile = gt_to_tile(gt);
+
        if (reg.addr < gt->mmio.adj_limit)
                reg.addr += gt->mmio.adj_offset;
 
-       return readq(gt->mmio.regs + reg.addr);
+       return readq(tile->mmio.regs + reg.addr);
 }
 
 static inline int xe_mmio_write32_and_verify(struct xe_gt *gt,