xref: /linux/drivers/gpu/nova-core/fb/hal/gb202.rs (revision 23d66dbab84e8518943563df2ced14aaab28b77a)
1 // SPDX-License-Identifier: GPL-2.0
2 // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 
4 //! Blackwell GB20x framebuffer HAL.
5 
6 use kernel::{
7     io::Io,
8     num::Bounded,
9     prelude::*,
10     sizes::SizeConstants, //
11 };
12 
13 use crate::{
14     driver::Bar0,
15     fb::hal::FbHal,
16     regs, //
17 };
18 
19 struct Gb202;
20 
21 fn read_sysmem_flush_page_gb202(bar: Bar0<'_>) -> u64 {
22     let lo = u64::from(
23         bar.read(regs::NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO)
24             .adr(),
25     );
26     let hi = u64::from(
27         bar.read(regs::NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI)
28             .adr(),
29     );
30 
31     (hi << 32) | lo
32 }
33 
34 /// Write the sysmem flush page address through the GB20x FBHUB0 registers.
35 fn write_sysmem_flush_page_gb202(bar: Bar0<'_>, addr: Bounded<u64, 52>) {
36     // Write HI first. The hardware will trigger the flush on the LO write.
37     bar.write_reg(
38         regs::NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI::zeroed()
39             .with_adr(addr.shr::<32, 20>().cast::<u32>()),
40     );
41     bar.write_reg(
42         // CAST: lower 32 bits. Hardware ignores bits 7:0.
43         regs::NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO::zeroed().with_adr(*addr as u32),
44     );
45 }
46 
47 impl FbHal for Gb202 {
48     fn read_sysmem_flush_page(&self, bar: Bar0<'_>) -> u64 {
49         read_sysmem_flush_page_gb202(bar)
50     }
51 
52     fn write_sysmem_flush_page(&self, bar: Bar0<'_>, addr: u64) -> Result {
53         let addr = Bounded::<u64, 52>::try_new(addr).ok_or(EINVAL)?;
54 
55         write_sysmem_flush_page_gb202(bar, addr);
56 
57         Ok(())
58     }
59 
60     fn supports_display(&self, bar: Bar0<'_>) -> bool {
61         super::ga100::display_enabled_ga100(bar)
62     }
63 
64     fn vidmem_size(&self, bar: Bar0<'_>) -> u64 {
65         super::ga102::vidmem_size_ga102(bar)
66     }
67 
68     fn pmu_reserved_size(&self) -> u32 {
69         super::gb100::pmu_reserved_size_gb100()
70     }
71 
72     fn non_wpr_heap_size(&self) -> u32 {
73         // Non-WPR heap for GB20x (see Open RM: kgspGetNonWprHeapSize, GB202+).
74         u32::SZ_2M + u32::SZ_128K
75     }
76 
77     fn frts_size(&self) -> u64 {
78         super::tu102::frts_size_tu102()
79     }
80 }
81 
82 const GB202: Gb202 = Gb202;
83 pub(super) const GB202_HAL: &dyn FbHal = &GB202;
84