Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

gpu: nova-core: convert PMC registers to kernel register macro

Convert all PMC registers to use the kernel's register macro and update
the code accordingly.

Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://patch.msgid.link/20260325-b4-nova-register-v4-2-bdf172f0f6ca@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>

+53 -57
+5 -2
drivers/gpu/nova-core/falcon.rs
··· 13 13 DmaAddress, 14 14 DmaMask, // 15 15 }, 16 - io::poll::read_poll_timeout, 16 + io::{ 17 + poll::read_poll_timeout, 18 + Io, // 19 + }, 17 20 prelude::*, 18 21 sync::aref::ARef, 19 22 time::Delta, ··· 534 531 self.hal.reset_wait_mem_scrubbing(bar)?; 535 532 536 533 regs::NV_PFALCON_FALCON_RM::default() 537 - .set_value(regs::NV_PMC_BOOT_0::read(bar).into()) 534 + .set_value(bar.read(regs::NV_PMC_BOOT_0).into()) 538 535 .write(bar, &E::ID); 539 536 540 537 Ok(())
+16 -37
drivers/gpu/nova-core/gpu.rs
··· 4 4 device, 5 5 devres::Devres, 6 6 fmt, 7 + io::Io, 8 + num::Bounded, 7 9 pci, 8 10 prelude::*, 9 11 sync::Arc, // 10 12 }; 11 13 12 14 use crate::{ 15 + bounded_enum, 13 16 driver::Bar0, 14 17 falcon::{ 15 18 gsp::Gsp as GspFalcon, ··· 131 128 } 132 129 } 133 130 134 - /// Enum representation of the GPU generation. 135 - /// 136 - /// TODO: remove the `Default` trait implementation, and the `#[default]` 137 - /// attribute, once the register!() macro (which creates Architecture items) no 138 - /// longer requires it for read-only fields. 139 - #[derive(fmt::Debug, Default, Copy, Clone)] 140 - #[repr(u8)] 141 - pub(crate) enum Architecture { 142 - #[default] 143 - Turing = 0x16, 144 - Ampere = 0x17, 145 - Ada = 0x19, 146 - } 147 - 148 - impl TryFrom<u8> for Architecture { 149 - type Error = Error; 150 - 151 - fn try_from(value: u8) -> Result<Self> { 152 - match value { 153 - 0x16 => Ok(Self::Turing), 154 - 0x17 => Ok(Self::Ampere), 155 - 0x19 => Ok(Self::Ada), 156 - _ => Err(ENODEV), 157 - } 158 - } 159 - } 160 - 161 - impl From<Architecture> for u8 { 162 - fn from(value: Architecture) -> Self { 163 - // CAST: `Architecture` is `repr(u8)`, so this cast is always lossless. 164 - value as u8 131 + bounded_enum! { 132 + /// Enum representation of the GPU generation. 133 + #[derive(fmt::Debug, Copy, Clone)] 134 + pub(crate) enum Architecture with TryFrom<Bounded<u32, 6>> { 135 + Turing = 0x16, 136 + Ampere = 0x17, 137 + Ada = 0x19, 165 138 } 166 139 } 167 140 168 141 pub(crate) struct Revision { 169 - major: u8, 170 - minor: u8, 142 + major: Bounded<u8, 4>, 143 + minor: Bounded<u8, 4>, 171 144 } 172 145 173 146 impl From<regs::NV_PMC_BOOT_42> for Revision { 174 147 fn from(boot0: regs::NV_PMC_BOOT_42) -> Self { 175 148 Self { 176 - major: boot0.major_revision(), 177 - minor: boot0.minor_revision(), 149 + major: boot0.major_revision().cast(), 150 + minor: boot0.minor_revision().cast(), 178 151 } 179 152 } 180 153 } ··· 187 208 // from an earlier (pre-Fermi) era, and then using boot42 to precisely identify the GPU. 188 209 // Somewhere in the Rubin timeframe, boot0 will no longer have space to add new GPU IDs. 189 210 190 - let boot0 = regs::NV_PMC_BOOT_0::read(bar); 211 + let boot0 = bar.read(regs::NV_PMC_BOOT_0); 191 212 192 213 if boot0.is_older_than_fermi() { 193 214 return Err(ENODEV); 194 215 } 195 216 196 - let boot42 = regs::NV_PMC_BOOT_42::read(bar); 217 + let boot42 = bar.read(regs::NV_PMC_BOOT_42); 197 218 Spec::try_from(boot42).inspect_err(|_| { 198 219 dev_err!(dev, "Unsupported chipset: {}\n", boot42); 199 220 })
+32 -18
drivers/gpu/nova-core/regs.rs
··· 8 8 pub(crate) mod macros; 9 9 10 10 use kernel::{ 11 + io, 11 12 prelude::*, 12 13 time, // 13 14 }; ··· 38 37 39 38 // PMC 40 39 41 - register!(NV_PMC_BOOT_0 @ 0x00000000, "Basic revision information about the GPU" { 42 - 3:0 minor_revision as u8, "Minor revision of the chip"; 43 - 7:4 major_revision as u8, "Major revision of the chip"; 44 - 8:8 architecture_1 as u8, "MSB of the architecture"; 45 - 23:20 implementation as u8, "Implementation version of the architecture"; 46 - 28:24 architecture_0 as u8, "Lower bits of the architecture"; 47 - }); 40 + io::register! { 41 + /// Basic revision information about the GPU. 42 + pub(crate) NV_PMC_BOOT_0(u32) @ 0x00000000 { 43 + /// Lower bits of the architecture. 44 + 28:24 architecture_0; 45 + /// Implementation version of the architecture. 46 + 23:20 implementation; 47 + /// MSB of the architecture. 48 + 8:8 architecture_1; 49 + /// Major revision of the chip. 50 + 7:4 major_revision; 51 + /// Minor revision of the chip. 52 + 3:0 minor_revision; 53 + } 54 + 55 + /// Extended architecture information. 56 + pub(crate) NV_PMC_BOOT_42(u32) @ 0x00000a00 { 57 + /// Architecture value. 58 + 29:24 architecture ?=> Architecture; 59 + /// Implementation version of the architecture. 60 + 23:20 implementation; 61 + /// Major revision of the chip. 62 + 19:16 major_revision; 63 + /// Minor revision of the chip. 64 + 15:12 minor_revision; 65 + } 66 + } 48 67 49 68 impl NV_PMC_BOOT_0 { 50 69 pub(crate) fn is_older_than_fermi(self) -> bool { 51 70 // From https://github.com/NVIDIA/open-gpu-doc/tree/master/manuals : 52 - const NV_PMC_BOOT_0_ARCHITECTURE_GF100: u8 = 0xc; 71 + const NV_PMC_BOOT_0_ARCHITECTURE_GF100: u32 = 0xc; 53 72 54 73 // Older chips left arch1 zeroed out. That, combined with an arch0 value that is less than 55 74 // GF100, means "older than Fermi". 56 75 self.architecture_1() == 0 && self.architecture_0() < NV_PMC_BOOT_0_ARCHITECTURE_GF100 57 76 } 58 77 } 59 - 60 - register!(NV_PMC_BOOT_42 @ 0x00000a00, "Extended architecture information" { 61 - 15:12 minor_revision as u8, "Minor revision of the chip"; 62 - 19:16 major_revision as u8, "Major revision of the chip"; 63 - 23:20 implementation as u8, "Implementation version of the architecture"; 64 - 29:24 architecture as u8 ?=> Architecture, "Architecture value"; 65 - }); 66 78 67 79 impl NV_PMC_BOOT_42 { 68 80 /// Combines `architecture` and `implementation` to obtain a code unique to the chipset. ··· 90 76 91 77 /// Returns the raw architecture value from the register. 92 78 fn architecture_raw(self) -> u8 { 93 - ((self.0 >> Self::ARCHITECTURE_RANGE.start()) & ((1 << Self::ARCHITECTURE_RANGE.len()) - 1)) 94 - as u8 79 + ((self.into_raw() >> Self::ARCHITECTURE_RANGE.start()) 80 + & ((1 << Self::ARCHITECTURE_RANGE.len()) - 1)) as u8 95 81 } 96 82 } 97 83 ··· 100 86 write!( 101 87 f, 102 88 "boot42 = 0x{:08x} (architecture 0x{:x}, implementation 0x{:x})", 103 - self.0, 89 + self.inner, 104 90 self.architecture_raw(), 105 91 self.implementation() 106 92 )