mipi/panel: Add 'poweroff' field to panel_serializable_data

Some payloads such as depthcharge need to run MIPI panel power-off
commands before booting to the kernel. Otherwise, the abnormal power-off
timing would prevent the pixel charge from being cleared before
power-off, leading to the risk of LCD overpotential hence resulting in
image stickiness or flicker upon restarting.

Therefore, add a 'poweroff' field to the panel_serializable_data struct,
which, in a follow-up patch, will be passed to payloads for running the
power-off commands. Each MIPI panel can define the power-off commands in
that field.

As both init and power-off commands are supported, remove "_init" from
related structs and enums.

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

Change-Id: I1a7c0a14d5c197a0887a26269e4c36e498e8b7ae
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90737
Reviewed-by: Yidi Lin <yidilin@google.com>
Reviewed-by: Alicja Michalska <ahplka19@gmail.com>
Reviewed-by: Subrata Banik <subratabanik@google.com>
Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Chen-Tsung Hsieh <chentsung@google.com>
This commit is contained in:
Yu-Ping Wu 2026-01-13 14:49:47 +08:00 committed by Yu-Ping Wu
commit a6407000f1
5 changed files with 25 additions and 22 deletions

View file

@ -7,15 +7,15 @@
#include <commonlib/mipi/dsi.h>
#include <stdint.h>
/* Definitions for cmd in panel_init_command */
enum panel_init_cmd {
/* Definitions for cmd in panel_command */
enum panel_cmd {
PANEL_CMD_END = 0,
PANEL_CMD_DELAY = 1,
PANEL_CMD_GENERIC = 2,
PANEL_CMD_DCS = 3,
};
struct panel_init_command {
struct panel_command {
u8 cmd;
u8 len;
u8 data[];
@ -39,17 +39,17 @@ struct panel_init_command {
PANEL_CMD_END
/*
* Callback function type for mipi_panel_parse_init_commands().
* Callback function type for mipi_panel_parse_commands().
* @param type MIPI DSI transaction type.
* @param data panel_init_command data.
* @param len panel_init_command len.
* @param user_data Arbitrary user data passed from mipi_panel_parse_init_commands().
* @param data panel_command data.
* @param len panel_command len.
* @param user_data Arbitrary user data passed from mipi_panel_parse_commands().
*/
typedef enum cb_err (*mipi_cmd_func_t)(enum mipi_dsi_transaction type, const u8 *data, u8 len,
void *user_data);
/* Parse a command array and call cmd_func() for each entry. Delays get handled internally. */
enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_func,
void *user_data);
enum cb_err mipi_panel_parse_commands(const void *buf, mipi_cmd_func_t cmd_func,
void *user_data);
#endif /* __COMMONLIB_MIPI_CMD_H__ */

View file

@ -5,26 +5,26 @@
#include <commonlib/mipi/cmd.h>
#include <delay.h>
enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_func,
void *user_data)
enum cb_err mipi_panel_parse_commands(const void *buf, mipi_cmd_func_t cmd_func,
void *user_data)
{
const struct panel_init_command *init = buf;
const struct panel_command *command = buf;
enum mipi_dsi_transaction type;
/*
* The given commands should be in a buffer containing a packed array of
* panel_init_command and each element may be in variable size so we have
* panel_command and each element may be in variable size so we have
* to parse and scan.
*/
for (; init->cmd != PANEL_CMD_END; init = (const void *)buf) {
for (; command->cmd != PANEL_CMD_END; command = (const void *)buf) {
/*
* For some commands like DELAY, the init->len should not be
* For some commands like DELAY, the command->len should not be
* counted for buf.
*/
buf += sizeof(*init);
buf += sizeof(*command);
u32 cmd = init->cmd, len = init->len;
u32 cmd = command->cmd, len = command->len;
if (cmd == PANEL_CMD_DELAY) {
mdelay(len);
@ -70,7 +70,7 @@ enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_
return CB_ERR;
}
enum cb_err ret = cmd_func(type, init->data, len, user_data);
enum cb_err ret = cmd_func(type, command->data, len, user_data);
if (ret != CB_SUCCESS)
return ret;
buf += len;

View file

@ -189,6 +189,8 @@ struct dsc_config {
u8 dsc_version_major;
};
#define PANEL_POWEROFF_CMD_MAX_LEN 16
/*
* The data to be serialized and put into CBFS.
* Note some fields, for example edid.mode.name, were actually pointers and
@ -198,7 +200,9 @@ struct panel_serializable_data {
u32 flags; /* flags of panel_flag */
struct edid edid; /* edid info of this panel */
struct dsc_config dsc_config; /* dsc config of this panel */
u8 init[]; /* A packed array of panel_init_command */
/* Packed arrays of panel_command */
u8 poweroff[PANEL_POWEROFF_CMD_MAX_LEN];
u8 init[];
};
#endif /* __MIPI_PANEL_H__ */

View file

@ -494,7 +494,7 @@ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid,
}
if (init_commands)
mipi_panel_parse_init_commands(init_commands, mtk_dsi_cmdq, &mode_flags);
mipi_panel_parse_commands(init_commands, mtk_dsi_cmdq, &mode_flags);
for (unsigned int i = 0; i < num_dsi; i++)
mtk_dsi_set_mode(dsi_mipi_regs[i].dsi_reg, mode_flags);

View file

@ -286,8 +286,7 @@ enum cb_err mdss_dsi_panel_initialize(const u8 *init_cmds)
/* Enable command mode before sending the commands */
write32(&dsi0->ctrl, ctrl_mode | 0x04);
enum cb_err ret = mipi_panel_parse_init_commands(init_cmds, mdss_dsi_send_init_cmd,
NULL);
enum cb_err ret = mipi_panel_parse_commands(init_cmds, mdss_dsi_send_init_cmd, NULL);
write32(&dsi0->ctrl, ctrl_mode);
mdss_dsi_clear_intr();