xref: /linux/drivers/gpu/nova-core/fb/hal/ga100.rs (revision bba2c3615bd6cfee7456d1130f2e6b01b3f4e9ba)
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