From: Daniel Almeida <[email protected]>

Convert the GPU_CONTROL register definitions to use the `register!` macro.

Using the `register!` macro allows us to replace manual bit masks and
shifts with typed register and field accessors, which makes the code
easier to read and avoids errors from bit manipulation.

Signed-off-by: Daniel Almeida <[email protected]>
Co-developed-by: Deborah Brouwer <[email protected]>
Signed-off-by: Deborah Brouwer <[email protected]>
---
 drivers/gpu/drm/tyr/driver.rs |  26 +-
 drivers/gpu/drm/tyr/gpu.rs    | 211 ++++++--------
 drivers/gpu/drm/tyr/regs.rs   | 644 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 687 insertions(+), 194 deletions(-)

diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs
index 
611434641580574ec6b5afa49a8fe79888bb7ace..10c212a3a01910858f02c6d637edff8a263f017b
 100644
--- a/drivers/gpu/drm/tyr/driver.rs
+++ b/drivers/gpu/drm/tyr/driver.rs
@@ -13,7 +13,10 @@
     devres::Devres,
     drm,
     drm::ioctl,
-    io::poll,
+    io::{
+        poll,
+        Io, //
+    },
     new_mutex,
     of,
     platform,
@@ -33,8 +36,11 @@
     file::TyrDrmFileData,
     gem::TyrObject,
     gpu,
-    gpu::GpuInfo,
-    regs, //
+    gpu::{
+        gpu_info_log, //
+        GpuInfo,
+    },
+    regs::*, //
 };
 
 pub(crate) type IoMem = kernel::io::mem::IoMem<SZ_2M>;
