soc/mediatek: Add common implementation to configure display
The sequences of configure_display() are similar on MediaTek platforms. The sequences usually involve following steps: 1. Setup mtcmos for display hardware block. - mtcmos_display_power_on() - mtcmos_protect_display_bus() 2. Configure backlight pins 3. Power on the panel - It also powers on the bridge in MIPI DSI to eDP case. 4. General initialization for DDP(display data path) 5. Initialize eDP/MIPI DSI accordingly, - For eDP path, it calls mtk_edp_init() to get edid from the panel and initializes eDP driver. - For MIPI DSI path, the edid is retrieved either from the bridge or from CBFS (the serializable data), and then initializes DSI driver. 6. Set framebuffer bits per pixel 7. Setup DDP mode 8. Setup panel orientation This patch extracts geralt/display.c to mediatek/common/display.c and refactors `struct panel_description` to generalize the display init sequences. configure_display() is also renamed to mtk_display_init(). TEST=check FW screen on geralt. Change-Id: I403bba8a826de5f3fb2ea96a5403725ff194164f Signed-off-by: Yidi Lin <yidilin@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/79776 Reviewed-by: Yu-Ping Wu <yupingso@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
7224999497
commit
ba604b558e
|
@ -20,7 +20,6 @@ romstage-y += sdram_configs.c
|
||||||
ramstage-y += memlayout.ld
|
ramstage-y += memlayout.ld
|
||||||
ramstage-y += boardid.c
|
ramstage-y += boardid.c
|
||||||
ramstage-y += chromeos.c
|
ramstage-y += chromeos.c
|
||||||
ramstage-y += display.c
|
|
||||||
ramstage-y += mainboard.c
|
ramstage-y += mainboard.c
|
||||||
ramstage-y += panel.c
|
ramstage-y += panel.c
|
||||||
ramstage-y += regulator.c
|
ramstage-y += regulator.c
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
||||||
|
|
||||||
#include <console/console.h>
|
|
||||||
#include <delay.h>
|
|
||||||
#include <edid.h>
|
|
||||||
#include <framebuffer_info.h>
|
|
||||||
#include <gpio.h>
|
|
||||||
#include <soc/ddp.h>
|
|
||||||
#include <soc/dptx.h>
|
|
||||||
#include <soc/dsi.h>
|
|
||||||
#include <soc/gpio_common.h>
|
|
||||||
#include <soc/mtcmos.h>
|
|
||||||
|
|
||||||
#include "display.h"
|
|
||||||
#include "gpio.h"
|
|
||||||
#include "panel.h"
|
|
||||||
|
|
||||||
int configure_display(void)
|
|
||||||
{
|
|
||||||
struct edid edid;
|
|
||||||
struct fb_info *info;
|
|
||||||
const char *name;
|
|
||||||
struct panel_description *panel = get_active_panel();
|
|
||||||
if (!panel)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
printk(BIOS_INFO, "%s: Starting display initialization\n", __func__);
|
|
||||||
|
|
||||||
mtcmos_display_power_on();
|
|
||||||
mtcmos_protect_display_bus();
|
|
||||||
|
|
||||||
panel->configure_panel_backlight();
|
|
||||||
panel->power_on();
|
|
||||||
|
|
||||||
mtk_ddp_init();
|
|
||||||
|
|
||||||
if (panel->disp_path == DISP_PATH_EDP) {
|
|
||||||
mdelay(200);
|
|
||||||
if (mtk_edp_init(&edid) < 0) {
|
|
||||||
printk(BIOS_ERR, "%s: Failed to initialize eDP\n", __func__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
u32 mipi_dsi_flags = (MIPI_DSI_MODE_VIDEO |
|
|
||||||
MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
|
|
||||||
MIPI_DSI_MODE_LPM |
|
|
||||||
MIPI_DSI_MODE_EOT_PACKET);
|
|
||||||
|
|
||||||
edid = panel->s->edid;
|
|
||||||
|
|
||||||
if (mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, 4, &edid,
|
|
||||||
panel->s->init) < 0) {
|
|
||||||
printk(BIOS_ERR, "%s: Failed in DSI init\n", __func__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
name = edid.ascii_string;
|
|
||||||
if (name[0] == '\0')
|
|
||||||
name = "unknown name";
|
|
||||||
printk(BIOS_INFO, "%s: '%s %s' %dx%d@%dHz\n", __func__,
|
|
||||||
edid.manufacturer_name, name, edid.mode.ha, edid.mode.va,
|
|
||||||
edid.mode.refresh);
|
|
||||||
|
|
||||||
edid_set_framebuffer_bits_per_pixel(&edid, 32, 0);
|
|
||||||
|
|
||||||
mtk_ddp_mode_set(&edid, panel->disp_path);
|
|
||||||
info = fb_new_framebuffer_info_from_edid(&edid, (uintptr_t)0);
|
|
||||||
if (info)
|
|
||||||
fb_set_orientation(info, LB_FB_ORIENTATION_BOTTOM_UP);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
||||||
|
|
||||||
#ifndef __MAINBOARD_GOOGLE_GERALT_DISPLAY_H__
|
|
||||||
#define __MAINBOARD_GOOGLE_GERALT_DISPLAY_H__
|
|
||||||
|
|
||||||
int configure_display(void);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -3,13 +3,13 @@
|
||||||
#include <bootmode.h>
|
#include <bootmode.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
#include <soc/bl31.h>
|
#include <soc/bl31.h>
|
||||||
|
#include <soc/display.h>
|
||||||
#include <soc/i2c.h>
|
#include <soc/i2c.h>
|
||||||
#include <soc/msdc.h>
|
#include <soc/msdc.h>
|
||||||
#include <soc/mt6359p.h>
|
#include <soc/mt6359p.h>
|
||||||
#include <soc/mtcmos.h>
|
#include <soc/mtcmos.h>
|
||||||
#include <soc/usb.h>
|
#include <soc/usb.h>
|
||||||
|
|
||||||
#include "display.h"
|
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
|
||||||
#define AFE_SE_SECURE_CON (AUDIO_BASE + 0x17a8)
|
#define AFE_SE_SECURE_CON (AUDIO_BASE + 0x17a8)
|
||||||
|
@ -44,7 +44,7 @@ static void mainboard_init(struct device *dev)
|
||||||
mt6359p_init_pmif_arb();
|
mt6359p_init_pmif_arb();
|
||||||
|
|
||||||
if (display_init_required()) {
|
if (display_init_required()) {
|
||||||
if (configure_display() < 0)
|
if (mtk_display_init() < 0)
|
||||||
printk(BIOS_ERR, "%s: Failed to init display\n", __func__);
|
printk(BIOS_ERR, "%s: Failed to init display\n", __func__);
|
||||||
} else {
|
} else {
|
||||||
printk(BIOS_INFO, "%s: Skipped display initialization\n", __func__);
|
printk(BIOS_INFO, "%s: Skipped display initialization\n", __func__);
|
||||||
|
|
|
@ -12,30 +12,6 @@
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "panel.h"
|
#include "panel.h"
|
||||||
|
|
||||||
static void get_mipi_cmd_from_cbfs(struct panel_description *desc)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The CBFS file name is panel-{MANUFACTURER}-${PANEL_NAME}, where MANUFACTURER is 3
|
|
||||||
* characters and PANEL_NAME is usually 13 characters.
|
|
||||||
*/
|
|
||||||
char cbfs_name[64];
|
|
||||||
static union {
|
|
||||||
u8 raw[4 * 1024]; /* Most panels only need < 2K. */
|
|
||||||
struct panel_serializable_data s;
|
|
||||||
} buffer;
|
|
||||||
|
|
||||||
if (!desc->name) {
|
|
||||||
printk(BIOS_ERR, "Missing panel CBFS file name.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(cbfs_name, sizeof(cbfs_name), "panel-%s", desc->name);
|
|
||||||
if (cbfs_load(cbfs_name, buffer.raw, sizeof(buffer)))
|
|
||||||
desc->s = &buffer.s;
|
|
||||||
else
|
|
||||||
printk(BIOS_ERR, "Missing %s in CBFS.\n", cbfs_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct panel_description __weak *get_panel_description(uint32_t panel_id)
|
struct panel_description __weak *get_panel_description(uint32_t panel_id)
|
||||||
{
|
{
|
||||||
printk(BIOS_WARNING, "%s: %s: the panel configuration is not ready\n",
|
printk(BIOS_WARNING, "%s: %s: the panel configuration is not ready\n",
|
||||||
|
@ -46,33 +22,7 @@ struct panel_description __weak *get_panel_description(uint32_t panel_id)
|
||||||
struct panel_description *get_active_panel(void)
|
struct panel_description *get_active_panel(void)
|
||||||
{
|
{
|
||||||
uint32_t active_panel_id = panel_id();
|
uint32_t active_panel_id = panel_id();
|
||||||
|
return get_panel_description(active_panel_id);
|
||||||
struct panel_description *panel = get_panel_description(active_panel_id);
|
|
||||||
if (!panel || panel->disp_path == DISP_PATH_NONE) {
|
|
||||||
printk(BIOS_ERR, "%s: Panel %u is not supported.\n", __func__, active_panel_id);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For eDP, we will get edid after eDP initialization is done, so we return directly. */
|
|
||||||
if (panel->disp_path == DISP_PATH_EDP) {
|
|
||||||
printk(BIOS_INFO, "%s: Use eDP as the display\n", __func__);
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We need to find init cmds for MIPI panel from CBFS */
|
|
||||||
get_mipi_cmd_from_cbfs(panel);
|
|
||||||
if (!panel->s)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
const struct edid *edid = &panel->s->edid;
|
|
||||||
const char *name = edid->ascii_string;
|
|
||||||
if (name[0] == '\0') {
|
|
||||||
name = "unknown name";
|
|
||||||
printk(BIOS_INFO, "%s: Found ID %u: '%s %s' %dx%d@%dHz\n", __func__,
|
|
||||||
active_panel_id, edid->manufacturer_name, name, edid->mode.ha,
|
|
||||||
edid->mode.va, edid->mode.refresh);
|
|
||||||
}
|
|
||||||
return panel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void configure_mipi_pwm_backlight(void)
|
void configure_mipi_pwm_backlight(void)
|
||||||
|
|
|
@ -3,23 +3,11 @@
|
||||||
#ifndef __MAINBOARD_GOOGLE_GERALT_PANEL_H__
|
#ifndef __MAINBOARD_GOOGLE_GERALT_PANEL_H__
|
||||||
#define __MAINBOARD_GOOGLE_GERALT_PANEL_H__
|
#define __MAINBOARD_GOOGLE_GERALT_PANEL_H__
|
||||||
|
|
||||||
#include <boot/coreboot_tables.h>
|
#include <soc/display.h>
|
||||||
#include <mipi/panel.h>
|
|
||||||
#include <soc/ddp.h>
|
|
||||||
|
|
||||||
struct panel_description {
|
|
||||||
const char *name;
|
|
||||||
struct panel_serializable_data *s;
|
|
||||||
void (*power_on)(void);
|
|
||||||
void (*configure_panel_backlight)(void);
|
|
||||||
enum disp_path_sel disp_path;
|
|
||||||
bool pwm_ctrl_gpio;
|
|
||||||
};
|
|
||||||
|
|
||||||
void configure_mipi_pwm_backlight(void);
|
void configure_mipi_pwm_backlight(void);
|
||||||
void fill_lp_backlight_gpios(struct lb_gpios *gpios);
|
void fill_lp_backlight_gpios(struct lb_gpios *gpios);
|
||||||
uint32_t panel_id(void);
|
uint32_t panel_id(void);
|
||||||
struct panel_description *get_panel_description(uint32_t panel_id);
|
struct panel_description *get_panel_description(uint32_t panel_id);
|
||||||
struct panel_description *get_active_panel(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,7 +52,8 @@ static struct panel_description panels[] = {
|
||||||
[1] = {
|
[1] = {
|
||||||
.name = "BOE_TV110C9M_LL0",
|
.name = "BOE_TV110C9M_LL0",
|
||||||
.power_on = power_on_mipi_boe_tv110c9m_ll0,
|
.power_on = power_on_mipi_boe_tv110c9m_ll0,
|
||||||
.configure_panel_backlight = configure_mipi_pwm_backlight,
|
.configure_backlight = configure_mipi_pwm_backlight,
|
||||||
|
.orientation = LB_FB_ORIENTATION_BOTTOM_UP,
|
||||||
.disp_path = DISP_PATH_MIPI,
|
.disp_path = DISP_PATH_MIPI,
|
||||||
.pwm_ctrl_gpio = true,
|
.pwm_ctrl_gpio = true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <cbfs.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <delay.h>
|
||||||
|
#include <edid.h>
|
||||||
|
#include <framebuffer_info.h>
|
||||||
|
#include <soc/ddp.h>
|
||||||
|
#include <soc/display.h>
|
||||||
|
#include <soc/dptx.h>
|
||||||
|
#include <soc/dsi.h>
|
||||||
|
#include <soc/mtcmos.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static struct panel_serializable_data *get_mipi_cmd_from_cbfs(struct panel_description *desc)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The CBFS file name is panel-{MANUFACTURER}-${PANEL_NAME}, where MANUFACTURER is 3
|
||||||
|
* characters and PANEL_NAME is usually 13 characters.
|
||||||
|
*/
|
||||||
|
char cbfs_name[64];
|
||||||
|
static union {
|
||||||
|
u8 raw[4 * 1024]; /* Most panels only need < 2K. */
|
||||||
|
struct panel_serializable_data s;
|
||||||
|
} buffer;
|
||||||
|
|
||||||
|
if (!desc->name) {
|
||||||
|
printk(BIOS_ERR, "Missing panel CBFS file name.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(cbfs_name, sizeof(cbfs_name), "panel-%s", desc->name);
|
||||||
|
if (cbfs_load(cbfs_name, buffer.raw, sizeof(buffer)))
|
||||||
|
return &buffer.s;
|
||||||
|
|
||||||
|
printk(BIOS_ERR, "Missing %s in CBFS.\n", cbfs_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mtk_display_init(void)
|
||||||
|
{
|
||||||
|
struct edid edid;
|
||||||
|
struct fb_info *info;
|
||||||
|
const char *name;
|
||||||
|
struct panel_description *panel = get_active_panel();
|
||||||
|
|
||||||
|
if (!panel || panel->disp_path == DISP_PATH_NONE) {
|
||||||
|
printk(BIOS_ERR, "%s: Failed to get the active panel\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printk(BIOS_INFO, "%s: Starting display initialization\n", __func__);
|
||||||
|
|
||||||
|
mtcmos_display_power_on();
|
||||||
|
mtcmos_protect_display_bus();
|
||||||
|
|
||||||
|
if (panel->configure_backlight)
|
||||||
|
panel->configure_backlight();
|
||||||
|
if (panel->power_on)
|
||||||
|
panel->power_on();
|
||||||
|
|
||||||
|
mtk_ddp_init();
|
||||||
|
|
||||||
|
if (panel->disp_path == DISP_PATH_EDP) {
|
||||||
|
mdelay(200);
|
||||||
|
if (mtk_edp_init(&edid) < 0) {
|
||||||
|
printk(BIOS_ERR, "%s: Failed to initialize eDP\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
struct panel_serializable_data *mipi_data = NULL;
|
||||||
|
|
||||||
|
if (panel->get_edid) {
|
||||||
|
if (panel->get_edid(&edid) < 0)
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
mipi_data = get_mipi_cmd_from_cbfs(panel);
|
||||||
|
if (!mipi_data)
|
||||||
|
return -1;
|
||||||
|
edid = mipi_data->edid;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 mipi_dsi_flags = (MIPI_DSI_MODE_VIDEO |
|
||||||
|
MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
|
||||||
|
MIPI_DSI_MODE_LPM |
|
||||||
|
MIPI_DSI_MODE_EOT_PACKET);
|
||||||
|
|
||||||
|
if (mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, 4, &edid,
|
||||||
|
mipi_data ? mipi_data->init : NULL) < 0) {
|
||||||
|
printk(BIOS_ERR, "%s: Failed in DSI init\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panel->post_power_on && panel->post_power_on(&edid) < 0) {
|
||||||
|
printk(BIOS_ERR, "%s: Failed to post power on bridge\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name = edid.ascii_string;
|
||||||
|
if (name[0] == '\0')
|
||||||
|
name = "unknown name";
|
||||||
|
printk(BIOS_INFO, "%s: '%s %s' %dx%d@%dHz\n", __func__,
|
||||||
|
edid.manufacturer_name, name, edid.mode.ha, edid.mode.va,
|
||||||
|
edid.mode.refresh);
|
||||||
|
|
||||||
|
edid_set_framebuffer_bits_per_pixel(&edid, 32, 0);
|
||||||
|
|
||||||
|
mtk_ddp_mode_set(&edid, panel->disp_path);
|
||||||
|
info = fb_new_framebuffer_info_from_edid(&edid, (uintptr_t)0);
|
||||||
|
if (info)
|
||||||
|
fb_set_orientation(info, panel->orientation);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#ifndef __SOC_MEDIATEK_COMMON_DISPLAY_H__
|
||||||
|
#define __SOC_MEDIATEK_COMMON_DISPLAY_H__
|
||||||
|
|
||||||
|
#include <commonlib/coreboot_tables.h>
|
||||||
|
#include <mipi/panel.h>
|
||||||
|
|
||||||
|
enum disp_path_sel {
|
||||||
|
DISP_PATH_NONE = 0,
|
||||||
|
DISP_PATH_EDP,
|
||||||
|
DISP_PATH_MIPI,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct panel_description {
|
||||||
|
const char *name;
|
||||||
|
void (*configure_backlight)(void);
|
||||||
|
void (*power_on)(void);
|
||||||
|
int (*get_edid)(struct edid *edid);
|
||||||
|
int (*post_power_on)(const struct edid *edid);
|
||||||
|
enum lb_fb_orientation orientation;
|
||||||
|
enum disp_path_sel disp_path;
|
||||||
|
bool pwm_ctrl_gpio;
|
||||||
|
};
|
||||||
|
|
||||||
|
int mtk_display_init(void);
|
||||||
|
struct panel_description *get_active_panel(void);
|
||||||
|
|
||||||
|
void mtk_ddp_init(void);
|
||||||
|
void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path);
|
||||||
|
|
||||||
|
#endif
|
|
@ -37,6 +37,7 @@ ramstage-y += cpu_input_gating.c
|
||||||
ramstage-y += ../common/ddp.c ddp.c
|
ramstage-y += ../common/ddp.c ddp.c
|
||||||
ramstage-y += ../common/devapc.c devapc.c
|
ramstage-y += ../common/devapc.c devapc.c
|
||||||
ramstage-y += ../common/dfd.c
|
ramstage-y += ../common/dfd.c
|
||||||
|
ramstage-y += ../common/display.c
|
||||||
ramstage-y += ../common/dp/dp_intf.c ../common/dp/dptx.c ../common/dp/dptx_hal.c dp_intf.c
|
ramstage-y += ../common/dp/dp_intf.c ../common/dp/dptx.c ../common/dp/dptx_hal.c dp_intf.c
|
||||||
ramstage-y += ../common/dpm.c
|
ramstage-y += ../common/dpm.c
|
||||||
ramstage-$(CONFIG_DPM_FOUR_CHANNEL) += ../common/dpm_4ch.c
|
ramstage-$(CONFIG_DPM_FOUR_CHANNEL) += ../common/dpm_4ch.c
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <soc/addressmap.h>
|
#include <soc/addressmap.h>
|
||||||
#include <soc/ddp_common.h>
|
#include <soc/ddp_common.h>
|
||||||
|
#include <soc/display.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#define MAIN_PATH_OVL_NR 1
|
#define MAIN_PATH_OVL_NR 1
|
||||||
|
@ -282,13 +283,4 @@ enum {
|
||||||
SMI_LARB_PORT_L0_OVL_RDMA0 = 0xF88,
|
SMI_LARB_PORT_L0_OVL_RDMA0 = 0xF88,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum disp_path_sel {
|
|
||||||
DISP_PATH_NONE = 0,
|
|
||||||
DISP_PATH_EDP,
|
|
||||||
DISP_PATH_MIPI,
|
|
||||||
};
|
|
||||||
|
|
||||||
void mtk_ddp_init(void);
|
|
||||||
void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue