Skip to content

Commit c3f2226

Browse files
GnurouDanilo Krummrich
authored andcommitted
gpu: nova-core: define registers layout using helper macro
Add the register!() macro, which defines a given register's layout and provide bit-field accessors with a way to convert them to a given type. This macro will allow us to make clear definitions of the registers and manipulate their fields safely. The long-term goal is to eventually move it to the kernel crate so it can be used by other drivers as well, but it was agreed to first land it into nova-core and make it mature there. To illustrate its usage, use it to define the layout for the Boot0 (renamed to NV_PMC_BOOT_0 to match OpenRM's naming scheme) and take advantage of its accessors. Suggested-by: Danilo Krummrich <[email protected]> Signed-off-by: Alexandre Courbot <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ Fix typo in commit message. - Danilo ] Signed-off-by: Danilo Krummrich <[email protected]>
1 parent a2a637f commit c3f2226

File tree

4 files changed

+403
-54
lines changed

4 files changed

+403
-54
lines changed

Documentation/gpu/nova/core/todo.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,13 @@ Usage:
102102
let boot0 = Boot0::read(&bar);
103103
pr_info!("Revision: {}\n", boot0.revision());
104104
105+
Note: a work-in-progress implementation currently resides in
106+
`drivers/gpu/nova-core/regs/macros.rs` and is used in nova-core. It would be
107+
nice to improve it (possibly using proc macros) and move it to the `kernel`
108+
crate so it can be used by other components as well.
109+
105110
| Complexity: Advanced
111+
| Contact: Alexandre Courbot
106112
107113
Delay / Sleep abstractions
108114
--------------------------

drivers/gpu/nova-core/gpu.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@ pub(crate) struct Revision {
112112
}
113113

114114
impl Revision {
115-
fn from_boot0(boot0: regs::Boot0) -> Self {
115+
fn from_boot0(boot0: regs::NV_PMC_BOOT_0) -> Self {
116116
Self {
117-
major: boot0.major_rev(),
118-
minor: boot0.minor_rev(),
117+
major: boot0.major_revision(),
118+
minor: boot0.minor_revision(),
119119
}
120120
}
121121
}
@@ -135,10 +135,10 @@ pub(crate) struct Spec {
135135

136136
impl Spec {
137137
fn new(bar: &Bar0) -> Result<Spec> {
138-
let boot0 = regs::Boot0::read(bar);
138+
let boot0 = regs::NV_PMC_BOOT_0::read(bar);
139139

140140
Ok(Self {
141-
chipset: boot0.chipset().try_into()?,
141+
chipset: boot0.chipset()?,
142142
revision: Revision::from_boot0(boot0),
143143
})
144144
}

drivers/gpu/nova-core/regs.rs

Lines changed: 12 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,18 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3-
use crate::driver::Bar0;
3+
// Required to retain the original register names used by OpenRM, which are all capital snake case
4+
// but are mapped to types.
5+
#![allow(non_camel_case_types)]
46

5-
// TODO
6-
//
7-
// Create register definitions via generic macros. See task "Generic register
8-
// abstraction" in Documentation/gpu/nova/core/todo.rst.
7+
#[macro_use]
8+
mod macros;
99

10-
const BOOT0_OFFSET: usize = 0x00000000;
10+
use crate::gpu::Chipset;
1111

12-
// 3:0 - chipset minor revision
13-
const BOOT0_MINOR_REV_SHIFT: u8 = 0;
14-
const BOOT0_MINOR_REV_MASK: u32 = 0x0000000f;
12+
/* PMC */
1513

16-
// 7:4 - chipset major revision
17-
const BOOT0_MAJOR_REV_SHIFT: u8 = 4;
18-
const BOOT0_MAJOR_REV_MASK: u32 = 0x000000f0;
19-
20-
// 23:20 - chipset implementation Identifier (depends on architecture)
21-
const BOOT0_IMPL_SHIFT: u8 = 20;
22-
const BOOT0_IMPL_MASK: u32 = 0x00f00000;
23-
24-
// 28:24 - chipset architecture identifier
25-
const BOOT0_ARCH_MASK: u32 = 0x1f000000;
26-
27-
// 28:20 - chipset identifier (virtual register field combining BOOT0_IMPL and
28-
// BOOT0_ARCH)
29-
const BOOT0_CHIPSET_SHIFT: u8 = BOOT0_IMPL_SHIFT;
30-
const BOOT0_CHIPSET_MASK: u32 = BOOT0_IMPL_MASK | BOOT0_ARCH_MASK;
31-
32-
#[derive(Copy, Clone)]
33-
pub(crate) struct Boot0(u32);
34-
35-
impl Boot0 {
36-
#[inline]
37-
pub(crate) fn read(bar: &Bar0) -> Self {
38-
Self(bar.read32(BOOT0_OFFSET))
39-
}
40-
41-
#[inline]
42-
pub(crate) fn chipset(&self) -> u32 {
43-
(self.0 & BOOT0_CHIPSET_MASK) >> BOOT0_CHIPSET_SHIFT
44-
}
45-
46-
#[inline]
47-
pub(crate) fn minor_rev(&self) -> u8 {
48-
((self.0 & BOOT0_MINOR_REV_MASK) >> BOOT0_MINOR_REV_SHIFT) as u8
49-
}
50-
51-
#[inline]
52-
pub(crate) fn major_rev(&self) -> u8 {
53-
((self.0 & BOOT0_MAJOR_REV_MASK) >> BOOT0_MAJOR_REV_SHIFT) as u8
54-
}
55-
}
14+
register!(NV_PMC_BOOT_0 @ 0x00000000, "Basic revision information about the GPU" {
15+
3:0 minor_revision as u8, "Minor revision of the chip";
16+
7:4 major_revision as u8, "Major revision of the chip";
17+
28:20 chipset as u32 ?=> Chipset, "Chipset model";
18+
});

0 commit comments

Comments
 (0)