summaryrefslogtreecommitdiff
path: root/src/soc/mediatek
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/mediatek')
-rw-r--r--src/soc/mediatek/common/display.c116
-rw-r--r--src/soc/mediatek/common/include/soc/display.h32
-rw-r--r--src/soc/mediatek/mt8188/Makefile.inc1
-rw-r--r--src/soc/mediatek/mt8188/include/soc/ddp.h10
4 files changed, 150 insertions, 9 deletions
diff --git a/src/soc/mediatek/common/display.c b/src/soc/mediatek/common/display.c
new file mode 100644
index 0000000000..72b7fe04bd
--- /dev/null
+++ b/src/soc/mediatek/common/display.c
@@ -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;
+}
diff --git a/src/soc/mediatek/common/include/soc/display.h b/src/soc/mediatek/common/include/soc/display.h
new file mode 100644
index 0000000000..61bc21fc98
--- /dev/null
+++ b/src/soc/mediatek/common/include/soc/display.h
@@ -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
diff --git a/src/soc/mediatek/mt8188/Makefile.inc b/src/soc/mediatek/mt8188/Makefile.inc
index 6a643b0057..4731fab14c 100644
--- a/src/soc/mediatek/mt8188/Makefile.inc
+++ b/src/soc/mediatek/mt8188/Makefile.inc
@@ -37,6 +37,7 @@ ramstage-y += cpu_input_gating.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/dp/dp_intf.c ../common/dp/dptx.c ../common/dp/dptx_hal.c dp_intf.c
ramstage-y += ../common/dpm.c
ramstage-$(CONFIG_DPM_FOUR_CHANNEL) += ../common/dpm_4ch.c
diff --git a/src/soc/mediatek/mt8188/include/soc/ddp.h b/src/soc/mediatek/mt8188/include/soc/ddp.h
index da14a2c4e7..94fdb810a7 100644
--- a/src/soc/mediatek/mt8188/include/soc/ddp.h
+++ b/src/soc/mediatek/mt8188/include/soc/ddp.h
@@ -5,6 +5,7 @@
#include <soc/addressmap.h>
#include <soc/ddp_common.h>
+#include <soc/display.h>
#include <types.h>
#define MAIN_PATH_OVL_NR 1
@@ -282,13 +283,4 @@ enum {
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