+ let texture_features = regs::TextureFeatures::read(io, 0).into();
+
+ let as_present = regs::AsPresent::read(io).into();
+
+ let shader_present =
u64::from(u32::from(regs::ShaderPresentLo::read(io)));
let shader_present =
- shader_present | u64::from(regs::GPU_SHADER_PRESENT_HI.read(dev,
iomem)?) << 32;
+ shader_present | u64::from(u32::from(regs::ShaderPresentHi::read(io)))
<< 32;
- let tiler_present = u64::from(regs::GPU_TILER_PRESENT_LO.read(dev, iomem)?);
+ let tiler_present =
u64::from(u32::from(regs::TilerPresentLo::read(io)));
let tiler_present =
- tiler_present | u64::from(regs::GPU_TILER_PRESENT_HI.read(dev, iomem)?)
<< 32;
+ tiler_present | u64::from(u32::from(regs::TilerPresentHi::read(io)))
<< 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 l2_present = u64::from(u32::from(regs::L2PresentLo::read(io)));
+ let l2_present = l2_present |
u64::from(u32::from(regs::L2PresentHi::read(io))) << 32;
Ok(Self {
gpu_id,
@@ -204,13 +206,14 @@ fn from(value: u32) -> Self {
/// 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)?;
+ regs::L2PwrOnLo::default().set_l2_pwron_lo(1).write(io);
// TODO: We cannot poll, as there is no support in Rust currently, so we
// sleep. Change this when read_poll_timeout() is implemented in Rust.
kernel::time::delay::fsleep(time::Delta::from_millis(100));
- if regs::L2_READY_LO.read(dev, iomem)? != 1 {
+ if regs::L2ReadyLo::read(io).l2_ready_lo() != 1 {
dev_err!(dev, "Failed to power on the GPU\n");
return Err(EIO);
}
diff --git a/drivers/gpu/drm/tyr/regs.rs b/drivers/gpu/drm/tyr/regs.rs
index f46933aaa221..a4e05ff463c0 100644
--- a/drivers/gpu/drm/tyr/regs.rs
+++ b/drivers/gpu/drm/tyr/regs.rs
@@ -8,44 +8,62 @@
#![allow(dead_code)]
use kernel::bits::bit_u32;
-use kernel::device::Bound;
-use kernel::device::Device;
-use kernel::devres::Devres;
use kernel::prelude::*;
+use kernel::register;
-use crate::driver::IoMem;
-
-/// Represents a register in the Register Set
-///
-/// TODO: Replace this with the Nova `register!()` macro when it is available.
-/// In particular, this will automatically give us 64bit register reads and
-/// writes.
-pub(crate) struct Register<const OFFSET: usize>;
-
-impl<const OFFSET: usize> Register<OFFSET> {
- #[inline]
- pub(crate) fn read(&self, dev: &Device<Bound>, iomem: &Devres<IoMem>) ->
Result<u32> {
- let value = (*iomem).access(dev)?.read32(OFFSET);
- Ok(value)
- }
-
- #[inline]
- pub(crate) fn write(&self, dev: &Device<Bound>, iomem: &Devres<IoMem>, value:
u32) -> Result {
- (*iomem).access(dev)?.write32(value, OFFSET);
- Ok(())
- }
-}
-
-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;
+register!(GpuId @ 0x0, "Information about the GPU architecture and release
version" {
+ 3:0 version_status as u32, "Status of the GPU release";
+ 11:4 version_minor as u32, "Minor release version number";
+ 15:12 version_major as u32, "Major release version number";
+ 19:16 product_major as u32, "Product identifier";
+ 23:20 arch_rev as u32, "Architecture patch revision";
+ 27:24 arch_minor as u32, "Architecture minor revision";
+ 31:28 arch_major as u32, "Architecture major revision";
+});
+
+register!(L2Features @ 0x4, "Level 2 cache features" {
+ 7:0 line_size as u32, "L2 cache line size";
+ 15:8 associativity as u32, "L2 cache associativity";
+ 23:16 cache_size as u32, "L2 cache slice size";
+ 31:24 bus_width as u32, "L2 cache bus width";
+});
+
+register!(CoreFeatures @ 0x8, "Information about the features of a shader
core" {
+ 7:0 core_variant as u32, "Shader core variant";
+});
+
+register!(CsfId @ 0x1c, "Version of the CSF hardware and MMU subsystem" {
+ 3:0 mcu_rev as u32, "MCU revision ID";
+ 9:4 mcu_minor as u32, "MCU minor revision number";
+ 15:10 mcu_major as u32, "MCU major revision number";
+ 19:16 cshw_rev as u32, "CSHW revision ID";
+ 25:20 cshw_minor as u32, "CSHW minor revision number";
+ 31:26 cshw_major as u32, "CSHW major revision number";
+});
+
+register!(RevIdr @ 0x280, "Extra revision information" {
+ 31:0 revision as u32, "Revision information";
+});
+
+register!(TilerFeatures @ 0xc, "Tiler features" {
+ 5:0 bin_size as u32, "Log of the tiler's bin size";
+ 11:8 max_levels as u32, "Maximum number of available levels";
+});
+
+register!(MemFeatures @ 0x10, "Memory features" {
+ 0:0 coherent_core_group as bool, "Core group is coherent";
+ 1:1 coherent_super_group as bool, "Core supergroup is coherent";
+ 11:8 l2_slices as u32, "L2 slice count";
+});
+
+register!(MmuFeatures @ 0x14, "MMU features" {
+ 7:0 va_bits as u32, "Number of bits supported in virtual addresses";
+ 15:8 pa_bits as u32, "Number of bits supported in physical addresses";
+});
+
+register!(AsPresent @ 0x18, "Address spaces present" {
+ 31:0 as_present as u32, "Bitmask of present address spaces";
+});
pub(crate) const GPU_IRQ_RAWSTAT_FAULT: u32 = bit_u32(0);
pub(crate) const GPU_IRQ_RAWSTAT_PROTECTED_FAULT: u32 = bit_u32(1);
@@ -56,53 +74,193 @@ pub(crate) fn write(&self, dev: &Device<Bound>, iomem:
&Devres<IoMem>, value: u3
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;
+register!(GpuIrqRawstat @ 0x20, "Raw unmasked interrupt status for the GPU" {
+ 0:0 fault as bool, "A GPU fault has occourred";
+ 1:1 protected_fault as bool, "Indicates a protected memory fault has
occurred";
+ 8:8 reset_completed as bool, "Indicates that a GPU reset has
completed";
+ 9:9 power_changed_single as bool, "Set when a single power domain has
powered up or down";
+ 10:10 power_changed_all as bool, "Set when all pending power domain changes
are completed ";
+ 17:17 clean_caches_completed as bool, "Indicates that a cache clean operation
has completed";
+ 18:18 doorbell_status as bool, "Mirrors the doorbell interrupt line to the
CPU";
+ 19:19 mcu_status as bool, "The MCU requires attention";
+});
+
+register!(GpuIrqClear @ 0x24, "Clears pending GPU interrupts" {
+ 0:0 fault as bool, "Clear the fault interrupt";
+ 1:1 protected_fault as bool, "Clear the protected_fault interrupt";
+ 8:8 reset_completed as bool, "Clear the reset_completed interrupt";
+ 9:9 power_changed_single as bool, "Clear the power_changed_single
interrupt";
+ 10:10 power_changed_all as bool, "Clear the power_changed_all interrupt";
+ 17:17 clean_caches_completed as bool, "Clear the clean_caches_completed
interrupt";
+ 18:18 doorbell_status as bool, "Clear the doorbell_status interrupt";
+ 19:19 mcu_status as bool, "Clear the mcu_status interrupt";
+});
+
+register!(GpuIrqMask @ 0x28, "Enabled GPU interrupts" {
+ 0:0 fault as bool, "Enable the fault interrupt";
+ 1:1 protected_fault as bool, "Enable the protected_fault interrupt";
+ 8:8 reset_completed as bool, "Enable the reset_completed interrupt";
+ 9:9 power_changed_single as bool, "Enable the power_changed_single
interrupt";
+ 10:10 power_changed_all as bool, "Enable the power_changed_all
interrupt";
+ 17:17 clean_caches_completed as bool, "Enable the clean_caches_completed
interrupt";
+ 18:18 doorbell_status as bool, "Enable the doorbell_status interrupt";
+ 19:19 mcu_status as bool, "Enable the mcu_status interrupt";
+});
+
+register!(GpuIrqStatus @ 0x2c, "Masked GPU interrupt status" {
+ 0:0 fault as bool, "The fault interrupt is pending";
+ 1:1 protected_fault as bool, "The protected_fault interrupt is
pending";
+ 8:8 reset_completed as bool, "The reset_completed interrupt is
pending";
+ 9:9 power_changed_single as bool, "The power_changed_single interrupt is
pending";
+ 10:10 power_changed_all as bool, "The power_changed_all interrupt is
pending";
+ 17:17 clean_caches_completed as bool, "The clean_caches_completed interrupt
is pending";
+ 18:18 doorbell_status as bool, "The doorbell_status interrupt is
pending";
+ 19:19 mcu_status as bool, "The mcu_status interrupt is pending";
+});
+
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;
+
+register!(GpuCommand @ 0x30, "GPU command register" {
+ 7:0 command as u32, "GPU-specific command to execute";
+ 31:8 payload as u32, "Payload for the command";
+});
+
+register!(ThreadFeatures @ 0xac, "Thread features of the GPU's threading
system" {
+ 21:0 max_registers as u32, "Total number of registers per core";
+ 23:22 implementation_technology as u32;
+ 31:24 max_task_queue as u32, "Maximum number of compute tasks waiting";
+
+});
+
+register!(ThreadMaxThreads @ 0xa0, "Maximum number of threads per core" {
+ 31:0 max_threads as u32, "Maximum number of threads per core";
+});
+
+register!(ThreadMaxWorkgroupSize @ 0xa4, "Maximum number of threads per
workgroup" {
+ 31:0 max_workgroup_size as u32, "Maximum number of threads per
workgroup";
+});
+
+register!(ThreadMaxBarrierSize @ 0xa8, "Maximum number of threads per barrier"
{
+ 31:0 max_barrier_size as u32, "Maximum number of threads per barrier";
+});
+
+register!(TextureFeatures @ 0xb0 [4], "Bitmap of supported texture formats"
{});
+
+register!(ShaderPresentLo @ 0x100, "Bitmap of shader cores present in the hardware
(lower 32 bits)" {
+ 31:0 shader_present_lo as u32, "Bitmap of shader cores present in the
hardware (lower 32 bits)";
+});
+
+register!(ShaderPresentHi @ 0x104, "Bitmap of shader cores present in the hardware
(higher 32 bits)" {
+ 31:0 shader_present_hi as u32, "Bitmap of shader cores present in the
hardware (higher 32 bits)";
+});
+
+register!(TilerPresentLo @ 0x110, "Bitmap of tiler cores present in the hardware
(lower 32 bits)" {
+ 31:0 tiler_present_lo as u32, "Bitmap of tiler cores present in the hardware
(lower 32 bits)";
+});
+
+register!(TilerPresentHi @ 0x114, "Bitmap of tiler cores present in the hardware
(higher 32 bits)" {
+ 31:0 tiler_present_hi as u32, "Bitmap of tiler cores present in the hardware
(higher 32 bits)";
+});
+
+register!(L2PresentLo @ 0x120, "Bitmap of L2 caches present in the hardware (lower
32 bits)" {
+ 31:0 l2_present_lo as u32, "Bitmap of L2 caches present in the hardware
(lower 32 bits)";
+});
+
+register!(L2PresentHi @ 0x124, "Bitmap of L2 caches present in the hardware (higher
32 bits)" {
+ 31:0 l2_present_hi as u32, "Bitmap of L2 caches present in the hardware
(higher 32 bits)";
+});
+
+register!(L2ReadyLo @ 0x160, "Bitmap of L2 caches ready (lower 32 bits)" {
+ 31:0 l2_ready_lo as u32, "Bitmap of L2 caches ready (lower 32 bits)";
+});
+
+register!(L2ReadyHi @ 0x164, "Bitmap of L2 caches ready (higher 32 bits)" {
+ 31:0 l2_ready_hi as u32, "Bitmap of L2 caches ready (higher 32 bits)";
+});
+
+register!(L2PwrOnLo @ 0x1a0, "Bitmap of L2 caches power on requests (lower 32
bits)" {
+ 31:0 l2_pwron_lo as u32, "Bitmap of L2 caches power on requests (lower 32
bits)";
+});
+
+register!(L2PwrOnHi @ 0x1a4, "Bitmap of L2 caches power on requests (higher 32
bits)" {
+ 31:0 l2_pwron_hi as u32, "Bitmap of L2 caches power on requests (higher 32
bits)";
+});
+
+register!(L2PwrTransLo @ 0x200, "Bitmap of L2 caches in power transition (lower 32
bits)" {
+ 31:0 l2_pwrtrans_lo as u32, "Bitmap of L2 caches in power transition (lower
32 bits)";
+});
+
+register!(L2PwrTransHi @ 0x204, "Bitmap of L2 caches in power transition (higher 32
bits)" {
+ 31:0 l2_pwrtrans_hi as u32, "Bitmap of L2 caches in power transition (higher
32 bits)";
+});
+
+register!(L2PowerActiveLo @ 0x260, "Bitmap of L2 caches active (lower 32
bits)" {
+ 31:0 l2_pwractive_lo as u32, "Bitmap of L2 caches active (lower 32
bits)";
+});
+
+register!(L2PowerActiveHi @ 0x264, "Bitmap of L2 caches active (higher 32
bits)" {
+ 31:0 l2_pwractive_hi as u32, "Bitmap of L2 caches active (higher 32
bits)";
+});
+
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;
+register!(McuControl @ 0x700, "Controls the execution state of the MCU
subsystem" {
+ 1:0 req as u32, "Request state change";
+});