Skip to content

Superbird - #4

Open
theoparis wants to merge 13 commits into
mainfrom
superbird
Open

Superbird#4
theoparis wants to merge 13 commits into
mainfrom
superbird

Conversation

@theoparis

Copy link
Copy Markdown

No description provided.

@theoparis
theoparis force-pushed the superbird branch 3 times, most recently from 9965555 to 4f55810 Compare August 31, 2026 02:22
lmore377 and others added 12 commits September 1, 2026 21:11
Squashed carthing port onto mainline u-boot v2026.07-rc2. Adds Amlogic
G12A "Spotify Car Thing" support and the fixes the port needed:

board/amlogic/spotify-carthing:
  board init, DT + defconfig, boot router/menu, A/B slot selector, charger
  (MAX14656), MFi coprocessor, rotary wheel + buttons, hwinfo/QR, panel
  probe + brightness, reboot-reason plumbing.

display:
  ST7701S MIPI-DSI panel driver + meson DSI host / VPU / vclk / venc
  bring-up; dw_mipi_dsi + meson-axg mipi PHY fixes for G12A.

reboot + maskrom (PREG_STICKY_REG3 reboot reason):
  reboot bootloader/fastboot/recovery, and software-triggered mask-ROM USB
  mode (`maskrom` cmd / `fastboot oem maskrom`) via the BL31 SCP USB_BOOT
  hook (see superbird-tfa + fip-tools/tfa).

fastboot:
  oem console/run/help/maskrom, `fastboot fetch`, "<cmd> <arg>" parsing.

other fixes:
  meson_gx_mmc DT-parse + HS200, env-in-FAT name addressing, UMS gadget,
  pwm-meson, meson sm reboot-reason.

Deep-dive writeups + datasheets live in the companion superbird-docs repo,
kept out of this tree. Full pre-squash history: superbird-uboot.bak-20260525.

Signed-off-by: Theo Paris <theo@theoparis.com>
Paint a slot-supplied /logo.bmp over the baked-in splash so an OS slot
can carry its own branding without reflashing u-boot. The active slot
(slot_active, default a) is tried first, then the other; first valid
BMP wins, else the baked-in logo is kept.

Hooked into the misc_init_r video probe: the probe paints the baked-in
logo as usual, then we overpaint the custom one at the same draw coords
before the panel syncs a frame, so there's no flicker and no need for
DM-internal headers. Read is capped at 4 MiB. Skipped under quick_boot
(panel isn't probed there).

Enable CONFIG_BMP_16/24/32BPP so full-colour BMPs render; without them
the video uclass only handles 8bpp palette images.
…ed env

A saved CONFIG_ENV_IS_IN_FAT uboot.env replaces the compiled-in environment
wholesale (it is not merged with CFG_EXTRA_ENV_SETTINGS), and our
CFG_EXTRA_ENV_SETTINGS override drops meson64.h's load-address defaults. So a
stale/sparse/foreign saved env can arrive missing `slot` and
`kernel_comp_addr_r`/`kernel_comp_size`, and boot dies with
`root=PARTLABEL=root_` (empty ${slot}) plus "kernel_comp_addr_r or
kernel_comp_size is not provided!" — even though CONFIG_BOOTCOMMAND and the
in-C ab_boot/boot_check were designed so a saved env can't break booting
(commit 7578f41b06). These two vars were the gap in that armor.

Close it: carthing_guarantee_env() runs on the unbypassable misc_init_r path
(like set_boot_source/set_serial_from_efuse) and set-if-absent backfills
kernel_comp_* and slot, so booting survives whatever bootcmd a foreign env
carries. Factor the slot resolution shared by the splash painter and ab_boot
into resolve_slot(). Also add kernel_comp_* to the default env so a no-saved-env
boot carries them too.

Hardware-tested on a Car Thing: with the unit's sparse FAT env (and a sparse
bootcmd, so ab_boot never ran) the kernel now boots with root_a + Image
decompression where the old binary failed both.
Follow-up to e23e36ff85e. That commit's `#undef CFG_EXTRA_ENV_SETTINGS` also
drops meson64.h's load/scratch addresses (kernel_addr_r, fdt_addr_r, scriptaddr,
pxefile_addr_r, fdtoverlay_addr_r, ramdisk_addr_r) — so the compiled default env
(used when there is no valid saved uboot.env: env reset, corruption, first boot,
wiped env partition) lacked them. A blank-env boot would carry kernel_comp_* yet
still die earlier: sysboot with no scriptaddr, or booti with no kernel_addr_r.

