uzbek-plus/logs/b9/lk/B9-LK-AUDIT.md
q 4a7224c41f B9: built-in display (ST7735S SPI) in Linux and persistent B9C cache
- B9A: read-only audit of stock LK/DT: the panel is an ST7735S 128x128 on SPI (BLSP1 QUP4,
  16 MHz, mode 3, D/C GPIO116, RESET GPIO118), backlight = PM8916 MPP4 current sink 40 mA.
- B9B: upstream panel-mipi-dbi with the stock init sequence as firmware; MPP4 sink via pinctrl
  + gpio-backlight; first light with correct colours/orientation/offsets.
- B9C: fbcon (6x8, 21x16) on tty1 + getty, UART console kept, aurora-display service;
  cache B9C b9ce13c9 written and verified, cold boots with LTE + Wi-Fi + display.
- B9L (RAM only): lk2nd second stage with an msm8916 SPI panel port shows a picture before Linux.
- Sanitizer: whitelist for b8/ and b9/.
2026-10-03 01:45:02 +03:00

135 lines
8.9 KiB
Markdown

# B9-LK audit — why the screen is black before Linux (read-only, 2026-10-03)
Nothing was patched, built or flashed. Sources:
- stock LK = `partitions/aboot.bin` → `bootchain/aboot-analysis/lk.bin`/`lk-arm.dis` (tools in `b9/b9a/`);
- lk1st/lk2nd = `lk2nd-build/src` (lk2nd 23.1, e9c8b217; the source of the aboot that is flashed now);
- UART logs `logs/uart/*`.
## 0. Correction to the premise: stock LK is NOT in the current chain
Since B5a (2026-09-30) `aboot` holds **our lk1st-aurora-autoboot** (built from the lk2nd tree, `ABOOT_STANDALONE=1`,
`LK2ND_DISPLAY=cont-splash`), not stock LK. The current chain is:
`PBL → SBL1 (stock) → lk1st (lk2nd code: lk2nd_init + extlinux in the same binary) → Linux`
Evidence: every current UART log has exactly one `[0] welcome to lk`, followed in the same LK by `lk2nd_init()` and
`Trying to boot 'b7c'/'b8f'/'b9c'`. Stock LK exists only as the backup `partitions/aboot.bin`.
The chain "stock LK → lk2nd" existed only once, in the 2026-09-29 test `logs/uart/lk2nd-boottest-20260929-203353.log`
(lk2nd in `recovery`).
## A. Exact stock display init chain (stock LK, disassembly)
```
app table 0x8f647da0 → aboot_init 0x8f614eec
→ read_device_info 0x8f614984
→ target_display_init 0x8f600eac(device.display_panel @0x8f64af94) ← UNCONDITIONAL, before any boot-mode decision
loop: gcdb_display_init 0x8f616918(rev, MDP_REV 12, fb 0x83200000)
→ oem_panel_select 0x8f600f20: panel_id := 1 (hardcoded, no ID read), prints "lcd_id == st7735s spi lcd";
id1 = qcom,mdss_spi_st7735s_wx144_128x128_cmd (19 cmds) [id0 = DSI st7796s 320p, id2 = SPI nv3023a]
→ pinfo.type = SPI_PANEL(13), power_func 0x8f6165e0, bl_func 0x8f616698
→ msm_display_init 0x8f60d624:
power_func: target_ldo_ctrl 0x8f600e98 (STUB, returns 0) → target_panel_reset 0x8f600bb8
(GPIO118: 1, 0 for 1 ms, 1, wait 120 ms) → "Panel power on done"
msm_display_config 0x8f60d2a0: "Config SPI PANEL." → spi_qup_init(BLSP1, QUP index 3 = 0x78b8000,
GPIO12-15 func1, 16 MHz, mode 3) → D/C GPIO116 → 19 commands (0x8f610b6c)
fbcon_setup 0x8f61642c (fb 0x83200000, 128x128 RGB565)
display_image_on_screen 0x8f61659c: splash partition has no "SPLASH!!" header (it is all zeros)
→ built-in 128x128 "4G LTE" image @0x8f64b004
msm_display_flush 0x8f60d46c (frame over SPI, D/C=1)
bl_func → target_backlight_ctrl 0x8f600b54: MPP4 0xa340=0x61, 0xa34c=7 (40 mA), 0xa346=0x80
→ … boot-mode decisions (fastboot / recovery / normal) come AFTER this
boot: cmdline += "mdss_mdp.panel=1:spi:0:qcom,mdss_spi_st7735s_wx144_128x128_cmd";
msm_display_off 0x8f60d78c: "Continuous splash enabled, keeping panel alive." (panel left on)
```
Conditions: none found. No alarm/charger/ffbm check guards the display call, so stock LK initialises the panel
**in every mode** (normal, recovery, fastboot, charger).
UART proof that it ran on this board:
- `[210] Panel power on done` / `[210] Config SPI PANEL.` in `coldboot-20260929-200018`, `preflight-recovery-…`, `lk2nd-boottest-…`;
- no "Send SPI … failed".
A visual confirmation that the logo appeared on stock firmware is still missing (operator question from B9A).
## B. Why the screen is black before Linux now
**The stock display code is not in the boot chain at all.** No flag or condition is switching it off.
lk1st (msm8916 build of the lk2nd tree) contains no SPI-panel code:
- `platform/msm_shared/rules.mk` builds `spi_qup.o`/`mdss_spi.o` only for `PLATFORM=msm8909` and `msm8952`.
- `LK2ND_DISPLAY=cont-splash` → `lk2nd/display/cont-splash/target_display.c` only *adopts* an MDP that is already running
(it checks `MDP_GDSCR`). Our panel never uses MDP, so even after stock LK it reports
`No continuous splash: MDP GDSC is not enabled` (seen in `lk2nd-boottest-…:74`).
- The alternative `LK2ND_DISPLAY=<panel>` mode = gcdb **DSI** panels (generated headers), no SPI.
- `lk2nd/device/2nd/spi-display.c` (re-use of a panel that a previous bootloader initialised) is built only when
`mdss_spi.o` is built, i.e. not for msm8916. It is also hard-coded to 240x320.
- The msm8916 clock table in lk2nd has only `gcc_blsp1_qup4_i2c_*`, no QUP4 SPI clocks.
`mdss_spi.c` is hard-wired to msm8909 (D/C = GPIO64, `SPI_QUP_ID 2`).
So nothing initialises the panel until Linux. RESET (GPIO118) stays at the SoC reset default (input, pull-down) until
panel-mipi-dbi probes at ~1.4 s of kernel time.
## C. What lk1st/lk2nd does with a panel that is already initialised
Checked in the lk2nd 23.1 source for msm8916:
- TLMM: only `target_volume_up()` configures the vol-up GPIO (when keys are checked). Nothing touches GPIO12-15/116/118.
- QUP4 / MPP4: not touched. `target/msm8916/target_display.c` (with its MTP-style MPP4 digital-output backlight) is
**filtered out** of the cont-splash build. `target_uninit()` only parks eMMC, crypto and CE clocks.
- Framebuffer: not adopted (no MDP); 0x83200000 is ordinary RAM to lk2nd.
So lk2nd **leaves the panel alone**: the GRAM keeps the image and the backlight stays as set. This matches the 2026-09-29
stock→lk2nd log, where lk2nd only printed the GDSC message.
Then Linux takes over:
- the panel's pinctrl keeps D/C/RESET as gpio outputs, and `reset-gpios` is requested OUT_HIGH (no glitch);
- the fbcon takeover modeset does a hardware reset and a full re-init at ~1.8 s, which replaces the logo;
- the gpio-backlight pinctrl state (`output-low`) switches MPP4 to 0x60 at probe → **backlight off from ~1.5 s until
aurora-display at ~8 s**;
- clk_disable_unused may gate the QUP4 clocks LK left on (harmless; spi-qup re-enables them).
L17: CAF `target/msm8916/target_display.c:608` says "The PMIC regulators needed for display are enabled in SBL. There is
no access to the regulators in LK." That explains the stock stub. But B9A measured **L17 OFF** in running Linux (who
turned it off is unknown: the RPM with no votes, or something later). The state at LK time is unproven.
## D. Smallest ways to get power → splash → Linux fbcon
There is no single condition or flag to flip: the stock code path is simply not present in lk1st.
1. **Port into lk1st/lk2nd (recommended).** Re-use the lk2nd tree's own CAF SPI stack (`spi_qup.c`, `mdss_spi.c`,
gcdb `SPI_PANEL` branch) for msm8916 with stock-LK parameters:
- build `spi_qup.o` + `mdss_spi.o` for msm8916;
- make D/C GPIO and QUP index parameters (116 / index 3);
- add `gcc_blsp1_qup4_spi_apps_clk(_src)` with a 16 MHz entry to the msm8916 clock table;
- add an ST7735S panel header (the verified 19 commands, reset sequence {1,0,1}/{1,1,120}, 128x128 RGB565);
- panel select;
- target reset on GPIO118;
- backlight as an MPP4 current sink 40 mA (the stock 0x61/7/0x80 sequence, not the MTP digital-output variant);
- LDO stub, as stock.
Optional: the stock logo (vendor artwork — do not publish).
2. **Restore stock LK as aboot + lk2nd as the 2nd stage in `boot`.** No code, but it reverts B5a and loses lk1st fastboot
(stock fastboot has only getvar/download). Compatibility of stock LK with the migrated TZ (DB410c) + qhypstub is untested,
and it needs two persistent writes. **Not recommended.**
## E. Risks of the handoff (variant 1)
- **L17 at LK time**: if SBL does not leave L17 on, LK can drive SPI but the panel shows nothing. The fix would be RPM
regulator code in LK (more porting). The test below settles this first.
- Wrong QUP/clock setup in LK can abort/hang LK → RAM test only, aboot untouched; recovery = power cycle.
- Handoff gap: Linux switches MPP4 off at gpio-backlight probe (~1.5 s) and re-inits the panel at fbcon takeover.
The visible sequence would be: logo (~0.3 s after power) → dark ~1.5 s → ~8 s console.
This can be fixed later on the Linux side (backlight default-on / output-high), not in LK.
- Boot time: +~0.3 s in LK (120 ms reset wait + 120 ms SLPOUT + ~20 ms frame).
- A later persistent step = reflashing aboot (B5a-style gates + `b5a/A4-rollback.sh`); needs its own GO.
## Proposed single non-persistent test (needs GO; it requires a build)
**B9L-RAM**: from the lk1st fastboot entered with RESET held at power-on, run `fastboot boot` of a **lk2nd 2nd-stage image**
(msm8916, lk2nd 23.1 + the variant-1 port), with no flashing.
- The lk2nd image initialises the panel (logo + MPP4 backlight), then chainloads the existing eMMC cache (B9C/B8F) → Linux.
- Pass = logo visible before the kernel; UART shows SPI init without errors; L17/QUP4 state is logged; Linux fbcon comes up
as in B9C.
- aboot, cache and eMMC are untouched.
Step 0 of the same session (no build needed): `fastboot boot lk2nd-build/out/lk2nd.img` (the existing unmodified 23.1, built with FORCE_FASTBOOT, so it stops in its own fastboot;
artifact). This proves that lk1st can chainload a 32-bit lk2nd image on the migrated TZ/qhypstub chain before any port work.
STOP.