soc/mediatek: Introduce mtk_edp_enable() to fix eDP init flow

In the current eDP initialization flow, eDP is configured and enabled
before display data pipe (DDP) initialization. The init flow is wrong,
because eDP should be enabled only after DDP is correctly set up. The
wrong flow may lead to garbage display between enabling eDP and
configuring DDP.

To fix the problem, the dptx_video_enable(true) call needs to be moved
after mtk_ddp_mode_set(). Introduce a new API mtk_edp_enable() for eDP
enablement, to be separated from the existing mtk_edp_init(). The fixed
eDP init flow is: mtk_edp_init -> mtk_ddp_mode_set -> mtk_edp_enable.

Change-Id: Ief847320caca1af1c6deb242dc224e7698a6603c
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/86028
Reviewed-by: Yidi Lin <yidilin@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Yu-Ping Wu 2025-01-17 09:53:15 +08:00 committed by Yu-Ping Wu
commit 1ad4474141
3 changed files with 35 additions and 15 deletions

View file

@ -37,7 +37,13 @@ static struct panel_serializable_data *get_mipi_cmd_from_cbfs(struct panel_descr
return NULL;
}
__weak int mtk_edp_init(struct edid *edid)
__weak int mtk_edp_init(struct mtk_dp *mtk_dp, struct edid *edid)
{
printk(BIOS_WARNING, "%s: Not supported\n", __func__);
return -1;
}
__weak int mtk_edp_enable(struct mtk_dp *mtk_dp)
{
printk(BIOS_WARNING, "%s: Not supported\n", __func__);
return -1;
@ -52,7 +58,8 @@ __weak int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes,
int mtk_display_init(void)
{
struct edid edid;
struct edid edid = {0};
struct mtk_dp mtk_edp = {0};
struct fb_info *info;
const char *name;
struct panel_description *panel = get_active_panel();
@ -76,7 +83,7 @@ int mtk_display_init(void)
if (panel->disp_path == DISP_PATH_EDP) {
mdelay(200);
if (mtk_edp_init(&edid) < 0) {
if (mtk_edp_init(&mtk_edp, &edid) < 0) {
printk(BIOS_ERR, "%s: Failed to initialize eDP\n", __func__);
return -1;
}
@ -120,6 +127,14 @@ int mtk_display_init(void)
edid_set_framebuffer_bits_per_pixel(&edid, 32, 0);
mtk_ddp_mode_set(&edid, panel->disp_path);
if (panel->disp_path == DISP_PATH_EDP) {
if (mtk_edp_enable(&mtk_edp) < 0) {
printk(BIOS_ERR, "%s: Failed to enable eDP\n", __func__);
return -1;
}
}
info = fb_new_framebuffer_info_from_edid(&edid, (uintptr_t)0);
if (info)
fb_set_orientation(info, panel->orientation);

View file

@ -478,29 +478,32 @@ static void dptx_init_port(struct mtk_dp *mtk_dp)
dptx_hal_hpd_int_en(mtk_dp, true);
}
int mtk_edp_init(struct edid *edid)
int mtk_edp_init(struct mtk_dp *mtk_dp, struct edid *edid)
{
struct mtk_dp mtk_edp;
dptx_init_variable(mtk_dp);
dptx_init_port(mtk_dp);
dptx_init_variable(&mtk_edp);
dptx_init_port(&mtk_edp);
if (!dptx_hal_hpd_high(&mtk_edp)) {
if (!dptx_hal_hpd_high(mtk_dp)) {
printk(BIOS_ERR, "HPD is low\n");
return -1;
}
dptx_check_sinkcap(&mtk_edp);
dptx_check_sinkcap(mtk_dp);
if (dptx_get_edid(&mtk_edp, edid) != 0) {
if (dptx_get_edid(mtk_dp, edid) != 0) {
printk(BIOS_ERR, "Failed to get EDID\n");
return -1;
}
dptx_set_trainingstart(&mtk_edp);
dptx_set_trainingstart(mtk_dp);
dp_intf_config(edid);
dptx_video_config(&mtk_edp);
dptx_video_enable(&mtk_edp, true);
dptx_video_config(mtk_dp);
return 0;
}
int mtk_edp_enable(struct mtk_dp *mtk_dp)
{
dptx_video_enable(mtk_dp, true);
return 0;
}

View file

@ -211,7 +211,9 @@ struct mtk_dp {
bool powered;
};
int mtk_edp_init(struct edid *edid);
int mtk_edp_init(struct mtk_dp *mtk_dp, struct edid *edid);
int mtk_edp_enable(struct mtk_dp *mtk_dp);
bool dptx_auxread_dpcd(struct mtk_dp *mtk_dp, u8 cmd, u32 dpcd_addr,
size_t length, u8 *rxbuf);
bool dptx_auxwrite_dpcd(struct mtk_dp *mtk_dp, u8 cmd, u32 dpcd_addr,