Restore them by meson64.h macro (defined before that header's #ifndef, so still
in scope under our redefine) — no magic numbers, no drift. Deliberately omit
BOOTENV (would pull in distro_bootcmd + a bootcmd conflicting with
CONFIG_BOOTCOMMAND="ab_boot") and dfu_alt_info/fdtfile — the board uses
ab_boot/boot_check and extlinux.conf names its own FDT.

Lower practical risk than e23e36ff85e (real saved envs carry these), so
default-env coverage only; no runtime force-set in carthing_guarantee_env.
The existing 16bpp path assumed the framebuffer was also 16bpp and
byte-copied two bytes per pixel. The format-pair guard rejected any
other combination with -EPERM, so a 16bpp BMP shipped against a 32bpp
LCD (e.g. the meson VPU, which sets uc_priv->bpix = VIDEO_BPP32) fell
through to the baked-in splash even when the file loaded cleanly.

Add a 32bpp branch that unpacks RGB565 to 8-bit components (left-shift
with top-bit replication so 0x1f -> 0xff) and writes them in the
appropriate framebuffer layout. Mirrors the existing case-24 dispatch
on eformat (VIDEO_X2R10G10B10, VIDEO_RGBA8888, and the default
B/G/R/X). The 16bpp-fb byte-copy path is preserved.

Signed-off-by: Joey Eamigh <55670930+JoeyEamigh@users.noreply.github.com>
The L_DITH_CNTL DITH10 enable targets a 10-bit ENCL output. This panel is
fed 8 bits per channel, so the dither only adds pseudo-random LSB noise
that reads as per-line speckle, visible on margin-sensitive panel batches.
Stock u-boot and the mainline kernel both leave this register at 0 for
this panel; since the kernel inherits u-boot's running pipeline unchanged
under the seamless-handoff design, u-boot must leave dither off too.

Signed-off-by: Joey Eamigh <55670930+JoeyEamigh@users.noreply.github.com>
Add CONFIG_FASTBOOT_MMC_BOOT_SUPPORT and CONFIG_FASTBOOT_MMC_USER_SUPPORT so
`fastboot flash` can target the eMMC boot0/boot1 hwparts and named user-area
GPT partitions (e.g. the env FAT). Backs the boot0/1 install and env-flash
workflows in the end-to-end install recipe.
ST7701S init table: replace the source-derived table (which had drifted from
what ships) with the verified shipping table RE'd from stock BL33 and
cross-checked against four sources. VCOM 0.80V -> 0.96V fixes ghosting/
retention; RTNI 0x02 -> 0x07 and GIP af b3 -> 9a a0 fix the horizontal lines;
shipping gamma/VGH/GIP/delays throughout. Mirror stock's H->L->H reset pulse.

Backlight: PWM 180 Hz -> 30 kHz (stock). A 30k->1k sweep confirmed the
min-brightness white tint is gamma-bound, not PWM-bound, so leave it at stock.

Boot-splash smear: light a dim glow early, set the video device's hide_logo
before probing so the panel syncs onto a cleared (black) FB instead of garbage,
then paint the logo and ramp the backlight up once it locks
(board_init / misc_init_r / apply_saved_brightness).

Add the `blramp` command for tuning the backlight ramp live over UART.
The eMMC parts fitted to this board are not interchangeable at DDR52
under this driver. 16 MiB sustained read, measured on two units:

             Samsung S40004      Kioxia 004GA0
   HS 26M    23.4 MB/s           23.4 MB/s
   HS52      38.5 MB/s           45.4 MB/s
   DDR52     42.4 MB/s           switch fails -> falls back to legacy

On the Kioxia part the DDR52 switch never completes; the mmc core
drops to legacy, reports success, and the board runs at 22.9 MB/s
while believing it is at DDR52. Where that switch half-succeeds
instead there is no fallback: small reads work, a kernel-sized read
does not, and the unit bootloops before handoff — which is what field
reports look like, right down to `mmc rescan` appearing to fix it
(a GPT read is two sectors; a kernel is 22 MB).

Drop mmc-ddr-1_8v from the u-boot DT overlay. HS52 is single-data-
rate, works on both parts, is faster than DDR52 on Kioxia and within
9% on Samsung, so this removes the failure mode at essentially no
cost. The driver already strips HS200/HS400 and caps f_max at 52 MHz,
so HS52 is what remains.

Then report it: misc_init_r prints the negotiated mode and warns
loudly if the bus came up below HS52, and publishes `emmc_mode` in the
environment. A silent downgrade is exactly how this went unnoticed, so
it should never again be invisible — and via the env it is readable
without a UART, from fastboot, the bootmenu or fw_printenv.

Not yet confirmed on a unit that actually bootloops; both measurements
above are from healthy units. Kept on its own branch until the two
field units can be tested.

Claude-Session: https://claude.ai/code/session_011m5fyDpVnWg8uYV2wQGA2C
…l UI

