coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
display.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <assert.h>
4 #include <console/console.h>
5 #include <delay.h>
8 #include <gpio.h>
9 #include <soc/ddp.h>
10 #include <soc/dsi.h>
11 #include <soc/gpio_common.h>
12 #include <soc/regulator.h>
13 #include <soc/i2c.h>
14 #include <soc/mtcmos.h>
15 
16 #include "display.h"
17 #include "gpio.h"
18 
19 /* Bridge functions */
20 static void bridge_ps8640_power_on(void)
21 {
22  /*
23  * PS8640 power-on sequence is described in chapter 14, PS8640_DS_V1.4_20200210.docx
24  * - set VDD12 to be 1.2V
25  * - set VDD33 to be 3.3V
26  * - pull hign PD#
27  * - pull down RST#
28  * - delay 2ms
29  * - pull high RST#
30  * - delay more than 50ms (55ms for margin)
31  * - pull down RST#
32  * - delay more than 50ms (55ms for margin)
33  * - pull high RST#
34  */
35 
36  /* Set VRF12 to 1.2V and VCN33 to 3.3V */
39  udelay(200);
40 
41  /* Turn on bridge */
44  mdelay(2);
46  mdelay(55);
48  mdelay(55);
50 }
51 
53 {
54  const u8 chip = 0x8;
55 
56  if (ps8640_init(i2c_bus, chip) < 0) {
57  printk(BIOS_ERR, "%s: Can't init PS8640 bridge\n", __func__);
58  return -1;
59  }
60  if (ps8640_get_edid(i2c_bus, chip, edid) < 0) {
61  printk(BIOS_ERR, "%s: Can't get panel's edid\n", __func__);
62  return -1;
63  }
64  return 0;
65 }
66 
68 {
69  /* Do nothing */
70  return 0;
71 }
72 
73 static void bridge_anx7625_power_on(void)
74 {
75  /* Turn on bridge */
80  mdelay(14);
82  mdelay(10);
84 }
85 
87 {
88  if (anx7625_init(i2c_bus) < 0) {
89  printk(BIOS_ERR, "%s: Can't init ANX7625 bridge\n", __func__);
90  return -1;
91  }
92  if (anx7625_dp_get_edid(i2c_bus, edid) < 0) {
93  printk(BIOS_ERR, "%s: Can't get panel's edid\n", __func__);
94  return -1;
95  }
96  return 0;
97 }
98 
100 {
101  return anx7625_dp_start(i2c_bus, edid);
102 }
103 
104 /* Display function */
105 static void backlight_control(void)
106 {
107  /* Disable backlight before turning on bridge */
111 }
112 
113 static const struct edp_bridge anx7625_bridge = {
115  .get_edid = bridge_anx7625_get_edid,
116  .post_power_on = bridge_anx7625_post_power_on,
117 };
118 
119 static const struct edp_bridge ps8640_bridge = {
121  .get_edid = bridge_ps8640_get_edid,
122  .post_power_on = bridge_ps8640_post_power_on,
123 };
124 
125 _Static_assert(CONFIG(BOARD_GOOGLE_KINGLER_COMMON) + CONFIG(BOARD_GOOGLE_KRABBY_COMMON) == 1,
126  "Exactly one of KINGLER and KRABBY must be set");
127 
129 {
130  struct edid edid;
131  const u8 i2c_bus = I2C0;
132  const struct edp_bridge *bridge;
133 
134  if (CONFIG(BOARD_GOOGLE_KINGLER_COMMON))
136  else /* BOARD_GOOGLE_KRABBY_COMMON */
138 
139  printk(BIOS_INFO, "%s: Starting display init\n", __func__);
140 
142 
143  /* Set up backlight control pins as output pin and power-off by default */
145 
146  assert(bridge->power_on);
147  bridge->power_on();
148 
149  assert(bridge->get_edid);
150  if (bridge->get_edid(i2c_bus, &edid) < 0) {
151  printk(BIOS_ERR, "%s: Failed to get edid\n", __func__);
152  return -1;
153  }
154 
155  const char *name = edid.ascii_string;
156  if (name[0] == '\0')
157  name = "unknown name";
158  printk(BIOS_INFO, "%s: '%s %s' %dx%d@%dHz\n", __func__,
160  edid.mode.refresh);
161 
164 
166  mtk_ddp_init();
167  u32 mipi_dsi_flags = (MIPI_DSI_MODE_VIDEO |
171 
172  if (mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, 4, &edid, NULL) < 0) {
173  printk(BIOS_ERR, "%s: Failed in DSI init\n", __func__);
174  return -1;
175  }
176 
177  if (bridge->post_power_on(i2c_bus, &edid) < 0) {
178  printk(BIOS_ERR, "%s: Failed to post power on bridge\n", __func__);
179  return -1;
180  }
181 
184 
185  return 0;
186 }
int anx7625_init(uint8_t bus)
Definition: anx7625.c:866
int anx7625_dp_get_edid(uint8_t bus, struct edid *out)
Definition: anx7625.c:845
int anx7625_dp_start(uint8_t bus, const struct edid *edid)
Definition: anx7625.c:828
const char * name
Definition: mmu.c:92
#define assert(statement)
Definition: assert.h:74
void mainboard_set_regulator_vol(enum mtk_regulator regulator, uint32_t voltage_uv)
Definition: regulator.c:41
#define printk(level,...)
Definition: stdlib.h:16
void mdelay(unsigned int msecs)
Definition: delay.c:2
@ CONFIG
Definition: dsi_common.h:201
@ MIPI_DSI_FMT_RGB888
Definition: dsi_common.h:13
@ MIPI_DSI_MODE_EOT_PACKET
Definition: dsi_common.h:39
@ MIPI_DSI_MODE_VIDEO_SYNC_PULSE
Definition: dsi_common.h:25
@ MIPI_DSI_MODE_VIDEO
Definition: dsi_common.h:21
@ MIPI_DSI_MODE_LPM
Definition: dsi_common.h:43
struct fb_info * fb_new_framebuffer_info_from_edid(const struct edid *edid, uintptr_t fb_addr)
Definition: edid_fill_fb.c:162
#define GPIO_BL_PWM_1V8
Definition: mainboard.c:54
#define GPIO_AP_EDP_BKLTEN
Definition: mainboard.c:53
#define GPIO_EDPBRDG_PWREN
Definition: mainboard.c:47
#define GPIO_EN_PP1000_EDPBRDG
Definition: mainboard.c:51
#define GPIO_EN_PP3300_DISP_X
Definition: mainboard.c:30
static struct tpm_chip chip
Definition: tis.c:17
@ I2C_SPEED_FAST
Definition: i2c.h:45
void edid_set_framebuffer_bits_per_pixel(struct edid *edid, int fb_bpp, int row_byte_alignment)
Definition: edid.c:1667
void gpio_output(gpio_t gpio, int value)
Definition: gpio.c:194
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
static int bridge_anx7625_get_edid(u8 i2c_bus, struct edid *edid)
Definition: display.c:86
static void bridge_anx7625_power_on(void)
Definition: display.c:73
static int bridge_anx7625_post_power_on(u8 i2c_bus, struct edid *edid)
Definition: display.c:99
static const struct edp_bridge anx7625_bridge
Definition: display.c:113
static int bridge_ps8640_post_power_on(u8 i2c_bus, struct edid *edid)
Definition: display.c:67
static void bridge_ps8640_power_on(void)
Definition: display.c:20
_Static_assert(CONFIG(BOARD_GOOGLE_KINGLER_COMMON)+CONFIG(BOARD_GOOGLE_KRABBY_COMMON)==1, "Exactly one of KINGLER and KRABBY must be set")
int configure_display(void)
Definition: display.c:128
static int bridge_ps8640_get_edid(u8 i2c_bus, struct edid *edid)
Definition: display.c:52
static void backlight_control(void)
Definition: display.c:105
static const struct edp_bridge ps8640_bridge
Definition: display.c:119
#define GPIO_EN_PP1800_EDPBRDG
Definition: gpio.h:38
#define GPIO_EN_PP3300_EDPBRDG
Definition: gpio.h:39
#define GPIO_EDPBRDG_RST_L
Definition: gpio.h:36
int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, const u8 *init_commands)
Definition: dsi.c:360
void mtk_ddp_init(void)
Definition: ddp.c:61
void mtk_ddp_mode_set(const struct edid *edid)
Definition: ddp.c:66
void mtcmos_display_power_on(void)
Definition: mtcmos.c:44
void mtcmos_protect_display_bus(void)
Definition: mtcmos.c:14
static const PCI_SUBCLASS bridge[]
Definition: pci_class.c:72
int ps8640_init(uint8_t bus, uint8_t chip)
Definition: ps8640.c:45
int ps8640_get_edid(uint8_t bus, uint8_t chip, struct edid *out)
Definition: ps8640.c:11
@ MTK_REGULATOR_VRF12
Definition: regulator.h:21
@ MTK_REGULATOR_VCN33
Definition: regulator.h:22
void mtk_i2c_bus_init(uint8_t bus)
Definition: i2c.c:65
@ I2C0
Definition: i2c.h:50
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
uint8_t u8
Definition: stdint.h:45
unsigned int refresh
Definition: edid.h:24
unsigned int va
Definition: edid.h:30
unsigned int ha
Definition: edid.h:25
Definition: edid.h:49
char ascii_string[EDID_ASCII_STRING_LENGTH+1]
Definition: edid.h:85
char manufacturer_name[3+1]
Definition: edid.h:86
struct edid_mode mode
Definition: edid.h:72
void(* power_on)(void)
Definition: display.h:9
Definition: i2c.c:65
void udelay(uint32_t us)
Definition: udelay.c:15