diff --git a/local/recipes/gpu/redox-drm/source/src/drivers/intel/info.rs b/local/recipes/gpu/redox-drm/source/src/drivers/intel/info.rs index f1f5229010..cdacd20784 100644 --- a/local/recipes/gpu/redox-drm/source/src/drivers/intel/info.rs +++ b/local/recipes/gpu/redox-drm/source/src/drivers/intel/info.rs @@ -11,6 +11,7 @@ pub enum IntelGeneration { Gen9_5, Gen12, Gen12_7, + GenXe2, Unknown, } @@ -26,6 +27,7 @@ impl IntelGeneration { Self::Gen9_5 => 11, Self::Gen12 => 12, Self::Gen12_7 => 14, + Self::GenXe2 => 20, Self::Unknown => 0, } } @@ -41,6 +43,7 @@ impl IntelGeneration { Self::Gen9_5 => 9, Self::Gen12 => 12, Self::Gen12_7 => 12, + Self::GenXe2 => 20, Self::Unknown => 0, } } @@ -50,6 +53,7 @@ impl IntelGeneration { Self::Gen4 | Self::Gen5 => 2, Self::Gen6 | Self::Gen7 | Self::Gen8 => 3, Self::Gen9 | Self::Gen9_5 | Self::Gen12 | Self::Gen12_7 => 4, + Self::GenXe2 => 4, Self::Unknown => 1, } } @@ -81,11 +85,12 @@ impl IntelDeviceInfo { | IntelGeneration::Gen9_5 | IntelGeneration::Gen12 | IntelGeneration::Gen12_7 + | IntelGeneration::GenXe2 ) } pub fn is_gen12_or_later(&self) -> bool { - matches!(self.generation, IntelGeneration::Gen12 | IntelGeneration::Gen12_7) + matches!(self.generation, IntelGeneration::Gen12 | IntelGeneration::Gen12_7 | IntelGeneration::GenXe2) } } @@ -143,6 +148,10 @@ const DEVICE_ID_TABLE: &[DeviceIdEntry] = &[ DeviceIdEntry { device_id: 0x7D60, gen: IntelGeneration::Gen12_7, platform_name: "Meteor Lake", dmc_fw_key: Some("MTL") }, DeviceIdEntry { device_id: 0x7D45, gen: IntelGeneration::Gen12_7, platform_name: "Meteor Lake", dmc_fw_key: Some("MTL") }, DeviceIdEntry { device_id: 0x7D67, gen: IntelGeneration::Gen12_7, platform_name: "Meteor Lake", dmc_fw_key: Some("MTL") }, + DeviceIdEntry { device_id: 0x7D41, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-U", dmc_fw_key: Some("ARL") }, + DeviceIdEntry { device_id: 0x7D51, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-P Arc Pro 130T/140T", dmc_fw_key: Some("ARL") }, + DeviceIdEntry { device_id: 0x7DD1, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-P", dmc_fw_key: Some("ARL") }, + DeviceIdEntry { device_id: 0xB640, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-H", dmc_fw_key: Some("ARL") }, ]; pub fn device_info_from_id(device_id: u16) -> IntelDeviceInfo { @@ -154,14 +163,14 @@ pub fn device_info_from_id(device_id: u16) -> IntelDeviceInfo { display_version: gen.display_version(), gt_version: gen.gt_version(), num_pipes: gen.num_pipes(), - num_ports: if gen == IntelGeneration::Gen12 || gen == IntelGeneration::Gen12_7 { 6 } else { 4 }, - has_ddi: matches!(gen, IntelGeneration::Gen9 | IntelGeneration::Gen9_5 | IntelGeneration::Gen12 | IntelGeneration::Gen12_7), - has_dp_aux: matches!(gen, IntelGeneration::Gen9 | IntelGeneration::Gen9_5 | IntelGeneration::Gen12 | IntelGeneration::Gen12_7), - has_gmbus: matches!(gen, IntelGeneration::Gen9 | IntelGeneration::Gen9_5 | IntelGeneration::Gen12 | IntelGeneration::Gen12_7), - has_dmc: matches!(gen, IntelGeneration::Gen9 | IntelGeneration::Gen9_5 | IntelGeneration::Gen12 | IntelGeneration::Gen12_7), - has_combo_phy: matches!(gen, IntelGeneration::Gen9_5 | IntelGeneration::Gen12 | IntelGeneration::Gen12_7), - has_dbuf_slice: gen == IntelGeneration::Gen12 || gen == IntelGeneration::Gen12_7, - has_separate_transcoder: gen == IntelGeneration::Gen12 || gen == IntelGeneration::Gen12_7, + num_ports: if gen == IntelGeneration::Gen12 || gen == IntelGeneration::Gen12_7 || gen == IntelGeneration::GenXe2 { 6 } else { 4 }, + has_ddi: matches!(gen, IntelGeneration::Gen9 | IntelGeneration::Gen9_5 | IntelGeneration::Gen12 | IntelGeneration::Gen12_7 | IntelGeneration::GenXe2), + has_dp_aux: matches!(gen, IntelGeneration::Gen9 | IntelGeneration::Gen9_5 | IntelGeneration::Gen12 | IntelGeneration::Gen12_7 | IntelGeneration::GenXe2), + has_gmbus: matches!(gen, IntelGeneration::Gen9 | IntelGeneration::Gen9_5), + has_dmc: matches!(gen, IntelGeneration::Gen9 | IntelGeneration::Gen9_5 | IntelGeneration::Gen12 | IntelGeneration::Gen12_7 | IntelGeneration::GenXe2), + has_combo_phy: matches!(gen, IntelGeneration::Gen9_5 | IntelGeneration::Gen12 | IntelGeneration::Gen12_7 | IntelGeneration::GenXe2), + has_dbuf_slice: gen == IntelGeneration::Gen12 || gen == IntelGeneration::Gen12_7 || gen == IntelGeneration::GenXe2, + has_separate_transcoder: gen == IntelGeneration::Gen12 || gen == IntelGeneration::Gen12_7 || gen == IntelGeneration::GenXe2, dmc_fw_key: entry.dmc_fw_key, platform_name: entry.platform_name, }; 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 f783fc8a48..6a204214cc 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 @@ -7,6 +7,7 @@ pub mod gtt; pub mod info; pub mod regs; pub mod regs_gen9; +pub mod regs_xe2; pub mod ring; use std::collections::HashMap; @@ -31,9 +32,10 @@ use self::display_dmc::DmcFirmware; use self::display_power::DisplayPower; use self::gmbus::GmbusController; use self::gtt::IntelGtt; -use self::info::{IntelDeviceInfo, device_info_from_id}; +use self::info::{IntelDeviceInfo, IntelGeneration, device_info_from_id}; use self::regs::IntelRegs; use self::regs_gen9::Gen9Regs; +use self::regs_xe2::Xe2Regs; use self::ring::{IntelRing, RingType}; const FORCEWAKE: usize = 0xA18C; @@ -54,7 +56,7 @@ pub struct IntelDriver { info: PciDeviceInfo, device_info: IntelDeviceInfo, mmio: Arc, - regs: &'static Gen9Regs, + regs: &'static dyn IntelRegs, irq_handle: Mutex>, display: IntelDisplay, gem: Mutex, @@ -63,7 +65,7 @@ pub struct IntelDriver { encoders: Mutex>, gtt: Mutex, ring: Mutex, - gmbus: GmbusController, + gmbus: Option, display_power: DisplayPower, dmc: DmcFirmware, cdclk: DisplayClock, @@ -119,16 +121,25 @@ impl IntelDriver { let device_info = device_info_from_id(info.device_id); info!( - "redox-drm: Intel {} detected (device {:#06x}, display ver {})", - device_info.platform_name, info.device_id, device_info.display_version + "redox-drm: Intel {} detected (device {:#06x}, display ver {}, gen {:?})", + device_info.platform_name, info.device_id, device_info.display_version, device_info.generation ); - let regs = &Gen9Regs; + let regs: &'static dyn IntelRegs = match device_info.generation { + IntelGeneration::GenXe2 => &Xe2Regs, + _ => &Gen9Regs, + }; let mmio_arc = Arc::new(mmio); let display_mmio_arc = Arc::new(display_mmio); - let gmbus = GmbusController::new(display_mmio_arc.clone(), regs); - gmbus.init()?; + let gmbus = if device_info.has_gmbus { + let ctrl = GmbusController::new(display_mmio_arc.clone(), regs); + ctrl.init()?; + Some(ctrl) + } else { + info!("redox-drm-intel: Xe2 platform — skipping GMBUS (uses DP AUX for EDID)"); + None + }; let display_power = DisplayPower::new(mmio_arc.clone(), regs); display_power.init_domains()?; diff --git a/local/recipes/gpu/redox-drm/source/src/drivers/intel/regs_xe2.rs b/local/recipes/gpu/redox-drm/source/src/drivers/intel/regs_xe2.rs new file mode 100644 index 0000000000..dc7306e116 --- /dev/null +++ b/local/recipes/gpu/redox-drm/source/src/drivers/intel/regs_xe2.rs @@ -0,0 +1,127 @@ +use super::regs::IntelRegs; + +pub struct Xe2Regs; + +impl IntelRegs for Xe2Regs { + fn forcewake_req(&self) -> usize { 0xa188 } + fn forcewake_ack(&self) -> usize { 0xdfc } + + fn power_well_ctl(&self) -> usize { 0x45400 } + + fn cdclk_ctl(&self) -> usize { 0x46000 } + + fn dmc_mmio_start(&self) -> usize { 0x80000 } + fn dmc_mmio_end(&self) -> usize { 0x8FFFF } + fn dmc_fw_base(&self) -> usize { 0x80008 } + fn dmc_ctrl(&self) -> usize { 0x80020 } + fn dmc_status(&self) -> usize { 0x80024 } + fn dmc_sram_base(&self) -> usize { 0x10000 } + + fn gmbus0(&self) -> usize { 0xC5100 } + fn gmbus1(&self) -> usize { 0xC5104 } + fn gmbus2(&self) -> usize { 0xC5108 } + fn gmbus3(&self) -> usize { 0xC510C } + fn gmbus4(&self) -> usize { 0xC5110 } + fn gmbus5(&self) -> usize { 0xC5120 } + + fn pipeconf(&self, pipe: u8) -> usize { + 0x70008 + (pipe as usize) * 0x1000 + } + fn pipeconf_enable_mask(&self) -> u32 { 1 << 31 } + + fn htotal(&self, pipe: u8) -> usize { + 0x60000 + (pipe as usize) * 0x1000 + } + fn hblank(&self, pipe: u8) -> usize { + 0x60004 + (pipe as usize) * 0x1000 + } + fn hsync(&self, pipe: u8) -> usize { + 0x60008 + (pipe as usize) * 0x1000 + } + fn vtotal(&self, pipe: u8) -> usize { + 0x6000C + (pipe as usize) * 0x1000 + } + fn vblank(&self, pipe: u8) -> usize { + 0x60010 + (pipe as usize) * 0x1000 + } + fn vsync(&self, pipe: u8) -> usize { + 0x60014 + (pipe as usize) * 0x1000 + } + fn pipe_src(&self, pipe: u8) -> usize { + 0x6001C + (pipe as usize) * 0x1000 + } + fn pipe_stride(&self) -> usize { 0x1000 } + + fn dspcntr(&self, pipe: u8) -> usize { + 0x70180 + (pipe as usize) * 0x1000 + } + fn dspcntr_enable_mask(&self) -> u32 { 1 << 31 } + fn dspsurf(&self, pipe: u8) -> usize { + 0x7019C + (pipe as usize) * 0x1000 + } + fn plane_size(&self, pipe: u8) -> usize { + 0x70190 + (pipe as usize) * 0x1000 + } + + fn ddi_buf_ctl(&self, port: u8) -> usize { + 0x64000 + (port as usize) * 0x100 + } + fn ddi_port_stride(&self) -> usize { 0x100 } + + fn curcntr(&self, pipe: u8) -> usize { + 0x70080 + (pipe as usize) * 0x1000 + } + fn curpos(&self, pipe: u8) -> usize { + 0x70084 + (pipe as usize) * 0x1000 + } + fn curbase(&self, pipe: u8) -> usize { + 0x70088 + (pipe as usize) * 0x1000 + } + + fn pipeframe_reg(&self, pipe: u8) -> usize { + 0x70040 + (pipe as usize) * 0x1000 + } + fn pipeframe_count_mask(&self) -> u32 { 0x00FFFFFF } + + fn gfx_flsh_cntl(&self) -> usize { 0x101008 } + + fn pp_status(&self) -> usize { 0xC7200 } +} + +pub struct Xe2LpdRegs { + pub de_cap: usize, + pub dfsm: usize, + pub dbuf_ctl: usize, + pub d2d_link_ctl: usize, + pub aux_ctl: usize, +} + +impl Xe2LpdRegs { + pub const fn new() -> Self { + Self { + de_cap: 0x41100, + dfsm: 0x51000, + dbuf_ctl: 0x45008, + d2d_link_ctl: 0x64200, + aux_ctl: 0x64010, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_xe2_forcewake() { + let regs = Xe2Regs; + assert_eq!(regs.forcewake_req(), 0xa188); + assert_ne!(regs.forcewake_req(), 0xA18C); + } + + #[test] + fn test_xe2_dmc() { + let regs = Xe2Regs; + assert_eq!(regs.dmc_mmio_start(), 0x80000); + } +}