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