A docs-and-structure pass over the board code, plus two small UI fixes
that came out of testing it on hardware.

Comments. The board files had drifted to roughly 40% comment: subsystem
essays above ab_boot and carthing_boot_route, numbered step-by-step
narration restating the code inside them, and register/protocol tables
already written down elsewhere. 1200 comment lines across 11 files, cut
to 738. What stays is what the code cannot say -- the PWM is inverted,
SD_CFG15 hangs the bus on any CPU write, a saved ENV_IS_IN_FAT env
replaces the compiled-in one rather than merging, board_init runs before
initr_dm_devices so the probe order is a real race, video_sync() is
load-bearing before the fastboot poll loop. Everything longer moved to
superbird-docs / superbird-misc-notes and is referenced by path.

Two comments were stale as well as long: cmd_wheel.c documented five CLI
modes when there are six, duplicating the U_BOOT_CMD help that already
listed them correctly.

README. The signing section still described the Python path
(fip-rebuild.sh, flash_boot_partition.py). That has been pure Go for a
while -- `fip-tool sign` does assembly and signing with no
amlogic-boot-fip clone, no aml_encrypt_g12a and no shell. Rewritten
against the tool's real flags. Also dropped the S905D2 claim: the exact
SKU was never confirmed, and the board file says S905X2.

Boot menu. cmd_bootmenu.c had grown to 1669 lines holding the drawing
primitives, the button edge tracker, the menu, and three sub-screens --
one of which is six pages, five caches, an NTC lookup table and a
direct-framebuffer QR renderer. The sub-screens also disagreed about who
owned the input loop: settings had a function, charger and hwinfo ran
theirs inline in do_bootmenu, nested three deep. Split into menu_ui
(primitives), cmd_bootmenu (items + main loop), cmd_fastboot_screen, and
one file per sub-screen, each exposing a menu_*_run() that owns its loop
and returns on back. struct menu_btns replaces the 4-pointer signatures,
menu_ui_begin() absorbs the panel bring-up both commands open-coded, and
the vc handle is now private behind vc_puts/vc_at/vc_clear/vc_sync so the
NULL guards live in one place.

Menu centring. "Hardware Info" was 13 characters, and an odd-length label
cannot sit exactly centred on a 50-column screen -- the spare column
always lands on one side, so that row read as shifted however it was
rounded. Renamed to "Hardware Details" (16), so all five items are now
even-length and land dead centre. item_label_col() rounds up for any
future odd label, and no longer counts the "> " cursor in the centring
width, since the cursor sits left of the label and must not pull it off
centre.

eMMC bus mode on the hwinfo overview:

  eMMC bus : MMC High Speed (52MHz), 8-bit

Deliberately mmc->selected_mode rather than what the DT offers -- a
failed mode switch drops to something slower while still reporting
success, which is why misc_init_r warns about it. Bus width is shown too,
since a silent fall back to 1-bit was a real bug here once.

Verified on hardware: flashed to boot0/boot1, menus and sub-screens work,
the unit reports HS52 8-bit.

Claude-Session: https://claude.ai/code/session_011MT9SvLMojs5cEdJeEB4wn
Signed-off-by: Theo Paris <theo@theoparis.com>
An accuracy audit of the notes trees turned up three things that live in
this repo.

cert_parse.c described the wrong algorithm. The comment claimed
find_x509() byte-pattern matches for `30 82 01` and checks the length.
It does not: it anchors on the v3 version marker `a0 03 02 01 02` and
walks backward to the SEQUENCE header, 3 or 4 bytes depending on whether
the length is 0x81- or 0x82-encoded. Anchoring on the marker is the point
-- a `30 82 01`-shaped SEQUENCE also occurs in the PKCS#7 envelope ahead
of the certificate, so a forward scan can land on the wrong one. The
description predates the current implementation and was carried forward
unchecked when the comments were trimmed.

README claimed eMMC runs 8-bit DDR52 at 42 MB/s. DDR52 was dropped in
89aaad0 because the mode switch fails on Kioxia parts and silently falls
back; it is HS52 SDR at 38-45 MB/s.

The rest is path updates: superbird-misc-notes has been merged into
superbird-docs under topic subdirs, so every doc reference in comments,
README and CLAUDE.md now points at its new home. No code changed --
`git diff` over board/ and drivers/ is comment-only.

Claude-Session: https://claude.ai/code/session_011MT9SvLMojs5cEdJeEB4wn
Signed-off-by: Theo Paris <theo@theoparis.com>
Signed-off-by: Theo Paris <theo@theoparis.com>
@theoparis
theoparis marked this pull request as ready for review September 2, 2026 04:33
Signed-off-by: Theo Paris <theo@theoparis.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants