soc/mediatek: Add mtk_mipi_panel_poweroff()

Introduce mtk_mipi_panel_poweroff() in common display layer and
mtk_dsi_panel_poweroff() in DSI driver. The DSI mode flags are
saved during init and reused for the power-off command path.

BUG=b:474187570
TEST=emerge-jedi coreboot chromeos-bootimage
BRANCH=skywalker

Change-Id: Ic684822bc5f20d3e2f5ce3d44035c902a2b44184
Signed-off-by: Yang Wu <wuyang5@huaqin.corp-partner.google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/91432
Reviewed-by: Yidi Lin <yidilin@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Zhengqiao Xia <xiazhengqiao@huaqin.corp-partner.google.com>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
This commit is contained in:
Yang Wu 2026-02-13 16:05:54 +08:00 committed by Yu-Ping Wu
commit 8a4937bf8f
4 changed files with 60 additions and 0 deletions

View file

@ -16,6 +16,7 @@
#include <symbols.h>
#include <timestamp.h>
static u32 dsi_mode_flags;
static struct panel_serializable_data *mipi_data;
static struct panel_serializable_data *get_mipi_cmd_from_cbfs(struct panel_description *desc)
@ -172,6 +173,8 @@ int mtk_display_init(void)
lanes = 4;
}
dsi_mode_flags = mipi_dsi_flags;
if (mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, lanes, &edid,
mipi_data ? mipi_data->init : NULL) < 0) {
printk(BIOS_ERR, "%s: Failed in DSI init\n", __func__);
@ -219,6 +222,14 @@ int mtk_display_init(void)
return 0;
}
int mtk_mipi_panel_poweroff(void)
{
if (!mipi_data)
return 0;
return mtk_dsi_panel_poweroff(dsi_mode_flags, mipi_data->poweroff);
}
u32 mtk_get_vrefresh(const struct edid *edid)
{
u32 width = edid->mode.ha;

View file

@ -444,6 +444,11 @@ static void mtk_dsi_reset_phy(struct dsi_regs *const dsi_reg)
clrbits32(&dsi_reg->dsi_con_ctrl, DPHY_RESET);
}
static void mtk_dsi_stop(struct dsi_regs *dsi)
{
write32(&dsi->dsi_start, 0);
}
int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid,
const u8 *init_commands)
{
@ -502,3 +507,45 @@ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid,
return 0;
}
int mtk_dsi_panel_poweroff(u32 mode_flags, const u8 *poweroff_cmds)
{
int ret;
unsigned int num_dsi = (mode_flags & MIPI_DSI_DUAL_CHANNEL) ? 2 : 1;
/* Stop DSI-0 engine */
mtk_dsi_stop(dsi_mipi_regs[0].dsi_reg);
/* Wait for DSI engines to become idle */
for (unsigned int i = 0; i < num_dsi; i++) {
struct dsi_regs *dsi = dsi_mipi_regs[i].dsi_reg;
if (!wait_ms(20, !(read32(&dsi->dsi_intsta) & DSI_BUSY))) {
u32 intsta = read32(&dsi->dsi_intsta);
printk(BIOS_ERR, "%s: Timeout (20ms) waiting for DSI-%d idle "
"and the panel may not power-off properly. "
"DSI_INTSTA=0x%08x.\n",
__func__, i, intsta);
return -1;
}
write32(&dsi->dsi_intsta, 0);
write32(&dsi->dsi_mode_ctrl, CMD_MODE);
}
/* Send panel poweroff commands */
ret = mipi_panel_parse_commands(poweroff_cmds, mtk_dsi_cmdq,
&mode_flags);
/* Final shutdown: stop + disable PHY */
mtk_dsi_stop(dsi_mipi_regs[0].dsi_reg);
for (unsigned int i = 0; i < num_dsi; i++) {
struct dsi_regs *dsi = dsi_mipi_regs[i].dsi_reg;
write32(&dsi->dsi_phy_lccon, 0x0);
}
return ret;
}

View file

@ -32,6 +32,7 @@ struct panel_description {
struct panel_description *get_active_panel(void);
void mtk_display_disable_secure_mode(void);
int mtk_display_init(void);
int mtk_mipi_panel_poweroff(void);
void mtk_ddp_init(void);
u32 mtk_get_vrefresh(const struct edid *edid);

View file

@ -51,5 +51,6 @@ enum {
/* Public API for common display code (display.c). */
int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid,
const u8 *init_commands);
int mtk_dsi_panel_poweroff(u32 mode_flags, const u8 *poweroff_cmds);
#endif /* SOC_MEDIATEK_DISPLAY_DSI_H */