Extracted from local/reference/linux-7.1/drivers/gpu/drm/i915/:
- Panel backlight: BLC_PWM_CTL/CTL2 register layouts, PWM frequency
formulas for all platforms (Gen2 through BXT/CNP), enable/disable sequences
- Panel power sequencing: PP_STATUS/PP_CONTROL/PP_*_DELAYS/PP_DIVISOR
register offsets and bit layouts, power-on/off/VDD sequences, delay computation
- GPU hang detection: ACTHD comparison, ring head/tail tracking,
hangcheck state machine, timeout thresholds
- GPU engine reset: GEN6_GDRST/GEN8_GDRST/RING_RESET_CTL register
definitions, per-engine reset sequences for Gen8+, global reset flows,
platform variations (Gen2 through MTL+)
Intended as technical reference for Intel driver implementation in
local/recipes/gpu/redox-drm/source/src/drivers/intel/.
Four fixes from the code quality and Linux cross-reference audit:
1. DP AUX endianness (dp_aux.rs): Data packing must be big-endian
(MSB first, bits [31:24] = byte 0), matching Linux i915
intel_dp_aux_pack(). Fix send: (3-j)*8 shift. Fix receive:
to_be_bytes(). This was the #1 correctness bug — wrong endianness
would corrupt all DP AUX transactions.
2. Cursor pipe_select collision (cursor.rs): Mode and pipe select
were using the same bit positions. Fix: pipe_select at [29:28],
mode_64x64_argb = 0x27 per Intel PRM CUR_CTL register layout
and Linux MCURSOR_MODE_64_ARGB_AX + CURSOR_PIPE_SELECT.
3. Missing DP link training constants (dp_link.rs): Add
DP_LANE_CR_DONE, DP_LANE_CHANNEL_EQ_DONE, DP_LANE_SYMBOL_LOCKED
used in clock_recovery() and channel_equalization().
4. Missing ARL device ID (info.rs): Add 0x7D67 Arrow Lake-S
from Linux INTEL_ARL_S_IDS.
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.
Add cursor_set() and cursor_move() to IntelDriver GpuDriver impl,
enabling hardware cursor plane operations through the DRM interface.
- cursor_set(): map cursor FB to GPU address, set surface via
curbase register, enable via curcntr, with hot_x/hot_y params
- cursor_move(): update curpos register with clamped x/y (max 8191)
Phase 3 (Full KMS) now at 4/5 — only atomic modesetting remains.
The atomic modesetting ioctl (ATOMIC_COMMIT) requires scheme.rs
changes to define the ioctl number and wire into GpuDriver trait.
All 5 phases: 0 ✅ 1 ✅ 2 ✅ 3 🚧 4/5 4 ✅
Implement redox_private_cs_submit() in the Intel GpuDriver,
completing Phase 4 (Render Path). This is the userspace GPU
command submission interface used by Mesa.
- redox_private_cs_submit(): map source GEM buffer to GPU address,
extract batch commands as u32 slice from src_offset with
byte_count dwords, submit to render ring via ring.submit_batch()
- Returns RedoxPrivateCsSubmitResult with seqno (0 for now —
fence integration deferred)
This completes all 4 modules of Phase 4:
batch.rs ✅ fence.rs ✅ execlists.rs ✅ Mesa winsys ✅
Remaining across all phases:
Phase 2: DBUF detailed programming
Phase 3: Atomic modesetting (requires scheme.rs changes)
Add display_transcoder.rs — TRANS_DDI_FUNC_CTL programming for
platforms with separate transcoders (Xe2/Gen12+ where pipe != transcoder).
- Transcoder::configure(): program TRANS_DDI_FUNC_CTL (0x60400 +
0x1000 per transcoder) with DDI select, DP/HDMI mode select,
port width (1/2/4 lanes), and enable bit
- disable(): clear TRANS_DDI_FUNC_ENABLE
- is_enabled(): check TRANS_DDI_FUNC_ENABLE status
- EDP transcoder at 0x6F400 for pipe 3
Wire into IntelDriver::set_crtc — configure transcoder after
modesetting, using pipe.port and TransDdiMode::Dp with 4 lanes.
Only active when has_separate_transcoder == true.
Linux reference: intel_ddi.c (TRANS_DDI_FUNC_CTL programming)
Add display_watermark.rs — DBUF slice enable and per-pipe
watermark programming for Xe2/Gen12+ platforms.
- init_xe2(): enable DBUF_CTL_S1 (0x45008) and DBUF_CTL_S2 (0x4500C)
with DBUF_SLICE_ENABLE + DBUF_TRACKER_STATE_SERVICE
- program_pipe_watermarks(): set PLANE_BUF_CFG (0x7017C) and
PLANE_WM (0x70240) per pipe — zero for initial program, needs
real values for production
- compute_min_cdclk(): calculate minimum CDCLK from pixel clock,
lane count, and bits-per-pixel
Wire into IntelDriver — initialized after power wells, before DMC.
Linux reference: intel_dbuf.c, skl_watermark.c
Add regs_gen12.rs implementing IntelRegs trait for Gen12 (TGL/ADL)
and Gen12_7 (MTL/ARL) display engines. Gen12 shares most display
register offsets with Gen9 but has different forcewake and DMC.
- Gen12Regs: same pipe/plane/DDI/cursor/vblank offsets as Gen9
but with Gen12 forcewake (0xa188/0xdfc) and DMC (0x80000+)
- Gen12DisplayRegs: Gen12-specific display registers:
TRANS_DDI_FUNC_CTL (0x60400) — separate transcoder control
DBUF_CTL_S1/S2 (0x45008/0x4500C) — display buffer slices
PLANE_CTL/SURF/STRIDE at standard plane offsets
Update mod.rs generation selector: Gen12/Gen12_7 → Gen12Regs.
Xe2 continues to use Xe2Regs, Gen9 uses Gen9Regs.
Linux reference: intel_display_regs.h, xe_gt_regs.h
Add display_dpll.rs — pixel clock PLL management.
Gen9 (SKL/KBL/CFL): enable LCPLL1/LCPLL2 at 0x46010/0x46014
and WRPLL1 at 0x46040 with WRPLL_REF_BCLK reference clock.
Poll PLL_LOCK bit for confirmation.
Xe2 (ARL/BMG): enable DPLL_CTRL1/DPLL_CTRL2 at 0x6C058/0x6C05C
with PLL_POWER_ENABLE. get_pll_for_clock() returns pdiv=1 or 2
based on pixel clock threshold (300 MHz).
Wire into IntelDriver constructor between CDCLK and display init.
Linux reference: intel_dpll_mgr.c (skl_wrpll, icl_dpll)
Rewrite display_cdclk.rs with generation-aware clock programming.
Gen9 (SKL/KBL/CFL): 337.5/450/540/675 MHz via CDCLK_CTL (0x46000)
with decimal + freq_select encoding. Existing code preserved.
Xe2 (ARL/BMG): 307.2/384/556.8/652.8 MHz via CDCLK_FREQ (0x46200)
with different freq_select/decimal encoding. Xe2 frequency table
ported from Linux intel_cdclk.c (DISPLAY_VER >= 20 path).
DisplayClock::new() now takes &IntelDeviceInfo for gen selection.
CDCLK init reads current hardware state rather than assuming defaults.
Linux reference: intel_cdclk.c (bxt_set_cdclk, skl_set_cdclk)
Rewrite display_power.rs to support both Gen9 (Skylake) and Xe2
(Arrow Lake/Battlemage) power well initialization.
Gen9 path (unchanged): single POWER_WELL_CTL register at 0x45400
with bitmask for PW1/PW2/DDI_A-E/AUX_A-D domains.
Xe2 path (new): multiple power well controllers:
- HSW_PWR_WELL_CTL1 (0x45400) — PW1/PW2 per-index REQ/STATE
- ICL_PWR_WELL_CTL_AUX1 (0x45440) — 4 AUX channels
- ICL_PWR_WELL_CTL_DDI1 (0x45450) — 4 DDI ports
- DC_STATE_EN (0x45504) — DC power state control
Each well uses 2-bit per-index encoding (REQ=0x2, STATE=0x1).
DisplayPower::new() now takes &IntelDeviceInfo to select
generation-appropriate initialization path.
Linux reference: intel_display_power_well.c (xelpdp_aux_power_well_*)
Document the fundamental architectural rule: Red Bear OS is a FULL FORK.
We do not depend on Redox. We reuse Redox code only when needed — and
when we do, we fork it into our own repos.
Key rules:
- Own your dependencies (local/sources/ or local/recipes/)
- No waiting for upstream (fix in our fork)
- Frozen snapshots only (never auto-pull)
- Upstream gitlab URLs are temporary (91 remaining, to be forked)
- Our code, our fixes (fix forward when APIs break)
- Durable state (commit to local/sources/)
Fix 4 E0277 errors in daemon/src/lib.rs where scheme_root()
and create_this_scheme_fd() return syscall::error::Error but
the function returns syscall::Error. Add .map_err() conversions.
redox-driver-sys errors (6 remaining E0308/E0061 in dma.rs/io.rs)
are pre-existing API mismatches between libredox and redox_syscall
crate versions — not addressed here.
Replace stub EDID reading with real DP AUX I2C-over-AUX EDID reads
for Xe2 platforms. For non-Xe2 platforms, continue using GMBUS.
- detect_display_topology(): accept Option<&[DpAux]> parameter,
try DP AUX read_edid() first for Xe2, fall back to display.read_edid()
(GMBUS) for Gen9 platforms
- IntelDriver::new(): pass dp_aux channels to detect_display_topology
- refresh_connectors(): pass dp_aux from self
Display detection flow for Arrow Lake:
DDI_BUF_CTL polling → DP AUX EDID → EDID parsing → mode list
(falls back to synthetic 1920x1080@60 if DP AUX fails)
Compiled: 0 new errors
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
Add dp_aux.rs implementing DisplayPort AUX channel for EDID reads
and DPCD capability queries. Critical for Xe2/Arrow Lake which lacks
GMBUS and must use DP AUX for all EDID operations.
- dp_aux.rs: DpAux struct with per-port AUX channel (CTL at 0x64010,
DATA at 0x64014, 0x100 stride). Implements do_transfer() with
native read/write and I2C-over-AUX protocols, wait_for_completion()
with busy/done/timeout/receive_error detection, read_dpcd() for
DPCD register access, read_dpcd_caps() for capability enumeration,
and read_edid() via I2C-over-AUX (MOT-based segmented reads)
- mod.rs: declare dp_aux module, add DpAux import, add dp_aux: Vec<DpAux>
field to IntelDriver, initialize one DpAux per port in constructor
Linux reference: intel_dp_aux.c, intel_dp_aux_regs.h
Compiled: 0 new errors (pre-existing daemon errors unrelated)
Kernel, relibc, and base forks now use the full pre-patched source
from the frozen 0.1.0 release archives (including .git history).
Build verification:
- kernel: BUILDS from local/sources/kernel
- relibc: BUILDS from local/sources/relibc
- base: BUILDS from local/sources/base
- redoxfs: BUILDS from local/sources/redoxfs
The mini ISO build fails due to pre-existing cached pkgar signature
issues (not migration-related).
- Create source symlinks for all 7 core components (kernel, relibc, base,
bootloader, installer, redoxfs, userutils) pointing at local/sources/
- Create redoxfs and userutils fork repos from frozen 0.1.0 archives
- Fix relibc-tests recipes: replace patch commands with direct fork build
- Archive all 417 patch files to local/archived/patches-2026-06-migration/
- Full AGENTS.md rewrite: remove all 31 remaining stale patch references,
update DURABILITY POLICY to describe git commit workflow, update WHERE TO
LOOK table, fix build flow description, replace Recipe Patch Wiring section
with Recipe Source Configuration
- Zero active patches = [...] arrays remain in any recipe.toml file
- All 13 remaining grep hits for 'patches' are TODO comments in WIP recipes
Comprehensive 6-phase plan (1,055 lines) for updating the Intel GPU driver from current 1,590-line stub to full Gen9+ support ported from Linux 7.1 i915. Covers register abstraction, GMBUS I2C, DMC firmware, power wells, CDCLK, display pipeline, modesetting, and hardware validation.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
userutils compiled redox-rt with default-features=false, disabling the proc feature. This caused login's fork to not pass proc fd to child shell, triggering assertion failed: info.has_proc_fd in redox-rt. P8 patch enables features=['proc']. Verified: zero panics on boot, login works for user/root.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
The driver incorrectly labeled Lunar Lake IDs (0x6420/64A0/64B0) as
Arrow Lake, and placed the real Arrow Lake IDs (0x7D41/7D51/etc.) in the
Meteor Lake bucket. This meant:
- Arrow Lake notebooks were misidentified as Meteor Lake
- Lunar Lake was completely missing from the device tables
- The 0xB640 ID (ARL-H) was also misfiled
Fix:
- Move real Arrow Lake IDs (0x7D41, 0x7D51, 0x7DD1, 0x7D67, 0xB640)
to INTEL_GEN12_ARL_IDS
- Move Lunar Lake IDs (0x6420, 0x64A0, 0x64B0) to INTEL_GEN12_LNL_IDS
- Map Arrow Lake DMC firmware to INTEL_MTL_DMC_KEYS (mtl_dmc.bin),
since Arrow Lake uses the same display IP 14.0 as Meteor Lake
- Remove Arrow Lake IDs from the Meteor Lake bucket
Per Linux 7.1 reference: Arrow Lake display engine is IP 14.0 (Xe_LPD+),
same as Meteor Lake — NOT Xe2. The i915-style register programming is
correct for Arrow Lake.
- ps2d: PS/2 keyboard/mouse (init service + driver-manager wildcard match)
- i2c-hidd: I2C HID keyboard/touchpad (init service + driver-manager match)
- intel-thc-hidd: Intel Touch Host Controller HID (init service + PCI match)
Fixes i2c-hidd path: /usr/bin/i2c-hidd (not /usr/lib/drivers/).
These drivers were already built in the base package but were not wired
into the boot process. Modern Intel notebooks typically use either
i8042 EC emulation (PS/2) or I2C HID for keyboard/touchpad.
The capability bitmask patch was missing the critical proc.rs hunk that
derives caps from euid when procmgr writes ProcSchemeAttrs to a child
context. Without this, all child processes had caps=0, causing
EACCES on dup("create-scheme") and crashing boot.
Fix: in ContextHandle::Attr kwrite path, after setting euid/egid/pid/prio,
set guard.caps = CAP_ALL when euid==0, else 0.