xref: /linux/drivers/gpu/nova-core/fb/hal/gb202.rs (revision 570f7e331f5febb30f1384817463c7e42b65ca7d)
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::{
16         hal::FbHal,
17         regs, //
18     },
19 };
20 
21 struct Gb202;
22 
23 fn read_sysmem_flush_page_gb202(bar: Bar0<'_>) -> u64 {
24     let lo = u64::from(
25         bar.read(regs::NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO)
26             .adr(),
27     );
28     let hi = u64::from(
29         bar.read(regs::NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI)
30             .adr(),
31     );
32 
33     (hi << 32) | lo
34 }
35 
36 /// Write the sysmem flush page address through the GB20x FBHUB0 registers.
37 fn write_sysmem_flush_page_gb202(bar: Bar0<'_>, addr: Bounded<u64, 52>) {
38     // Write HI first. The hardware will trigger the flush on the LO write.
39     bar.write_reg(
40         regs::NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI::zeroed()
41             .with_adr(addr.shr::<32, 20>().cast::<u32>()),
42     );
43     bar.write_reg(
44         // CAST: lower 32 bits. Hardware ignores bits 7:0.
45         regs::NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO::zeroed().with_adr(*addr as u32),
46     );
47 }
48 
49 impl FbHal for Gb202 {
50     fn read_sysmem_flush_page(&self, bar: Bar0<'_>) -> u64 {
51         read_sysmem_flush_page_gb202(bar)
52     }
53 
54     fn write_sysmem_flush_page(&self, bar: Bar0<'_>, addr: u64) -> Result {
55         let addr = Bounded::<u64, 52>::try_new(addr).ok_or(EINVAL)?;
56 
57         write_sysmem_flush_page_gb202(bar, addr);
58 
59         Ok(())
60     }
61 
62     fn supports_display(&self, bar: Bar0<'_>) -> bool {
63         super::ga100::display_enabled_ga100(bar)
64     }
65 
66     fn vidmem_size(&self, bar: Bar0<'_>) -> u64 {
67         super::ga102::vidmem_size_ga102(bar)
68     }
69 
70     fn pmu_reserved_size(&self) -> u32 {
71         super::gb100::pmu_reserved_size_gb100()
72     }
73 
74     fn non_wpr_heap_size(&self) -> u64 {
75         // Non-WPR heap for GB20x (see Open RM: kgspGetNonWprHeapSize, GB202+).
76         // This size is r570-specific.
77         u64::SZ_2M + u64::SZ_128K
78     }
79 
80     fn frts_size(&self) -> u64 {
81         super::tu102::frts_size_tu102()
82     }
83 }
84 
85 const GB202: Gb202 = Gb202;
86 pub(super) const GB202_HAL: &dyn FbHal = &GB202;
87