mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
drm/xe: Move register MMIO into xe_tile
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>
This commit is contained in:
@@ -75,6 +75,22 @@ struct xe_tile {
|
|||||||
struct xe_gt primary_gt;
|
struct xe_gt primary_gt;
|
||||||
|
|
||||||
/* TODO: Add media GT here */
|
/* 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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)
|
int xe_ggtt_init_noalloc(struct xe_gt *gt, struct xe_ggtt *ggtt)
|
||||||
{
|
{
|
||||||
struct xe_device *xe = gt_to_xe(gt);
|
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);
|
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
|
||||||
unsigned int gsm_size;
|
unsigned int gsm_size;
|
||||||
|
|
||||||
@@ -106,7 +107,7 @@ int xe_ggtt_init_noalloc(struct xe_gt *gt, struct xe_ggtt *ggtt)
|
|||||||
return -ENOMEM;
|
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;
|
ggtt->size = (gsm_size / 8) * (u64) XE_PAGE_SIZE;
|
||||||
|
|
||||||
if (IS_DGFX(xe) && xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K)
|
if (IS_DGFX(xe) && xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K)
|
||||||
|
|||||||
@@ -124,14 +124,11 @@ struct xe_gt {
|
|||||||
} info;
|
} info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @mmio: mmio info for GT, can be subset of the global device mmio
|
* @mmio: mmio info for GT. All GTs within a tile share the same
|
||||||
* space
|
* register space, but have their own copy of GSI registers at a
|
||||||
|
* specific offset, as well as their own forcewake handling.
|
||||||
*/
|
*/
|
||||||
struct {
|
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 */
|
/** @fw: force wake for GT */
|
||||||
struct xe_force_wake fw;
|
struct xe_force_wake fw;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -346,6 +346,7 @@ static void xe_mmio_probe_tiles(struct xe_device *xe)
|
|||||||
|
|
||||||
if (xe->info.tile_count > 1) {
|
if (xe->info.tile_count > 1) {
|
||||||
const int mmio_bar = 0;
|
const int mmio_bar = 0;
|
||||||
|
struct xe_tile *tile;
|
||||||
size_t size;
|
size_t size;
|
||||||
void *regs;
|
void *regs;
|
||||||
|
|
||||||
@@ -359,11 +360,11 @@ static void xe_mmio_probe_tiles(struct xe_device *xe)
|
|||||||
size = xe->mmio.size / adj_tile_count;
|
size = xe->mmio.size / adj_tile_count;
|
||||||
regs = xe->mmio.regs;
|
regs = xe->mmio.regs;
|
||||||
|
|
||||||
for_each_gt(gt, xe, id) {
|
for_each_tile(tile, xe, id) {
|
||||||
if (id && !xe_gt_is_media_type(gt))
|
tile->mmio.size = size;
|
||||||
regs += size;
|
tile->mmio.regs = regs;
|
||||||
gt->mmio.size = size;
|
|
||||||
gt->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)
|
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);
|
struct xe_gt *gt = xe_device_get_gt(xe, 0);
|
||||||
const int mmio_bar = 0;
|
const int mmio_bar = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map the entire BAR, which includes registers (0-4MB), reserved space
|
* Map the first 16MB of th BAR, which includes the registers (0-4MB),
|
||||||
* (4MB-8MB), and GGTT (8MB-16MB). Other parts of the driver (GTs,
|
* reserved space (4MB-8MB), and GGTT (8MB-16MB) for a single tile.
|
||||||
* GGTTs) will derive the pointers they need from the mapping in the
|
* This will get remapped later if we determine that we're running
|
||||||
* device structure.
|
* on a multi-tile system.
|
||||||
*/
|
*/
|
||||||
xe->mmio.size = SZ_16M;
|
xe->mmio.size = SZ_16M;
|
||||||
xe->mmio.regs = pci_iomap(to_pci_dev(xe->drm.dev), mmio_bar,
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* 1 GT for now, 1 to 1 mapping, may change on multi-GT devices */
|
/* Setup first tile; other tiles (if present) will be setup later. */
|
||||||
gt->mmio.size = xe->mmio.size;
|
root_tile->mmio.size = xe->mmio.size;
|
||||||
gt->mmio.regs = xe->mmio.regs;
|
root_tile->mmio.regs = xe->mmio.regs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The boot firmware initializes local memory and assesses its health.
|
* The boot firmware initializes local memory and assesses its health.
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <linux/io-64-nonatomic-lo-hi.h>
|
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||||
|
|
||||||
#include "regs/xe_reg_defs.h"
|
#include "regs/xe_reg_defs.h"
|
||||||
|
#include "xe_device_types.h"
|
||||||
#include "xe_gt_types.h"
|
#include "xe_gt_types.h"
|
||||||
|
|
||||||
struct drm_device;
|
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)
|
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)
|
if (reg.addr < gt->mmio.adj_limit)
|
||||||
reg.addr += gt->mmio.adj_offset;
|
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,
|
static inline void xe_mmio_write32(struct xe_gt *gt,
|
||||||
struct xe_reg reg, u32 val)
|
struct xe_reg reg, u32 val)
|
||||||
{
|
{
|
||||||
|
struct xe_tile *tile = gt_to_tile(gt);
|
||||||
|
|
||||||
if (reg.addr < gt->mmio.adj_limit)
|
if (reg.addr < gt->mmio.adj_limit)
|
||||||
reg.addr += gt->mmio.adj_offset;
|
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)
|
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)
|
if (reg.addr < gt->mmio.adj_limit)
|
||||||
reg.addr += gt->mmio.adj_offset;
|
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,
|
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,
|
static inline void xe_mmio_write64(struct xe_gt *gt,
|
||||||
struct xe_reg reg, u64 val)
|
struct xe_reg reg, u64 val)
|
||||||
{
|
{
|
||||||
|
struct xe_tile *tile = gt_to_tile(gt);
|
||||||
|
|
||||||
if (reg.addr < gt->mmio.adj_limit)
|
if (reg.addr < gt->mmio.adj_limit)
|
||||||
reg.addr += gt->mmio.adj_offset;
|
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)
|
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)
|
if (reg.addr < gt->mmio.adj_limit)
|
||||||
reg.addr += gt->mmio.adj_offset;
|
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,
|
static inline int xe_mmio_write32_and_verify(struct xe_gt *gt,
|
||||||
|
|||||||
Reference in New Issue
Block a user