coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mainboard.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <bootmode.h>
4 #include <cbfs.h>
5 #include <console/console.h>
6 #include <delay.h>
7 #include <device/device.h>
8 #include <device/i2c_simple.h>
9 #include <device/mmio.h>
10 #include <mipi/panel.h>
13 #include <edid.h>
14 #include <framebuffer_info.h>
15 #include <soc/display/mipi_dsi.h>
16 #include <soc/display/mdssreg.h>
19 #include <soc/qupv3_i2c_common.h>
20 #include <soc/qcom_qup_se.h>
21 #include <soc/usb/usb_common.h>
22 #include <soc/usb/qusb_phy.h>
23 #include "board.h"
24 #include <soc/addressmap.h>
25 
26 #define BRIDGE_BUS QUPV3_0_SE2
27 #define BRIDGE_SN65DSI86_CHIP 0x2d
28 #define BRIDGE_PS8640_CHIP 0x08
29 
30 static struct usb_board_data usb0_board_data = {
31  .pll_bias_control_2 = 0x22,
32  .imp_ctrl1 = 0x08,
33  .port_tune1 = 0xc5,
34 };
35 
36 static void setup_usb(void)
37 {
38  /* Assert EN_PP3300_HUB for those board variants that use it. */
39  gpio_output(GPIO(84), 1);
40 
42 }
43 
44 static void qi2s_configure_gpios(void)
45 {
46  gpio_configure(GPIO(49), GPIO49_FUNC_MI2S_1_SCK,
48 
49  gpio_configure(GPIO(50), GPIO50_FUNC_MI2S_1_WS,
51 
52  gpio_configure(GPIO(51), GPIO51_FUNC_MI2S_1_DATA0,
54 }
55 
56 static void load_qup_fw(void)
57 {
63  /*
64  * When coreboot firmware disables serial output,
65  * we still need to load console UART QUP FW for OS.
66  */
67  if (!CONFIG(CONSOLE_SERIAL))
69 
73 }
74 
75 static bool is_ps8640_bridge(void)
76 {
77  /*
78  * Because the board_id pins for the early Homestar builds were
79  * misstuffed, after we enable tri-state board_id pins, a -rev1
80  * board reports itself as -rev19, and a -rev2 board reports itself
81  * as -rev23. We need to account for those quirks here.
82  */
83  return (CONFIG(BOARD_GOOGLE_HOMESTAR) && board_id() >= 4 &&
84  board_id() != 19 && board_id() != 23) ||
85  (CONFIG(BOARD_GOOGLE_LAZOR) && board_id() >= 9) ||
86  (CONFIG(BOARD_GOOGLE_KINGOFTOWN) && board_id() >= 1) ||
87  (CONFIG(BOARD_GOOGLE_PAZQUEL) && (sku_id() & 0x4));
88 }
89 
90 static void power_on_sn65dsi86_bridge(void)
91 {
92  printk(BIOS_INFO, "%s: Bridge gpio init\n", __func__);
93 
94  /* Bridge Enable GPIO */
96 
97  /* PP3300 EDP power supply */
99 }
100 
101 static void power_on_ps8640_bridge(void)
102 {
103  printk(BIOS_INFO, "%s: Bridge gpio init\n", __func__);
104 
105  /* PP3300 EDP panel power supply */
107 
109 
110  /*
111  * According to ps8640 v1.4 spec, and the raise time of vdd33 is a bit
112  * long, so wait for 4ms after VDD33 goes high and then deassert PD.
113  */
114  mdelay(4);
115 
117 
118  /*
119  * According to ps8640 app note v0.6, wait for 2ms after VDD33 goes
120  * high and then deassert RST.
121  */
122  mdelay(2);
123 
125 }
126 
127 static void configure_mipi_panel(void)
128 {
129  int panel_id = sku_id() >> 8;
131  mdelay(5);
133  mdelay(5);
135  mdelay(15);
137  mdelay(15);
138  /*
139  * In mrbland, BOE panel_id = 3(EVT) or 4(DVT and after),
140  * it needs 15ms delay and do reset again according to spec
141  * (See in b/197300876).
142  */
143  if (CONFIG(BOARD_GOOGLE_MRBLAND) && ((panel_id == 3) || (panel_id == 4))) {
145  mdelay(5);
147  }
148  /*
149  * In mipi panel, TP_EN(GPIO 85) need pull up before
150  * GPIO_BACKLIGHT_ENABLE(GPIO12) up.
151  */
152  if (CONFIG(TROGDOR_HAS_MIPI_PANEL))
154 }
155 
157 {
158  const char *cbfs_filename = NULL;
159  int panel_id = sku_id() >> 8;
160 
161  if (CONFIG(BOARD_GOOGLE_MRBLAND)) {
162  switch (panel_id) {
163  case 3:
164  case 4:
165  cbfs_filename = "panel-BOE_TV101WUM_N53";
166  *orientation = LB_FB_ORIENTATION_LEFT_UP;
167  break;
168  case 6:
169  cbfs_filename = "panel-AUO_B101UAN08_3";
170  *orientation = LB_FB_ORIENTATION_LEFT_UP;
171  break;
172  }
173  }
174 
175  if (CONFIG(BOARD_GOOGLE_QUACKINGSTICK)) {
176  switch (panel_id) {
177  case 6:
178  cbfs_filename = "panel-AUO_B101UAN08_3";
179  *orientation = LB_FB_ORIENTATION_LEFT_UP;
180  break;
181  }
182  }
183 
184  if (CONFIG(BOARD_GOOGLE_WORMDINGLER)) {
185  switch (panel_id) {
186  case 0:
187  cbfs_filename = "panel-INX_P110ZZD_DF0";
188  *orientation = LB_FB_ORIENTATION_LEFT_UP;
189  break;
190  case 4:
191  cbfs_filename = "panel-BOE_TV110C9M_LL0";
192  *orientation = LB_FB_ORIENTATION_LEFT_UP;
193  break;
194  }
195  }
196 
197  if (!cbfs_filename)
198  return NULL;
199 
200  struct panel_serializable_data *panel = cbfs_map(cbfs_filename, NULL);
201  if (!panel) {
202  printk(BIOS_ERR, "Could not find panel data for %s!\n", cbfs_filename);
203  return NULL;
204  }
205 
206  return panel;
207 }
208 
209 static enum cb_err display_init(struct panel_serializable_data *panel)
210 {
211  uint32_t dsi_bpp = 24;
212  uint32_t lanes = 4;
213 
214  if (mdss_dsi_config(&panel->edid, lanes, dsi_bpp))
215  return CB_ERR;
216 
217  if (CONFIG(TROGDOR_HAS_MIPI_PANEL)) {
218  if (mdss_dsi_panel_initialize(panel->init))
219  return CB_ERR;
220  } else if (!is_ps8640_bridge()) {
221  /*
222  * Parade ps8640 is auto-configured based on a pre-programmed
223  * SPI-ROM. Only TI sn65dsi86 needs to be configured here.
224  */
226  &panel->edid, lanes, dsi_bpp);
227  if (CONFIG(TROGDOR_HAS_BRIDGE_BACKLIGHT))
229  }
230 
231  mdp_dsi_video_config(&panel->edid);
232  mdss_dsi_video_mode_config(&panel->edid, dsi_bpp);
234 
235  return CB_SUCCESS;
236 }
237 
238 static void display_startup(void)
239 {
240  struct panel_serializable_data edp_panel = {0};
241  struct panel_serializable_data *panel = &edp_panel;
242  enum lb_fb_orientation orientation = LB_FB_ORIENTATION_NORMAL;
243 
244  /* Always initialize this so QUP firmware is loaded for the kernel. */
246 
247  if (!display_init_required()) {
248  printk(BIOS_INFO, "Skipping display init.\n");
249  return;
250  }
251 
252  if (CONFIG(TROGDOR_HAS_MIPI_PANEL)) {
254  panel = get_mipi_panel(&orientation);
255  if (!panel)
256  return;
257  } else if (is_ps8640_bridge()) {
261  return;
262  } else {
263  enum dp_pll_clk_src ref_clk = SN65_SEL_19MHZ;
265  mdelay(250); /* Delay for the panel to be up */
268  &panel->edid) < 0)
269  return;
270  }
271 
272  printk(BIOS_INFO, "display init!\n");
274  if (display_init(panel) == CB_SUCCESS) {
275  struct fb_info *fb = fb_new_framebuffer_info_from_edid(&panel->edid, 0);
276  fb_set_orientation(fb, orientation);
277  }
278 }
279 
280 static void configure_sdhci(void)
281 {
282  /* Program eMMC drive strength to 16/16/16 mA */
283  write32((void *)SDC1_TLMM_CFG_ADDR, 0x9FFF);
284  /* Program SD card drive strength to 16/10/10 mA */
285  write32((void *)SDC2_TLMM_CFG_ADDR, 0x1FE4);
286 }
287 
288 static void mainboard_init(struct device *dev)
289 {
290  /* Take FPMCU out of reset. Power was already applied
291  in romstage and should have stabilized by now. */
292  if (CONFIG(TROGDOR_HAS_FINGERPRINT))
294 
295  setup_usb();
297  load_qup_fw();
298  display_startup();
299  configure_sdhci();
300 }
301 
302 static void mainboard_enable(struct device *dev)
303 {
304  dev->ops->init = &mainboard_init;
305 }
306 
309 };
struct chip_operations mainboard_ops
Definition: mainboard.c:19
#define GPIO_OUTPUT
Definition: gpio_ftns.h:23
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
int display_init_required(void)
Definition: bootmode.c:22
cb_err
coreboot error codes
Definition: cb_err.h:15
@ CB_ERR
Generic error code.
Definition: cb_err.h:17
@ CB_SUCCESS
Call completed successfully.
Definition: cb_err.h:16
static void * cbfs_map(const char *name, size_t *size_out)
Definition: cbfs.h:246
lb_fb_orientation
coreboot framebuffer
@ LB_FB_ORIENTATION_NORMAL
@ LB_FB_ORIENTATION_LEFT_UP
#define printk(level,...)
Definition: stdlib.h:16
void mdelay(unsigned int msecs)
Definition: delay.c:2
@ GPIO
Definition: chip.h:84
@ CONFIG
Definition: dsi_common.h:201
uint32_t board_id(void)
board_id() - Get the board version
Definition: ec_boardid.c:6
struct fb_info * fb_new_framebuffer_info_from_edid(const struct edid *edid, uintptr_t fb_addr)
Definition: edid_fill_fb.c:162
void fb_set_orientation(struct fb_info *info, enum lb_fb_orientation orientation)
Definition: edid_fill_fb.c:151
#define GPIO_FP_RST_L
Definition: board.h:48
uint32_t sku_id(void)
Definition: mainboard.c:11
void display_startup(struct device *dev)
Definition: mainboard.c:189
#define GPIO_TP_EN
Definition: board.h:37
#define GPIO_VDD_RESET_1V8
Definition: board.h:36
#define GPIO_EN_PP3300_DX_EDP
Definition: board.h:39
#define GPIO_MIPI_1V8_ENABLE
Definition: board.h:33
#define GPIO_PS8640_EDP_BRIDGE_RST_L
Definition: board.h:46
#define GPIO_PS8640_EDP_BRIDGE_PD_L
Definition: board.h:45
#define GPIO_AVEE_LCD_ENABLE
Definition: board.h:35
#define GPIO_PS8640_EDP_BRIDGE_3V3_ENABLE
Definition: board.h:47
#define GPIO_EDP_BRIDGE_ENABLE
Definition: board.h:38
#define GPIO_AVDD_LCD_ENABLE
Definition: board.h:34
static void mainboard_init(struct device *dev)
Definition: mainboard.c:288
static bool is_ps8640_bridge(void)
Definition: mainboard.c:75
static enum cb_err display_init(struct panel_serializable_data *panel)
Definition: mainboard.c:209
static void qi2s_configure_gpios(void)
Definition: mainboard.c:44
static struct panel_serializable_data * get_mipi_panel(enum lb_fb_orientation *orientation)
Definition: mainboard.c:156
#define BRIDGE_SN65DSI86_CHIP
Definition: mainboard.c:27
static void configure_sdhci(void)
Definition: mainboard.c:280
#define BRIDGE_BUS
Definition: mainboard.c:26
static struct usb_board_data usb0_board_data
Definition: mainboard.c:30
static void configure_mipi_panel(void)
Definition: mainboard.c:127
static void setup_usb(void)
Definition: mainboard.c:36
static void mainboard_enable(struct device *dev)
Definition: mainboard.c:302
static void power_on_sn65dsi86_bridge(void)
Definition: mainboard.c:90
static void power_on_ps8640_bridge(void)
Definition: mainboard.c:101
static void load_qup_fw(void)
Definition: mainboard.c:56
#define BRIDGE_PS8640_CHIP
Definition: mainboard.c:28
@ 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 uint8_t panel_id(void)
Definition: boardid.c:45
void mdp_dsi_video_config(struct edid *edid)
Definition: mdss.c:167
void mdp_dsi_video_on(void)
Definition: mdss.c:184
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
@ GPIO_8MA
Definition: gpio_common.h:73
@ GPIO_NO_PULL
Definition: gpio_common.h:62
void setup_usb_host0(void *board_data)
Definition: usb.c:137
void mdss_dsi_video_mode_config(struct edid *edid, uint32_t bpp)
Definition: dsi.c:99
enum cb_err mdss_dsi_panel_initialize(const u8 *init_cmds)
Definition: dsi.c:280
enum cb_err mdss_dsi_config(struct edid *edid, uint32_t num_of_lanes, uint32_t bpp)
Definition: dsi.c:141
@ SE_PROTOCOL_I2C
@ SE_PROTOCOL_UART
@ SE_PROTOCOL_SPI
void qupv3_se_fw_load_and_init(unsigned int bus, unsigned int protocol, unsigned int mode)
Definition: qupv3_config.c:13
@ QUPV3_0_SE3
Definition: qcom_qup_se.h:16
@ QUPV3_0_SE5
Definition: qcom_qup_se.h:18
@ QUPV3_1_SE4
Definition: qcom_qup_se.h:23
@ QUPV3_1_SE5
Definition: qcom_qup_se.h:24
@ QUPV3_1_SE2
Definition: qcom_qup_se.h:21
@ QUPV3_0_SE1
Definition: qcom_qup_se.h:14
@ QUPV3_1_SE3
Definition: qcom_qup_se.h:22
@ QUPV3_0_SE4
Definition: qcom_qup_se.h:17
@ QUPV3_1_SE1
Definition: qcom_qup_se.h:20
void sn65dsi86_backlight_enable(uint8_t bus, uint8_t chip)
void sn65dsi86_bridge_init(uint8_t bus, uint8_t chip, enum dp_pll_clk_src ref_clk)
void sn65dsi86_bridge_configure(uint8_t bus, uint8_t chip, struct edid *edid, uint32_t num_of_lanes, uint32_t dsi_bpp)
enum cb_err sn65dsi86_bridge_read_edid(uint8_t bus, uint8_t chip, struct edid *out)
dp_pll_clk_src
@ SN65_SEL_19MHZ
void i2c_init(unsigned int bus)
Definition: i2c.c:198
void gpio_configure(gpio_t gpio, uint32_t func, uint32_t pull, uint32_t drive_str, uint32_t enable)
Definition: gpio.c:7
#define SDC1_TLMM_CFG_ADDR
Definition: addressmap.h:13
#define SDC2_TLMM_CFG_ADDR
Definition: addressmap.h:61
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
void(* enable_dev)(struct device *dev)
Definition: device.h:24
void(* init)(struct device *dev)
Definition: device.h:42
Definition: device.h:107
struct device_operations * ops
Definition: device.h:143
struct lb_framebuffer fb
Definition: edid_fill_fb.c:13
struct edid edid
Definition: panel.h:30
u32 pll_bias_control_2
Definition: qusb_phy.h:44