diff --git a/src/mainboard/google/corsola/Makefile.inc b/src/mainboard/google/corsola/Makefile.inc index dce226f20c..5483167e38 100644 --- a/src/mainboard/google/corsola/Makefile.inc +++ b/src/mainboard/google/corsola/Makefile.inc @@ -19,8 +19,8 @@ romstage-y += sdram_configs.c ramstage-y += memlayout.ld ramstage-y += boardid.c ramstage-y += chromeos.c -ramstage-y += display.c ramstage-y += mainboard.c +ramstage-y += panel.c ramstage-y += panel_anx7625.c ramstage-y += panel_ps8640.c ramstage-y += regulator.c diff --git a/src/mainboard/google/corsola/boardid.c b/src/mainboard/google/corsola/boardid.c index 59c9f5cf03..443c3d1149 100644 --- a/src/mainboard/google/corsola/boardid.c +++ b/src/mainboard/google/corsola/boardid.c @@ -6,7 +6,7 @@ #include #include -#include "display.h" +#include "panel.h" /* board_id is provided by ec/google/chromeec/ec_boardid.c */ diff --git a/src/mainboard/google/corsola/display.c b/src/mainboard/google/corsola/display.c deleted file mode 100644 index c7a6578a00..0000000000 --- a/src/mainboard/google/corsola/display.c +++ /dev/null @@ -1,131 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "display.h" -#include "gpio.h" - -void aw37503_init(unsigned int bus) -{ - i2c_write_field(bus, PMIC_AW37503_SLAVE, 0x00, 0x14, 0x1F, 0); - i2c_write_field(bus, PMIC_AW37503_SLAVE, 0x01, 0x14, 0x1F, 0); - i2c_write_field(bus, PMIC_AW37503_SLAVE, 0x21, 0x4C, 0xFF, 0); - i2c_write_field(bus, PMIC_AW37503_SLAVE, 0x03, 0x43, 0xFF, 0); - i2c_write_field(bus, PMIC_AW37503_SLAVE, 0x21, 0x00, 0xFF, 0); -} - -bool is_pmic_aw37503(unsigned int bus) -{ - u8 vendor_id; - return (!i2c_read_field(bus, PMIC_AW37503_SLAVE, - 0x04, &vendor_id, 0x0F, 0) && vendor_id == 0x01); -} - -static void backlight_control(void) -{ - /* Disable backlight before turning on bridge */ - gpio_output(GPIO_AP_EDP_BKLTEN, 0); - gpio_output(GPIO_BL_PWM_1V8, 0); - /* For staryu variants, GPIO_EN_PP3300_DISP_X is controlled in - mipi_panel_power_on() */ - if (!CONFIG(BOARD_GOOGLE_STARYU_COMMON)) - gpio_output(GPIO_EN_PP3300_DISP_X, 1); -} - -struct panel_description *get_panel_from_cbfs(struct panel_description *desc) -{ - char cbfs_name[64]; - static union { - u8 raw[4 * 1024]; - struct panel_serializable_data s; - } buffer; - - if (!desc->name) - return NULL; - - 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); - - return desc->s ? desc : NULL; -} - -static struct panel_description *get_active_panel(void) -{ - /* Board-specific exceptions */ - if (CONFIG(BOARD_GOOGLE_STEELIX) && board_id() < 2) /* Early builds use PS8640 */ - return get_ps8640_description(); - - if (CONFIG(DRIVER_ANALOGIX_ANX7625)) - return get_anx7625_description(); - - if (CONFIG(DRIVER_PARADE_PS8640)) - return get_ps8640_description(); - - /* MIPI panels */ - return get_panel_description(); -} - -int configure_display(void) -{ - /* Set up backlight control pins as output pin and power-off by default */ - backlight_control(); - - const struct panel_description *panel = get_active_panel(); - - if (!panel) - return -1; - - printk(BIOS_INFO, "%s: Starting display init\n", __func__); - - if (panel->power_on) - panel->power_on(); - - struct edid edid = panel->s->edid; - const char *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); - - mtcmos_display_power_on(); - mtcmos_protect_display_bus(); - - edid_set_framebuffer_bits_per_pixel(&edid, 32, 0); - mtk_ddp_init(); - 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, - panel->s->init) < 0) { - printk(BIOS_ERR, "%s: Failed in DSI init\n", __func__); - return -1; - } - - if (panel->post_power_on && panel->post_power_on(BRIDGE_I2C, &edid) < 0) { - printk(BIOS_ERR, "%s: Failed to post power on bridge\n", __func__); - return -1; - } - - mtk_ddp_mode_set(&edid); - struct fb_info *info = fb_new_framebuffer_info_from_edid(&edid, - (uintptr_t)0); - if (info) - fb_set_orientation(info, panel->orientation); - - return 0; -} diff --git a/src/mainboard/google/corsola/mainboard.c b/src/mainboard/google/corsola/mainboard.c index 37f3a70941..a1ba5f9356 100644 --- a/src/mainboard/google/corsola/mainboard.c +++ b/src/mainboard/google/corsola/mainboard.c @@ -6,13 +6,14 @@ #include #include #include +#include #include #include #include #include -#include "display.h" #include "gpio.h" +#include "panel.h" static void configure_alc1019(void) { @@ -65,7 +66,7 @@ static void mainboard_init(struct device *dev) register_reset_to_bl31(GPIO_RESET.id, true); if (display_init_required()) { - if (configure_display() < 0) + if (mtk_display_init() < 0) printk(BIOS_ERR, "%s: Failed to init display\n", __func__); } else { if (CONFIG(BOARD_GOOGLE_STARYU_COMMON)) { diff --git a/src/mainboard/google/corsola/panel.c b/src/mainboard/google/corsola/panel.c new file mode 100644 index 0000000000..0eb9420c8c --- /dev/null +++ b/src/mainboard/google/corsola/panel.c @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gpio.h" +#include "panel.h" + +void aw37503_init(unsigned int bus) +{ + i2c_write_field(bus, PMIC_AW37503_SLAVE, 0x00, 0x14, 0x1F, 0); + i2c_write_field(bus, PMIC_AW37503_SLAVE, 0x01, 0x14, 0x1F, 0); + i2c_write_field(bus, PMIC_AW37503_SLAVE, 0x21, 0x4C, 0xFF, 0); + i2c_write_field(bus, PMIC_AW37503_SLAVE, 0x03, 0x43, 0xFF, 0); + i2c_write_field(bus, PMIC_AW37503_SLAVE, 0x21, 0x00, 0xFF, 0); +} + +bool is_pmic_aw37503(unsigned int bus) +{ + u8 vendor_id; + return (!i2c_read_field(bus, PMIC_AW37503_SLAVE, + 0x04, &vendor_id, 0x0F, 0) && vendor_id == 0x01); +} + +void backlight_control(void) +{ + /* Set up backlight control pins as output pin and power-off by default */ + gpio_output(GPIO_AP_EDP_BKLTEN, 0); + gpio_output(GPIO_BL_PWM_1V8, 0); +} + +struct panel_description *get_active_panel(void) +{ + /* Board-specific exceptions */ + if (CONFIG(BOARD_GOOGLE_STEELIX) && board_id() < 2) /* Early builds use PS8640 */ + return get_ps8640_description(); + + if (CONFIG(DRIVER_ANALOGIX_ANX7625)) + return get_anx7625_description(); + + if (CONFIG(DRIVER_PARADE_PS8640)) + return get_ps8640_description(); + + /* MIPI panels */ + return get_panel_description(); +} diff --git a/src/mainboard/google/corsola/display.h b/src/mainboard/google/corsola/panel.h similarity index 59% rename from src/mainboard/google/corsola/display.h rename to src/mainboard/google/corsola/panel.h index 7631bb9bae..a4198f3ecd 100644 --- a/src/mainboard/google/corsola/display.h +++ b/src/mainboard/google/corsola/panel.h @@ -3,26 +3,17 @@ #ifndef __MAINBOARD_GOOGLE_CORSOLA_DISPLAY_H__ #define __MAINBOARD_GOOGLE_CORSOLA_DISPLAY_H__ -#include -#include +#include #include #define BRIDGE_I2C I2C0 #define PMIC_AW37503_SLAVE 0x3E #define PMIC_I2C_BUS I2C6 -struct panel_description { - void (*power_on)(void); /* Callback to turn on panel */ - int (*post_power_on)(u8 i2c_bus, struct edid *edid); - const char *name; /* Panel name in CBFS */ - struct panel_serializable_data *s; - enum lb_fb_orientation orientation; -}; - void aw37503_init(unsigned int bus); bool is_pmic_aw37503(unsigned int bus); -int configure_display(void); uint32_t panel_id(void); +void backlight_control(void); /* Return the mipi panel description from given panel id */ struct panel_description *get_panel_description(void); @@ -33,7 +24,4 @@ struct panel_description *get_anx7625_description(void); /* Return the PS8640 bridge description */ struct panel_description *get_ps8640_description(void); -/* Load panel serializable data from CBFS */ -struct panel_description *get_panel_from_cbfs(struct panel_description *desc); - #endif diff --git a/src/mainboard/google/corsola/panel_anx7625.c b/src/mainboard/google/corsola/panel_anx7625.c index 7b50e476ec..193a501b87 100644 --- a/src/mainboard/google/corsola/panel_anx7625.c +++ b/src/mainboard/google/corsola/panel_anx7625.c @@ -7,8 +7,8 @@ #include #include -#include "display.h" #include "gpio.h" +#include "panel.h" static void bridge_anx7625_power_on(void) { @@ -23,39 +23,42 @@ static void bridge_anx7625_power_on(void) gpio_output(GPIO_EDPBRDG_RST_L, 1); } -static int bridge_anx7625_get_edid(u8 i2c_bus, struct edid *edid) +static int bridge_anx7625_get_edid(struct edid *edid) { - if (anx7625_init(i2c_bus) < 0) { + if (anx7625_init(BRIDGE_I2C) < 0) { printk(BIOS_ERR, "%s: Can't init ANX7625 bridge\n", __func__); return -1; } - if (anx7625_dp_get_edid(i2c_bus, edid) < 0) { + if (anx7625_dp_get_edid(BRIDGE_I2C, edid) < 0) { printk(BIOS_ERR, "%s: Can't get panel's edid\n", __func__); return -1; } return 0; } -static int bridge_anx7625_post_power_on(u8 i2c_bus, struct edid *edid) +static int bridge_anx7625_post_power_on(const struct edid *edid) { - return anx7625_dp_start(i2c_bus, edid); + return anx7625_dp_start(BRIDGE_I2C, edid); } -static struct panel_serializable_data anx7625_data; +static void panel_power_on(void) +{ + /* Turn on the panel */ + gpio_output(GPIO_EN_PP3300_DISP_X, 1); + bridge_anx7625_power_on(); +} static struct panel_description anx7625_bridge = { - .s = &anx7625_data, + .configure_backlight = backlight_control, + .power_on = panel_power_on, + .get_edid = bridge_anx7625_get_edid, .post_power_on = bridge_anx7625_post_power_on, + .disp_path = DISP_PATH_MIPI, .orientation = LB_FB_ORIENTATION_NORMAL, }; struct panel_description *get_anx7625_description(void) { mtk_i2c_bus_init(BRIDGE_I2C, I2C_SPEED_FAST); - bridge_anx7625_power_on(); - if (bridge_anx7625_get_edid(BRIDGE_I2C, &anx7625_bridge.s->edid) < 0) { - printk(BIOS_ERR, "Can't get panel's edid\n"); - return NULL; - } return &anx7625_bridge; } diff --git a/src/mainboard/google/corsola/panel_ps8640.c b/src/mainboard/google/corsola/panel_ps8640.c index bb1e4eb7ce..94bf47d312 100644 --- a/src/mainboard/google/corsola/panel_ps8640.c +++ b/src/mainboard/google/corsola/panel_ps8640.c @@ -8,8 +8,8 @@ #include #include -#include "display.h" #include "gpio.h" +#include "panel.h" static void bridge_ps8640_power_on(void) { @@ -45,35 +45,38 @@ static void bridge_ps8640_power_on(void) gpio_output(GPIO_EDPBRDG_RST_L, 1); } -static int bridge_ps8640_get_edid(u8 i2c_bus, struct edid *edid) +static void panel_power_on(void) +{ + /* Turn on the panel */ + gpio_output(GPIO_EN_PP3300_DISP_X, 1); + bridge_ps8640_power_on(); +} + +static int bridge_ps8640_get_edid(struct edid *edid) { const u8 chip = 0x8; - if (ps8640_init(i2c_bus, chip) < 0) { + if (ps8640_init(BRIDGE_I2C, chip) < 0) { printk(BIOS_ERR, "%s: Can't init PS8640 bridge\n", __func__); return -1; } - if (ps8640_get_edid(i2c_bus, chip, edid) < 0) { + if (ps8640_get_edid(BRIDGE_I2C, chip, edid) < 0) { printk(BIOS_ERR, "%s: Can't get panel's edid\n", __func__); return -1; } return 0; } -static struct panel_serializable_data ps8640_data; - static struct panel_description ps8640_bridge = { - .s = &ps8640_data, + .configure_backlight = backlight_control, + .power_on = panel_power_on, + .get_edid = bridge_ps8640_get_edid, + .disp_path = DISP_PATH_MIPI, .orientation = LB_FB_ORIENTATION_NORMAL, }; struct panel_description *get_ps8640_description(void) { mtk_i2c_bus_init(BRIDGE_I2C, I2C_SPEED_FAST); - bridge_ps8640_power_on(); - if (bridge_ps8640_get_edid(BRIDGE_I2C, &ps8640_bridge.s->edid) < 0) { - printk(BIOS_ERR, "Can't get panel's edid\n"); - return NULL; - } return &ps8640_bridge; } diff --git a/src/mainboard/google/corsola/panel_starmie.c b/src/mainboard/google/corsola/panel_starmie.c index 55e9dbf1b6..1de2c61a08 100644 --- a/src/mainboard/google/corsola/panel_starmie.c +++ b/src/mainboard/google/corsola/panel_starmie.c @@ -6,8 +6,8 @@ #include #include -#include "display.h" #include "gpio.h" +#include "panel.h" static void mipi_panel_power_on(void) { @@ -51,20 +51,26 @@ static struct panel_description starmie_panels[] = { /* K&D panel vendor and ILI9882T chip, K&D and STA panel are identical except manufacturer_name. */ [6] = { + .configure_backlight = backlight_control, .power_on = mipi_panel_power_on, .name = "STA_ILI9882T", + .disp_path = DISP_PATH_MIPI, .orientation = LB_FB_ORIENTATION_LEFT_UP, }, /* STA panel vendor and ILI9882T chip */ [9] = { + .configure_backlight = backlight_control, .power_on = mipi_panel_power_on, .name = "STA_ILI9882T", + .disp_path = DISP_PATH_MIPI, .orientation = LB_FB_ORIENTATION_LEFT_UP, }, /* STA panel vendor and HIMAX83102_J02 chip */ [10] = { + .configure_backlight = backlight_control, .power_on = mipi_panel_power_on, .name = "STA_HIMAX83102_J02", + .disp_path = DISP_PATH_MIPI, .orientation = LB_FB_ORIENTATION_LEFT_UP, }, }; @@ -75,5 +81,5 @@ struct panel_description *get_panel_description(void) if (id >= ARRAY_SIZE(starmie_panels)) return NULL; - return get_panel_from_cbfs(&starmie_panels[id]); + return &starmie_panels[id]; } diff --git a/src/soc/mediatek/common/display.c b/src/soc/mediatek/common/display.c index 72b7fe04bd..d51151ecab 100644 --- a/src/soc/mediatek/common/display.c +++ b/src/soc/mediatek/common/display.c @@ -37,6 +37,12 @@ static struct panel_serializable_data *get_mipi_cmd_from_cbfs(struct panel_descr return NULL; } +__weak int mtk_edp_init(struct edid *edid) +{ + printk(BIOS_WARNING, "%s: Not supported\n", __func__); + return -1; +} + int mtk_display_init(void) { struct edid edid; diff --git a/src/soc/mediatek/mt8186/Makefile.inc b/src/soc/mediatek/mt8186/Makefile.inc index 8fe923f294..3a3cc07ce6 100644 --- a/src/soc/mediatek/mt8186/Makefile.inc +++ b/src/soc/mediatek/mt8186/Makefile.inc @@ -38,6 +38,7 @@ ramstage-$(CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE) += ../common/bl31.c ramstage-y += ../common/ddp.c ddp.c ramstage-y += ../common/devapc.c devapc.c ramstage-y += ../common/dfd.c +ramstage-y += ../common/display.c ramstage-y += ../common/dsi.c ../common/mtk_mipi_dphy.c ramstage-y += ../common/emi.c ramstage-y += ../common/mcu.c @@ -53,6 +54,7 @@ ramstage-y += ../common/tps65132s.c ramstage-y += ../common/usb.c usb.c CPPFLAGS_common += -Isrc/soc/mediatek/mt8186/include +CPPFLAGS_common += -Isrc/soc/mediatek/common/dp/include CPPFLAGS_common += -Isrc/soc/mediatek/common/include BL31_MAKEARGS += PLAT=mt8186 diff --git a/src/soc/mediatek/mt8186/ddp.c b/src/soc/mediatek/mt8186/ddp.c index 6706ed7d00..5a5f5447ff 100644 --- a/src/soc/mediatek/mt8186/ddp.c +++ b/src/soc/mediatek/mt8186/ddp.c @@ -141,7 +141,7 @@ void mtk_ddp_init(void) write32((void *)(SMI_LARB0 + SMI_LARB_PORT_L0_OVL_RDMA0), 0); } -void mtk_ddp_mode_set(const struct edid *edid) +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path) { u32 fmt = OVL_INFMT_RGBA8888; u32 bpp = edid->framebuffer_bits_per_pixel / 8; diff --git a/src/soc/mediatek/mt8186/include/soc/ddp.h b/src/soc/mediatek/mt8186/include/soc/ddp.h index e66563d9a0..f6e690a607 100644 --- a/src/soc/mediatek/mt8186/include/soc/ddp.h +++ b/src/soc/mediatek/mt8186/include/soc/ddp.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #define SMI_LARB_PORT_L0_OVL_RDMA0 0x388 @@ -254,7 +255,4 @@ static struct disp_gamma_regs *const disp_gamma = (void *)DISP_GAMMA0_BASE; static struct disp_postmask_regs *const disp_postmask = (void *)DISP_POSTMASK0_BASE; static struct disp_dither_regs *const disp_dither = (void *)DISP_DITHER0_BASE; -void mtk_ddp_init(void); -void mtk_ddp_mode_set(const struct edid *edid); - #endif