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