Display pipe binds and the panel stays dark; touch worked once and stopped. Both have a named single-boot test rather than a theory. Driver changes and rails are ruled out by test; the display path is not.
219 lines
11 KiB
Markdown
219 lines
11 KiB
Markdown
# HANDOFF — 2026-08-10, the iPhone 7
|
||
|
||
For Codex. The d10 is at `172.16.43.1`, root, `~/.ssh/ani`. It is running, it is
|
||
reachable, and **it shows nothing on the glass and takes no touch.** Both of
|
||
those are regressions from earlier the same night, and both have a named next
|
||
test rather than a theory.
|
||
|
||
Read `docs/tasks/63-d10-second-body.md` and `devices/d10/README.md`. Everything
|
||
below is what a fresh session would otherwise spend hours rediscovering.
|
||
|
||
---
|
||
|
||
## 1. State right now
|
||
|
||
| | |
|
||
|---|---|
|
||
| kernel | `7.2.0-rc1-g2e349ddf2fe3-dirty`, variant `adp4`, booted with `-a` |
|
||
| display | ADP owns `card0`. CRTC `active=1`, `fb=43`, plane `750x1334+0+0`, connector `card0-DSI-1` connected+enabled. **Panel dark.** |
|
||
| touch | `apple_z2` bound on `spi0.0`, init completes, **IRQ never moves for a finger** |
|
||
| session | greetd → `casey` on `seat0`/tty1, sessiond + shell active, locked |
|
||
| backlights | two, both raised — the darkness is content, not brightness |
|
||
|
||
The boot that produced this used `boot.sh -a`, which blacklists simpledrm so ADP
|
||
is the only DRM device. **Booting without `-a` gives simpledrm back and the
|
||
screen works.** That is the first thing to do if the device needs to be usable
|
||
before it needs to be understood.
|
||
|
||
```sh
|
||
~/Projects/hoolock/boot.sh -k adp2 # simpledrm, screen works
|
||
~/Projects/hoolock/boot.sh -k adp4 -a # ADP alone, dark
|
||
```
|
||
|
||
DFU is buttons only: power off, Vol-Down + Power 8s, release Power, keep
|
||
Vol-Down ~10s. The script waits for it and drives everything after.
|
||
|
||
---
|
||
|
||
## 2. The display pipe binds and the panel stays dark
|
||
|
||
**This is new capability, not a broken thing that used to work.** No T8010 has
|
||
ever had a DRM display pipe — Sandcastle, pmOS, uPhone and the original 2020
|
||
boot all scan out `simple-framebuffer`. ADP now binds here:
|
||
|
||
```
|
||
[drm] Initialized adp 0.1.0 for 206200000.display-pipe on minor 1
|
||
```
|
||
|
||
Every address was derived, not guessed: read off the phone's own ADT and
|
||
cross-checked against `HoolockLinux/linux:tests/adp` commit `2b3b1a7fc`
|
||
("t8012 dts: display pipe" — T8012 is T2, A10-family, and its `disp0_dart` is
|
||
literally `apple,t8010-dart`).
|
||
|
||
| node | reg | irq |
|
||
|---|---|---|
|
||
| `disp0` | be `0x06200000/0x9000`, fe `0x06400000/0x4000` | be 154, fe 158 |
|
||
| `disp0_dart` | `0x06304000/0x4000` | 156 |
|
||
| `disp0_mipi` | `0x06600000/0x100000` — byte-identical to T8012's | 163 |
|
||
|
||
The be/fe split is not a coin flip: ADP binds only `be`/`fe` by name, pokes `be`
|
||
to `0x40f4` and `fe` to `0x100`, and T8012's IRQ layout puts its DART *between*
|
||
the pipe's two (210/212/214 there, 154/156/158 here).
|
||
|
||
**Two things in this port were guessed, and the darkness is almost certainly one
|
||
of them:**
|
||
|
||
1. **The mode timings.** Nothing in the ADT publishes a raster, so
|
||
`panel-summit`'s d10 mode carries porches I invented — `750 758 774 790 /
|
||
1334 1338 1346 1354`, 64179 kHz. m1n1 already programmed Apple's real
|
||
timings and ADP re-modesets over them.
|
||
2. **`panel-summit` sends no DCS display-on**, and never sets `dsi->lanes`,
|
||
`format` or `mode_flags`. That is correct for a Touch Bar, where the loader
|
||
leaves the panel running. D10's ADT says `#lanes = 2`. If `adp-mipi`
|
||
reprograms the host from unset defaults, the link comes up wrong.
|
||
|
||
Where to look for real timings: m1n1 programmed them, so `m1n1-pauli`'s display
|
||
path knows. The ADT `mipi-dsim` node carries `phy-test`, `sac-frequency-list`,
|
||
`agile-line-count = 9`, `#lanes = 2` — enough to reconstruct, none of it read
|
||
yet. **Do not probe MMIO to find out** (see §5).
|
||
|
||
---
|
||
|
||
## 3. Touch worked once. Three layers were fixed; a fourth is unexplained
|
||
|
||
**It genuinely worked**, on the first boot after the rails came up: 2407 events,
|
||
270 `SYN_REPORT`, 13 balanced down/up, X 53..735, Y 107..1333, with
|
||
`MT_TOUCH_MAJOR` and `MT_ORIENTATION`. Kernel-native `apple_z2`, no `hx-touchd`,
|
||
no Sandcastle daemon — which is ahead of every other port on this hardware.
|
||
|
||
Three real defects were found and fixed, each hiding the next:
|
||
|
||
1. **`apple/t8010-smartio.bin` was not on the rootfs.** SIO DMA times out
|
||
(`-ETIMEDOUT` after the 60 s sysfs fallback), `apple-spi` gets no TX DMA, the
|
||
SPI bus never probes. The blobs existed since 2026-08-08 but shipped in the
|
||
*install ramdisk only*, and the disk-boot blob has no initramfs. Now
|
||
`CONFIG_EXTRA_FIRMWARE`, compiled into the Image — the only placement that
|
||
beats rootfs to the probe.
|
||
2. **`# CONFIG_REGULATOR is not set`** silently dropped
|
||
`REGULATOR_APPLE_PMIC_TOUCH` (`drivers/regulator/apple-pmic-touch-regulator.c`,
|
||
marked `default y if ARCH_APPLE`), so `apple_z2`'s mandatory `hv`/`core`
|
||
supplies resolved to no-op stubs and the controller was never powered.
|
||
3. **Runtime report activation was gated to D11.**
|
||
`apple_z2_enable_d11_reports_locked()` is what turns runtime reports on; D10
|
||
never called it. Four `is_d11()` sites now go through
|
||
`apple_z2_is_gen2_reports()` = D10 ∨ D11.
|
||
|
||
**And it still does not work.** The init trace is clean and complete — firmware
|
||
blobs load, `firmware ready IRQ received`, wake, D9 info, surface geometry read
|
||
back off the part (5850×10405, 13 units/mm), *"report initialization complete"*,
|
||
`d11-e2` sent and answered. Then `apple-z2-irq` (166) does not move for a
|
||
finger. Not a parse problem, not routing: the controller stops raising the line.
|
||
|
||
**Ruled out by test, not by reasoning:**
|
||
|
||
- **The driver changes.** Booted the original `touch` variant — no ADP, none of
|
||
the z2 edits, the exact kernel that gave 2407 events. IRQ delta **0**.
|
||
- **The rails.** Added a forced power cycle at probe
|
||
(`regulator_force_disable` both supplies, 20 ms, then normal power-on) because
|
||
`regulator_enable()` on an already-on rail is only a refcount bump and a warm
|
||
re-exploit inherits them up. No change. A driver rebind cleanly re-inits
|
||
(IRQ 3→6, full trace) and still yields nothing on touch.
|
||
|
||
**Untested, and the leading candidate: the display path.** That working boot was
|
||
the last one where simpledrm drove the panel. Apple's touch controllers sync to
|
||
display scan — `t8010-ipad7.dtsi` gives its touchscreen `display-sync-gpios`,
|
||
and D10's `disp0` carries `function-lcd_enable`. Every boot since has changed
|
||
the display: first ADP alongside simpledrm, then ADP alone.
|
||
|
||
**The one boot that settles it:**
|
||
|
||
```sh
|
||
~/Projects/hoolock/boot.sh -k touch # note: no -a, so simpledrm drives the panel
|
||
ssh -i ~/.ssh/ani root@172.16.43.1 'grep apple-z2-irq /proc/interrupts' # twice, touching between
|
||
```
|
||
|
||
That restores the exact conditions of the run that worked. If the IRQ climbs,
|
||
touch is display-coupled and the fix is ordering, not the z2 driver. If it stays
|
||
frozen, the regression predates every change made after that boot and the search
|
||
moves to what else the first boot had — it was the first boot after a true cold
|
||
power-off, and nothing since has been one.
|
||
|
||
---
|
||
|
||
## 4. What shipped, and where
|
||
|
||
| repo | ref | what |
|
||
|---|---|---|
|
||
| `Fimeg/hoolock-d10` | `0e80de6` (new repo) | the whole d10 port — `boot.sh`, board DTS from the ADT, the kernel patch, `config-d10-full-16k`, `BOOT-d10.md`. Apple firmware, SysCfg and the ADT dump are gitignored |
|
||
| `SouveraineOS` | `37b570e..46685ae` | `devices/` matrix, TASK-63, START-HERE now names both phones |
|
||
| `Souveraine` | `b2774c8..bf469c4` | dim-by-percent; lock surface answers on a cold start |
|
||
|
||
**The kernel commit `2e349ddf2` lives on archdev only** (`~/Projects/hoolock/linux-pauli`,
|
||
a clone of `Pauli1Go/HoolockLinux` that cannot be pushed to). It is exported as
|
||
`PAF/evidence/d10-adp-touch-2026-08-09.patch` and duplicated in `hoolock-d10`.
|
||
That commit also captured the 141-line `t8010-d10.dts` board port, which had
|
||
been sitting uncommitted against the 14-line mainline stub.
|
||
|
||
**One revert is in the archdev tree and not in the patch**: the `LAST`-command
|
||
`-EPROTO` check at `apple_z2.c:851` was widened to D10 and put back to D11-only,
|
||
because making a protocol check stricter can only cause failures. Rebuild before
|
||
trusting the tree.
|
||
|
||
---
|
||
|
||
## 5. Traps, each of which cost real time
|
||
|
||
1. **Do not read MMIO on live display registers.** Probing `/dev/mem` to
|
||
identify a register window put the phone into recovery **twice**. A wrong
|
||
`reg` in a DT node is safe by comparison — the driver maps what it is told
|
||
and fails to probe with an errno.
|
||
2. **A device node is not a working device.** A registered `input` device with
|
||
unpowered rails is byte-identical to working touch in `/proc/bus/input/devices`.
|
||
Verify with events (`SYN_REPORT`, balanced down/up, changing ABS) or with the
|
||
IRQ counter. This was asserted wrongly more than once.
|
||
3. **Change one thing per boot.** ADP and the z2 gates landed together; when
|
||
touch died there was no way to attribute it, and isolating it cost three more
|
||
boots.
|
||
4. **`config_16k` is the bare upstream reference** — no `PCIE_APPLE_H9P`, no
|
||
`APPLE_SIO`, no `TOUCHSCREEN_APPLE_Z2`. Building d10 from it yields a kernel
|
||
with no storage and no touch. Use `config-d10-full-16k`.
|
||
5. **`status = "disabled"` on `framebuffer0` does nothing.** m1n1's `kboot`
|
||
fills and re-enables `/chosen/framebuffer` itself. Only
|
||
`initcall_blacklist=simpledrm_platform_driver_init` removes it.
|
||
6. **`pgrep -f` matches your own ssh command line.** It killed a session and
|
||
produced two false "phone is down" readings in one night.
|
||
7. **Warm re-exploit is not a cold boot.** Rails, clocks and controller state
|
||
survive it.
|
||
|
||
---
|
||
|
||
## 6. Open, ranked
|
||
|
||
1. **Touch.** §3's single boot. Everything else on the device is watching a
|
||
screen that cannot answer.
|
||
2. **The panel is dark under ADP.** §2. Read the real timings out of m1n1 or the
|
||
ADT rather than guessing again, and give `panel-summit` a d10 `prepare` that
|
||
sets `dsi->lanes = 2` and sends a DCS display-on.
|
||
3. **The panel cannot sleep.** `Blank` shells out to `blueline-screen-toggle`,
|
||
absent here, so it no-ops; `Dim` is `brightnessctl set 10`, an absolute that
|
||
is 0.5% of 2047 and reads as off. The device therefore offers lit-forever or
|
||
black-forever. `eb0292c` fixes the dim and needs a CI build plus
|
||
`pacman -Syu`. **The parity fix is viewtop owning the blank as a verb** — it
|
||
holds the CRTC and has `power.rs` with the EBUSY deferral on both bodies.
|
||
4. **Buttons are unrouted.** `gpio-keys` reports `KEY_MUTE`, `KEY_VOLUMEDOWN`,
|
||
`KEY_VOLUMEUP`, `KEY_POWER` on event1, and viewtop already classifies the
|
||
last three (`buttons.rs:52-54`). Nothing routes them on this body. `KEY_MUTE`
|
||
is the ringer switch and has no `Button` variant anywhere — new hardware the
|
||
Pixel does not have.
|
||
5. **`sessiond eb0292c` and `Souveraine bf469c4` need to reach the device** by
|
||
package, not by hand.
|
||
6. **`hyprctl`** is still asked for windows, monitors, layers and workspaces.
|
||
Dead under viewtop on both bodies; blueline merely still has the binary.
|
||
|
||
## Connects to
|
||
|
||
TASK-63 (owner), TASK-25/27/28 (the overlay-vs-package hole, three more
|
||
instances), TASK-43/51/53 (viewtop), TASK-61 (the colour path — ADP changes what
|
||
"the compositor owns the LUT" means here), `DEVICE-STATE-MACHINE.md` §12 (the
|
||
blank belongs in the executor table, not a script named after one phone),
|
||
`devices/README.md` (the per-body matrix).
|