main: revive display pipeline at handoff (fix black screen)
Root cause of the black screen, verified against the DEVICE's depthcharge (v0.0.22-10476, ChromeOS R93-era): display_cleanup() runs at CleanupOnHandoff before jumping to the payload and 1. clears the LBIO framebuffer to black, 2. drives DISP_PWM (GPIO 43) and EN_LCD_BL (GPIO 176) low, 3. disables the OVL engines (OVL_EN=0, OVL0_2L_EN=0). DSI/panel/MTCMOS remain up (panel poweroff only exists in 2025+ code), so the stub just undoes those three steps: re-enable both OVLs, set both backlight GPIOs, then paint. The OVL_L0_ADDR register still points at the menu framebuffer, which is the LBIO record address our parser already extracts.
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -233,6 +233,48 @@ static void fill_screen(const struct fbinfo *f, u64 val)
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- display revival ----------------------------------------------------
|
||||
*
|
||||
* Verified against the DEVICE's depthcharge (v0.0.22-10476, 2021/2022):
|
||||
* display_cleanup() runs at CleanupOnHandoff before jumping here:
|
||||
* 1. clear_screen(black) — LBIO framebuffer painted black
|
||||
* 2. backlight_update(false) — GPIO 43 (DISP_PWM) and GPIO 176
|
||||
* (EN_LCD_BL) driven low
|
||||
* 3. mtk_display_stop() — OVL_EN=0 and OVL0_2L_EN=0
|
||||
* The DSI link, panel and display MTCMOS stay up (no panel poweroff in this
|
||||
* firmware generation). So the stub just needs to undo exactly those three
|
||||
* steps — no DSI/panel re-init required.
|
||||
*/
|
||||
|
||||
#define DISP_OVL0_BASE 0x14008000u
|
||||
#define DISP_REG_OVL_EN 0x0F00u /* 2021 mtk_ddp.c */
|
||||
#define DISP_REG_OVL0_2L_EN 0x100Cu /* 2021 mtk_ddp.c */
|
||||
|
||||
#define GPIO_BASE 0x10005000u
|
||||
/* GpioValRegs: val@0, set@4, rst@8, 16 bytes per 32-pin group */
|
||||
#define GPIO_DOUT_SET(pin) (GPIO_BASE + 0x140 + ((pin) / 32) * 16 + 4)
|
||||
#define GPIO_DOUT_BIT(pin) (1u << ((pin) % 32))
|
||||
|
||||
#define PAD_DISP_PWM 43 /* DISP_PWM */
|
||||
#define PAD_EN_LCD_BL 176 /* PERIPHERAL_EN13 */
|
||||
|
||||
static void wr32(u64 addr, u32 val)
|
||||
{
|
||||
*(volatile u32 *)addr = val;
|
||||
}
|
||||
|
||||
/* Undo depthcharge's display_cleanup() so our fills are visible. */
|
||||
static void display_revive(void)
|
||||
{
|
||||
/* Same buffer depthcharge scanned out for the menu. */
|
||||
wr32(DISP_OVL0_BASE + DISP_REG_OVL_EN, 1);
|
||||
wr32(DISP_OVL0_BASE + DISP_REG_OVL0_2L_EN, 1);
|
||||
|
||||
/* Backlight on (both pins), matching kukui_backlight_update(true). */
|
||||
wr32(GPIO_DOUT_SET(PAD_DISP_PWM), GPIO_DOUT_BIT(PAD_DISP_PWM));
|
||||
wr32(GPIO_DOUT_SET(PAD_EN_LCD_BL), GPIO_DOUT_BIT(PAD_EN_LCD_BL));
|
||||
}
|
||||
|
||||
/* ---- main checkpoint sequence ------------------------------------------- */
|
||||
|
||||
static void checkpoint(const struct fbinfo *f, int r, int g, int b)
|
||||
@@ -248,17 +290,20 @@ void cmain(u64 dtb)
|
||||
u32 lbio_size;
|
||||
|
||||
/*
|
||||
* Parse everything first (instantaneous); see deviation note above.
|
||||
* If either stage fails we halt having painted nothing — the screen
|
||||
* keeps depthcharge's output, which identifies the failure stage.
|
||||
* Parse everything first (instantaneous). On failure halt unpainted:
|
||||
* depthcharge blacked the screen and disabled the OVL engine, so the
|
||||
* failure signature is a black screen right after the menu.
|
||||
*/
|
||||
if (find_coreboot_reg((const void *)dtb, &lbio_addr, &lbio_size))
|
||||
halt(); /* stuck on depthcharge output */
|
||||
halt(); /* black screen: DTB parse failed */
|
||||
|
||||
if (find_framebuffer(lbio_addr, &fb))
|
||||
halt(); /* stuck on depthcharge output */
|
||||
halt(); /* black screen: LBIO/fb record bad */
|
||||
|
||||
/* Checkpoint 1: red — we entered, parsed, and can draw. */
|
||||
/* Re-enable scanout + backlight, then paint. */
|
||||
display_revive();
|
||||
|
||||
/* Checkpoint 1: red — we entered, parsed, revived the display. */
|
||||
checkpoint(&fb, 1, 0, 0); /* red */
|
||||
/* Checkpoint 2: yellow — DTB stage. */
|
||||
checkpoint(&fb, 1, 1, 0); /* yellow */
|
||||
|
||||
Reference in New Issue
Block a user