From c0410449cb20d53d30986f3b13c851bf0563a104 Mon Sep 17 00:00:00 2001 From: vasilito Date: Wed, 22 Jul 2026 19:15:05 +0900 Subject: [PATCH] =?UTF-8?q?base:=20bump=20submodule=20=E2=80=94=20acpid=20?= =?UTF-8?q?GPE=20=5FLxx/=5FExx=20dispatch=20+=20PM=20timer=20(0485ae66)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also: redox-drm DPCD AUX stub replaced with real implementation. - redox-drm/intel/display.rs: read_dpcd skeleton (hardcoded vec![0x12,0x0A,0x84,0x01]) replaced with real native AUX channel read. aux_read() implements the DP AUX protocol: native read cmd (0x9) + 20-bit address + len-1 written to DP_AUX_CH_DATA, SEND_BUSY + message size + MTL POWER_REQUEST to DP_AUX_CH_CTL, DONE/error polling, ACK reply check, payload extract. Per zero-stub policy. Reference: Linux intel_dp_aux.c + intel_dp_aux_regs.h, VESA DP 1.4. - redox-drm/intel/backlight.rs: remove leftover fake_mmio_size test artifact. - Plan doc: Phase 3.3 marked code-complete (GMBUS EDID real, DPCD AUX real; modeset proof needs host). ACPICA assessment updated with GPE _Lxx/_Exx dispatch and PM timer. --- .../LG-GRAM-16Z90TP-COMPATIBILITY-PLAN.md | 4 +- .../source/src/drivers/intel/backlight.rs | 2 - .../source/src/drivers/intel/display.rs | 87 ++++++++++++++++++- local/sources/base | 2 +- 4 files changed, 89 insertions(+), 6 deletions(-) diff --git a/local/docs/LG-GRAM-16Z90TP-COMPATIBILITY-PLAN.md b/local/docs/LG-GRAM-16Z90TP-COMPATIBILITY-PLAN.md index 91878e02bb..63200b2afb 100644 --- a/local/docs/LG-GRAM-16Z90TP-COMPATIBILITY-PLAN.md +++ b/local/docs/LG-GRAM-16Z90TP-COMPATIBILITY-PLAN.md @@ -101,6 +101,8 @@ the existing `acpi-rs` vendored fork + `acpid` daemon: | _DSW/_PSW wake arming | ✅ Ported (2026-07-22) | `WakeRegistry::arm_wake_devices()` / `disarm_wake_devices()` — _DSW(1)/_PSW(1) enable + GPE wake enable | | Sleep state discovery | ✅ Ported (2026-07-22) | `SleepStates::discover()` — _S0 through _S5 enumeration | | GPE block handling | ✅ Already in acpid/gpe.rs | FADT-driven, write-1-to-clear, enable preserve | +| GPE _Lxx/_Exx dispatch | ✅ Ported (2026-07-22) | `enabled_active_gpes()` + `\_GPE._L{gpe:02X}`/`_E{gpe:02X}` method evaluation in handle_sci (evgpe.c acpi_ev_gpe_detect) | +| ACPI PM timer | ✅ Ported (2026-07-22) | `pm_timer_read()` from FADT pm_timer_block; `/scheme/acpi/pmtimer` endpoint (3.579545 MHz) | | EC query protocol | ✅ Already in acpid/ec.rs | SCI_EVT poll/IRQ, QR_EC drain, bounded at 32 | | Fixed event dispatch | ✅ Already in acpid/power_events.rs | PM1_STS PWRBTN/SLPBTN/RTC | | Sleep/wake (S0ix entry) | 🟡 Partial | `enter_s2idle()` now arms wake devices; `exit_s2idle()` disarms them. MWAIT idle loop remains (kernel idle-loop work) | @@ -235,7 +237,7 @@ Follows `local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md` Workstream C. |---|---|---|---| | 3.1 | Validate vesad at native panel mode (eDP; likely 2560×1600); confirm fbcond + any framebuffer consumers | vesad/bootloader EDID handoff | S | | 3.2 | ~~Per-generation display differentiation~~ **INVESTIGATED AND DISPROVEN (2026-07-22)** — register offsets are IDENTICAL from Gen8 (SKL) through Gen14 (MTL): PIPECONF=0x70008, PLANE_CTL=0x70180, PLANE_SURF=0x7019C, DDI_BUF_CTL=0x64000, HTOTAL=0x60000. Only CHICKEN_TRANS has a DISPLAY_VER>=14 branch. The real MTL gap is DMC firmware loading (Phase 3.4), not register offsets. | `redox-drm/source/src/drivers/intel/{mod,display}.rs` | ~~L~~ → ✅ DONE (investigation) | -| 3.3 | Real connector/EDID bring-up on eDP: GMBUS read at panel; bounded modeset proof via `redbear-drm-display-check` on the host | display.rs + test-drm-display-runtime.sh | M | +| 3.3 | Real connector/EDID bring-up on eDP: GMBUS read at panel; bounded modeset proof via `redbear-drm-display-check` on the host | display.rs + test-drm-display-runtime.sh | M → 🟡 CODE-COMPLETE (2026-07-22) — GMBUS EDID read already real (I2C via GMBUS0-3); **DPCD AUX stub replaced with real native AUX channel read** (DP_AUX_CH_CTL/DATA, native read cmd 0x9, ACK check, MTL POWER_REQUEST). Modeset proof + panel bring-up need host boot. | | 3.4 | **DMC firmware load sequence**: CSS header parse, DMA-to-DMC-store, DC state enable — port from Linux i915 `intel_dmc.c`. Consume the already-preloaded `mtl_dmc.bin` | `intel/mod.rs`, new `intel/dmc.rs`; firmware-loader | M–L → ✅ DONE (2026-07-22) — full DMC v1+v3 parser, payload MMIO loading, DisplayPlatform enum, wired into IntelDriver::new() | | 3.5 | eDP backlight control (DDI PWM / DPCD) — brightness keys need WMI (Phase 9); scheme-level brightness first | new `intel/backlight.rs` | M → ✅ DONE (2026-07-22) — CPU PWM backlight with UTIL_PIN mode setup, BLC_PWM_CPU_CTL[2] duty cycle control, enable/disable/set_brightness, Gen9+ register offsets | | 3.6 | GuC/HuC/GSC: manifest entries now, load sequences **deferred** (render path, not display blocker). Document as convergence work in DRM plan | `main.rs` firmware keys | S (manifest only) → ✅ DONE (2026-07-22) — guc_firmware_key(), huc_firmware_key(), gsc_firmware_key() on DisplayPlatform; manifest logged at IntelDriver::new() | diff --git a/local/recipes/gpu/redox-drm/source/src/drivers/intel/backlight.rs b/local/recipes/gpu/redox-drm/source/src/drivers/intel/backlight.rs index bfc489e61b..b51ca753fa 100644 --- a/local/recipes/gpu/redox-drm/source/src/drivers/intel/backlight.rs +++ b/local/recipes/gpu/redox-drm/source/src/drivers/intel/backlight.rs @@ -138,8 +138,6 @@ mod tests { #[test] fn brightness_clamped_to_max() { let mut bl = Backlight::new(0); - let fake_mmio_size = 0x50000; - let _ = fake_mmio_size; bl.current = bl.max_brightness + 1; assert!(bl.current > bl.max_brightness); } 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 5574210220..5b1eb2252d 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 @@ -61,6 +61,21 @@ const EDID_SLAVE_ADDR: u8 = 0x50; /// EDID block size in bytes. const EDID_BLOCK_SIZE: usize = 128; +const DP_AUX_CH_CTL_BASE: usize = 0x64010; +const DP_AUX_CH_DATA_BASE: usize = 0x64014; + +const AUX_CTL_SEND_BUSY: u32 = 1 << 31; +const AUX_CTL_DONE: u32 = 1 << 30; +const AUX_CTL_TIME_OUT_ERROR: u32 = 1 << 28; +const AUX_CTL_RECEIVE_ERROR: u32 = 1 << 25; +const AUX_CTL_MESSAGE_SIZE_SHIFT: u32 = 20; +const AUX_CTL_POWER_REQUEST: u32 = 1 << 19; +const AUX_CTL_POWER_STATUS: u32 = 1 << 18; + +const AUX_NATIVE_READ: u8 = 0x9; +const AUX_REPLY_ACK: u8 = 0x0; +const AUX_MAX_PAYLOAD: usize = 16; + #[derive(Clone, Copy, Debug)] pub struct DisplayPipe { pub index: u8, @@ -247,8 +262,76 @@ impl IntelDisplay { return Vec::new(); } - debug!("redox-drm: Intel AUX/DPCD skeleton read on port {}", port); - vec![0x12, 0x0A, 0x84, 0x01] + let mut dpcd = vec![0u8; 16]; + match self.aux_read(port, 0x00000, &mut dpcd) { + Ok(()) => { + debug!("redox-drm: DPCD read on port {}: {:02x?}", port, &dpcd[..4]); + dpcd + } + Err(e) => { + debug!("redox-drm: DPCD AUX read failed on port {}: {}", port, e); + Vec::new() + } + } + } + + /// Native AUX DPCD read (Linux intel_dp_aux.c, VESA DP 1.4 §2.6): + /// request [cmd<<4|addr19:16, addr15:8, addr7:0, len-1], reply byte0 nibble = ACK. + fn aux_read(&self, port: u8, address: u32, buf: &mut [u8]) -> Result<()> { + let len = buf.len().min(AUX_MAX_PAYLOAD); + if len == 0 { + return Err(DriverError::InvalidArgument("AUX read of zero length".into())); + } + let ctl = DP_AUX_CH_CTL_BASE + usize::from(port) * PORT_STRIDE; + let data_base = DP_AUX_CH_DATA_BASE + usize::from(port) * PORT_STRIDE; + + let b0 = (AUX_NATIVE_READ << 4) | ((address >> 16) & 0x0F) as u8; + let b1 = ((address >> 8) & 0xFF) as u8; + let b2 = (address & 0xFF) as u8; + let b3 = (len - 1) as u8; + self.write32(data_base, u32::from_ne_bytes([b0, b1, b2, b3]))?; + for i in 1..5 { + self.write32(data_base + i * 4, 0)?; + } + + let ctl_val = AUX_CTL_SEND_BUSY + | (5u32 << AUX_CTL_MESSAGE_SIZE_SHIFT) + | AUX_CTL_POWER_REQUEST; + self.write32(ctl, ctl_val)?; + + let mut timeout: u32 = 200_000; + let status = loop { + let status = self.read32(ctl)?; + if status & AUX_CTL_DONE != 0 { + break status; + } + if status & (AUX_CTL_TIME_OUT_ERROR | AUX_CTL_RECEIVE_ERROR) != 0 { + return Err(DriverError::Io(format!( + "AUX read error on port {port}: status={status:#010x}" + ))); + } + timeout = timeout + .checked_sub(1) + .ok_or_else(|| DriverError::Io(format!("AUX read timeout on port {port}")))?; + }; + + if status & AUX_CTL_POWER_REQUEST != 0 && status & AUX_CTL_POWER_STATUS == 0 { + debug!("redox-drm: AUX power status not set on port {}", port); + } + + let mut resp = [0u8; 20]; + for i in 0..5 { + let val = self.read32(data_base + i * 4)?; + resp[i * 4..i * 4 + 4].copy_from_slice(&val.to_ne_bytes()); + } + if (resp[0] >> 4) & 0x3 != AUX_REPLY_ACK { + return Err(DriverError::Io(format!( + "AUX read NACK/DEFER on port {port}: reply={:#04x}", + resp[0] + ))); + } + buf[..len].copy_from_slice(&resp[1..1 + len]); + Ok(()) } pub fn set_mode(&self, pipe: &DisplayPipe, mode: &ModeInfo) -> Result<()> { diff --git a/local/sources/base b/local/sources/base index 94d1b92d91..0485ae662a 160000 --- a/local/sources/base +++ b/local/sources/base @@ -1 +1 @@ -Subproject commit 94d1b92d915d86cea70a4609994321936aa302d2 +Subproject commit 0485ae662adba316b1a133674e6ed0401372934e