diff options
Diffstat (limited to 'drivers/gpu/nova-core/gpu.rs')
| -rw-r--r-- | drivers/gpu/nova-core/gpu.rs | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index 88a6d7af9f37..3e3375f8fe99 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -160,8 +160,8 @@ pub(crate) struct Revision { minor: u8, } -impl From<regs::NV_PMC_BOOT_0> for Revision { - fn from(boot0: regs::NV_PMC_BOOT_0) -> Self { +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(), @@ -183,19 +183,41 @@ pub(crate) struct Spec { impl Spec { fn new(bar: &Bar0) -> Result<Spec> { + // Some brief notes about boot0 and boot42, in chronological order: + // + // NV04 through NV50: + // + // Not supported by Nova. boot0 is necessary and sufficient to identify these GPUs. + // boot42 may not even exist on some of these GPUs. + // + // Fermi through Volta: + // + // Not supported by Nova. boot0 is still sufficient to identify these GPUs, but boot42 + // is also guaranteed to be both present and accurate. + // + // Turing and later: + // + // Supported by Nova. Identified by first checking boot0 to ensure that the GPU is not + // 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); - Spec::try_from(boot0) + if boot0.is_older_than_fermi() { + return Err(ENODEV); + } + + Spec::try_from(regs::NV_PMC_BOOT_42::read(bar)) } } -impl TryFrom<regs::NV_PMC_BOOT_0> for Spec { +impl TryFrom<regs::NV_PMC_BOOT_42> for Spec { type Error = Error; - fn try_from(boot0: regs::NV_PMC_BOOT_0) -> Result<Self> { + fn try_from(boot42: regs::NV_PMC_BOOT_42) -> Result<Self> { Ok(Self { - chipset: boot0.chipset()?, - revision: boot0.into(), + chipset: boot42.chipset()?, + revision: boot42.into(), }) } } |