Draft: Separate GT and tile
Series posted for review at https://patchwork.freedesktop.org/series/117614/
A 'tile' is not the same thing as a 'GT.' For historical reasons, i915 attempted to use a single 'struct intel_gt' to represent both concepts, although this design hasn't worked out terribly well. For Xe we have the opportunity to design the driver in a way that more accurately reflects the real hardware behavior.
Different vendors use the term "tile" a bit differently, but in the Intel world, a 'tile' is pretty close to what most people would think of as being a complete GPU. When multiple GPUs are placed behind a single PCI device, that's what we refer to as a "multi-tile device." In such cases, pretty much all hardware is replicated per-tile, although certain responsibilities like PCI communication, reporting of interrupts to the OS, etc. are handled solely by the "root tile." A multi-tile platform takes care of tying the tiles together in a way such that interrupt notifications from remote tiles are forwarded to the root tile, the per-tile vram is combined into a single address space, etc.
In contrast, a "GT" (which officially stands for "Graphics Technology") is the subset of a GPU/tile that is responsible for implementing graphics and/or media operations. The GT is where a lot of the driver implementation happens since it's where the hardware engines, the execution units, and the GuC all reside.
Historically most Intel devices were single-tile devices that contained a single GT. PVC is currently the only released Intel platform built on a multi-tile design (i.e., multiple GPUs behind a single PCI device); each PVC tile only has a single GT. In contrast, platforms like MTL that have separate chips for render and media IP are still only a single logical GPU, but the graphics and media IP blocks are exposed each exposed as a separate GT within that single GPU. This is important from a software perspective because multi-GT platforms like MTL only replicate a subset of the GPU hardware and behave differently than multi-tile platforms like PVC where nearly everything is replicated.
This series separates tiles from GTs in a manner that more closely matches the hardware behavior. We now consider a PCI device (xe_device) to contain one or more tiles (struct xe_tile). Each tile will contain one or two GTs (struct xe_gt). Although we don't have any platforms yet that are multi-tile and contain more than one GT per tile, that may change in the future. This driver redesign splits functionality as follows:
Per-tile functionality (shared by all GTs within the tile):
- Complete 4MB MMIO space (containing SGunit/SoC registers, GT registers, display registers, etc.)
- Global GTT
- VRAM (if discrete)
- Interrupt flows
- Migration context
- kernel batchbuffer pool
- Primary GT
- Media GT (if media version >= 13)
Per-GT functionality:
- GuC
- Hardware engines
- Programmable hardware units (subslices, EUs)
- GSI subset of registers (multiple copies of these registers reside within the complete MMIO space provided by the tile, but at different offsets --- 0 for render, 0x380000 for media)
- Multicast register steering
- TLBs to cache page table translations
- Reset capability
- Low-level power management (e.g., C6)
- Clock frequency
- MOCS and PAT programming
At the moment I've left USM / pagefault handling at the GT level, although I'm not familiar enough with that specific feature to know whether it's truly correct or not.
The first patch in this series temporarily drops MTL media GT support. The driver doesn't load properly on MTL today, largely due to the mishandling of GT vs tile; dropping support completely allows us to more easily make the necessary driver redesign required. The media GT is re-enabled (properly this time) near the end of the series and this allows the driver to load successfully without error on MTL for the first time. There are still issues when submitting workloads to MTL after driver load (i.e., CAT errors), but those seem to be a separate platform-specific issues unrelated to the GT/tile work in this series that will need to be debugged and fixed separately.
This series leaves a few open questions and FIXME's:
- Unlike i915, the Xe driver has chosen to expose GTs to userspace rather than keeping them a hidden implementation detail. With the separation of xe_tile and xe_gt, we need to decide whether we also want to expose tiles (in addition to GTs), whether we want to only expose tiles (and keep the primary vs media GT separation a hidden internal detail), or something else.
- How should GTs be numbered? Today it's straightforward --- PVC assigns GT IDs 0 and 1 to the primary GT of each tile. MTL assigns GT IDs 0 and 1 to the primary and media GTs of its sole tile. But if we have a platform in the future that has multiple tiles and multiple GTs per tile, how should we handle the numbering in that case?
- Xe (mis)design used xe_gt as the target of all MMIO operations (i.e., xe_mmio_*()). This really doesn't make sense, especially since there's a lot of MMIO accesses that are completely unrelated to GT (i.e., sgunit registers, display registers, etc.). i915 used 'intel_uncore' as the MMIO target, although that wasn't really an accurate reflection of the hardware either. What we really want is something that combines the MMIO register space (stored in the tile) with the GSI offset (stored in the GT). My current plan is to introduce an "xe_mmio_view" (name may change) in a future series that will serve as a target for register operations. There will be sensible APIs to obtain an xe_mmio_view appropriate to the type of register access being performed (and that will also be able to do some range sanity checking in debug drivers to help catch misuse). That's a somewhat large/invasive change, so I'm saving that for a follow-up series after this one is completed.
Cc: Matthew Brost matthew.brost@intel.com Cc: Lucas De Marchi lucas.demarchi@intel.com Cc: Rodrigo Vivi rodrigo.vivi@intel.com Cc: Michael J. Ruhl michael.j.ruhl@intel.com Cc: Nirmoy Das nirmoy.das@intel.com