From: "Gary Guo" <gary@garyguo.net>
To: "Alexandre Courbot" <acourbot@nvidia.com>,
"Danilo Krummrich" <dakr@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun@kernel.org>, "Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Trevor Gross" <tmgross@umich.edu>
Cc: "John Hubbard" <jhubbard@nvidia.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Joel Fernandes" <joelagnelf@nvidia.com>,
"Timur Tabi" <ttabi@nvidia.com>, "Zhi Wang" <zhiw@nvidia.com>,
"Eliot Courtney" <ecourtney@nvidia.com>,
<dri-devel@lists.freedesktop.org>, <linux-kernel@vger.kernel.org>,
<linux-riscv@lists.infradead.org>, <linux-doc@vger.kernel.org>,
<rust-for-linux@vger.kernel.org>
Subject: Re: [PATCH 1/8] gpu: nova-core: convert PMC registers to kernel register macro
Date: Wed, 18 Mar 2026 13:28:57 +0000 [thread overview]
Message-ID: <DH5XZP4LPOXG.XL69OTK91FIX@garyguo.net> (raw)
In-Reply-To: <20260318-b4-nova-register-v1-1-22a358aa4c63@nvidia.com>
On Wed Mar 18, 2026 at 8:05 AM GMT, Alexandre Courbot wrote:
> Convert all PMC registers to use the kernel's register macro and update
> the code accordingly.
>
> nova-core's registers have some constant properties (like a 32-bit size
> and a crate visibility), so introduce the `nv_reg` macro to shorten
> their declaration.
>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> ---
> drivers/gpu/nova-core/falcon.rs | 7 ++--
> drivers/gpu/nova-core/gpu.rs | 37 ++++++++++-----------
> drivers/gpu/nova-core/regs.rs | 73 +++++++++++++++++++++++++++++++----------
> 3 files changed, 78 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs
> index 7097a206ec3c..4721865f59d9 100644
> --- a/drivers/gpu/nova-core/falcon.rs
> +++ b/drivers/gpu/nova-core/falcon.rs
> @@ -13,7 +13,10 @@
> DmaAddress,
> DmaMask, //
> },
> - io::poll::read_poll_timeout,
> + io::{
> + poll::read_poll_timeout, //
> + Io,
> + },
> prelude::*,
> sync::aref::ARef,
> time::Delta,
> @@ -532,7 +535,7 @@ pub(crate) fn reset(&self, bar: &Bar0) -> Result {
> self.hal.reset_wait_mem_scrubbing(bar)?;
>
> regs::NV_PFALCON_FALCON_RM::default()
> - .set_value(regs::NV_PMC_BOOT_0::read(bar).into())
> + .set_value(bar.read(regs::NV_PMC_BOOT_0).into())
> .write(bar, &E::ID);
>
> Ok(())
> diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
> index 8579d632e717..d81abc7de3d7 100644
> --- a/drivers/gpu/nova-core/gpu.rs
> +++ b/drivers/gpu/nova-core/gpu.rs
> @@ -4,6 +4,8 @@
> device,
> devres::Devres,
> fmt,
> + io::Io,
> + num::Bounded,
> pci,
> prelude::*,
> sync::Arc, //
> @@ -129,24 +131,18 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
> }
>
> /// Enum representation of the GPU generation.
> -///
> -/// TODO: remove the `Default` trait implementation, and the `#[default]`
> -/// attribute, once the register!() macro (which creates Architecture items) no
> -/// longer requires it for read-only fields.
> -#[derive(fmt::Debug, Default, Copy, Clone)]
> -#[repr(u8)]
> +#[derive(fmt::Debug, Copy, Clone)]
> pub(crate) enum Architecture {
> - #[default]
> Turing = 0x16,
> Ampere = 0x17,
> Ada = 0x19,
> }
>
> -impl TryFrom<u8> for Architecture {
> +impl TryFrom<Bounded<u32, 6>> for Architecture {
> type Error = Error;
>
> - fn try_from(value: u8) -> Result<Self> {
> - match value {
> + fn try_from(value: Bounded<u32, 6>) -> Result<Self> {
> + match u8::from(value) {
> 0x16 => Ok(Self::Turing),
> 0x17 => Ok(Self::Ampere),
> 0x19 => Ok(Self::Ada),
> @@ -155,23 +151,26 @@ fn try_from(value: u8) -> Result<Self> {
> }
> }
>
> -impl From<Architecture> for u8 {
> +impl From<Architecture> for Bounded<u32, 6> {
> fn from(value: Architecture) -> Self {
> - // CAST: `Architecture` is `repr(u8)`, so this cast is always lossless.
> - value as u8
> + match value {
> + Architecture::Turing => Bounded::<u32, 6>::new::<0x16>(),
> + Architecture::Ampere => Bounded::<u32, 6>::new::<0x17>(),
> + Architecture::Ada => Bounded::<u32, 6>::new::<0x19>(),
Yikes.. this looks ugly.
> + }
> }
> }
>
> pub(crate) struct Revision {
> - major: u8,
> - minor: u8,
> + major: Bounded<u8, 4>,
> + minor: Bounded<u8, 4>,
> }
>
> impl From<regs::NV_PMC_BOOT_42> for Revision {
> fn from(boot0: regs::NV_PMC_BOOT_42) -> Self {
> Self {
> - major: boot0.major_revision(),
> - minor: boot0.minor_revision(),
> + major: boot0.major_revision().cast(),
> + minor: boot0.minor_revision().cast(),
> }
> }
> }
> @@ -208,13 +207,13 @@ fn new(dev: &device::Device, bar: &Bar0) -> Result<Spec> {
> // from an earlier (pre-Fermi) era, and then using boot42 to precisely identify the GPU.
> // Somewhere in the Rubin timeframe, boot0 will no longer have space to add new GPU IDs.
>
> - let boot0 = regs::NV_PMC_BOOT_0::read(bar);
> + let boot0 = bar.read(regs::NV_PMC_BOOT_0);
>
> if boot0.is_older_than_fermi() {
> return Err(ENODEV);
> }
>
> - let boot42 = regs::NV_PMC_BOOT_42::read(bar);
> + let boot42 = bar.read(regs::NV_PMC_BOOT_42);
> Spec::try_from(boot42).inspect_err(|_| {
> dev_err!(dev, "Unsupported chipset: {}\n", boot42);
> })
> diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
> index 53f412f0ca32..62c2065e63ef 100644
> --- a/drivers/gpu/nova-core/regs.rs
> +++ b/drivers/gpu/nova-core/regs.rs
> @@ -35,20 +35,64 @@
> num::FromSafeCast,
> };
>
> +// All nova-core registers are 32-bit and `pub(crate)`. Wrap the `register!` macro to avoid
> +// repeating this information for every register.
> +macro_rules! nv_reg {
> + (
> + $(
> + $(#[$attr:meta])* $name:ident $([ $size:expr $(, stride = $stride:expr)? ])?
> + $(@ $offset:literal)?
> + $(@ $base:ident + $base_offset:literal)?
> + $(=> $alias:ident $(+ $alias_offset:ident)? $([$alias_idx:expr])? )?
> + $(, $comment:literal)? { $($fields:tt)* }
> + )*
> + )=> {
> + $(
> + ::kernel::io::register!(
> + @reg $(#[$attr])* pub(crate) $name(u32) $([$size $(, stride = $stride)?])?
> + $(@ $offset)?
> + $(@ $base + $base_offset)?
> + $(=> $alias $(+ $alias_offset)? $([$alias_idx])? )?
> + $(, $comment)? { $($fields)* }
> + );
> + )*
> + };
> +}
> +
> // PMC
>
> -register!(NV_PMC_BOOT_0 @ 0x00000000, "Basic revision information about the GPU" {
> - 3:0 minor_revision as u8, "Minor revision of the chip";
> - 7:4 major_revision as u8, "Major revision of the chip";
> - 8:8 architecture_1 as u8, "MSB of the architecture";
> - 23:20 implementation as u8, "Implementation version of the architecture";
> - 28:24 architecture_0 as u8, "Lower bits of the architecture";
> -});
> +nv_reg! {
> + /// Basic revision information about the GPU.
> + NV_PMC_BOOT_0 @ 0x00000000 {
> + /// Minor revision of the chip.
> + 3:0 minor_revision;
> + /// Major revision of the chip.
> + 7:4 major_revision;
> + /// MSB of the architecture.
> + 8:8 architecture_1;
> + /// Implementation version of the architecture.
> + 23:20 implementation;
> + /// Lower bits of the architecture.
> + 28:24 architecture_0;
> + }
> +
> + /// Extended architecture information.
> + NV_PMC_BOOT_42 @ 0x00000a00 {
> + /// Minor revision of the chip.
> + 15:12 minor_revision;
> + /// Major revision of the chip.
> + 19:16 major_revision;
> + /// Implementation version of the architecture.
> + 23:20 implementation;
> + /// Architecture value.
> + 29:24 architecture ?=> Architecture;
> + }
> +}
>
> impl NV_PMC_BOOT_0 {
> pub(crate) fn is_older_than_fermi(self) -> bool {
> // From https://github.com/NVIDIA/open-gpu-doc/tree/master/manuals :
> - const NV_PMC_BOOT_0_ARCHITECTURE_GF100: u8 = 0xc;
> + const NV_PMC_BOOT_0_ARCHITECTURE_GF100: u32 = 0xc;
>
> // Older chips left arch1 zeroed out. That, combined with an arch0 value that is less than
> // GF100, means "older than Fermi".
> @@ -56,13 +100,6 @@ pub(crate) fn is_older_than_fermi(self) -> bool {
> }
> }
>
> -register!(NV_PMC_BOOT_42 @ 0x00000a00, "Extended architecture information" {
> - 15:12 minor_revision as u8, "Minor revision of the chip";
> - 19:16 major_revision as u8, "Major revision of the chip";
> - 23:20 implementation as u8, "Implementation version of the architecture";
> - 29:24 architecture as u8 ?=> Architecture, "Architecture value";
> -});
> -
> impl NV_PMC_BOOT_42 {
> /// Combines `architecture` and `implementation` to obtain a code unique to the chipset.
> pub(crate) fn chipset(self) -> Result<Chipset> {
> @@ -76,8 +113,8 @@ pub(crate) fn chipset(self) -> Result<Chipset> {
>
> /// Returns the raw architecture value from the register.
> fn architecture_raw(self) -> u8 {
> - ((self.0 >> Self::ARCHITECTURE_RANGE.start()) & ((1 << Self::ARCHITECTURE_RANGE.len()) - 1))
> - as u8
> + ((self.inner >> Self::ARCHITECTURE_RANGE.start())
This should be using `self.into_raw()` rather than accessing the `inner` field
directly (which should be considered impl detail of the macro).
Best,
Gary
> + & ((1 << Self::ARCHITECTURE_RANGE.len()) - 1)) as u8
> }
> }
>
> @@ -86,7 +123,7 @@ fn fmt(&self, f: &mut kernel::fmt::Formatter<'_>) -> kernel::fmt::Result {
> write!(
> f,
> "boot42 = 0x{:08x} (architecture 0x{:x}, implementation 0x{:x})",
> - self.0,
> + self.inner,
> self.architecture_raw(),
> self.implementation()
> )
next prev parent reply other threads:[~2026-03-18 13:29 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-18 8:05 [PATCH 0/8] gpu: nova-core: convert registers to use the kernel register macro Alexandre Courbot
2026-03-18 8:05 ` [PATCH 1/8] gpu: nova-core: convert PMC registers to " Alexandre Courbot
2026-03-18 13:28 ` Gary Guo [this message]
2026-03-19 14:39 ` Alexandre Courbot
2026-03-19 1:42 ` Eliot Courtney
2026-03-19 2:07 ` Alexandre Courbot
2026-03-19 2:16 ` Eliot Courtney
2026-03-19 14:18 ` Alexandre Courbot
2026-03-18 8:06 ` [PATCH 2/8] gpu: nova-core: convert PBUS " Alexandre Courbot
2026-03-19 1:43 ` Eliot Courtney
2026-03-18 8:06 ` [PATCH 3/8] gpu: nova-core: convert PFB " Alexandre Courbot
2026-03-19 1:51 ` Eliot Courtney
2026-03-18 8:06 ` [PATCH 4/8] gpu: nova-core: convert GC6 " Alexandre Courbot
2026-03-19 2:07 ` Eliot Courtney
2026-03-19 14:19 ` Alexandre Courbot
2026-03-18 8:06 ` [PATCH 5/8] gpu: nova-core: convert FUSE " Alexandre Courbot
2026-03-19 2:17 ` Eliot Courtney
2026-03-19 14:24 ` Alexandre Courbot
2026-03-18 8:06 ` [PATCH 6/8] gpu: nova-core: convert PDISP " Alexandre Courbot
2026-03-19 2:18 ` Eliot Courtney
2026-03-18 8:06 ` [PATCH 7/8] gpu: nova-core: convert falcon " Alexandre Courbot
2026-03-19 5:35 ` Eliot Courtney
2026-03-19 14:34 ` Alexandre Courbot
2026-03-18 8:06 ` [PATCH 8/8] Documentation: nova: remove register abstraction task Alexandre Courbot
2026-03-19 2:20 ` Eliot Courtney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DH5XZP4LPOXG.XL69OTK91FIX@garyguo.net \
--to=gary@garyguo.net \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=airlied@gmail.com \
--cc=aliceryhl@google.com \
--cc=apopple@nvidia.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=ecourtney@nvidia.com \
--cc=jhubbard@nvidia.com \
--cc=joelagnelf@nvidia.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=lossin@kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=tmgross@umich.edu \
--cc=ttabi@nvidia.com \
--cc=tzimmermann@suse.de \
--cc=zhiw@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox