[PATCH 05/17] gpu: nova-core: add the GIN CPU interrupt tree and MSI EOI registers
John Hubbard <[email protected]>
| Newsgroups | dev.linux.lists.nova-gpu,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
GIN is the GPU's interrupt controller. It records interrupt sources in a two-level tree and signals the CPU over PCI when an enabled vector becomes pending. Add the CPU tree registers needed to receive GSP interrupts and to run the software-triggered interrupt self-test. A pre-Hopper GPU that signals over MSI requires delivery to be rearmed after each interrupt, by a write to the MSI end-of-interrupt register. Add that register. Assisted-by: Cursor:claude-opus-5 Reviewed-by: Will Pierce <[email protected]> Signed-off-by: John Hubbard <[email protected]> --- drivers/gpu/nova-core/regs.rs | 71 +++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs index caeef4d85874..1db92d36c5ac 100644 --- a/drivers/gpu/nova-core/regs.rs +++ b/drivers/gpu/nova-core/regs.rs @@ -456,6 +456,64 @@ pub(crate) fn mem_scrubbing_done(self) -> bool { } } +// GIN, the GPU's interrupt controller: the CPU interrupt tree. +// +// These registers are the two-level CPU interrupt tree at the +// `NV_VIRTUAL_FUNCTION_PRIV` aperture (base `0x00b8_0000`), which any function +// uses to reach its own tree. The leaf arrays have 16 entries, the widest tree +// on any supported part. Pre-Hopper parts implement the first eight, and the +// interrupt HAL supplies the count for a given architecture. See +// `Documentation/gpu/nova/core/interrupts.rst`. + +register! { + /// Latched state of the 32 vectors that belong to one leaf, one bit per vector. + /// + /// A read yields the vectors currently latched in leaf `i`. Vector `v` occupies bit `v % 32` + /// of leaf `v / 32`. Each bit is write-1-to-clear, and a write of `0` does not affect the + /// value. Each bit must be cleared before its vector is serviced. + pub(crate) NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF(u32)[16] @ 0x00b81000 {} + + /// Enables individual vectors within one leaf. + /// + /// Each `1` written enables the matching vector for delivery to the CPU. Zero bits leave + /// their vector as it was. + pub(crate) NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF_EN_SET(u32)[16] @ 0x00b81200 {} + + /// Disables individual vectors within one leaf. + /// + /// Each `1` written disables the matching vector. The enable governs delivery alone: a + /// disabled vector still latches in `LEAF`. + pub(crate) NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF_EN_CLEAR(u32)[16] @ 0x00b81400 {} + + /// Enables whole subtrees at the top of the tree. + /// + /// Bit `N` covers subtree `N`, which spans leaves `2N` and `2N + 1`. Each `1` written enables + /// that subtree for delivery to the CPU, and zero bits leave their subtree as it was. + /// + /// Hardware defines a single-element array here, and its one element covers subtrees 0 through + /// 31, every subtree of the widest supported tree. nova-core declares it as a scalar. + pub(crate) NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_TOP_EN_SET(u32) @ 0x00b81608 {} + + /// Disables whole subtrees at the top of the tree. + /// + /// Bit `N` covers subtree `N`. Each `1` written disables that subtree, and zero bits leave + /// their subtree as it was. + /// + /// Hardware defines a single-element array here, and its one element covers subtrees 0 through + /// 31, every subtree of the widest supported tree. nova-core declares it as a scalar. + pub(crate) NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_TOP_EN_CLEAR(u32) @ 0x00b81610 {} + + /// Latches a vector from software. + /// + /// The vector named in the `vector` field latches in its `LEAF` register exactly as a hardware + /// source would latch it, and then reaches the CPU under the same enable conditions. The + /// register is write-only. Every supported part implements it. + pub(crate) NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF_TRIGGER(u32) @ 0x00b81640 { + /// Vector to latch. + 11:0 vector; + } +} + // The modules below provide registers that are not identical on all supported chips. They should // only be used in HAL modules. @@ -471,6 +529,19 @@ pub(crate) mod gm107 { } } +pub(crate) mod tu102 { + use kernel::io::register; + + // PCI configuration-space mirror. + + register! { + /// MSI end-of-interrupt register. + /// + /// A `u32` write rearms MSI delivery on pre-Hopper GPUs. The value is ignored. + pub(crate) NV_XVE_CYA_2(u32) @ 0x0008_8704 {} + } +} + pub(crate) mod ga100 { use kernel::io::register; -- 2.55.0