summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2025-07-18 16:26:23 +0900
committerAlexandre Courbot <acourbot@nvidia.com>2025-08-15 12:02:56 +0900
commitec2f6c81d2a16a93d882488062e8e09e2f1d6865 (patch)
treec96c9f0a5c5b3b45022f3f090f6582a6eef0f017
parent20ed4a8695b277c296e3a30306ef8551903e1e04 (diff)
gpu: nova-core: falcon: use register arrays for FUSE registers
FUSE registers are an array of 16 consecutive registers. Use the newly available register array feature to define them properly and improve the code using them. Reviewed-by: Lyude Paul <lyude@redhat.com> Link: https://lore.kernel.org/r/20250718-nova-regs-v2-18-7b6a762aa1cd@nvidia.com Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
-rw-r--r--drivers/gpu/nova-core/falcon/hal/ga102.rs33
-rw-r--r--drivers/gpu/nova-core/regs.rs8
2 files changed, 20 insertions, 21 deletions
diff --git a/drivers/gpu/nova-core/falcon/hal/ga102.rs b/drivers/gpu/nova-core/falcon/hal/ga102.rs
index 3fdacd19322d..13c945fd6d6b 100644
--- a/drivers/gpu/nova-core/falcon/hal/ga102.rs
+++ b/drivers/gpu/nova-core/falcon/hal/ga102.rs
@@ -42,35 +42,32 @@ fn signature_reg_fuse_version_ga102(
engine_id_mask: u16,
ucode_id: u8,
) -> Result<u32> {
- // TODO[REGA]: The ucode fuse versions are contained in the
- // FUSE_OPT_FPF_<ENGINE>_UCODE<X>_VERSION registers, which are an array. Our register
- // definition macros do not allow us to manage them properly, so we need to hardcode their
- // addresses for now. Clean this up once we support register arrays.
+ const NV_FUSE_OPT_FPF_SIZE: u8 = regs::NV_FUSE_OPT_FPF_SIZE as u8;
// Each engine has 16 ucode version registers numbered from 1 to 16.
- if ucode_id == 0 || ucode_id > 16 {
- dev_err!(dev, "invalid ucode id {:#x}", ucode_id);
- return Err(EINVAL);
- }
+ let ucode_idx = match ucode_id {
+ 1..=NV_FUSE_OPT_FPF_SIZE => (ucode_id - 1) as usize,
+ _ => {
+ dev_err!(dev, "invalid ucode id {:#x}", ucode_id);
+ return Err(EINVAL);
+ }
+ };
- // Base address of the FUSE registers array corresponding to the engine.
- let reg_fuse_base = if engine_id_mask & 0x0001 != 0 {
- regs::NV_FUSE_OPT_FPF_SEC2_UCODE1_VERSION::OFFSET
+ // `ucode_idx` is guaranteed to be in the range [0..15], making the `read` calls provable valid
+ // at build-time.
+ let reg_fuse_version = if engine_id_mask & 0x0001 != 0 {
+ regs::NV_FUSE_OPT_FPF_SEC2_UCODE1_VERSION::read(bar, ucode_idx).data()
} else if engine_id_mask & 0x0004 != 0 {
- regs::NV_FUSE_OPT_FPF_NVDEC_UCODE1_VERSION::OFFSET
+ regs::NV_FUSE_OPT_FPF_NVDEC_UCODE1_VERSION::read(bar, ucode_idx).data()
} else if engine_id_mask & 0x0400 != 0 {
- regs::NV_FUSE_OPT_FPF_GSP_UCODE1_VERSION::OFFSET
+ regs::NV_FUSE_OPT_FPF_GSP_UCODE1_VERSION::read(bar, ucode_idx).data()
} else {
dev_err!(dev, "unexpected engine_id_mask {:#x}", engine_id_mask);
return Err(EINVAL);
};
- // Read `reg_fuse_base[ucode_id - 1]`.
- let reg_fuse_version =
- bar.read32(reg_fuse_base + ((ucode_id - 1) as usize * core::mem::size_of::<u32>()));
-
// TODO[NUMM]: replace with `last_set_bit` once it lands.
- Ok(u32::BITS - reg_fuse_version.leading_zeros())
+ Ok(u16::BITS - reg_fuse_version.leading_zeros())
}
fn program_brom_ga102<E: FalconEngine>(bar: &Bar0, params: &FalconBromParams) -> Result {
diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
index c45de208055d..4ae2a91bcce8 100644
--- a/drivers/gpu/nova-core/regs.rs
+++ b/drivers/gpu/nova-core/regs.rs
@@ -182,15 +182,17 @@ impl NV_PDISP_VGA_WORKSPACE_BASE {
// FUSE
-register!(NV_FUSE_OPT_FPF_NVDEC_UCODE1_VERSION @ 0x00824100 {
+pub(crate) const NV_FUSE_OPT_FPF_SIZE: usize = 16;
+
+register!(NV_FUSE_OPT_FPF_NVDEC_UCODE1_VERSION @ 0x00824100[NV_FUSE_OPT_FPF_SIZE] {
15:0 data as u16;
});
-register!(NV_FUSE_OPT_FPF_SEC2_UCODE1_VERSION @ 0x00824140 {
+register!(NV_FUSE_OPT_FPF_SEC2_UCODE1_VERSION @ 0x00824140[NV_FUSE_OPT_FPF_SIZE] {
15:0 data as u16;
});
-register!(NV_FUSE_OPT_FPF_GSP_UCODE1_VERSION @ 0x008241c0 {
+register!(NV_FUSE_OPT_FPF_GSP_UCODE1_VERSION @ 0x008241c0[NV_FUSE_OPT_FPF_SIZE] {
15:0 data as u16;
});