Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/saf/device/display.md
Fimeg bde961c6f2 saf: one spine — device, state, and work under the index
PAF becomes saf/device (history kept), STATE.md dissolves
into saf/state.md with the dated era archived, the substrate
SAF moves up from souveraine, and every agreement points at
saf/INDEX.md and nowhere else. one map, nothing to remember
2026-08-18 09:47:30 -04:00

109 lines
5.9 KiB
Markdown

# PAF · Display — SW43408 panel, DSI, bias rails (SOLVED 2026-07-10)
## Current regression — verified on glass 2026-07-11
On current kernel `7.1.1-sdm845-g56b0a053bef8`, a true unplugged cold boot
still produces a green flash during boot. Green flashes also remain on wake.
During AP-side DT2W testing the first double tap sometimes does a visible
green-flash/black half-wake and the second wakes the panel. The kernel trace
shows the first gesture reaches panel prepare and is immediately followed by
unprepare; there are no DSI/DPU errors. In one successful wake the visible
frame remained stale despite a synchronized system clock and live Hyprland +
Quickshell processes. This is an observation, **not** proof of a panel-only
root cause; preserve it for the display/DPMS investigation.
**Recovery and clock distinction, 2026-07-11:** after an instrumented
libssc-triggered lockup, `blueline-screen-toggle on` re-prepared the panel but
it unprepared again seconds later even with `hypridle` stopped. Do not churn
panel/FTS resets in that state. A normal reboot of the known-good current slot
restored the panel and compositor. The first post-boot `ii` screenshot still
showed the Jul-06 20:00 clock floor even though NTP had corrected system time;
restarting only Quickshell (`qs -c ii kill`, then `qs -c ii`) refreshed it to
the real time. Therefore an old ii clock is not alone evidence of a frozen
scanout. The remaining task is to prevent ii from retaining the pre-NTP clock,
not to reset the panel again.
Cold boot → Hyprland AND power-button sleep/wake visually verified on
kernel `g766205b60588`. Read this whole file before touching
`panel-lg-sw43408.c`, the labibb regulator, or the display DT.
## The doctrine: WARM-CYCLE. Do not dismantle again.
The working design in `drivers/gpu/drm/panel/panel-lg-sw43408.c`:
- `.prepare` = regulators + reset pulse only. No DCS.
- `.enable` = the ENTIRE DCS init (gamma, TE, sleep-out, vendor regs, PPS,
compression, display-on) — runs over a fully-up DSI link, onto a
still-powered DDIC, on every DPMS-on.
- `.disable` = display_off + enter_sleep (HS mode). That is ALL DPMS-off does.
- **No `.unprepare` power-off.** The panel keeps vddi/vpnl forever after
first boot; reset is never re-asserted at runtime.
Why: **upstream's prepare-time cold-cycle design cannot cold-start this
panel.** Full power-off + reset + re-init produces a green flash (display-on
latching onto random GRAM) then permanent black, on every transition. That
is the original "screen won't wake without the sdm845-mainline hack" bug
(David's report). The warm-cycle shape IS the fix — the panel is
re-initialized warm, never cold.
History: the working design was dismantled on 2026-07-09 by ee6611adb
("adopt upstream prepare-time init") and a day of ordering experiments
failed to make cold-start work (display-on before PPS, after PPS, downstream
power sequencing — all green-flash-black). 766205b60 restored the warm-cycle
architecture. Any future "align with upstream" refactor must first prove
cold-start on real glass.
## Bias rails: LAB/IBB under SWIRE (hardware) control
Matching downstream: the DDIC drives the OLED bias rails over the SWIRE
wire, not software.
- DT: `qcom,swire-control` on the pmi8998 labibb node (1b02532a4).
- Driver: SWIRE ops are software no-ops (enable/disable/set_voltage return 0);
probe writes IBB `ENABLE_CTL=0x40` (SWIRE_RDY, module-enable cleared).
LAB `ENABLE_CTL=0x00` is CORRECT in SWIRE mode (slaved to IBB in hardware).
- Behavior: panel sleep-in → rails physically drop; sleep-out → rails rise.
Register-verified live across DPMS cycles: STATUS1 (IBB 0xdc08 / LAB
0xde08 on regmap 0-03) reads 00/00 off → 80/a0 on.
- The panel driver's supplies are vddi + vpnl ONLY. It never touches
LAB/IBB. c789daaa8 fixed the tail end of the old design (unprepare
disabling never-enabled rails → unbalanced-disable → `panel->prepared`
stuck true → EBUSY zombie); moot under warm-cycle but the lesson stands:
an error return from unprepare wedges the prepared flag forever.
- Voltage: software set_voltage is a no-op; hardware stays at the
bootloader's 5.5V programming.
## Userspace wake path
- Hyprland (Lua build) power-button / tap-to-wake toggle:
`blueline-screen-toggle` on the phone. Wake needs BOTH
`hl.dsp.dpms("on")` AND `hl.dsp.force_renderer_reload()` — dpms-on alone
can issue a commit with no real CRTC transition (crtc=NULL skips
drm_panel_prepare; long-standing compositor-side hole).
**Gotcha fixed 2026-07-10:** the script called `forceRendererReload()`,
which the Lua Hyprland renamed to `force_renderer_reload()` — every
power-button wake silently no-op'd. Dispatcher names must be verified
against the running Hyprland, errors surface only in the hyprctl reply.
- greetd → `start-hyprland` as initial session; the boot chain
fbcon → greetd → Hyprland does one panel takeover, warm.
## Diagnostic quick kit
- Rails now: `sudo grep -E "^(dc08|de08):" /sys/kernel/debug/regmap/0-03/registers`
(80/a0 = up, 00/00 = SWIRE-dropped).
- Compositor truth: `grim` screenshot — separates "compositor renders" from
"glass shows" (they diverged for two days; the screenshot was pixel-perfect
while the glass was black).
- DPMS from SSH:
`HYPRLAND_INSTANCE_SIGNATURE=$(ls /run/user/1000/hypr/) XDG_RUNTIME_DIR=/run/user/1000 hyprctl dispatch 'hl.dsp.dpms("off"|"on")'`.
- drm.debug=0x1ff wraps the dmesg ring in ~130ms of transition traffic —
use `journalctl -k` or a lower mask for transition captures.
- Boot-time `DSI PLL lock failed` + `already disabled/unprepared` clk
warnings at ~0.4s: probe-time deferred-probe noise, once per boot,
benign-but-ugly (error path double-disables a clk). Not a transition bug.
## Known-good fallback
`../staging/deploy-139aa/boot-139aa7748181-pmoschain.img` — pre-SWIRE-era
kernel (stmfts touch, warm-cycle display of that era). Module tree already
on the phone. Prefer fixing forward on the blueline tip.