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