1 // SPDX-License-Identifier: GPL-2.0 2 // SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 4 use kernel::{ 5 io::Io, 6 num::Bounded, 7 prelude::*, // 8 }; 9 10 use crate::{ 11 driver::Bar0, 12 fb::hal::FbHal, 13 regs, // 14 }; 15 16 use super::tu102::FLUSH_SYSMEM_ADDR_SHIFT; 17 18 struct Ga100; 19 20 pub(super) fn read_sysmem_flush_page_ga100(bar: Bar0<'_>) -> u64 { 21 u64::from(bar.read(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR).adr_39_08()) << FLUSH_SYSMEM_ADDR_SHIFT 22 | u64::from(bar.read(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI).adr_63_40()) 23 << FLUSH_SYSMEM_ADDR_SHIFT_HI 24 } 25 26 pub(super) fn write_sysmem_flush_page_ga100(bar: Bar0<'_>, addr: u64) { 27 bar.write_reg( 28 regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI::zeroed().with_adr_63_40( 29 Bounded::<u64, _>::from(addr) 30 .shr::<FLUSH_SYSMEM_ADDR_SHIFT_HI, _>() 31 .cast(), 32 ), 33 ); 34 35 bar.write_reg( 36 regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR::zeroed() 37 // CAST: `as u32` is used on purpose since we want to strip the upper bits that have 38 // been written to `NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI`. 39 .with_adr_39_08((addr >> FLUSH_SYSMEM_ADDR_SHIFT) as u32), 40 ); 41 } 42 43 pub(super) fn display_enabled_ga100(bar: Bar0<'_>) -> bool { 44 !bar.read(regs::ga100::NV_FUSE_STATUS_OPT_DISPLAY) 45 .display_disabled() 46 } 47 48 /// Shift applied to the sysmem address before it is written into 49 /// `NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI`, 50 const FLUSH_SYSMEM_ADDR_SHIFT_HI: u32 = 40; 51 52 impl FbHal for Ga100 { 53 fn read_sysmem_flush_page(&self, bar: Bar0<'_>) -> u64 { 54 read_sysmem_flush_page_ga100(bar) 55 } 56 57 fn write_sysmem_flush_page(&self, bar: Bar0<'_>, addr: u64) -> Result { 58 write_sysmem_flush_page_ga100(bar, addr); 59 60 Ok(()) 61 } 62 63 fn supports_display(&self, bar: Bar0<'_>) -> bool { 64 display_enabled_ga100(bar) 65 } 66 67 fn vidmem_size(&self, bar: Bar0<'_>) -> u64 { 68 super::tu102::vidmem_size_gp102(bar) 69 } 70 71 fn pmu_reserved_size(&self) -> u32 { 72 super::tu102::pmu_reserved_size_tu102() 73 } 74 75 fn non_wpr_heap_size(&self) -> u32 { 76 super::tu102::non_wpr_heap_size_tu102() 77 } 78 79 // GA100 is a special case where its FRTS region exists, but is empty. We 80 // return a size of 0 because we still need to record where the region starts. 81 fn frts_size(&self) -> u64 { 82 0 83 } 84 } 85 86 const GA100: Ga100 = Ga100; 87 pub(super) const GA100_HAL: &dyn FbHal = &GA100; 88