add missing prompts

This commit is contained in:
vhaudiquet
2026-09-01 18:42:25 +02:00
parent fb84be4fde
commit 31ea66070f
2 changed files with 308 additions and 0 deletions
+148
View File
@@ -0,0 +1,148 @@
# Task: proper MT8183 display pipeline bring-up (MIPI DSI host + PHY + BOE TV101WUM-NL6 panel driver) for U-Boot on the Lenovo IdeaPad Duet (google,krane sku176)
You are taking over an in-progress U-Boot port on this machine. U-Boot already
boots on the device with a working rotated vidconsole. Today's display path is
a "scanout" driver that *revives* the display pipeline left running by the boot
firmware (coreboot + depthcharge) instead of bringing it up itself. Your job is
to add a real display pipeline: a MediaTek MT8183 MIPI DSI host driver, the
MIPI TX PHY, and a proper driver for the panel (BOE TV101WUM-NL6), so U-Boot
brings the panel up from scratch and no longer depends on firmware handoff.
## Hard requirement: upstreamable work
Everything must be written to be sent to the U-Boot mailing list with minimal
rework:
- `scripts/checkpatch.pl` clean; Kconfig/Makefile style matching neighbouring
drivers; DM/uclass APIs (`UCLASS_DSI_HOST`, `UCLASS_PANEL`, `VIDEO`,
`vidconsole`).
- Commit history: small, single-purpose, upstream-ready commits. Commit as you
go; never leave the tree with a broken build.
- Document every magic register with its source (Linux driver file or
coreboot file you ported it from), in the style of the existing
`drivers/video/mt8183_scanout.c`.
- Board-specific glue stays in board code; common drivers stay generic.
## Where things are
- U-Boot tree: `/home/vhaudiquet/u-boot` (mainline ~2026-08 + local
`krane-updates` branch commits; HEAD has everything working — do not rebase
or rewrite existing commits, add on top).
- Previous bring-up research (read first — it contains device facts confirmed
on the real hardware): `/home/vhaudiquet/krane-fb-stub/RESEARCH.md` and
`/home/vhaudiquet/krane-fb-stub/U-BOOT.md`.
- The current fallback display driver: `drivers/video/mt8183_scanout.c` — its
header comment documents the platform handoff model and the OVL register
facts.
- Board files: `board/mediatek/mt8183/`, `configs/mt8183_kukui_krane_defconfig`.
- Control DTB: OF_UPSTREAM, krane DTs at
`dts/upstream/src/arm64/mediatek/mt8183-kukui*.dtsi` — the DSI host node and
the panel child node (compatible `"boe,tv101wum-nl6"`) already exist there.
Do not fork the DT; bind from it.
- Toolchain: `aarch64-linux-gnu-gcc`. Build:
`make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)`.
- Network access works: fetch reference sources (see below) with curl from
raw.kernel.org / github raw, e.g.
`https://raw.githubusercontent.com/torvalds/linux/master/drivers/gpu/drm/panel/panel-boe-tv101wum.c`.
- **The user flashes and tests on the real device.** You cannot test display
output yourself. Build the payload, prepare exact flashing instructions
(depthcharge-tools `mkdepthcharge` + `futility vbutil_kernel` + dd to
`/dev/mmcblk0p1`, as used in this project), and instrument your code with
clearly-prefixed serial prints (e.g. `[dsi] phase N`) so the user can report
where bring-up stalls.
## Reference implementations to port from
Fetch these (do not invent register values):
1. Linux panel driver (authoritative init sequence + timings for this panel):
`drivers/gpu/drm/panel/panel-boe-tv101wum.c` — the `"boe,tv101wum-nl6"`
entry: 1200x1920 @ 60Hz, 4 data lanes, DSC-less, init sequence of DSI
commands, AVDD/AVEE supplies + reset GPIO handling.
2. Linux MIPI TX PHY (MT8183 variant): `drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c`
(and the shared `phy-mtk-mipi-dsi.c` if the 8183 variant pulls from it).
3. Linux DSI host: `drivers/gpu/drm/mediatek/mtk_dsi.c` — register map for the
DSI host block, timing parameter computation (phy timing, HPW/VPW etc.),
command-mode panel init flow.
4. coreboot 4.14 (the generation on this device):
`src/mainboard/google/kukui/display.c` and the kukui panel files, plus
`src/soc/mediatek/mt8183/{dsi,mipi_tx,mmsys}.c` — a second opinion on
sequencing and on which MMSYS gates/clocks matter. Note what coreboot does
*not* touch: it relies on clocks already on at boot.
5. U-Boot's existing DSI infrastructure: `drivers/video/mipi_dsi.c` +
`include/mipi_dsi.h` (CONFIG_VIDEO_MIPI_DSI helpers — use them for D-PHY
timing computation and packet encoding), `drivers/video/dw_mipi_dsi.c` as an
example DSI_HOST uclass driver, `drivers/video/panel_uclass.c` /
`simple_panel.c` for the PANEL uclass.
## Confirmed hardware facts (verified on this device — do not re-derive)
- Panel: BOE TV101WUM-NL6, 1200x1920 native portrait, 4-lane MIPI DSI,
mounted rotated 270° in the chassis; the console is therefore used with
`uc_priv->rot = 3` (see mt8183_scanout.c).
- At payload entry the panel is *powered and initialized* (coreboot ran the
full DSI init sequence), the DSI link is up, but depthcharge's
`display_cleanup()` stopped the overlay engines and turned the backlight
off. OVL0 base register block: `OVL_EN +0x0c`, `OVL0_2L_EN +0x100c`,
`OVL_L0_ADDR +0x0f40` (layer-0 scanout address, still holds the last-used
address across handoff).
- Backlight: two dedicated GPIOs driven high — DISP_PWM (pin 43) and EN_LCD_BL
(pin 176) on the MT8183 GPIO controller at 0x10005000 (dout set@+0x100,
16 bytes per 32-pin group).
- Coreboot table: fixed at 0xffed9000 on this device (LB_TAG_FRAMEBUFFER
record; physical_address may be 0, then OVL_L0_ADDR is authoritative).
- The scanout framebuffer address is outside the DTB DRAM description; any
buffer you allocate must be mapped with `mmu_map_region()` (see the existing
driver) and *reserved* (see the FDT/LMB reservation pattern already in
mt8183_scanout.c — reuse it for your own framebuffer).
- `drivers/clk/mediatek/clk-mt8183.c` exists in-tree. CHECK which clocks it
registers and whether the MMSYS display gates (OVL0, OVL0_2L, RDMA0, COLOR0,
DSI0, and the MMSYS CG registers) are covered. If display gates are missing,
either extend the clock driver (preferred, upstreamable) or sequence the
MMSYS CG registers directly with documented offsets — pick one and justify.
- Power domains (SCPSYS display domain) are on at handoff; for full cold
bring-up you may need `mtk_scpsys` — check what exists in-tree
(`drivers/power/domain/`); if absent, document the gap rather than
half-implementing it.
## Architecture guidance (use judgment, document decisions)
- New DSI host driver: `drivers/video/mtk_dsi.c` + `drivers/video/mtk_mipi_tx.c`
(PHY), bound from the existing DSI node in the upstream krane DT. Use
UCLASS_DSI_HOST ops (enable/phy_set_mode/dsi transfers) and the
VIDEO_MIPI_DSI helpers.
- Panel driver: `drivers/video/panel_boe_tv101wum.c`, UCLASS_PANEL, driven
from the panel child node of the DSI node (compatible `"boe,tv101wum-nl6"`),
porting the init sequence from the Linux panel driver. Supplies/reset GPIO
handling via regulator uclass/GPIO uclass as described by the DT node.
- Integrate with the video uclass: the display driver (`mt8183_scanout.c` or a
successor) must decide between (a) full cold bring-up through your new
pipeline and (b) the existing firmware-handoff revival path. Suggested
shape: try full bring-up first; fall back to handoff revival if the panel
fails to respond, logging which path was taken. Keep both paths Kconfig
selectable so each can be tested in isolation.
- The framebuffer you allocate for bring-up must be reserved exactly like the
scanout buffer is today (FDT memreserve + LMB), or the kernel will corrupt
it after handoff — this was a real bug, see commit 1ae771d9f90.
- Endianness/format: VIDEO_BPP32 XRGB like today; `line_length` from the
panel mode (1200 px * 4).
## Deliverables and acceptance criteria
1. DSI host + PHY + panel drivers in-tree, Kconfig-gated, krane defconfig
selecting them; existing boot path unchanged when the fallback is chosen.
2. Full bring-up path verified on device by the user: with the fallback
path disabled, the vidconsole comes up on the panel from cold (i.e. your
code performs clock gating, PHY, DSI init, panel init sequence, framebuffer
setup, backlight). Instrument each phase with serial prints and give the
user a step-by-step test recipe; iterate on their serial reports.
3. `make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu-` builds clean;
checkpatch clean; each commit compiles and is upstream-shaped.
4. `RESEARCH.md` in `/home/vhaudiquet/krane-fb-stub/` updated with numbered
findings (what was ported from where, what you measured/guessed).
5. Final report: what works, what is untested, known gaps (e.g. missing
SCPSYS cold-power sequencing if that applies).
Work incrementally: fetch references, map the register model, write the PHY +
DSI host first with bring-up prints, get the panel's first frame, then clean
up into upstream-shaped commits.
+160
View File
@@ -0,0 +1,160 @@
# Task: bring up mainline U-Boot on the Lenovo IdeaPad Duet (google,krane sku176, MT8183)
You are taking over a bring-up that just passed its first milestone: a minimal
bare-metal payload ("krane-fb-stub") boots via depthcharge and draws to the
panel. Your job is to replace it with mainline U-Boot as the payload, with a
working framebuffer console, in a form that is **upstreamable to mainline
U-Boot later**.
## Hard requirement: upstreamable work
All changes must be written so they can be sent to the U-Boot mailing list
with minimal rework:
- Follow U-Boot conventions: `scripts/checkpatch.pl` clean, Kconfig/Makefile
style of neighbouring drivers, DM/uclass APIs (`vidconsole`, `VIDEO`,
`MMC`, `serial`), proper `bind()`/`probe()` structure.
- Board support as a proper target: `board/mediatek/`, `configs/*_defconfig`,
MAINTAINERS entry, defconfig minimal and matching pumpkin's style.
- Any DT additions must match the upstream Linux DTS files (the krane DTs are
already synced from Linux into `dts/upstream/src/arm64/mediatek/` — reuse
them, do not fork them).
- Keep board-specific workarounds in board code, never inside common
drivers; document every magic register with its source (see the device
facts below).
- Small, reviewable, single-purpose commits.
## Current state and where things live
- U-Boot shallow clone: `/home/vhaudiquet/u-boot` (mainline main,
~2026-08). SoC support exists: `arch/arm/mach-mediatek/mt8183/`.
Reference target: `configs/mt8183_pumpkin_defconfig`
(`CONFIG_POSITION_INDEPENDENT=y`, MTK serial, `mtk-sd` MMC, WDT, USB).
`dts/upstream/src/arm64/mediatek/mt8183-kukui-krane-sku176.dts` exists;
there is NO krane/kukui defconfig or board dir yet — that is your starting
point.
- Validated stub project (read it first):
`/home/vhaudiquet/krane-fb-stub/` — contains `main.c` (the working
payload: display revival + parse + fills), `build.sh`, `build-payload.sh`
(packing via depthcharge-tools mkdepthcharge + vbutil devkeys), the
stub's ARM64 Image-header wrapper `stub.S`, and `RESEARCH.md` — the full
lab notebook of the display bring-up. READ RESEARCH.md before touching
anything; it documents every [REVERSED] claim.
- The stub's working payload is currently flashed to `mmcblk0p1`; keep it
as the regression test. Its payload hash and the exact flash/verify
procedure are in RESEARCH.md.
## Environment
- The target device is this machine. It boots postmarketOS from USB
(`sda`); you work inside a chroot into the internal rootfs
(`/dev/mmcblk0p3` mounted at `/`). The boot firmware (coreboot +
depthcharge) lives in SPI and is NEVER modified.
- `mmcblk0p1` (32 MiB, ChromeOS kernel partition) is the only thing you
flash. Tools available: `aarch64-linux-gnu-gcc`,
`futility vbutil_kernel`, depthcharge-tools (`mkdepthcharge`), `dtc`.
- Flash procedure (same as the stub): `dd if=payload of=/dev/mmcblk0p1
bs=4M conv=fsync`, then `cmp -n <size>` against the payload, then
`futility vbutil_kernel --verify /dev/mmcblk0p1`. After flashing, hand
the device to the user to reboot into internal — the user reports what
the screen shows. Never flash anything else. Recovery exists: USB boot
+ `~/mmcblk0p1-pmos-backup.img` (see RESEARCH.md).
- There is NO serial console. The framebuffer is the only output channel;
the user photographs/describes the screen.
## Boot contract (verified on device, RESEARCH.md Round 10)
depthcharge (R93-era, in SPI) boots the dev-signed FIT from `mmcblk0p1`,
decompresses the kernel subimage to an arbitrary 2 MiB-aligned DRAM slot,
checks the ARM64 Image header magic (0x644d5241), and jumps to the first
byte with x0 = FDT pointer, x1-x3 = 0, MMU off. U-Boot's `u-boot.bin` has
no Image header — wrap it: 64-byte header (branch past header,
text_offset=0, image_size patched at 0x10 LE, flags bit 3,
magic at 0x38) exactly like `krane-fb-stub/stub.S`, then pack with
mkdepthcharge.
## Device facts for the display (all verified — do not re-derive)
- Panel: BOE TV101WUM_NL6, 1200×1920, 32bpp xRGB (r@16/8 g@8/8 b@0/8),
4-lane DSI, `xres*bpl`-style geometry comes from the coreboot LBIO
record (1200×1920, bpl 4800, bpp 32).
- coreboot initializes the panel and DSI before depthcharge; at payload
handoff the display pipeline is live but STOPPED: depthcharge's
`display_cleanup()` disabled the overlay engines and killed the
backlight. The panel/DSI link stays up — no panel re-init is needed.
- Revive = three MMIO/GPIO writes (offsets verified against device-era
depthcharge sources; the two Round-1 misreads cost nine rounds — trust
these):
- `OVL_EN = 1` at OVL0 base + 0x000C (OVL0 base 0x14008000)
- `OVL0_2L_EN = 1` at OVL0 base + 0x100C
- backlight GPIOs high: GPIO controller 0x10005000, dout block at
**+0x100** (NOT 0x140), 16 B per 32-pin group, set@+4:
pin 43 (DISP_PWM) → 0x10005114, pin 176 (EN_LCD_BL) → 0x10005154.
- Scanout address: read `OVL_L0_ADDR` at OVL0 base + 0x0F40. The coreboot
LBIO record (fixed address **0xffed9000**, size 0x380, verified live via
sysfs + /sys/firmware/fdt) may report `physical_address = 0`; upstream
coreboot 4.14 kukui does that, and libpayload's cbgfx rejects pa=0.
The live scanout on this unit was 0xFD536000 (top-of-DRAM reserved).
Strategy: geometry from the LBIO record, address from the record if
non-zero else from OVL_L0_ADDR (guard: >= 0x40000000).
- The LBIO table parse reference implementation is `krane-fb-stub/main.c`
(`find_framebuffer`); its layout comments are verified.
- Panel geometry facts also matter for the console: portrait 1200 wide;
pick a font/rotation accordingly.
## Known trap (open bug — carry it, don't trip on it)
depthcharge hands off x0 = `_fit_fdt_start` = 0x5F800000 (its internal FDT
buffer; the kernel reserves `5f800000-5f815fff` for it), but at payload
entry that buffer reads as ALL ZEROS. The kernel boot path works (the
kernel sees a valid FDT there), the payload path does not — root cause
open, leading suspicion cache-flush asymmetry between depthcharge's cached
writes and our MMU-off reads (pmOS kernel ~30 MB vs 18 KB stub is the
variable). Consequence: U-Boot MUST NOT depend on the handoff FDT. Use
U-Boot's own embedded control DTB (CONFIG_DEFAULT_DEVICE_TREE with the
krane dts), and get the coreboot table from the fixed 0xffed9000 when
needed. Investigating/fixing the zeros (e.g., adding cache clean to the
wrapper's handoff, or reading with cache disabled) is a stretch goal.
## Milestones
1. **Buildable target**: `board/mediatek/` krane board + `configs/mt8183_kukui_krane_defconfig`
forked from mt8183_pumpkin_defconfig; `CONFIG_DEFAULT_DEVICE_TREE=mt8183-kukui-krane-sku176`;
keep `CONFIG_POSITION_INDEPENDENT=y` (depthcharge's slot is arbitrary),
DEBUG_UART params (0x11002000 @ 26 MHz) as harmless default, drop
pumpkin-specific bits (fastboot, TPHY, mtu3 gadget) for now.
Deliverable: `make mt8183_kukui_krane_defconfig && make -j` with
aarch64 toolchain produces `u-boot.bin`.
2. **Boot wrapper + flash**: prepend the 64-byte ARM64 Image header
(reuse/wrap `krane-fb-stub/stub.S` pattern; patch image_size = header +
u-boot.bin size), pack with mkdepthcharge, flash, verify. User reboots.
Expected: something — U-Boot's debug UART goes nowhere visible, so
absence of colors is NOT failure. This milestone is only worth flashing
together with 3, or with a crude framebuffer "hello" (write RGB stripes
at the scanout address early in U-Boot, e.g. from board_early_init) as
a life sign.
3. **Framebuffer console**: minimal U-Boot video driver + vidconsole using
the facts above (no full display init — reuse the live pipeline):
revive writes, scanout discovery (LBIO @0xffed9000 / OVL_L0_ADDR), a
simple 8x16 font `vidconsole` drawing into the framebuffer. Upstreamable
shape: a `drivers/video/` driver + Kconfig (e.g. VIDEO_MT8183_SCANOUT
or a proper "coreboot framebuffer" video driver — check what exists in
tree first and fit the uclass). Deliverable: U-Boot banner + prompt
visible on the panel; user confirms.
4. **Then**: eMMC via the krane DT (mtk-sd should work out of the box),
`bootflow`/distro boot of the pmOS kernel from mmcblk0p3, USB keyboard
(Duet keyboard is USB over the pogo connector) for a real shell.
## Working rules
- Update `/home/vhaudiquet/krane-fb-stub/RESEARCH.md` with one numbered
round per experiment: observation, root cause, fix, verification. That
notebook is the project's memory.
- Commit every verified step (the stub repo history shows the expected
style); U-Boot work happens in `/home/vhaudiquet/u-boot` on a branch
(e.g. `krane`).
- Verify before every reboot: build → wrap → mkdepthcharge → `vbutil_kernel
--verify` → dd → cmp → on-device vbutil verify. Never yield an unverified
flash claim.
- The user performs reboots and reports the screen; frame your asks as one
flash-reboot per experiment with the expected observation spelled out.