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