1 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <console/console.h>
7 #include <device/device.h>
8 #include <device/i2c_simple.h>
9 #include <device/mmio.h>
10 #include <mipi/panel.h>
11 #include <drivers/ti/sn65dsi86bridge/sn65dsi86bridge.h>
12 #include <drivers/parade/ps8640/ps8640.h>
14 #include <framebuffer_info.h>
15 #include <soc/display/mipi_dsi.h>
16 #include <soc/display/mdssreg.h>
17 #include <soc/qupv3_config_common.h>
18 #include <soc/qup_se_handlers_common.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>
24 #include <soc/addressmap.h>
26 #define BRIDGE_BUS QUPV3_0_SE2
27 #define BRIDGE_SN65DSI86_CHIP 0x2d
28 #define BRIDGE_PS8640_CHIP 0x08
30 static struct usb_board_data usb0_board_data
= {
31 .pll_bias_control_2
= 0x22,
36 static void setup_usb(void)
38 /* Assert EN_PP3300_HUB for those board variants that use it. */
39 gpio_output(GPIO(84), 1);
41 setup_usb_host0(&usb0_board_data
);
44 static void qi2s_configure_gpios(void)
46 gpio_configure(GPIO(49), GPIO49_FUNC_MI2S_1_SCK
,
47 GPIO_NO_PULL
, GPIO_8MA
, GPIO_OUTPUT
);
49 gpio_configure(GPIO(50), GPIO50_FUNC_MI2S_1_WS
,
50 GPIO_NO_PULL
, GPIO_8MA
, GPIO_OUTPUT
);
52 gpio_configure(GPIO(51), GPIO51_FUNC_MI2S_1_DATA0
,
53 GPIO_NO_PULL
, GPIO_8MA
, GPIO_OUTPUT
);
56 static void load_qup_fw(void)
58 qupv3_se_fw_load_and_init(QUPV3_0_SE1
, SE_PROTOCOL_SPI
, MIXED
); /* ESIM SPI */
59 qupv3_se_fw_load_and_init(QUPV3_0_SE3
, SE_PROTOCOL_UART
, FIFO
); /* BT UART */
60 qupv3_se_fw_load_and_init(QUPV3_0_SE4
, SE_PROTOCOL_I2C
, MIXED
); /* Pen Detect I2C */
61 qupv3_se_fw_load_and_init(QUPV3_0_SE5
, SE_PROTOCOL_I2C
, MIXED
); /* SAR I2C */
62 qupv3_se_fw_load_and_init(QUPV3_1_SE1
, SE_PROTOCOL_I2C
, MIXED
); /* Trackpad I2C */
64 * When coreboot firmware disables serial output,
65 * we still need to load console UART QUP FW for OS.
67 if (!CONFIG(CONSOLE_SERIAL
))
68 qupv3_se_fw_load_and_init(QUPV3_1_SE2
, SE_PROTOCOL_UART
, FIFO
);
70 qupv3_se_fw_load_and_init(QUPV3_1_SE3
, SE_PROTOCOL_I2C
, MIXED
); /* Speaker Amps I2C */
71 qupv3_se_fw_load_and_init(QUPV3_1_SE4
, SE_PROTOCOL_SPI
, MIXED
); /* Fingerprint SPI */
72 qupv3_se_fw_load_and_init(QUPV3_1_SE5
, SE_PROTOCOL_I2C
, MIXED
); /* Codec I2C */
75 static bool is_ps8640_bridge(void)
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.
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));
90 static void power_on_sn65dsi86_bridge(void)
92 printk(BIOS_INFO
, "%s: Bridge gpio init\n", __func__
);
94 /* Bridge Enable GPIO */
95 gpio_output(GPIO_EDP_BRIDGE_ENABLE
, 1);
97 /* PP3300 EDP power supply */
98 gpio_output(GPIO_EN_PP3300_DX_EDP
, 1);
101 static void power_on_ps8640_bridge(void)
103 printk(BIOS_INFO
, "%s: Bridge gpio init\n", __func__
);
105 /* PP3300 EDP panel power supply */
106 gpio_output(GPIO_EN_PP3300_DX_EDP
, 1);
108 gpio_output(GPIO_PS8640_EDP_BRIDGE_3V3_ENABLE
, 1);
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.
116 gpio_output(GPIO_PS8640_EDP_BRIDGE_PD_L
, 1);
119 * According to ps8640 app note v0.6, wait for 2ms after VDD33 goes
120 * high and then deassert RST.
124 gpio_output(GPIO_PS8640_EDP_BRIDGE_RST_L
, 1);
127 static void configure_mipi_panel(void)
129 int panel_id
= sku_id() >> 8;
130 gpio_output(GPIO_MIPI_1V8_ENABLE
, 1);
132 gpio_output(GPIO_AVDD_LCD_ENABLE
, 1);
134 gpio_output(GPIO_AVEE_LCD_ENABLE
, 1);
136 gpio_output(GPIO_VDD_RESET_1V8
, 1);
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).
143 if (CONFIG(BOARD_GOOGLE_MRBLAND
) && ((panel_id
== 3) || (panel_id
== 4))) {
144 gpio_output(GPIO_VDD_RESET_1V8
, 0);
146 gpio_output(GPIO_VDD_RESET_1V8
, 1);
149 * In mipi panel, TP_EN(GPIO 85) need pull up before
150 * GPIO_BACKLIGHT_ENABLE(GPIO12) up.
152 if (CONFIG(TROGDOR_HAS_MIPI_PANEL
))
153 gpio_output(GPIO_TP_EN
, 1);
156 static struct panel_serializable_data
*get_mipi_panel(enum lb_fb_orientation
*orientation
)
158 const char *cbfs_filename
= NULL
;
159 int panel_id
= sku_id() >> 8;
161 if (CONFIG(BOARD_GOOGLE_MRBLAND
)) {
165 cbfs_filename
= "panel-BOE_TV101WUM_N53";
166 *orientation
= LB_FB_ORIENTATION_LEFT_UP
;
169 cbfs_filename
= "panel-AUO_B101UAN08_3";
170 *orientation
= LB_FB_ORIENTATION_LEFT_UP
;
175 if (CONFIG(BOARD_GOOGLE_QUACKINGSTICK
)) {
178 cbfs_filename
= "panel-AUO_B101UAN08_3";
179 *orientation
= LB_FB_ORIENTATION_LEFT_UP
;
184 if (CONFIG(BOARD_GOOGLE_WORMDINGLER
)) {
187 cbfs_filename
= "panel-INX_HJ110IZ_01A_B2";
188 *orientation
= LB_FB_ORIENTATION_LEFT_UP
;
191 cbfs_filename
= "panel-BOE_TV110C9M_LL0";
192 *orientation
= LB_FB_ORIENTATION_LEFT_UP
;
200 struct panel_serializable_data
*panel
= cbfs_map(cbfs_filename
, NULL
);
202 printk(BIOS_ERR
, "Could not find panel data for %s!\n", cbfs_filename
);
209 static enum cb_err
display_init(struct panel_serializable_data
*panel
)
211 uint32_t dsi_bpp
= 24;
214 if (mdss_dsi_config(&panel
->edid
, lanes
, dsi_bpp
))
217 if (CONFIG(TROGDOR_HAS_MIPI_PANEL
)) {
218 if (mdss_dsi_panel_initialize(panel
->init
))
220 } else if (!is_ps8640_bridge()) {
222 * Parade ps8640 is auto-configured based on a pre-programmed
223 * SPI-ROM. Only TI sn65dsi86 needs to be configured here.
225 sn65dsi86_bridge_configure(BRIDGE_BUS
, BRIDGE_SN65DSI86_CHIP
,
226 &panel
->edid
, lanes
, dsi_bpp
);
227 if (CONFIG(TROGDOR_HAS_BRIDGE_BACKLIGHT
))
228 sn65dsi86_backlight_enable(BRIDGE_BUS
, BRIDGE_SN65DSI86_CHIP
);
231 mdp_dsi_video_config(&panel
->edid
);
232 mdss_dsi_video_mode_config(&panel
->edid
, dsi_bpp
);
238 static void display_startup(void)
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
;
244 /* Always initialize this so QUP firmware is loaded for the kernel. */
245 i2c_init(BRIDGE_BUS
, I2C_SPEED_FAST
);
247 if (!display_init_required()) {
248 printk(BIOS_INFO
, "Skipping display init.\n");
252 if (CONFIG(TROGDOR_HAS_MIPI_PANEL
)) {
253 configure_mipi_panel();
254 panel
= get_mipi_panel(&orientation
);
257 } else if (is_ps8640_bridge()) {
258 power_on_ps8640_bridge();
259 ps8640_init(BRIDGE_BUS
, BRIDGE_PS8640_CHIP
);
260 if (ps8640_get_edid(BRIDGE_BUS
, BRIDGE_PS8640_CHIP
, &panel
->edid
) < 0)
263 enum dp_pll_clk_src ref_clk
= SN65_SEL_19MHZ
;
264 power_on_sn65dsi86_bridge();
265 mdelay(250); /* Delay for the panel to be up */
266 sn65dsi86_bridge_init(BRIDGE_BUS
, BRIDGE_SN65DSI86_CHIP
, ref_clk
);
267 if (sn65dsi86_bridge_read_edid(BRIDGE_BUS
, BRIDGE_SN65DSI86_CHIP
,
272 printk(BIOS_INFO
, "display init!\n");
273 edid_set_framebuffer_bits_per_pixel(&panel
->edid
, 32, 0);
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
);
280 static void configure_sdhci(void)
282 /* Program eMMC drive strength to 16/16/16 mA */
283 write32p(SDC1_TLMM_CFG_ADDR
, 0x9FFF);
284 /* Program SD card drive strength to 16/10/10 mA */
285 write32p(SDC2_TLMM_CFG_ADDR
, 0x1FE4);
288 static void mainboard_init(struct device
*dev
)
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
))
293 gpio_output(GPIO_FP_RST_L
, 1);
296 qi2s_configure_gpios();
302 static void mainboard_enable(struct device
*dev
)
304 dev
->ops
->init
= &mainboard_init
;
307 struct chip_operations mainboard_ops
= {
308 .enable_dev
= mainboard_enable
,