intel: fix read_edid_block stub — wire to GMBUS controller

Replace the hard stub in display.rs::read_edid_block() with a real
GMBUS I2C EDID read. Fixes the #1 plan gap identified in the
code quality audit.

- display.rs: add gmbus: Option<GmbusController> to IntelDisplay
  struct and new() constructor. read_edid_block() now calls
  gmbus.read_edid() via GymbusPort::from_connector_index().
  Falls back to DriverError if no GMBUS controller available.
- mod.rs: pass gmbus controller (cloned) to IntelDisplay::new()

This completes the EDID path for Gen9 platforms (Gen8-9 have
GMBUS, Xe2 uses DP AUX). The synthetic 1080p fallback remains
as the final safety net.
This commit is contained in:
2026-05-30 10:00:36 +03:00
parent 381c2984b7
commit 0dee6ec9da
2 changed files with 21 additions and 4 deletions
@@ -3,6 +3,7 @@ use std::sync::Mutex;
use log::{debug, info};
use redox_driver_sys::memory::MmioRegion;
use super::gmbus::{GmbusController, GmbusPort};
use super::regs::IntelRegs;
use crate::driver::{DriverError, Result};
use crate::kms::connector::synthetic_edid;
@@ -26,10 +27,11 @@ pub struct IntelDisplay {
mmio: MmioRegion,
pipes: Mutex<Vec<DisplayPipe>>,
regs: &'static dyn IntelRegs,
gmbus: Option<GmbusController>,
}
impl IntelDisplay {
pub fn new(mmio: MmioRegion, regs: &'static dyn IntelRegs) -> Result<Self> {
pub fn new(mmio: MmioRegion, regs: &'static dyn IntelRegs, gmbus: Option<GmbusController>) -> Result<Self> {
let pipes = Self::detect_pipes(&mmio, regs)?;
info!(
"redox-drm: Intel display initialized with {} pipe(s)",
@@ -39,6 +41,7 @@ impl IntelDisplay {
mmio,
pipes: Mutex::new(pipes),
regs,
gmbus,
})
}
@@ -145,9 +148,22 @@ impl IntelDisplay {
synthetic_edid()
}
fn read_edid_block(&self, _port: u8, _block: u8, _buf: &mut [u8]) -> Result<()> {
fn read_edid_block(&self, port: u8, _block: u8, buf: &mut [u8]) -> Result<()> {
if let Some(ref gmbus) = self.gmbus {
let gmbus_port = GmbusPort::from_connector_index(port);
match gmbus.read_edid(gmbus_port) {
Ok(edid) => {
let len = edid.len().min(buf.len());
buf[..len].copy_from_slice(&edid[..len]);
return Ok(());
}
Err(e) => {
debug!("redox-drm: Intel GMBUS EDID read failed on port {}: {}", port, e);
}
}
}
Err(DriverError::Initialization(
"EDID I2C/DDC not yet implemented".into(),
"EDID I2C/DDC not available — no GMBUS controller".into(),
))
}
@@ -224,7 +224,8 @@ impl IntelDriver {
}
}
let display = IntelDisplay::new(display_mmio, regs)?;
let display_gmbus = gmbus.clone();
let display = IntelDisplay::new(display_mmio, regs, display_gmbus)?;
let mut gtt = IntelGtt::init(gtt_mmio, gtt_control_mmio)?;
let mut ring = IntelRing::create(ring_mmio, RingType::Render)?;
ring.bind_gtt(&mut gtt)?;