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 <assert.h>
4 #include <bl31.h>
5 #include <boardid.h>
6 #include <bootmode.h>
7 #include <cbfs.h>
8 #include <console/console.h>
9 #include <delay.h>
10 #include <device/device.h>
11 #include <ec/google/chromeec/ec.h>
12 #include <edid.h>
13 #include <framebuffer_info.h>
14 #include <gpio.h>
15 #include <soc/ddp.h>
16 #include <soc/dsi.h>
17 #include <soc/gpio.h>
18 #include <soc/mmu_operations.h>
19 #include <soc/mtcmos.h>
20 #include <soc/spm.h>
21 #include <soc/usb.h>
22 #include <string.h>
23 
24 #include "gpio.h"
25 #include "panel.h"
26 
27 #include <arm-trusted-firmware/include/export/plat/mediatek/common/plat_params_exp.h>
28 
29 static void configure_emmc(void)
30 {
31  const gpio_t emmc_pin[] = {
32  GPIO(MSDC0_DAT0), GPIO(MSDC0_DAT1),
33  GPIO(MSDC0_DAT2), GPIO(MSDC0_DAT3),
34  GPIO(MSDC0_DAT4), GPIO(MSDC0_DAT5),
35  GPIO(MSDC0_DAT6), GPIO(MSDC0_DAT7),
36  GPIO(MSDC0_CMD), GPIO(MSDC0_RSTB),
37  };
38 
39  for (size_t i = 0; i < ARRAY_SIZE(emmc_pin); i++)
41 }
42 
43 static void configure_usb(void)
44 {
46 }
47 
48 static void configure_audio(void)
49 {
50  /* Audio PWR*/
52 
53  /* SoC I2S */
54  gpio_set_mode(GPIO(CAM_RST0), PAD_CAM_RST0_FUNC_I2S2_LRCK);
55  gpio_set_mode(GPIO(CAM_PDN1), PAD_CAM_PDN1_FUNC_I2S2_BCK);
56  gpio_set_mode(GPIO(CAM_PDN0), PAD_CAM_PDN0_FUNC_I2S2_MCK);
57  gpio_set_mode(GPIO(EINT3), PAD_EINT3_FUNC_I2S3_DO);
58 }
59 
60 static void configure_ec(void)
61 {
62  /* EC may need SKU ID to identify if it is clamshell or convertible. */
63  if (CONFIG(BOARD_GOOGLE_JACUZZI_COMMON))
65 }
66 
67 /* Default implementation for boards without panels defined yet. */
69 {
70  printk(BIOS_ERR, "%s: ERROR: No panels defined for board: %s.\n",
71  __func__, CONFIG_MAINBOARD_PART_NUMBER);
72  return NULL;
73 }
74 
75 /* Set up backlight control pins as output pin and power-off by default */
76 static void configure_panel_backlight(void)
77 {
78  gpio_output(GPIO(PERIPHERAL_EN13), 0);
79  gpio_output(GPIO(DISP_PWM), 0);
80 }
81 
82 static void power_on_panel(struct panel_description *panel)
83 {
84  if (panel->power_on) {
85  panel->power_on();
86  return;
87  }
88 
89  /* Default power sequence for most panels. */
95  mdelay(15);
97  mdelay(6);
98 }
99 
101 {
102  /* The CBFS name will be panel-{MANUFACTURER}-${PANEL_NAME},
103  * where MANUFACTURER is 3 characters and PANEL_NAME is usually
104  * 13 characters.
105  */
106  char cbfs_name[64];
107  static union {
108  u8 raw[4 * 1024]; /* Most panels only need < 2K. */
109  struct panel_serializable_data s;
110  } buffer;
111 
112  if (!desc->name)
113  return NULL;
114 
115  snprintf(cbfs_name, sizeof(cbfs_name), "panel-%s", desc->name);
116  if (cbfs_load(cbfs_name, buffer.raw, sizeof(buffer)))
117  desc->s = &buffer.s;
118  else
119  printk(BIOS_ERR, "Missing %s in CBFS.\n", cbfs_name);
120 
121  return desc->s ? desc : NULL;
122 }
123 
125 {
126  /* TODO(hungte) Create a dedicated panel_id() in board_id.c */
127  int panel_id = sku_id() >> 4 & 0x0F;
128 
130  if (!panel) {
131  printk(BIOS_ERR, "%s: Panel %d is not supported.\n",
132  __func__, panel_id);
133  return NULL;
134  }
135  assert(panel->s);
136 
137  const struct edid *edid = &panel->s->edid;
138  const char *name = edid->ascii_string;
139  if (name[0] == '\0')
140  name = "unknown name";
141  printk(BIOS_INFO, "%s: Found ID %d: '%s %s' %dx%d@%dHz\n", __func__,
143  edid->mode.va, edid->mode.refresh);
144  return panel;
145 }
146 
147 static bool configure_display(void)
148 {
149  struct panel_description *panel = get_active_panel();
150  if (!panel)
151  return false;
152 
156  power_on_panel(panel);
157 
158  struct edid *edid = &panel->s->edid;
160  mtk_ddp_init();
161  u32 mipi_dsi_flags = (MIPI_DSI_MODE_VIDEO |
164  if (CONFIG(DRIVER_ANALOGIX_ANX7625))
165  mipi_dsi_flags |= MIPI_DSI_MODE_EOT_PACKET |
167  if (mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, 4, edid,
168  panel->s->init) < 0) {
169  printk(BIOS_ERR, "%s: Failed in DSI init.\n", __func__);
170  return false;
171  }
172 
173  if (panel->post_power_on)
174  panel->post_power_on();
175 
178  if (info)
180 
181  return true;
182 }
183 
184 static void register_reset_to_bl31(void)
185 {
186  static struct bl_aux_param_gpio param_reset = {
187  .h = { .type = BL_AUX_PARAM_MTK_RESET_GPIO },
188  .gpio = { .polarity = ARM_TF_GPIO_LEVEL_HIGH },
189  };
190 
191  param_reset.gpio.index = GPIO_RESET.id;
192  register_bl31_aux_param(&param_reset.h);
193 }
194 
195 static void mainboard_init(struct device *dev)
196 {
197  if (display_init_required()) {
198  printk(BIOS_INFO, "%s: Starting display init.\n", __func__);
199  if (!configure_display())
200  printk(BIOS_ERR, "%s: Failed to init display.\n",
201  __func__);
202  } else {
203  printk(BIOS_INFO, "%s: Skipped display init.\n", __func__);
204  }
205 
206  configure_emmc();
207  configure_usb();
208  configure_audio();
209  configure_ec();
210  if (spm_init())
212  "SPM initialization failed, suspend/resume may fail.\n");
213 
215 }
216 
217 static void mainboard_enable(struct device *dev)
218 {
219  dev->ops->init = &mainboard_init;
220 }
221 
224 };
struct chip_operations mainboard_ops
Definition: mainboard.c:19
u8 raw[sizeof(struct arm64_kernel_header)+0x100]
Definition: fit_payload.c:31
const char * name
Definition: mmu.c:92
#define assert(statement)
Definition: assert.h:74
void register_bl31_aux_param(struct bl_aux_param_header *param)
Definition: bl31.c:54
int display_init_required(void)
Definition: bootmode.c:22
#define ARRAY_SIZE(a)
Definition: helpers.h:12
static size_t cbfs_load(const char *name, void *buf, size_t size)
Definition: cbfs.h:282
#define printk(level,...)
Definition: stdlib.h:16
void mdelay(unsigned int msecs)
Definition: delay.c:2
@ GPIO
Definition: chip.h:84
static struct smmstore_params_info info
Definition: ramstage.c:12
@ CONFIG
Definition: dsi_common.h:201
@ MIPI_DSI_FMT_RGB888
Definition: dsi_common.h:13
@ MIPI_DSI_MODE_LINE_END
Definition: dsi_common.h:45
@ 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
int google_chromeec_set_sku_id(uint32_t skuid)
Definition: ec.c:753
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
uint32_t sku_id(void)
Definition: mainboard.c:11
static void mainboard_init(struct device *dev)
Definition: mainboard.c:195
static void power_on_panel(struct panel_description *panel)
Definition: mainboard.c:82
static void configure_audio(void)
Definition: mainboard.c:48
struct panel_description __weak * get_panel_description(int panel_id)
Definition: mainboard.c:68
static void configure_panel_backlight(void)
Definition: mainboard.c:76
static void configure_ec(void)
Definition: mainboard.c:60
static bool configure_display(void)
Definition: mainboard.c:147
static void configure_usb(void)
Definition: mainboard.c:43
static void configure_emmc(void)
Definition: mainboard.c:29
static void mainboard_enable(struct device *dev)
Definition: mainboard.c:217
struct panel_description * get_panel_from_cbfs(struct panel_description *desc)
Definition: mainboard.c:100
static struct panel_description * get_active_panel(void)
Definition: mainboard.c:124
static void register_reset_to_bl31(void)
Definition: mainboard.c:184
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
#define GPIO_RESET
Definition: gpio.h:16
#define GPIO_PPVARP_LCD_EN
Definition: panel.h:31
#define GPIO_PP3300_LCM_EN
Definition: panel.h:29
#define GPIO_PPVARN_LCD_EN
Definition: panel.h:30
#define GPIO_LCM_RST_1V8
Definition: panel.h:24
#define GPIO_PP1800_LCM_EN
Definition: panel.h:28
static uint8_t panel_id(void)
Definition: boardid.c:45
int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, const u8 *init_commands)
Definition: dsi.c:360
@ GPIO_PULL_ENABLE
Definition: gpio_common.h:13
void gpio_set_pull(gpio_t gpio, enum pull_enable enable, enum pull_select select)
Definition: gpio.c:17
void setup_usb_host(void)
Definition: usb.c:153
void mtk_ddp_init(void)
Definition: ddp.c:61
void mtk_ddp_mode_set(const struct edid *edid)
Definition: ddp.c:66
int spm_init(void)
Definition: spm.c:298
void mtcmos_audio_power_on(void)
Definition: mtcmos.c:52
void mtcmos_display_power_on(void)
Definition: mtcmos.c:44
void mtcmos_protect_display_bus(void)
Definition: mtcmos.c:14
u8 buffer[C2P_BUFFER_MAXSIZE]
Definition: psp_smm.c:18
const struct smm_save_state_ops *legacy_ops __weak
Definition: save_state.c:8
void gpio_set_mode(gpio_t gpio, int mode)
Definition: gpio.c:45
#define GPIO_PULL_UP
Definition: gpio.h:24
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
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
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
const char * name
Definition: panel.h:10
void(* power_on)(void)
Definition: panel.h:12
void(* post_power_on)(void)
Definition: panel.h:13
struct panel_serializable_data * s
Definition: panel.h:11
enum lb_fb_orientation orientation
Definition: panel.h:14
struct edid edid
Definition: panel.h:30
int snprintf(char *buf, size_t size, const char *fmt,...)
Note: This file is only for POSIX compatibility, and is meant to be chain-included via string....
Definition: vsprintf.c:35