xref: /linux/drivers/gpu/nova-core/fb/regs.rs (revision 4e69c1856bfd9ffb7e9d335a25842fa211628929)
19102e655SAntonin Malzieu Ridolfi // SPDX-License-Identifier: GPL-2.0
29102e655SAntonin Malzieu Ridolfi 
3*81aa6f19SAntonin Malzieu Ridolfi use kernel::{
4*81aa6f19SAntonin Malzieu Ridolfi     io::register,
5*81aa6f19SAntonin Malzieu Ridolfi     sizes::SizeConstants, //
6*81aa6f19SAntonin Malzieu Ridolfi };
79102e655SAntonin Malzieu Ridolfi 
89102e655SAntonin Malzieu Ridolfi // PDISP
99102e655SAntonin Malzieu Ridolfi 
109102e655SAntonin Malzieu Ridolfi register! {
119102e655SAntonin Malzieu Ridolfi     pub(super) NV_PDISP_VGA_WORKSPACE_BASE(u32) @ 0x00625f04 {
129102e655SAntonin Malzieu Ridolfi         /// VGA workspace base address divided by 0x10000.
139102e655SAntonin Malzieu Ridolfi         31:8    addr;
149102e655SAntonin Malzieu Ridolfi         /// Set if the `addr` field is valid.
159102e655SAntonin Malzieu Ridolfi         3:3     status_valid => bool;
169102e655SAntonin Malzieu Ridolfi     }
179102e655SAntonin Malzieu Ridolfi }
189102e655SAntonin Malzieu Ridolfi 
199102e655SAntonin Malzieu Ridolfi impl NV_PDISP_VGA_WORKSPACE_BASE {
209102e655SAntonin Malzieu Ridolfi     /// Returns the base address of the VGA workspace, or `None` if none exists.
219102e655SAntonin Malzieu Ridolfi     pub(super) fn vga_workspace_addr(self) -> Option<u64> {
229102e655SAntonin Malzieu Ridolfi         if self.status_valid() {
239102e655SAntonin Malzieu Ridolfi             Some(u64::from(self.addr()) << 16)
249102e655SAntonin Malzieu Ridolfi         } else {
259102e655SAntonin Malzieu Ridolfi             None
269102e655SAntonin Malzieu Ridolfi         }
279102e655SAntonin Malzieu Ridolfi     }
289102e655SAntonin Malzieu Ridolfi }
29*81aa6f19SAntonin Malzieu Ridolfi 
30*81aa6f19SAntonin Malzieu Ridolfi // PFB
31*81aa6f19SAntonin Malzieu Ridolfi 
32*81aa6f19SAntonin Malzieu Ridolfi register! {
33*81aa6f19SAntonin Malzieu Ridolfi     /// Low bits of the physical system memory address used by the GPU to perform sysmembar
34*81aa6f19SAntonin Malzieu Ridolfi     /// operations (see [`crate::fb::SysmemFlush`]).
35*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_NISO_FLUSH_SYSMEM_ADDR(u32) @ 0x00100c10 {
36*81aa6f19SAntonin Malzieu Ridolfi         31:0    adr_39_08;
37*81aa6f19SAntonin Malzieu Ridolfi     }
38*81aa6f19SAntonin Malzieu Ridolfi 
39*81aa6f19SAntonin Malzieu Ridolfi     /// High bits of the physical system memory address used by the GPU to perform sysmembar
40*81aa6f19SAntonin Malzieu Ridolfi     /// operations.
41*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI(u32) @ 0x00100c40 {
42*81aa6f19SAntonin Malzieu Ridolfi         23:0    adr_63_40;
43*81aa6f19SAntonin Malzieu Ridolfi     }
44*81aa6f19SAntonin Malzieu Ridolfi 
45*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_PRI_MMU_LOCAL_MEMORY_RANGE(u32) @ 0x00100ce0 {
46*81aa6f19SAntonin Malzieu Ridolfi         30:30   ecc_mode_enabled => bool;
47*81aa6f19SAntonin Malzieu Ridolfi         9:4     lower_mag;
48*81aa6f19SAntonin Malzieu Ridolfi         3:0     lower_scale;
49*81aa6f19SAntonin Malzieu Ridolfi     }
50*81aa6f19SAntonin Malzieu Ridolfi 
51*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_PRI_MMU_WPR2_ADDR_LO(u32) @ 0x001fa824 {
52*81aa6f19SAntonin Malzieu Ridolfi         /// Bits 12..40 of the lower (inclusive) bound of the WPR2 region.
53*81aa6f19SAntonin Malzieu Ridolfi         31:4    lo_val;
54*81aa6f19SAntonin Malzieu Ridolfi     }
55*81aa6f19SAntonin Malzieu Ridolfi 
56*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_PRI_MMU_WPR2_ADDR_HI(u32) @ 0x001fa828 {
57*81aa6f19SAntonin Malzieu Ridolfi         /// Bits 12..40 of the higher (exclusive) bound of the WPR2 region.
58*81aa6f19SAntonin Malzieu Ridolfi         31:4    hi_val;
59*81aa6f19SAntonin Malzieu Ridolfi     }
60*81aa6f19SAntonin Malzieu Ridolfi }
61*81aa6f19SAntonin Malzieu Ridolfi 
62*81aa6f19SAntonin Malzieu Ridolfi /// Base of the GB10x HSHUB0 register window (`NV_HSHUB0_PRIV_BASE` in Open RM).
63*81aa6f19SAntonin Malzieu Ridolfi ///
64*81aa6f19SAntonin Malzieu Ridolfi /// The base is provided by the GB10x framebuffer HAL.
65*81aa6f19SAntonin Malzieu Ridolfi pub(super) struct Hshub0Base(());
66*81aa6f19SAntonin Malzieu Ridolfi 
67*81aa6f19SAntonin Malzieu Ridolfi register! {
68*81aa6f19SAntonin Malzieu Ridolfi     // GB10x sysmem flush registers, relative to the HSHUB0 base. GB10x routes sysmembar
69*81aa6f19SAntonin Malzieu Ridolfi     // through a primary and an EG (egress) pair that must both be programmed to the same
70*81aa6f19SAntonin Malzieu Ridolfi     // address. Hardware ignores bits 7:0 of each LO register. The boot path uses a fixed
71*81aa6f19SAntonin Malzieu Ridolfi     // HSHUB0 base, so the multiple runtime-discovered HSHUB bases are not needed here.
72*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ Hshub0Base + 0x00000e50 {
73*81aa6f19SAntonin Malzieu Ridolfi         31:0    adr => u32;
74*81aa6f19SAntonin Malzieu Ridolfi     }
75*81aa6f19SAntonin Malzieu Ridolfi 
76*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ Hshub0Base + 0x00000e54 {
77*81aa6f19SAntonin Malzieu Ridolfi         19:0    adr;
78*81aa6f19SAntonin Malzieu Ridolfi     }
79*81aa6f19SAntonin Malzieu Ridolfi 
80*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ Hshub0Base + 0x000006c0 {
81*81aa6f19SAntonin Malzieu Ridolfi         31:0    adr => u32;
82*81aa6f19SAntonin Malzieu Ridolfi     }
83*81aa6f19SAntonin Malzieu Ridolfi 
84*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ Hshub0Base + 0x000006c4 {
85*81aa6f19SAntonin Malzieu Ridolfi         19:0    adr;
86*81aa6f19SAntonin Malzieu Ridolfi     }
87*81aa6f19SAntonin Malzieu Ridolfi }
88*81aa6f19SAntonin Malzieu Ridolfi 
89*81aa6f19SAntonin Malzieu Ridolfi register! {
90*81aa6f19SAntonin Malzieu Ridolfi     // GB20x FBHUB0 sysmem flush registers. Unlike the older
91*81aa6f19SAntonin Malzieu Ridolfi     // NV_PFB_NISO_FLUSH_SYSMEM_ADDR registers, which encode the address with an
92*81aa6f19SAntonin Malzieu Ridolfi     // 8-bit right-shift, these take the raw address split into lower and upper
93*81aa6f19SAntonin Malzieu Ridolfi     // halves. Hardware ignores bits 7:0 of the LO register.
94*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ 0x008a1d58 {
95*81aa6f19SAntonin Malzieu Ridolfi         31:0    adr => u32;
96*81aa6f19SAntonin Malzieu Ridolfi     }
97*81aa6f19SAntonin Malzieu Ridolfi 
98*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ 0x008a1d5c {
99*81aa6f19SAntonin Malzieu Ridolfi         19:0    adr;
100*81aa6f19SAntonin Malzieu Ridolfi     }
101*81aa6f19SAntonin Malzieu Ridolfi }
102*81aa6f19SAntonin Malzieu Ridolfi 
103*81aa6f19SAntonin Malzieu Ridolfi register! {
104*81aa6f19SAntonin Malzieu Ridolfi     /// Low bits of the physical system memory address used by the GPU to perform
105*81aa6f19SAntonin Malzieu Ridolfi     /// sysmembar operations on Hopper.
106*81aa6f19SAntonin Malzieu Ridolfi     ///
107*81aa6f19SAntonin Malzieu Ridolfi     /// Like the GB20x FBHUB0 registers, and unlike the Ampere
108*81aa6f19SAntonin Malzieu Ridolfi     /// `NV_PFB_NISO_FLUSH_SYSMEM_ADDR` registers (which encode the address with an
109*81aa6f19SAntonin Malzieu Ridolfi     /// 8-bit right-shift), these take the raw address split into lower and upper
110*81aa6f19SAntonin Malzieu Ridolfi     /// halves. Hardware ignores bits 7:0 of the LO register.
111*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ 0x00100a34 {
112*81aa6f19SAntonin Malzieu Ridolfi         31:0    adr => u32;
113*81aa6f19SAntonin Malzieu Ridolfi     }
114*81aa6f19SAntonin Malzieu Ridolfi 
115*81aa6f19SAntonin Malzieu Ridolfi     /// High bits of the physical system memory address used by the GPU to perform
116*81aa6f19SAntonin Malzieu Ridolfi     /// sysmembar operations on Hopper.
117*81aa6f19SAntonin Malzieu Ridolfi     pub(super) NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ 0x00100a38 {
118*81aa6f19SAntonin Malzieu Ridolfi         19:0    adr;
119*81aa6f19SAntonin Malzieu Ridolfi     }
120*81aa6f19SAntonin Malzieu Ridolfi }
121*81aa6f19SAntonin Malzieu Ridolfi 
122*81aa6f19SAntonin Malzieu Ridolfi impl NV_PFB_PRI_MMU_LOCAL_MEMORY_RANGE {
123*81aa6f19SAntonin Malzieu Ridolfi     /// Returns the usable framebuffer size, in bytes.
124*81aa6f19SAntonin Malzieu Ridolfi     pub(super) fn usable_fb_size(self) -> u64 {
125*81aa6f19SAntonin Malzieu Ridolfi         let size = (u64::from(self.lower_mag()) << u64::from(self.lower_scale())) * u64::SZ_1M;
126*81aa6f19SAntonin Malzieu Ridolfi 
127*81aa6f19SAntonin Malzieu Ridolfi         if self.ecc_mode_enabled() {
128*81aa6f19SAntonin Malzieu Ridolfi             // Remove the amount of memory reserved for ECC (one per 16 units).
129*81aa6f19SAntonin Malzieu Ridolfi             size / 16 * 15
130*81aa6f19SAntonin Malzieu Ridolfi         } else {
131*81aa6f19SAntonin Malzieu Ridolfi             size
132*81aa6f19SAntonin Malzieu Ridolfi         }
133*81aa6f19SAntonin Malzieu Ridolfi     }
134*81aa6f19SAntonin Malzieu Ridolfi }
135*81aa6f19SAntonin Malzieu Ridolfi 
136*81aa6f19SAntonin Malzieu Ridolfi impl NV_PFB_PRI_MMU_WPR2_ADDR_LO {
137*81aa6f19SAntonin Malzieu Ridolfi     /// Returns the lower (inclusive) bound of the WPR2 region.
138*81aa6f19SAntonin Malzieu Ridolfi     pub(super) fn lower_bound(self) -> u64 {
139*81aa6f19SAntonin Malzieu Ridolfi         u64::from(self.lo_val()) << 12
140*81aa6f19SAntonin Malzieu Ridolfi     }
141*81aa6f19SAntonin Malzieu Ridolfi }
142*81aa6f19SAntonin Malzieu Ridolfi 
143*81aa6f19SAntonin Malzieu Ridolfi impl NV_PFB_PRI_MMU_WPR2_ADDR_HI {
144*81aa6f19SAntonin Malzieu Ridolfi     /// Returns the higher (exclusive) bound of the WPR2 region.
145*81aa6f19SAntonin Malzieu Ridolfi     ///
146*81aa6f19SAntonin Malzieu Ridolfi     /// A value of zero means the WPR2 region is not set.
147*81aa6f19SAntonin Malzieu Ridolfi     pub(super) fn higher_bound(self) -> u64 {
148*81aa6f19SAntonin Malzieu Ridolfi         u64::from(self.hi_val()) << 12
149*81aa6f19SAntonin Malzieu Ridolfi     }
150*81aa6f19SAntonin Malzieu Ridolfi 
151*81aa6f19SAntonin Malzieu Ridolfi     /// Returns whether the WPR2 region is currently set.
152*81aa6f19SAntonin Malzieu Ridolfi     pub(super) fn is_wpr2_set(self) -> bool {
153*81aa6f19SAntonin Malzieu Ridolfi         self.hi_val() != 0
154*81aa6f19SAntonin Malzieu Ridolfi     }
155*81aa6f19SAntonin Malzieu Ridolfi }
156