Attention is currently required from: Hung-Te Lin, Yu-Ping Wu.
Yidi Lin has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/79777?usp=email )
Change subject: mb/google/corsola: use common configure_display ......................................................................
mb/google/corsola: use common configure_display
TEST=check FW screen on Steelix, Tentacruel and Starmie
Change-Id: I429218d59389a6ab86b522dd597c07fa5b8ea821 Signed-off-by: Yidi Lin yidilin@chromium.org --- M src/mainboard/google/corsola/Makefile.inc M src/mainboard/google/corsola/boardid.c D src/mainboard/google/corsola/display.c M src/mainboard/google/corsola/mainboard.c A src/mainboard/google/corsola/panel.c R src/mainboard/google/corsola/panel.h M src/mainboard/google/corsola/panel_anx7625.c M src/mainboard/google/corsola/panel_ps8640.c M src/mainboard/google/corsola/panel_starmie.c M src/soc/mediatek/common/display.c M src/soc/mediatek/mt8186/Makefile.inc M src/soc/mediatek/mt8186/ddp.c M src/soc/mediatek/mt8186/include/soc/ddp.h 13 files changed, 129 insertions(+), 168 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/77/79777/1
diff --git a/src/mainboard/google/corsola/Makefile.inc b/src/mainboard/google/corsola/Makefile.inc index dce226f..5483167 100644 --- a/src/mainboard/google/corsola/Makefile.inc +++ b/src/mainboard/google/corsola/Makefile.inc @@ -19,8 +19,8 @@ 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 59c9f5c..443c3d1 100644 --- a/src/mainboard/google/corsola/boardid.c +++ b/src/mainboard/google/corsola/boardid.c @@ -6,7 +6,7 @@ #include <ec/google/chromeec/ec.h> #include <soc/auxadc.h>
-#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 c7a6578..0000000 --- a/src/mainboard/google/corsola/display.c +++ /dev/null @@ -1,131 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <boardid.h> -#include <cbfs.h> -#include <console/console.h> -#include <device/i2c_simple.h> -#include <edid.h> -#include <gpio.h> -#include <soc/ddp.h> -#include <soc/dsi.h> -#include <soc/gpio_common.h> -#include <soc/mtcmos.h> - -#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 37f3a70..5c2abc8 100644 --- a/src/mainboard/google/corsola/mainboard.c +++ b/src/mainboard/google/corsola/mainboard.c @@ -6,13 +6,14 @@ #include <fw_config.h> #include <gpio.h> #include <soc/bl31.h> +#include <soc/display.h> #include <soc/i2c.h> #include <soc/msdc.h> #include <soc/spm.h> #include <soc/usb.h>
-#include "display.h" #include "gpio.h" +#include "panel.h"
static void configure_alc1019(void) { diff --git a/src/mainboard/google/corsola/panel.c b/src/mainboard/google/corsola/panel.c new file mode 100644 index 0000000..71f154d --- /dev/null +++ b/src/mainboard/google/corsola/panel.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <boardid.h> +#include <cbfs.h> +#include <console/console.h> +#include <device/i2c_simple.h> +#include <edid.h> +#include <gpio.h> +#include <soc/ddp.h> +#include <soc/dsi.h> +#include <soc/gpio_common.h> +#include <soc/mtcmos.h> + +#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_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; +} + +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 70% rename from src/mainboard/google/corsola/display.h rename to src/mainboard/google/corsola/panel.h index 7631bb9..ba2097d 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 <edid.h> -#include <mipi/panel.h> +#include <soc/display.h> #include <soc/i2c.h>
#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); diff --git a/src/mainboard/google/corsola/panel_anx7625.c b/src/mainboard/google/corsola/panel_anx7625.c index 7b50e47..2ff0ed2 100644 --- a/src/mainboard/google/corsola/panel_anx7625.c +++ b/src/mainboard/google/corsola/panel_anx7625.c @@ -7,8 +7,8 @@ #include <gpio.h> #include <soc/i2c.h>
-#include "display.h" #include "gpio.h" +#include "panel.h"
static void bridge_anx7625_power_on(void) { @@ -23,39 +23,45 @@ 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(const struct panel_description *panel) { - 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, &panel->s->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 panel_description *panel) { - return anx7625_dp_start(i2c_bus, edid); + return anx7625_dp_start(BRIDGE_I2C, &panel->s->edid); +} + +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_serializable_data anx7625_data;
static struct panel_description anx7625_bridge = { .s = &anx7625_data, + .configure_panel_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 bb1e4eb..6a87c73 100644 --- a/src/mainboard/google/corsola/panel_ps8640.c +++ b/src/mainboard/google/corsola/panel_ps8640.c @@ -8,8 +8,8 @@ #include <soc/i2c.h> #include <soc/regulator.h>
-#include "display.h" #include "gpio.h" +#include "panel.h"
static void bridge_ps8640_power_on(void) { @@ -45,15 +45,22 @@ 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(const struct panel_description *panel) { 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, &panel->s->edid) < 0) { printk(BIOS_ERR, "%s: Can't get panel's edid\n", __func__); return -1; } @@ -64,16 +71,15 @@
static struct panel_description ps8640_bridge = { .s = &ps8640_data, + .configure_panel_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 55e9dbf..28d3e86 100644 --- a/src/mainboard/google/corsola/panel_starmie.c +++ b/src/mainboard/google/corsola/panel_starmie.c @@ -6,8 +6,8 @@ #include <soc/regulator.h> #include <soc/tps65132s.h>
-#include "display.h" #include "gpio.h" +#include "panel.h"
static void mipi_panel_power_on(void) { @@ -51,20 +51,26 @@ /* K&D panel vendor and ILI9882T chip, K&D and STA panel are identical except manufacturer_name. */ [6] = { + .configure_panel_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_panel_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_panel_backlight = backlight_control, .power_on = mipi_panel_power_on, .name = "STA_HIMAX83102_J02", + .disp_path = DISP_PATH_MIPI, .orientation = LB_FB_ORIENTATION_LEFT_UP, }, }; diff --git a/src/soc/mediatek/common/display.c b/src/soc/mediatek/common/display.c index 79651d5..e3051b4 100644 --- a/src/soc/mediatek/common/display.c +++ b/src/soc/mediatek/common/display.c @@ -10,6 +10,12 @@ #include <soc/dsi.h> #include <soc/mtcmos.h>
+__weak int mtk_edp_init(struct edid *edid) +{ + printk(BIOS_WARNING, "%s: Not supported\n", __func__); + return -1; +} + int configure_display(void) { struct edid edid; diff --git a/src/soc/mediatek/mt8186/Makefile.inc b/src/soc/mediatek/mt8186/Makefile.inc index 8fe923f..3a3cc07 100644 --- a/src/soc/mediatek/mt8186/Makefile.inc +++ b/src/soc/mediatek/mt8186/Makefile.inc @@ -38,6 +38,7 @@ 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/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 6706ed7..5a5f544 100644 --- a/src/soc/mediatek/mt8186/ddp.c +++ b/src/soc/mediatek/mt8186/ddp.c @@ -141,7 +141,7 @@ 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 e66563d..76ca6e1 100644 --- a/src/soc/mediatek/mt8186/include/soc/ddp.h +++ b/src/soc/mediatek/mt8186/include/soc/ddp.h @@ -255,6 +255,6 @@ 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); +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path);
#endif