From 5dd1178d834fbe2d2fe908bd1cef33f028cd92f1 Mon Sep 17 00:00:00 2001 From: Admin Pupkin Date: Sat, 30 May 2026 07:31:59 +0300 Subject: [PATCH] intel: D2D link enable for Xe2 display connection Add enable_d2d_links() for Xe2/Arrow Lake platforms where the display connection requires D2D (die-to-die) link setup before connector detection. Programs DDI_BUF_CTL with D2D_LINK_ENABLE (bit 29) and polls D2D_LINK_STATE (bit 28) for each port. Called from IntelDriver::new() when generation == GenXe2, before power well initialization. Linux reference: intel_ddi.c (XE2LPD_DDI_BUF_D2D_LINK_ENABLE) Compiled: 0 new errors --- .../redox-drm/source/src/drivers/intel/mod.rs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) 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 28d197d5af..33ca96350b 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 @@ -149,6 +149,10 @@ impl IntelDriver { .collect(); info!("redox-drm-intel: initialized {} DP AUX channels", dp_aux.len()); + if device_info.generation == IntelGeneration::GenXe2 { + enable_d2d_links(&mmio_arc, regs, device_info.num_ports)?; + } + let display_power = DisplayPower::new(mmio_arc.clone(), regs); display_power.init_domains()?; @@ -227,6 +231,37 @@ impl IntelDriver { cdclk, }) } +} + +fn enable_d2d_links(mmio: &Arc, regs: &dyn IntelRegs, num_ports: u8) -> Result<()> { + use std::time::{Duration, Instant}; + const D2D_LINK_ENABLE: u32 = 1 << 29; + const D2D_LINK_STATE: u32 = 1 << 28; + const D2D_TIMEOUT_MS: u64 = 10; + + for port in 0..num_ports { + let ddi_ctl = regs.ddi_buf_ctl(port); + let current = mmio.read_u32(ddi_ctl); + if current & D2D_LINK_STATE != 0 { + continue; + } + mmio.write_u32(ddi_ctl, current | D2D_LINK_ENABLE); + let deadline = Instant::now() + Duration::from_millis(D2D_TIMEOUT_MS); + loop { + let status = mmio.read_u32(ddi_ctl); + if status & D2D_LINK_STATE != 0 { + info!("redox-drm-intel: D2D link enabled on port {}", port); + break; + } + if Instant::now() > deadline { + warn!("redox-drm-intel: D2D link timeout on port {}", port); + break; + } + std::hint::spin_loop(); + } + } + Ok(()) + } fn refresh_connectors(&self) -> Result> { let (connectors, encoders) = detect_display_topology(&self.display)?;