diff --git a/local/recipes/gpu/redox-drm/source/src/drivers/intel/display.rs b/local/recipes/gpu/redox-drm/source/src/drivers/intel/display.rs index e9fdc13a7a..ba42d55210 100644 --- a/local/recipes/gpu/redox-drm/source/src/drivers/intel/display.rs +++ b/local/recipes/gpu/redox-drm/source/src/drivers/intel/display.rs @@ -3,6 +3,7 @@ use std::sync::Mutex; use log::{debug, info}; use redox_driver_sys::memory::MmioRegion; +use super::regs::IntelRegs; use crate::driver::{DriverError, Result}; use crate::kms::connector::synthetic_edid; use crate::kms::{ConnectorInfo, ConnectorStatus, ConnectorType, ModeInfo}; @@ -10,24 +11,6 @@ use crate::kms::{ConnectorInfo, ConnectorStatus, ConnectorType, ModeInfo}; const PIPE_COUNT: usize = 4; const PORT_COUNT: usize = 6; -const PP_STATUS: usize = 0xC7200; -const PIPECONF_BASE: usize = 0x70008; -const DSPCNTR_BASE: usize = 0x70180; -const DSPSURF_BASE: usize = 0x7019C; -const DDI_BUF_CTL_BASE: usize = 0x64000; - -const HTOTAL_BASE: usize = 0x60000; -const HBLANK_BASE: usize = 0x60004; -const HSYNC_BASE: usize = 0x60008; -const VTOTAL_BASE: usize = 0x6000C; -const VBLANK_BASE: usize = 0x60010; -const VSYNC_BASE: usize = 0x60014; -const PIPE_SRC_BASE: usize = 0x6001C; -const PLANE_SIZE_BASE: usize = 0x70190; - -const PIPE_STRIDE: usize = 0x1000; -const PORT_STRIDE: usize = 0x100; - const PIPECONF_ENABLE: u32 = 1 << 31; const DSPCNTR_ENABLE: u32 = 1 << 31; const DDI_BUF_CTL_ENABLE: u32 = 1 << 31; @@ -42,11 +25,12 @@ pub struct DisplayPipe { pub struct IntelDisplay { mmio: MmioRegion, pipes: Mutex>, + regs: &'static dyn IntelRegs, } impl IntelDisplay { - pub fn new(mmio: MmioRegion) -> Result { - let pipes = Self::detect_pipes(&mmio)?; + pub fn new(mmio: MmioRegion, regs: &'static dyn IntelRegs) -> Result { + let pipes = Self::detect_pipes(&mmio, regs)?; info!( "redox-drm: Intel display initialized with {} pipe(s)", pipes.len() @@ -54,6 +38,7 @@ impl IntelDisplay { Ok(Self { mmio, pipes: Mutex::new(pipes), + regs, }) } @@ -72,13 +57,13 @@ impl IntelDisplay { .ok_or_else(|| DriverError::NotFound(format!("unknown Intel pipe for CRTC {crtc_id}"))) } - pub fn detect_pipes(mmio: &MmioRegion) -> Result> { + pub fn detect_pipes(mmio: &MmioRegion, regs: &dyn IntelRegs) -> Result> { let mut pipes = Vec::with_capacity(PIPE_COUNT); - let pp_status = read32(mmio, PP_STATUS).unwrap_or(0); - let connected_ports = connected_ports(mmio); + let pp_status = read32(mmio, regs.pp_status()).unwrap_or(0); + let connected_ports = connected_ports(mmio, regs); for index in 0..PIPE_COUNT { - let conf = read32(mmio, pipe_offset(PIPECONF_BASE, index))?; + let conf = read32(mmio, regs.pipeconf(index as u8))?; let enabled = conf & PIPECONF_ENABLE != 0; let mut port = connected_ports.get(index).copied(); @@ -106,12 +91,12 @@ impl IntelDisplay { } pub fn detect_connectors(&self) -> Result> { - let pp_status = self.read32(PP_STATUS).unwrap_or(0); + let pp_status = self.read32(self.regs.pp_status()).unwrap_or(0); let pipes = self.refresh_pipes()?; let mut connectors = Vec::with_capacity(PORT_COUNT); for port in 0..PORT_COUNT as u8 { - let status = self.read32(ddi_offset(port)).unwrap_or(0); + let status = self.read32(self.regs.ddi_buf_ctl(port)).unwrap_or(0); let connected = status & DDI_BUF_CTL_ENABLE != 0 || pipes .iter() @@ -167,7 +152,7 @@ impl IntelDisplay { } pub fn read_dpcd(&self, port: u8) -> Vec { - let status = self.read32(ddi_offset(port)).unwrap_or(0); + let status = self.read32(self.regs.ddi_buf_ctl(port)).unwrap_or(0); if status & DDI_BUF_CTL_ENABLE == 0 { return Vec::new(); } @@ -179,50 +164,50 @@ impl IntelDisplay { pub fn set_mode(&self, pipe: &DisplayPipe, mode: &ModeInfo) -> Result<()> { let index = usize::from(pipe.index); self.write32( - pipe_offset(HTOTAL_BASE, index), + self.regs.htotal(index as u8), pack_pair(mode.htotal, mode.hdisplay), )?; self.write32( - pipe_offset(HBLANK_BASE, index), + self.regs.hblank(index as u8), pack_pair(mode.htotal, mode.hdisplay), )?; self.write32( - pipe_offset(HSYNC_BASE, index), + self.regs.hsync(index as u8), pack_pair(mode.hsync_end, mode.hsync_start), )?; self.write32( - pipe_offset(VTOTAL_BASE, index), + self.regs.vtotal(index as u8), pack_pair(mode.vtotal, mode.vdisplay), )?; self.write32( - pipe_offset(VBLANK_BASE, index), + self.regs.vblank(index as u8), pack_pair(mode.vtotal, mode.vdisplay), )?; self.write32( - pipe_offset(VSYNC_BASE, index), + self.regs.vsync(index as u8), pack_pair(mode.vsync_end, mode.vsync_start), )?; self.write32( - pipe_offset(PIPE_SRC_BASE, index), + self.regs.pipe_src(index as u8), pack_pair(mode.vdisplay, mode.hdisplay), )?; self.write32( - pipe_offset(PLANE_SIZE_BASE, index), + self.regs.plane_size(index as u8), pack_pair(mode.vdisplay, mode.hdisplay), )?; - let mut dspcntr = self.read32(pipe_offset(DSPCNTR_BASE, index))?; + let mut dspcntr = self.read32(self.regs.dspcntr(index as u8))?; dspcntr |= DSPCNTR_ENABLE; - self.write32(pipe_offset(DSPCNTR_BASE, index), dspcntr)?; + self.write32(self.regs.dspcntr(index as u8), dspcntr)?; - let mut pipeconf = self.read32(pipe_offset(PIPECONF_BASE, index))?; + let mut pipeconf = self.read32(self.regs.pipeconf(index as u8))?; pipeconf |= PIPECONF_ENABLE; - self.write32(pipe_offset(PIPECONF_BASE, index), pipeconf)?; + self.write32(self.regs.pipeconf(index as u8), pipeconf)?; if let Some(port) = pipe.port { - let mut ddi = self.read32(ddi_offset(port))?; + let mut ddi = self.read32(self.regs.ddi_buf_ctl(port))?; ddi |= DDI_BUF_CTL_ENABLE; - self.write32(ddi_offset(port), ddi)?; + self.write32(self.regs.ddi_buf_ctl(port), ddi)?; } self.update_pipe(pipe.index, true, pipe.port)?; @@ -233,12 +218,12 @@ impl IntelDisplay { pub fn page_flip(&self, pipe: &DisplayPipe, fb_addr: u64) -> Result<()> { if fb_addr > u64::from(u32::MAX) { self.write32( - pipe_offset(DSPSURF_BASE, usize::from(pipe.index)), + self.regs.dspsurf(pipe.index), (fb_addr >> 32) as u32, )?; } let index = usize::from(pipe.index); - self.write32(pipe_offset(DSPSURF_BASE, index), fb_addr as u32) + self.write32(self.regs.dspsurf(index as u8), fb_addr as u32) } fn refresh_pipes(&self) -> Result> { @@ -311,10 +296,10 @@ impl IntelDisplay { } } -fn connected_ports(mmio: &MmioRegion) -> Vec { +fn connected_ports(mmio: &MmioRegion, regs: &dyn IntelRegs) -> Vec { let mut ports = Vec::new(); for port in 0..PORT_COUNT as u8 { - if read32(mmio, ddi_offset(port)).unwrap_or(0) & DDI_BUF_CTL_ENABLE != 0 { + if read32(mmio, regs.ddi_buf_ctl(port)).unwrap_or(0) & DDI_BUF_CTL_ENABLE != 0 { ports.push(port); } } @@ -354,14 +339,6 @@ fn ensure_access(mmio_size: usize, offset: usize, width: usize, op: &str) -> Res Ok(()) } -fn pipe_offset(base: usize, index: usize) -> usize { - base + index * PIPE_STRIDE -} - -fn ddi_offset(port: u8) -> usize { - DDI_BUF_CTL_BASE + usize::from(port) * PORT_STRIDE -} - fn pack_pair(upper: u16, lower: u16) -> u32 { ((u32::from(upper).saturating_sub(1)) << 16) | u32::from(lower).saturating_sub(1) } diff --git a/local/recipes/gpu/redox-drm/source/src/drivers/intel/mod.rs b/local/recipes/gpu/redox-drm/source/src/drivers/intel/mod.rs index 4bbba9235e..c0964232a1 100644 --- a/local/recipes/gpu/redox-drm/source/src/drivers/intel/mod.rs +++ b/local/recipes/gpu/redox-drm/source/src/drivers/intel/mod.rs @@ -184,7 +184,7 @@ impl IntelDriver { cdclk_state.frequency_khz, cdclk_state.voltage_level ); - let display = IntelDisplay::new(display_mmio)?; + let display = IntelDisplay::new(display_mmio, regs)?; let mut gtt = IntelGtt::init(gtt_mmio, gtt_control_mmio)?; let mut ring = IntelRing::create(ring_mmio, RingType::Render)?; ring.bind_gtt(&mut gtt)?;