diff --git a/local/recipes/gpu/redox-drm/source/src/drivers/intel/display_combo_phy.rs b/local/recipes/gpu/redox-drm/source/src/drivers/intel/display_combo_phy.rs new file mode 100644 index 0000000000..c48b5a9ffb --- /dev/null +++ b/local/recipes/gpu/redox-drm/source/src/drivers/intel/display_combo_phy.rs @@ -0,0 +1,88 @@ +use std::sync::Arc; + +use log::{debug, info, warn}; +use redox_driver_sys::memory::MmioRegion; + +use crate::driver::Result; + +const PORT_CL_DW5_OFFSET: usize = 0x14; +const PORT_CL_DW10_OFFSET: usize = 0x28; +const PORT_CL_DW12_OFFSET: usize = 0x30; + +const COMBO_PHY_BASE: &[usize] = &[ + 0x162000, + 0x6C000, + 0x160000, + 0x161000, + 0x16B000, +]; + +pub struct ComboPhy { + mmio: Arc, +} + +impl ComboPhy { + pub fn new(mmio: Arc) -> Self { + Self { mmio } + } + + pub fn init_all(&self, num_phys: usize) -> Result<()> { + info!("redox-drm-intel: initializing {} combo PHY(s)", num_phys.min(COMBO_PHY_BASE.len())); + for i in 0..num_phys.min(COMBO_PHY_BASE.len()) { + self.init_phy(i)?; + } + Ok(()) + } + + fn init_phy(&self, phy_idx: usize) -> Result<()> { + let base = COMBO_PHY_BASE[phy_idx]; + debug!("redox-drm-intel: initializing combo PHY {} at {:#08x}", phy_idx, base); + + let dw5 = self.mmio.read_u32(base + PORT_CL_DW5_OFFSET); + if dw5 & 0x80000000 != 0 { + self.mmio.write_u32(base + PORT_CL_DW5_OFFSET, dw5 & !0x80000000); + } + + let powered = 0x00000001; + self.mmio.write_u32(base + PORT_CL_DW5_OFFSET, powered); + + let dw5_verify = self.mmio.read_u32(base + PORT_CL_DW5_OFFSET); + debug!( + "redox-drm-intel: combo PHY {} DW5 = {:#010x}", + phy_idx, dw5_verify + ); + + let dw10 = self.mmio.read_u32(base + PORT_CL_DW10_OFFSET); + let pwr_up = 0x00005555; + self.mmio.write_u32(base + PORT_CL_DW10_OFFSET, dw10 | pwr_up); + + let dw10_verify = self.mmio.read_u32(base + PORT_CL_DW10_OFFSET); + let lanes_powered = (dw10_verify & 0x0000FFFF).count_ones(); + debug!( + "redox-drm-intel: combo PHY {} DW10 = {:#010x}, {} lanes powered", + phy_idx, dw10_verify, lanes_powered + ); + + let dw12 = self.mmio.read_u32(base + PORT_CL_DW12_OFFSET); + let idle_mask: u32 = 0x0000000F; + self.mmio.write_u32(base + PORT_CL_DW12_OFFSET, dw12 | idle_mask); + + info!("redox-drm-intel: combo PHY {} initialized", phy_idx); + Ok(()) + } + + pub fn power_up_lanes(&self, phy_idx: usize) -> Result<()> { + let base = COMBO_PHY_BASE[phy_idx]; + let dw10 = self.mmio.read_u32(base + PORT_CL_DW10_OFFSET); + let pwr_up: u32 = 0x00005555; + self.mmio.write_u32(base + PORT_CL_DW10_OFFSET, dw10 | pwr_up); + debug!("redox-drm-intel: combo PHY {} lanes powered up", phy_idx); + Ok(()) + } + + pub fn is_enabled(&self, phy_idx: usize) -> bool { + let base = COMBO_PHY_BASE[phy_idx]; + let dw5 = self.mmio.read_u32(base + PORT_CL_DW5_OFFSET); + dw5 & 0x00000001 != 0 + } +} 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 46eea36a7a..4bbba9235e 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 @@ -1,5 +1,6 @@ pub mod display; pub mod display_cdclk; +pub mod display_combo_phy; pub mod display_dmc; pub mod display_power; pub mod dp_aux; @@ -29,6 +30,7 @@ use crate::kms::{ConnectorInfo, ConnectorType, ModeInfo}; use self::display::{DisplayPipe, IntelDisplay}; use self::display_cdclk::DisplayClock; +use self::display_combo_phy::ComboPhy; use self::display_dmc::DmcFirmware; use self::display_power::DisplayPower; use self::dp_aux::DpAux; @@ -69,6 +71,7 @@ pub struct IntelDriver { ring: Mutex, gmbus: Option, dp_aux: Vec, + combo_phy: Option, display_power: DisplayPower, dmc: DmcFirmware, cdclk: DisplayClock, @@ -153,6 +156,14 @@ impl IntelDriver { enable_d2d_links(&mmio_arc, regs, device_info.num_ports)?; } + let combo_phy = if device_info.has_combo_phy { + let phy = ComboPhy::new(mmio_arc.clone()); + phy.init_all(device_info.num_ports as usize)?; + Some(phy) + } else { + None + }; + let display_power = DisplayPower::new(mmio_arc.clone(), regs); display_power.init_domains()?; @@ -231,6 +242,7 @@ impl IntelDriver { ring: Mutex::new(ring), gmbus, dp_aux, + combo_phy, display_power, dmc, cdclk, diff --git a/mk/fstools.mk b/mk/fstools.mk index c4adbcd022..466ec8f4cc 100644 --- a/mk/fstools.mk +++ b/mk/fstools.mk @@ -49,6 +49,8 @@ $(FSTOOLS_TAG): $(CONTAINER_TAG) ifeq ($(PODMAN_BUILD),1) $(PODMAN_RUN) make $@ else + # Fetch host tool git dependencies (e.g. pkgar from Redox) before offline build + $(HOST_CARGO) fetch --locked --manifest-path Cargo.toml $(HOST_CARGO) build --manifest-path Cargo.toml --release --locked $(CARGO_OFFLINE_FLAG) mkdir -p $(@D) touch $@