mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 19:43:40 +02:00
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>
This commit is contained in:
parent
b525d0c5e9
commit
1b155edcab
|
|
@ -13,7 +13,10 @@
|
|||
DmaAddress,
|
||||
DmaMask, //
|
||||
},
|
||||
io::poll::read_poll_timeout,
|
||||
io::{
|
||||
poll::read_poll_timeout,
|
||||
Io, //
|
||||
},
|
||||
prelude::*,
|
||||
sync::aref::ARef,
|
||||
time::Delta,
|
||||
|
|
@ -531,7 +534,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(())
|
||||
|
|
|
|||
|
|
@ -4,12 +4,15 @@
|
|||
device,
|
||||
devres::Devres,
|
||||
fmt,
|
||||
io::Io,
|
||||
num::Bounded,
|
||||
pci,
|
||||
prelude::*,
|
||||
sync::Arc, //
|
||||
};
|
||||
|
||||
use crate::{
|
||||
bounded_enum,
|
||||
driver::Bar0,
|
||||
falcon::{
|
||||
gsp::Gsp as GspFalcon,
|
||||
|
|
@ -128,50 +131,26 @@ 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)]
|
||||
pub(crate) enum Architecture {
|
||||
#[default]
|
||||
Turing = 0x16,
|
||||
Ampere = 0x17,
|
||||
Ada = 0x19,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for Architecture {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self> {
|
||||
match value {
|
||||
0x16 => Ok(Self::Turing),
|
||||
0x17 => Ok(Self::Ampere),
|
||||
0x19 => Ok(Self::Ada),
|
||||
_ => Err(ENODEV),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Architecture> for u8 {
|
||||
fn from(value: Architecture) -> Self {
|
||||
// CAST: `Architecture` is `repr(u8)`, so this cast is always lossless.
|
||||
value as u8
|
||||
bounded_enum! {
|
||||
/// Enum representation of the GPU generation.
|
||||
#[derive(fmt::Debug, Copy, Clone)]
|
||||
pub(crate) enum Architecture with TryFrom<Bounded<u32, 6>> {
|
||||
Turing = 0x16,
|
||||
Ampere = 0x17,
|
||||
Ada = 0x19,
|
||||
}
|
||||
}
|
||||
|
||||
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 +187,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);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
pub(crate) mod macros;
|
||||
|
||||
use kernel::{
|
||||
io,
|
||||
prelude::*,
|
||||
time, //
|
||||
};
|
||||
|
|
@ -37,18 +38,38 @@
|
|||
|
||||
// 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";
|
||||
});
|
||||
io::register! {
|
||||
/// Basic revision information about the GPU.
|
||||
pub(crate) NV_PMC_BOOT_0(u32) @ 0x00000000 {
|
||||
/// Lower bits of the architecture.
|
||||
28:24 architecture_0;
|
||||
/// Implementation version of the architecture.
|
||||
23:20 implementation;
|
||||
/// MSB of the architecture.
|
||||
8:8 architecture_1;
|
||||
/// Major revision of the chip.
|
||||
7:4 major_revision;
|
||||
/// Minor revision of the chip.
|
||||
3:0 minor_revision;
|
||||
}
|
||||
|
||||
/// Extended architecture information.
|
||||
pub(crate) NV_PMC_BOOT_42(u32) @ 0x00000a00 {
|
||||
/// Architecture value.
|
||||
29:24 architecture ?=> Architecture;
|
||||
/// Implementation version of the architecture.
|
||||
23:20 implementation;
|
||||
/// Major revision of the chip.
|
||||
19:16 major_revision;
|
||||
/// Minor revision of the chip.
|
||||
15:12 minor_revision;
|
||||
}
|
||||
}
|
||||
|
||||
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 +77,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 +90,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.into_raw() >> Self::ARCHITECTURE_RANGE.start())
|
||||
& ((1 << Self::ARCHITECTURE_RANGE.len()) - 1)) as u8
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +100,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()
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user