@@ -78,11 +84,17 @@ unsafe impl Send for TyrDrmDeviceData {}
 unsafe impl Sync for TyrDrmDeviceData {}
 
 fn issue_soft_reset(dev: &Device<Bound>, iomem: &Devres<IoMem>) -> Result {
-    regs::GPU_CMD.write(dev, iomem, regs::GPU_CMD_SOFT_RESET)?;
+    let io = (*iomem).access(dev)?;
+    io.write_val(
+        GPU_COMMAND_RESET::zeroed().with_const_reset_mode::<{ 
GPU_COMMAND_RESET::SOFT_RESET }>(),
+    );
 
     poll::read_poll_timeout(
-        || regs::GPU_IRQ_RAWSTAT.read(dev, iomem),
-        |status| *status & regs::GPU_IRQ_RAWSTAT_RESET_COMPLETED != 0,
+        || {
+            let io = (*iomem).access(dev)?;
+            Ok(io.read(GPU_IRQ_RAWSTAT))
+        },
+        |status| status.reset_completed().get() != 0,
         time::Delta::from_millis(1),
         time::Delta::from_millis(100),
     )
@@ -127,7 +139,7 @@ fn probe(
         gpu::l2_power_on(pdev.as_ref(), &iomem)?;
 
         let gpu_info = GpuInfo::new(pdev.as_ref(), &iomem)?;
-        gpu_info.log(pdev);
+        gpu_info_log(pdev.as_ref(), &iomem)?;
 
         let platform: ARef<platform::Device> = pdev.into();
 
diff --git a/drivers/gpu/drm/tyr/gpu.rs b/drivers/gpu/drm/tyr/gpu.rs
index 
a88775160f981e899e9c9b58debbda33e1b7244d..51a250570f375e12bb0f7fb32f047bf219ef9b70
 100644
--- a/drivers/gpu/drm/tyr/gpu.rs
+++ b/drivers/gpu/drm/tyr/gpu.rs
@@ -5,14 +5,15 @@
     DerefMut, //
 };
 use kernel::{
-    bits::genmask_u32,
     device::{
         Bound,
         Device, //
     },
     devres::Devres,
-    io::poll,
-    platform,
+    io::{
+        poll,
+        Io, //
+    },
     prelude::*,
     time::Delta,
     transmute::AsBytes,
@@ -21,7 +22,7 @@
 
 use crate::{
     driver::IoMem,
-    regs, //
+    regs::*, //
 };
 
 /// Struct containing information that can be queried by userspace. This is 
read from
@@ -29,120 +30,42 @@
 ///
 /// # Invariants
 ///
-/// - The layout of this struct identical to the C `struct 
drm_panthor_gpu_info`.
+/// - The layout of this struct is identical to the C `struct 
drm_panthor_gpu_info`.
 #[repr(transparent)]
 #[derive(Clone, Copy)]
 pub(crate) struct GpuInfo(pub(crate) uapi::drm_panthor_gpu_info);
 
 impl GpuInfo {
     pub(crate) fn new(dev: &Device<Bound>, iomem: &Devres<IoMem>) -> 
Result<Self> {
-        let gpu_id = regs::GPU_ID.read(dev, iomem)?;
-        let csf_id = regs::GPU_CSF_ID.read(dev, iomem)?;
-        let gpu_rev = regs::GPU_REVID.read(dev, iomem)?;
-        let core_features = regs::GPU_CORE_FEATURES.read(dev, iomem)?;
-        let l2_features = regs::GPU_L2_FEATURES.read(dev, iomem)?;
-        let tiler_features = regs::GPU_TILER_FEATURES.read(dev, iomem)?;
-        let mem_features = regs::GPU_MEM_FEATURES.read(dev, iomem)?;
-        let mmu_features = regs::GPU_MMU_FEATURES.read(dev, iomem)?;
-        let thread_features = regs::GPU_THREAD_FEATURES.read(dev, iomem)?;
-        let max_threads = regs::GPU_THREAD_MAX_THREADS.read(dev, iomem)?;
-        let thread_max_workgroup_size = 
regs::GPU_THREAD_MAX_WORKGROUP_SIZE.read(dev, iomem)?;
-        let thread_max_barrier_size = 
regs::GPU_THREAD_MAX_BARRIER_SIZE.read(dev, iomem)?;
-        let coherency_features = regs::GPU_COHERENCY_FEATURES.read(dev, 
iomem)?;
-
-        let texture_features = regs::GPU_TEXTURE_FEATURES0.read(dev, iomem)?;
-
-        let as_present = regs::GPU_AS_PRESENT.read(dev, iomem)?;
-
-        let shader_present = u64::from(regs::GPU_SHADER_PRESENT_LO.read(dev, 
iomem)?);
-        let shader_present =
-            shader_present | u64::from(regs::GPU_SHADER_PRESENT_HI.read(dev, 
iomem)?) << 32;
-
-        let tiler_present = u64::from(regs::GPU_TILER_PRESENT_LO.read(dev, 
iomem)?);
-        let tiler_present =
-            tiler_present | u64::from(regs::GPU_TILER_PRESENT_HI.read(dev, 
iomem)?) << 32;
-
-        let l2_present = u64::from(regs::GPU_L2_PRESENT_LO.read(dev, iomem)?);
-        let l2_present = l2_present | 
u64::from(regs::GPU_L2_PRESENT_HI.read(dev, iomem)?) << 32;
+        let io = (*iomem).access(dev)?;
 
         Ok(Self(uapi::drm_panthor_gpu_info {
-            gpu_id,
-            gpu_rev,
-            csf_id,
-            l2_features,
-            tiler_features,
-            mem_features,
-            mmu_features,
-            thread_features,
-            max_threads,
-            thread_max_workgroup_size,
-            thread_max_barrier_size,
-            coherency_features,
+            gpu_id: io.read(GPU_ID).into_raw(),
+            gpu_rev: io.read(REVIDR).into_raw(),
+            csf_id: io.read(CSF_ID).into_raw(),
+            l2_features: io.read(L2_FEATURES).into_raw(),
+            tiler_features: io.read(TILER_FEATURES).into_raw(),
+            mem_features: io.read(MEM_FEATURES).into_raw(),
+            mmu_features: io.read(MMU_FEATURES).into_raw(),
+            thread_features: io.read(THREAD_FEATURES).into_raw(),
+            max_threads: io.read(THREAD_MAX_THREADS).into_raw(),
+            thread_max_workgroup_size: 
io.read(THREAD_MAX_WORKGROUP_SIZE).into_raw(),
+            thread_max_barrier_size: 
io.read(THREAD_MAX_BARRIER_SIZE).into_raw(),
+            coherency_features: io.read(COHERENCY_FEATURES).into_raw(),
             // TODO: Add texture_features_{1,2,3}.
-            texture_features: [texture_features, 0, 0, 0],
-            as_present,
+            texture_features: [io.read(TEXTURE_FEATURES_0).into_raw(), 0, 0, 
0],
+            as_present: io.read(AS_PRESENT).into_raw(),
             selected_coherency: 
uapi::drm_panthor_gpu_coherency_DRM_PANTHOR_GPU_COHERENCY_NONE,
-            shader_present,
-            l2_present,
-            tiler_present,
-            core_features,
+            shader_present: io.read(SHADER_PRESENT).into_raw(),
+            l2_present: io.read(L2_PRESENT).into_raw(),
+            tiler_present: io.read(TILER_PRESENT).into_raw(),
+            core_features: io.read(CORE_FEATURES).into_raw(),
+            // Padding must be zero.
             pad: 0,
+            //GPU_FEATURES register is not available; it was introduced in 
arch 11.x.
             gpu_features: 0,
         }))
     }
-
-    pub(crate) fn log(&self, pdev: &platform::Device) {
-        let gpu_id = GpuId::from(self.gpu_id);
-
-        let model_name = if let Some(model) = GPU_MODELS
-            .iter()
-            .find(|&f| f.arch_major == gpu_id.arch_major && f.prod_major == 
gpu_id.prod_major)
-        {
-            model.name
-        } else {
-            "unknown"
-        };
-
-        dev_info!(
-            pdev,
-            "mali-{} id 0x{:x} major 0x{:x} minor 0x{:x} status 0x{:x}",
-            model_name,
-            self.gpu_id >> 16,
-            gpu_id.ver_major,
-            gpu_id.ver_minor,
-            gpu_id.ver_status
-        );
-
-        dev_info!(
-            pdev,
-            "Features: L2:{:#x} Tiler:{:#x} Mem:{:#x} MMU:{:#x} AS:{:#x}",
-            self.l2_features,
-            self.tiler_features,
-            self.mem_features,
-            self.mmu_features,
-            self.as_present
-        );
-
-        dev_info!(
-            pdev,
-            "shader_present=0x{:016x} l2_present=0x{:016x} 
tiler_present=0x{:016x}",
-            self.shader_present,
-            self.l2_present,
-            self.tiler_present
-        );
-    }
-
-    /// Returns the number of virtual address bits supported by the GPU.
-    #[expect(dead_code)]
-    pub(crate) fn va_bits(&self) -> u32 {
-        self.mmu_features & genmask_u32(0..=7)
-    }
-
-    /// Returns the number of physical address bits supported by the GPU.
-    #[expect(dead_code)]
-    pub(crate) fn pa_bits(&self) -> u32 {
-        (self.mmu_features >> 8) & genmask_u32(0..=7)
-    }
 }
 
 impl Deref for GpuInfo {
@@ -182,37 +105,67 @@ struct GpuModels {
     prod_major: 7,
 }];
 
-#[allow(dead_code)]
-pub(crate) struct GpuId {
-    pub(crate) arch_major: u32,
-    pub(crate) arch_minor: u32,
-    pub(crate) arch_rev: u32,
-    pub(crate) prod_major: u32,
-    pub(crate) ver_major: u32,
-    pub(crate) ver_minor: u32,
-    pub(crate) ver_status: u32,
-}
-
-impl From<u32> for GpuId {
-    fn from(value: u32) -> Self {
-        GpuId {
-            arch_major: (value & genmask_u32(28..=31)) >> 28,
-            arch_minor: (value & genmask_u32(24..=27)) >> 24,
-            arch_rev: (value & genmask_u32(20..=23)) >> 20,
-            prod_major: (value & genmask_u32(16..=19)) >> 16,
-            ver_major: (value & genmask_u32(12..=15)) >> 12,
-            ver_minor: (value & genmask_u32(4..=11)) >> 4,
-            ver_status: value & genmask_u32(0..=3),
-        }
-    }
+pub(crate) fn gpu_info_log(dev: &Device<Bound>, iomem: &Devres<IoMem>) -> 
Result {
+    let io = (*iomem).access(dev)?;
+    let gpu_id = io.read(GPU_ID);
+
+    let model_name = if let Some(model) = GPU_MODELS.iter().find(|&f| {
+        f.arch_major == gpu_id.arch_major().get() && f.prod_major == 
gpu_id.prod_major().get()
+    }) {
+        model.name
+    } else {
+        "unknown"
+    };
+
+    // Create canonical product ID with only arch/product fields, excluding 
version
+    // fields. This ensures the same product at different revisions has the 
same ID.
+    let id = GPU_ID::zeroed()
+        .with_arch_major(gpu_id.arch_major())
+        .with_arch_minor(gpu_id.arch_minor())
+        .with_arch_rev(gpu_id.arch_rev())
+        .with_prod_major(gpu_id.prod_major())
+        .into_raw();
+
+    dev_info!(
+        dev,
+        "mali-{} id 0x{:x} major 0x{:x} minor 0x{:x} status 0x{:x}",
+        model_name,
+        id,
+        gpu_id.ver_major().get(),
+        gpu_id.ver_minor().get(),
+        gpu_id.ver_status().get()
+    );
+
+    dev_info!(
+        dev,
+        "Features: L2:{:#x} Tiler:{:#x} Mem:{:#x} MMU:{:#x} AS:{:#x}",
+        io.read(L2_FEATURES).into_raw(),
+        io.read(TILER_FEATURES).into_raw(),
+        io.read(MEM_FEATURES).into_raw(),
+        io.read(MMU_FEATURES).into_raw(),
+        io.read(AS_PRESENT).into_raw(),
+    );
+
+    dev_info!(
+        dev,
+        "shader_present=0x{:016x} l2_present=0x{:016x} 
tiler_present=0x{:016x}",
+        io.read(SHADER_PRESENT).into_raw(),
+        io.read(L2_PRESENT).into_raw(),
+        io.read(TILER_PRESENT).into_raw(),
+    );
+    Ok(())
 }
 
 /// Powers on the l2 block.
 pub(crate) fn l2_power_on(dev: &Device<Bound>, iomem: &Devres<IoMem>) -> 
Result {
-    regs::L2_PWRON_LO.write(dev, iomem, 1)?;
+    let io = (*iomem).access(dev)?;
+    io.write_val(L2_PWRON::zeroed().with_const_request::<1>());
 
     poll::read_poll_timeout(
-        || regs::L2_READY_LO.read(dev, iomem),
+        || {
+            let io = (*iomem).access(dev)?;
+            Ok(io.read(L2_READY).into_raw())
+        },
         |status| *status == 1,
         Delta::from_millis(1),
         Delta::from_millis(100),
diff --git a/drivers/gpu/drm/tyr/regs.rs b/drivers/gpu/drm/tyr/regs.rs
index 
611870c2e6af50a35daaef052db2dd33a7e8059c..ba61a3dbe2a3e6fa1169b03d4f62e82769041057
 100644
--- a/drivers/gpu/drm/tyr/regs.rs
+++ b/drivers/gpu/drm/tyr/regs.rs
@@ -1,5 +1,25 @@
 // SPDX-License-Identifier: GPL-2.0 or MIT
 
+//! # Definitions
+//!
+//! - **CEU**: Command Execution Unit - A hardware component that executes 
commands (instructions)
+//!   from the command stream.
+//! - **CS**: Command Stream - A sequence of instructions (commands) used to 
control a particular
+//!   job or sequence of jobs. The instructions exist in one or more command 
buffers.
+//! - **CSF**: Command Stream Frontend - The interface and implementation for 
job submission
+//!   exposed to the host CPU driver. This includes the global interface, as 
well as CSG and CS
+//!   interfaces.
+//! - **CSG**: Command Stream Group - A group of related command streams. The 
CSF manages multiple
+//!   CSGs, and each CSG contains multiple CSs.
+//! - **CSHW**: Command Stream Hardware - The hardware interpreting command 
streams, including the
+//!   iterator control aspects. Implements the CSF in conjunction with the MCU.
+//! - **GLB**: Global - Prefix for global interface registers that control 
operations common to
+//!   all CSs.
+//! - **JASID**: Job Address Space ID - Identifies the address space for a job.
+//! - **MCU**: Microcontroller Unit - Implements the CSF in conjunction with 
the command stream
+//!   hardware.
+//! - **MMU**: Memory Management Unit - Handles address translation and memory 
access protection.
+
 // We don't expect that all the registers and fields will be used, even in the
 // future.
 //
@@ -41,64 +61,572 @@ pub(crate) fn write(&self, dev: &Device<Bound>, iomem: 
&Devres<IoMem>, value: u3
     }
 }
 
-pub(crate) const GPU_ID: Register<0x0> = Register;
-pub(crate) const GPU_L2_FEATURES: Register<0x4> = Register;
-pub(crate) const GPU_CORE_FEATURES: Register<0x8> = Register;
-pub(crate) const GPU_CSF_ID: Register<0x1c> = Register;
-pub(crate) const GPU_REVID: Register<0x280> = Register;
-pub(crate) const GPU_TILER_FEATURES: Register<0xc> = Register;
-pub(crate) const GPU_MEM_FEATURES: Register<0x10> = Register;
-pub(crate) const GPU_MMU_FEATURES: Register<0x14> = Register;
-pub(crate) const GPU_AS_PRESENT: Register<0x18> = Register;
-pub(crate) const GPU_IRQ_RAWSTAT: Register<0x20> = Register;
-
-pub(crate) const GPU_IRQ_RAWSTAT_FAULT: u32 = bit_u32(0);
-pub(crate) const GPU_IRQ_RAWSTAT_PROTECTED_FAULT: u32 = bit_u32(1);
-pub(crate) const GPU_IRQ_RAWSTAT_RESET_COMPLETED: u32 = bit_u32(8);
-pub(crate) const GPU_IRQ_RAWSTAT_POWER_CHANGED_SINGLE: u32 = bit_u32(9);
-pub(crate) const GPU_IRQ_RAWSTAT_POWER_CHANGED_ALL: u32 = bit_u32(10);
-pub(crate) const GPU_IRQ_RAWSTAT_CLEAN_CACHES_COMPLETED: u32 = bit_u32(17);
-pub(crate) const GPU_IRQ_RAWSTAT_DOORBELL_STATUS: u32 = bit_u32(18);
-pub(crate) const GPU_IRQ_RAWSTAT_MCU_STATUS: u32 = bit_u32(19);
-
-pub(crate) const GPU_IRQ_CLEAR: Register<0x24> = Register;
-pub(crate) const GPU_IRQ_MASK: Register<0x28> = Register;
-pub(crate) const GPU_IRQ_STAT: Register<0x2c> = Register;
-pub(crate) const GPU_CMD: Register<0x30> = Register;
-pub(crate) const GPU_CMD_SOFT_RESET: u32 = 1 | (1 << 8);
-pub(crate) const GPU_CMD_HARD_RESET: u32 = 1 | (2 << 8);
-pub(crate) const GPU_THREAD_FEATURES: Register<0xac> = Register;
-pub(crate) const GPU_THREAD_MAX_THREADS: Register<0xa0> = Register;
-pub(crate) const GPU_THREAD_MAX_WORKGROUP_SIZE: Register<0xa4> = Register;
-pub(crate) const GPU_THREAD_MAX_BARRIER_SIZE: Register<0xa8> = Register;
-pub(crate) const GPU_TEXTURE_FEATURES0: Register<0xb0> = Register;
-pub(crate) const GPU_SHADER_PRESENT_LO: Register<0x100> = Register;
-pub(crate) const GPU_SHADER_PRESENT_HI: Register<0x104> = Register;
-pub(crate) const GPU_TILER_PRESENT_LO: Register<0x110> = Register;
-pub(crate) const GPU_TILER_PRESENT_HI: Register<0x114> = Register;
-pub(crate) const GPU_L2_PRESENT_LO: Register<0x120> = Register;
-pub(crate) const GPU_L2_PRESENT_HI: Register<0x124> = Register;
-pub(crate) const L2_READY_LO: Register<0x160> = Register;
-pub(crate) const L2_READY_HI: Register<0x164> = Register;
-pub(crate) const L2_PWRON_LO: Register<0x1a0> = Register;
-pub(crate) const L2_PWRON_HI: Register<0x1a4> = Register;
-pub(crate) const L2_PWRTRANS_LO: Register<0x220> = Register;
-pub(crate) const L2_PWRTRANS_HI: Register<0x204> = Register;
-pub(crate) const L2_PWRACTIVE_LO: Register<0x260> = Register;
-pub(crate) const L2_PWRACTIVE_HI: Register<0x264> = Register;
-
-pub(crate) const MCU_CONTROL: Register<0x700> = Register;
-pub(crate) const MCU_CONTROL_ENABLE: u32 = 1;
-pub(crate) const MCU_CONTROL_AUTO: u32 = 2;
-pub(crate) const MCU_CONTROL_DISABLE: u32 = 0;
-
-pub(crate) const MCU_STATUS: Register<0x704> = Register;
-pub(crate) const MCU_STATUS_DISABLED: u32 = 0;
-pub(crate) const MCU_STATUS_ENABLED: u32 = 1;
-pub(crate) const MCU_STATUS_HALT: u32 = 2;
-pub(crate) const MCU_STATUS_FATAL: u32 = 3;
-
-pub(crate) const GPU_COHERENCY_FEATURES: Register<0x300> = Register;
+/// These registers correspond to the GPU_CONTROL register page.
+/// They are involved in GPU configuration and control.
+pub(super) mod gpu_control {
+    use kernel::{
+        register,
+        uapi, //
+    };
+
+    register! {
+        /// GPU identification register.
+        pub(crate) GPU_ID(u32) @ 0x0 {
+            /// Status of the GPU release.
+            3:0     ver_status;
+            /// Minor release version number.
+            11:4    ver_minor;
+            /// Major release version number.
+            15:12   ver_major;
+            /// Product identifier.
+            19:16   prod_major;
+            /// Architecture patch revision.
+            23:20   arch_rev;
+            /// Architecture minor revision.
+            27:24   arch_minor;
+            /// Architecture major revision.
+            31:28   arch_major;
+        }
+
+        /// Level 2 cache features register.
+        pub(crate) L2_FEATURES(u32) @ 0x4 {
+            /// Cache line size.
+            7:0     line_size;
+            /// Cache associativity.
+            15:8    associativity;
+            /// Cache slice size.
+            23:16   cache_size;
+            /// External bus width.
+            31:24   bus_width;
+        }
+
+        /// Shader core features.
+        pub(crate) CORE_FEATURES(u32) @ 0x8 {
+            /// Shader core variant.
+            7:0     core_variant;
+        }
+
+        /// Tiler features.
+        pub(crate) TILER_FEATURES(u32) @ 0xc {
+            /// Log of the tiler's bin size.
+            5:0     bin_size;
+            /// Maximum number of active levels.
+            11:8    max_levels;
+        }
+
+        /// Memory system features.
+        pub(crate) MEM_FEATURES(u32) @ 0x10 {
+            0:0     coherent_core_group;
+            1:1     coherent_super_group;
+            11:8    l2_slices;
+        }
+
+        /// Memory management unit features.
+        pub(crate) MMU_FEATURES(u32) @ 0x14 {
+            /// Number of bits supported in virtual addresses.
+            7:0     va_bits;
+            /// Number of bits supported in physical addresses.
+            15:8    pa_bits;
+        }
+
+        /// Address spaces present.
+        pub(crate) AS_PRESENT(u32) @ 0x18 {
+            31:0    present;
+        }
+
+        /// CSF version information.
+        pub(crate) CSF_ID(u32) @ 0x1c {
+            /// MCU revision ID.
+            3:0     mcu_rev;
+            /// MCU minor revision number.
+            9:4     mcu_minor;
+            /// MCU major revision number.
+            15:10   mcu_major;
+            /// CSHW revision ID.
+            19:16   cshw_rev;
+            /// CSHW minor revision number.
+            25:20   cshw_minor;
+            /// CSHW major revision number.
+            31:26   cshw_major;
+        }
+
+        /// IRQ sources raw status.
+        /// Writing to this register forces bits on, but does not clear them.
+        pub(crate) GPU_IRQ_RAWSTAT(u32) @ 0x20 {
+            /// A GPU fault has occurred.
+            0:0     gpu_fault;
+            /// A GPU fault has occurred.
+            1:1     gpu_protected_fault;
+            /// Reset has completed.
+            8:8     reset_completed;
+            /// Set when a single power domain has powered up or down.
+            9:9     power_changed_single;
+            /// Set when the all pending power domain changes are completed.
+            10:10   power_changed_all;
+            /// Set when cache cleaning has completed.
+            17:17   clean_caches_completed;
+            /// Mirrors the doorbell interrupt line to the CPU.
+            18:18   doorbell_mirror;
+            /// MCU requires attention.
+            19:19   mcu_status;
+        }
+
+        /// IRQ sources to clear. Write only.
+        pub(crate) GPU_IRQ_CLEAR(u32) @ 0x24 {
+            /// Clear the GPU_FAULT interrupt.
+            0:0     gpu_fault;
+            /// Clear the GPU_PROTECTED_FAULT interrupt.
+            1:1     gpu_protected_fault;
+            /// Clear the RESET_COMPLETED interrupt.
+            8:8     reset_completed;
+            /// Clear the POWER_CHANGED_SINGLE interrupt.
+            9:9     power_changed_single;
+            /// Clear the POWER_CHANGED_ALL interrupt.
+            10:10   power_changed_all;
+            /// Clear the CLEAN_CACHES_COMPLETED interrupt.
+            17:17   clean_caches_completed;
+            /// Clear the MCU_STATUS interrupt.
+            19:19   mcu_status;
+        }
+
+        /// IRQ sources enabled.
+        pub(crate) GPU_IRQ_MASK(u32) @ 0x28 {
+            /// Enable the GPU_FAULT interrupt.
+            0:0     gpu_fault;
+            /// Enable the GPU_PROTECTED_FAULT interrupt.
+            1:1     gpu_protected_fault;
+            /// Enable the RESET_COMPLETED interrupt.
+            8:8     reset_completed;
+            /// Enable the POWER_CHANGED_SINGLE interrupt.
+            9:9     power_changed_single;
+            /// Enable the POWER_CHANGED_ALL interrupt.
+            10:10   power_changed_all;
+            /// Enable the CLEAN_CACHES_COMPLETED interrupt.
+            17:17   clean_caches_completed;
+            /// Enable the DOORBELL_MIRROR interrupt.
+            18:18   doorbell_mirror;
+            /// Enable the MCU_STATUS interrupt.
+            19:19   mcu_status;
+        }
+
+        /// IRQ status for enabled sources. Read only.
+        pub(crate) GPU_IRQ_STATUS(u32) @ 0x2c {
+            /// GPU_FAULT interrupt status.
+            0:0     gpu_fault;
+            /// GPU_PROTECTED_FAULT interrupt status.
+            1:1     gpu_protected_fault;
+            /// RESET_COMPLETED interrupt status.
+            8:8     reset_completed;
+            /// POWER_CHANGED_SINGLE interrupt status.
+            9:9     power_changed_single;
+            /// POWER_CHANGED_ALL interrupt status.
+            10:10   power_changed_all;
+            /// CLEAN_CACHES_COMPLETED interrupt status.
+            17:17   clean_caches_completed;
+            /// DOORBELL_MIRROR interrupt status.
+            18:18   doorbell_mirror;
+            /// MCU_STATUS interrupt status.
+            19:19   mcu_status;
+        }
+
+        /// Layout is interpreted differently depending on the command value.
+        /// Default command is [`GPU_COMMAND::NOP`] with no payload.
+        pub(crate) GPU_COMMAND (u32) @ 0x30 {
+            7:0     command;
+        }
+    }
+
+    impl GPU_COMMAND {
+        /// No operation. This is the default value.
+        pub(crate) const NOP: u32 = 0;
+        /// Reset the GPU.
+        pub(crate) const RESET: u32 = 1;
+        /// Flush caches.
+        pub(crate) const FLUSH_CACHES: u32 = 4;
+        /// Clear GPU faults.
+        pub(crate) const CLEAR_FAULT: u32 = 7;
+    }
+
+    register! {
+        /// GPU command register in reset mode.
+        /// Set command to [`GPU_COMMAND::RESET`] to set reset_mode.
+        pub(crate) GPU_COMMAND_RESET (u32) => GPU_COMMAND {
+            7:0     command;
+            11:8    reset_mode;
+        }
+    }
+
+    impl GPU_COMMAND_RESET {
+        /// Stop all external bus interfaces, then reset the entire GPU.
+        pub(crate) const SOFT_RESET: u32 = 1;
+        /// Force a full GPU reset.
+        pub(crate) const HARD_RESET: u32 = 2;
+    }
+
+    register! {
+        /// GPU command register in cache flush mode.
+        /// Set command to [`GPU_COMMAND::FLUSH_CACHES`] to set flush modes.
+        pub(crate) GPU_COMMAND_FLUSH (u32) => GPU_COMMAND {
+            7:0     command;
+            /// L2 cache flush mode.
+            11:8    l2_flush;
+            /// Shader core load/store cache flush mode.
+            15:12   lsc_flush;
+            /// Shader core other caches flush mode.
+            19:16   other_flush;
+        }
+    }
+
+    impl GPU_COMMAND_FLUSH {
+        /// No flush.
+        pub(crate) const NONE: u32 = 0;
+        /// Clean the caches.
+        pub(crate) const CLEAN: u32 = 1;
+        /// Invalidate the caches.
+        pub(crate) const INVALIDATE: u32 = 2;
+        /// Clean and invalidate the caches.
+        pub(crate) const CLEAN_INVALIDATE: u32 = 3;
+    }
+
+    register! {
+        /// GPU status register. Read only.
+        pub(crate) GPU_STATUS(u32) @ 0x34 {
+            /// GPU active.
+            0:0     gpu_active;
+            /// Power manager active.
+            1:1     pwr_active;
+            /// Page fault active.
+            4:4     page_fault;
+            /// Protected mode active.
+            7:7     protected_mode_active;
+            /// Debug mode active.
+            8:8     gpu_dbg_enabled;
+        }
+
+        /// GPU fault status register. Read only.
+        pub(crate) GPU_FAULTSTATUS(u32) @ 0x3c {
+            /// Exception type.
+            7:0     exception_type;
+            /// Access type.
+            9:8     access_type;
+            /// The GPU_FAULTADDRESS is valid.
+            10:10   address_valid;
+            /// The JASID field is valid.
+            11:11   jasid_valid;
+            /// JASID of the fault, if known.
+            15:12   jasid;
+            /// ID of the source that triggered the fault.
+            31:16   source_id;
+        }
+    }
+
+    impl GPU_FAULTSTATUS {
+        /// Exception type: No error.
+        pub(crate) const EXCEPTION_OK: u32 = 0x00;
+        /// Exception type: GPU external bus error.
+        pub(crate) const EXCEPTION_GPU_BUS_FAULT: u32 = 0x80;
+        /// Exception type: GPU shareability error.
+        pub(crate) const EXCEPTION_GPU_SHAREABILITY_FAULT: u32 = 0x88;
+        /// Exception type: System shareability error.
+        pub(crate) const EXCEPTION_SYSTEM_SHAREABILITY_FAULT: u32 = 0x89;
+        /// Exception type: GPU cacheability error.
+        pub(crate) const EXCEPTION_GPU_CACHEABILITY_FAULT: u32 = 0x8A;
+
+        /// Access type: An atomic (read/write) transaction.
+        pub(crate) const ACCESS_ATOMIC: u32 = 0;
+        /// Access type: An execute transaction.
+        pub(crate) const ACCESS_EXECUTE: u32 = 1;
+        /// Access type: A read transaction.
+        pub(crate) const ACCESS_READ: u32 = 2;
+        /// Access type: A write transaction.
+        pub(crate) const ACCESS_WRITE: u32 = 3;
+    }
+
+    register! {
+        /// GPU fault address. Read only.
+        /// Once a fault is reported, it must be manually cleared by issuing a
+        /// [`GPU_COMMAND::CLEAR_FAULT`] command to the [`GPU_COMMAND`] 
register. No further GPU
+        /// faults will be reported until the previous fault has been cleared.
+        pub(crate) GPU_FAULTADDRESS(u64) @ 0x40 {
+            63:0    pointer;
+        }
+
+        /// Level 2 cache configuration.
+        pub(crate) L2_CONFIG(u32) @ 0x48 {
+            /// Requested cache size.
+            23:16   cache_size;
+            /// Requested hash function index.
+            31:24   hash_function;
+        }
+
+        /// Power state key. Write only.
+        pub(crate) PWR_KEY(u32) @ 0x50 {
+            /// Set to [`PWR_KEY::KEY_UNLOCK`] to unlock writes to other power 
state registers.
+            31:0    key;
+        }
+    }
+
+    impl PWR_KEY {
+        /// Key value to unlock writes to other power state registers.
+        /// This value was generated at random.
+        pub(crate) const KEY_UNLOCK: u32 = 0x2968A819;
+    }
+
+    register! {
+        /// Power manager override settings.
+        pub(crate) PWR_OVERRIDE0(u32) @ 0x54 {
+            /// Override the PWRUP signal.
+            1:0     pwrup_override;
+            /// Override the ISOLATE signal.
+            3:2     isolate_override;
+            /// Override the RESET signal.
+            5:4     reset_override;
+            /// Override the PWRUP_ACK signal.
+            9:8     pwrup_ack_override;
+            /// Override the ISOLATE_ACK signal.
+            11:10   isolate_ack_override;
+            /// Override the FUNC_ISOLATE signal.
+            13:12   func_iso_override;
+            /// Override the FUNC_ISOLATE_ACK signal.
+            15:14   func_iso_ack_override;
+            /// Maximum number of power transitions.
+            21:16   pwrtrans_limit;
+            /// Core startup throttling enabled.
+            23:23   throttle_enable;
+            /// Maximum number of simultaneous core startups.
+            29:24   throttle_limit;
+        }
+    }
+
+    /// Power override mode constants (`pwr_override_t` in hardware spec).
+    ///
+    /// These constants can be used with any field in [`PWR_OVERRIDE0`] that 
ends with
+    /// the `_override` suffix.
+    impl PWR_OVERRIDE0 {
+        /// The signal behaves normally.
+        pub(crate) const NONE: u32 = 0;
+        /// The signal is inverted (on when normally off, and off when 
normally on).
+        pub(crate) const INVERT: u32 = 1;
+        /// The signal is always kept on.
+        pub(crate) const ON: u32 = 2;
+        /// The signal is always kept off.
+        pub(crate) const OFF: u32 = 3;
+    }
+
+    register! {
+        /// Power manager override settings for device manufacturer.
+        pub(crate) PWR_OVERRIDE1(u32) @ 0x58 {
+            31:0    pwrtrans_vendor;
+        }
+
+        /// Global time stamp offset.
+        pub(crate) TIMESTAMP_OFFSET(u64) @ 0x88 {
+            63:0    offset;
+        }
+
+        /// GPU cycle counter. Read only.
+        pub(crate) CYCLE_COUNT(u64) @ 0x90 {
+            63:0    count;
+        }
+
+        /// Global time stamp. Read only.
+        pub(crate) TIMESTAMP(u64) @ 0x98 {
+            63:0    timestamp;
+        }
+
+        /// Maximum number of threads per core. Read only constant.
+        pub(crate) THREAD_MAX_THREADS(u32) @ 0xa0 {
+            31:0    threads;
+        }
+
+        /// Maximum number of threads per workgroup. Read only constant.
+        pub(crate) THREAD_MAX_WORKGROUP_SIZE(u32) @ 0xa4 {
+            31:0    threads;
+        }
+
+        /// Maximum number of threads per barrier. Read only constant.
+        pub(crate) THREAD_MAX_BARRIER_SIZE(u32) @ 0xa8 {
+            31:0    threads;
+        }
+
+        /// Thread features. Read only constant.
+        pub(crate) THREAD_FEATURES(u32) @ 0xac {
+            /// Total number of registers per core.
+            21:0    max_registers;
+            /// Implementation technology type.
+            23:22   implementation_technology;
+            /// Maximum number of compute tasks waiting.
+            31:24   max_task_queue;
+        }
+
+        /// Support flags for compressed texture formats. Read only constant.
+        pub(crate) TEXTURE_FEATURES_0(u32) @ 0xb0 {
+            31:0    format;
+        }
+
+        /// Shader core present bitmap. Read only constant.
+        pub(crate) SHADER_PRESENT(u64) @ 0x100 {
+            63:0    present;
+        }
+
+        /// Tiler present bitmap. Read only constant.
+        pub(crate) TILER_PRESENT(u64) @ 0x110 {
+            63:0    present;
+        }
+
+        /// L2 cache present bitmap. Read only constant.
+        pub(crate) L2_PRESENT(u64) @ 0x120 {
+            63:0    present;
+        }
+
+        /// Shader core ready bitmap. Read only.
+        pub(crate) SHADER_READY(u64) @ 0x140 {
+            63:0    ready;
+        }
+
+        /// Tiler ready bitmap. Read only.
+        pub(crate) TILER_READY(u64) @ 0x150 {
+            63:0    ready;
+        }
+
+        /// L2 ready bitmap. Read only.
+        pub(crate) L2_READY(u64) @ 0x160 {
+            63:0    ready;
+        }
+
+        /// Shader core power up bitmap.
+        pub(crate) SHADER_PWRON(u64) @ 0x180 {
+            63:0    request;
+        }
+
+        /// Tiler power up bitmap.
+        pub(crate) TILER_PWRON(u64) @ 0x190 {
+            63:0    request;
+        }
+
+        /// L2 power up bitmap.
+        pub(crate) L2_PWRON(u64) @ 0x1a0 {
+            63:0 request;
+        }
+
+        /// Shader core power down bitmap.
+        pub(crate) SHADER_PWROFF(u64) @ 0x1c0 {
+            63:0 request;
+        }
+
+        /// Tiler power down bitmap.
+        pub(crate) TILER_PWROFF(u64) @ 0x1d0 {
+            63:0 request;
+        }
+
+        /// L2 power down bitmap.
+        pub(crate) L2_PWROFF(u64) @ 0x1e0 {
+            63:0 request;
+        }
+
+        /// Shader core power transition bitmap. Read-only.
+        pub(crate) SHADER_PWRTRANS(u64) @ 0x200 {
+            63:0 changing;
+        }
+
+        /// Tiler power transition bitmap. Read-only.
+        pub(crate) TILER_PWRTRANS(u64) @ 0x210 {
+            63:0 changing;
+        }
+
+        /// L2 power transition bitmap. Read-only.
+        pub(crate) L2_PWRTRANS(u64) @ 0x220 {
+            63:0 changing;
+        }
+
+        /// Shader core active bitmap. Read-only.
+        pub(crate) SHADER_PWRACTIVE(u64) @ 0x240 {
+            63:0 active;
+        }
+
+        /// Tiler active bitmap. Read-only.
+        pub(crate) TILER_PWRACTIVE(u64) @ 0x250 {
+            63:0 active;
+        }
+
+        /// L2 active bitmap.  Read-only.
+        pub(crate) L2_PWRACTIVE(u64) @ 0x260 {
+            63:0 active;
+        }
+
+        /// Revision ID. Read only constant.
+        pub(crate) REVIDR(u32) @ 0x280 {
+            31:0    revision;
+        }
+
+        /// Coherency features present. Read only constant.
+        /// Supported protocols on the interconnect between the GPU and the
+        /// system into which it is integrated.
+        pub(crate) COHERENCY_FEATURES(u32) @ 0x300 {
+            /// ACE-Lite protocol supported.
+            0:0     ace_lite;
+            /// ACE protocol supported.
+            1:1     ace;
+        }
+
+        /// Coherency enable. An index of which coherency protocols should be 
used.
+        /// Possible values are in
+        /// This register only selects the protocol for coherency messages on 
the
+        /// interconnect. This is not to enable or disable coherency 
controlled by MMU.
+        pub(crate) COHERENCY_ENABLE(u32) @ 0x304 {
+            31:0    l2_cache_protocol_select;
+        }
+    }
+
+    impl COHERENCY_ENABLE {
+        /// ACE-Lite coherency protocol.
+        pub(crate) const ACE_LITE: u32 =
+            uapi::drm_panthor_gpu_coherency_DRM_PANTHOR_GPU_COHERENCY_ACE_LITE;
+        /// ACE coherency protocol.
+        pub(crate) const ACE: u32 = 
uapi::drm_panthor_gpu_coherency_DRM_PANTHOR_GPU_COHERENCY_ACE;
+        /// No coherency protocol.
+        pub(crate) const NO_COHERENCY: u32 =
+            uapi::drm_panthor_gpu_coherency_DRM_PANTHOR_GPU_COHERENCY_NONE;
+    }
+
+    register! {
+        /// MCU control.
+        pub(crate) MCU_CONTROL(u32) @ 0x700 {
+            /// Request MCU state change.
+            1:0 req;
+        }
+    }
+
+    impl MCU_CONTROL {
+        /// Disable the MCU.
+        pub(crate) const DISABLE: u32 = 0;
+        /// Enable the MCU.
+        pub(crate) const ENABLE: u32 = 1;
+        /// Enable the MCU to execute and automatically reboot after a fast 
reset.
+        pub(crate) const AUTO: u32 = 2;
+    }
+
+    register! {
+        /// MCU status. Read only.
+        pub(crate) MCU_STATUS(u32) @ 0x704 {
+            /// Read current state of MCU.
+            1:0 value;
+        }
+    }
+
+    impl MCU_STATUS {
+        /// MCU is disabled.
+        pub(crate) const DISABLED: u32 = 0;
+        /// MCU is enabled.
+        pub(crate) const ENABLED: u32 = 1;
+        /// The MCU has halted by itself in an orderly manner to enable the 
core group to be powered down.
+        pub(crate) const HALT: u32 = 2;
+        /// The MCU has encountered an error that prevents it from continuing.
+        pub(crate) const FATAL: u32 = 3;
+    }
+}
+
+pub(super) use gpu_control::*;
 
 pub(crate) const JOB_IRQ_RAWSTAT: Register<0x1000> = Register;
 pub(crate) const JOB_IRQ_CLEAR: Register<0x1004> = Register;

-- 
2.52.0

Reply via email to