summaryrefslogtreecommitdiff
path: root/src/mainboard/google/corsola/display.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainboard/google/corsola/display.c')
-rw-r--r--src/mainboard/google/corsola/display.c215
1 files changed, 98 insertions, 117 deletions
diff --git a/src/mainboard/google/corsola/display.c b/src/mainboard/google/corsola/display.c
index 22d8c399fd..697db0759e 100644
--- a/src/mainboard/google/corsola/display.c
+++ b/src/mainboard/google/corsola/display.c
@@ -2,163 +2,141 @@
#include <assert.h>
#include <boardid.h>
+#include <cbfs.h>
#include <console/console.h>
#include <delay.h>
-#include <drivers/analogix/anx7625/anx7625.h>
-#include <drivers/parade/ps8640/ps8640.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/regulator.h>
#include <soc/i2c.h>
#include <soc/mtcmos.h>
#include "display.h"
#include "gpio.h"
-/* Bridge functions */
-static void bridge_ps8640_power_on(void)
+static void backlight_control(void)
{
- /*
- * PS8640 power-on sequence is described in chapter 14, PS8640_DS_V1.4_20200210.docx
- * - set VDD12 to be 1.2V
- * - delay 100us
- * - set VDD33 to be 3.3V
- * - pull hign PD#
- * - pull down RST#
- * - delay 2ms
- * - pull high RST#
- * - delay more than 50ms (55ms for margin)
- * - pull down RST#
- * - delay more than 50ms (55ms for margin)
- * - pull high RST#
- */
-
- /* Set VRF12 to 1.2V and VCN33 to 3.3V */
- mainboard_set_regulator_voltage(MTK_REGULATOR_VRF12, 1200000);
- udelay(100);
- mainboard_set_regulator_voltage(MTK_REGULATOR_VCN33, 3300000);
- udelay(200);
-
- /* Turn on bridge */
- gpio_output(GPIO_EDPBRDG_PWREN, 1);
- gpio_output(GPIO_EDPBRDG_RST_L, 0);
- mdelay(2);
- gpio_output(GPIO_EDPBRDG_RST_L, 1);
- mdelay(55);
- gpio_output(GPIO_EDPBRDG_RST_L, 0);
- mdelay(55);
- gpio_output(GPIO_EDPBRDG_RST_L, 1);
+ /* Disable backlight before turning on bridge */
+ gpio_output(GPIO_AP_EDP_BKLTEN, 0);
+ gpio_output(GPIO_BL_PWM_1V8, 0);
+ gpio_output(GPIO_EN_PP3300_DISP_X, 1);
}
-static int bridge_ps8640_get_edid(u8 i2c_bus, struct edid *edid)
+int panel_pmic_reg_mask(unsigned int bus, uint8_t chip, uint8_t addr,
+ uint8_t val, uint8_t mask)
{
- const u8 chip = 0x8;
+ uint8_t msg = 0;
- if (ps8640_init(i2c_bus, chip) < 0) {
- printk(BIOS_ERR, "%s: Can't init PS8640 bridge\n", __func__);
+ if (i2c_read_field(bus, chip, addr, &msg, 0xFF, 0) < 0) {
+ printk(BIOS_ERR, "%s: Failed to read i2c(%u): addr(%u)\n",
+ __func__, bus, addr);
return -1;
}
- if (ps8640_get_edid(i2c_bus, chip, edid) < 0) {
- printk(BIOS_ERR, "%s: Can't get panel's edid\n", __func__);
- return -1;
- }
- return 0;
-}
-static int bridge_ps8640_post_power_on(u8 i2c_bus, struct edid *edid)
-{
- /* Do nothing */
- return 0;
-}
+ msg &= ~mask;
+ msg |= val;
-static void bridge_anx7625_power_on(void)
-{
- /* Turn on bridge */
- gpio_output(GPIO_EDPBRDG_RST_L, 0);
- gpio_output(GPIO_EN_PP1000_EDPBRDG, 1);
- gpio_output(GPIO_EN_PP1800_EDPBRDG, 1);
- gpio_output(GPIO_EN_PP3300_EDPBRDG, 1);
- mdelay(14);
- gpio_output(GPIO_EDPBRDG_PWREN, 1);
- mdelay(80);
- gpio_output(GPIO_EDPBRDG_RST_L, 1);
+ return i2c_write_field(bus, chip, addr, msg, 0xFF, 0);
}
-static int bridge_anx7625_get_edid(u8 i2c_bus, struct edid *edid)
+void tps65132s_program_eeprom(void)
{
- if (anx7625_init(i2c_bus) < 0) {
- printk(BIOS_ERR, "%s: Can't init ANX7625 bridge\n", __func__);
- return -1;
- }
- if (anx7625_dp_get_edid(i2c_bus, edid) < 0) {
- printk(BIOS_ERR, "%s: Can't get panel's edid\n", __func__);
- return -1;
+ u8 value = 0;
+ u8 value1 = 0;
+
+ /* Initialize I2C6 for PMIC TPS65132 */
+ mtk_i2c_bus_init(PMIC_TPS65132_I2C, I2C_SPEED_FAST);
+ mdelay(10);
+
+ /* EN_PP6000_MIPI_DISP */
+ gpio_output(GPIO_EN_PP3300_DISP_X, 1);
+ /* EN_PP6000_MIPI_DISP_150MA */
+ gpio_output(GPIO_EN_PP3300_SDBRDG_X, 1);
+ mdelay(10);
+
+ i2c_read_field(PMIC_TPS65132_I2C, PMIC_TPS65132_SLAVE, 0x00, &value, 0xFF, 0);
+ i2c_read_field(PMIC_TPS65132_I2C, PMIC_TPS65132_SLAVE, 0x01, &value1, 0xFF, 0);
+
+ if (value != 0x14 || value1 != 0x14) {
+ printk(BIOS_INFO, "Set AVDD AVEE 6.0V to EEPROM Data in first time\n");
+
+ /* Set AVDD = 6.0V */
+ if (panel_pmic_reg_mask(PMIC_TPS65132_I2C, PMIC_TPS65132_SLAVE, 0x00, 0x14,
+ 0x1F) < 0)
+ return;
+
+ /* Set AVEE = -6.0V */
+ if (panel_pmic_reg_mask(PMIC_TPS65132_I2C, PMIC_TPS65132_SLAVE, 0x01, 0x14,
+ 0x1F) < 0)
+ return;
+
+ /* Set EEPROM Data */
+ if (panel_pmic_reg_mask(PMIC_TPS65132_I2C, PMIC_TPS65132_SLAVE, 0xFF, 0x80,
+ 0xFC) < 0)
+ return;
+ mdelay(50);
}
- return 0;
+ /* EN_PP6000_MIPI_DISP */
+ gpio_output(GPIO_EN_PP3300_DISP_X, 0);
+ /* EN_PP6000_MIPI_DISP_150MA */
+ gpio_output(GPIO_EN_PP3300_SDBRDG_X, 0);
+ mdelay(5);
}
-static int bridge_anx7625_post_power_on(u8 i2c_bus, struct edid *edid)
+struct panel_description *get_panel_from_cbfs(struct panel_description *desc)
{
- return anx7625_dp_start(i2c_bus, edid);
+ 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;
}
-/* Display function */
-static void backlight_control(void)
+static struct panel_description *get_active_panel(void)
{
- /* Disable backlight before turning on bridge */
- gpio_output(GPIO_AP_EDP_BKLTEN, 0);
- gpio_output(GPIO_BL_PWM_1V8, 0);
- gpio_output(GPIO_EN_PP3300_DISP_X, 1);
+ if (CONFIG(BOARD_GOOGLE_KINGLER_COMMON))
+ if (CONFIG(BOARD_GOOGLE_STEELIX) && board_id() < 2)
+ return get_ps8640_description();
+ else
+ return get_anx7625_description();
+ else if (CONFIG(BOARD_GOOGLE_KRABBY_COMMON))
+ return get_ps8640_description();
+ else if (CONFIG(BOARD_GOOGLE_STARYU_COMMON))
+ return get_panel_description();
+ else
+ return NULL;
}
-static const struct edp_bridge anx7625_bridge = {
- .power_on = bridge_anx7625_power_on,
- .get_edid = bridge_anx7625_get_edid,
- .post_power_on = bridge_anx7625_post_power_on,
-};
-
-static const struct edp_bridge ps8640_bridge = {
- .power_on = bridge_ps8640_power_on,
- .get_edid = bridge_ps8640_get_edid,
- .post_power_on = bridge_ps8640_post_power_on,
-};
-
int configure_display(void)
{
- struct edid edid;
- const u8 i2c_bus = I2C0;
- const struct edp_bridge *bridge = NULL;
- uint32_t board_version = board_id();
-
- if (CONFIG(BOARD_GOOGLE_KINGLER_COMMON))
- if (CONFIG(BOARD_GOOGLE_STEELIX) && board_version < 2)
- bridge = &ps8640_bridge;
- else
- bridge = &anx7625_bridge;
- else if (CONFIG(BOARD_GOOGLE_KRABBY_COMMON))
- bridge = &ps8640_bridge;
+ const struct panel_description *panel = get_active_panel();
- if (!bridge)
+ if (!panel)
return -1;
printk(BIOS_INFO, "%s: Starting display init\n", __func__);
- mtk_i2c_bus_init(i2c_bus, I2C_SPEED_FAST);
-
/* Set up backlight control pins as output pin and power-off by default */
backlight_control();
- assert(bridge->power_on);
- bridge->power_on();
-
- assert(bridge->get_edid);
- if (bridge->get_edid(i2c_bus, &edid) < 0) {
- printk(BIOS_ERR, "%s: Failed to get edid\n", __func__);
- return -1;
- }
+ 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";
@@ -176,19 +154,22 @@ int configure_display(void)
MIPI_DSI_MODE_LPM |
MIPI_DSI_MODE_EOT_PACKET);
- if (mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, 4, &edid, NULL) < 0) {
+ 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;
}
- assert(bridge->post_power_on);
- if (bridge->post_power_on(i2c_bus, &edid) < 0) {
+ 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);
- fb_new_framebuffer_info_from_edid(&edid, (uintptr_t)0);
+ struct fb_info *info = fb_new_framebuffer_info_from_edid(&edid,
+ (uintptr_t)0);
+ if (info)
+ fb_set_orientation(info, panel->orientation);
return 0;
}