blob: afbea9c77004b5a729f3dff568254f583e715341 [file] [log] [blame]
Angel Pons141402d2020-04-05 13:22:16 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Yidi Lin3d7b6062015-07-31 17:10:40 +08002
Yidi Lin3d7b6062015-07-31 17:10:40 +08003#include <boardid.h>
Jitao Shi4a04a7b2016-01-08 16:02:13 +08004#include <bootmode.h>
5#include <console/console.h>
Koro Chen9733ba52015-07-31 17:11:04 +08006#include <delay.h>
Yidi Lin3d7b6062015-07-31 17:10:40 +08007#include <device/device.h>
Jitao Shi4a04a7b2016-01-08 16:02:13 +08008#include <drivers/parade/ps8640/ps8640.h>
9#include <edid.h>
Koro Chen9733ba52015-07-31 17:11:04 +080010#include <gpio.h>
henryc.chen316ded82016-03-11 14:55:30 +080011#include <soc/da9212.h>
Jitao Shi4a04a7b2016-01-08 16:02:13 +080012#include <soc/ddp.h>
13#include <soc/dsi.h>
jun.gaof059e972015-12-17 16:59:55 +080014#include <soc/i2c.h>
henryc.chen316ded82016-03-11 14:55:30 +080015#include <soc/mt6311.h>
Koro Chen9733ba52015-07-31 17:11:04 +080016#include <soc/mt6391.h>
17#include <soc/mtcmos.h>
Koro Chen9733ba52015-07-31 17:11:04 +080018#include <soc/pll.h>
Ben Loka7379402015-07-31 17:11:11 +080019#include <soc/usb.h>
CC Ma72980b12015-09-15 17:33:38 +080020#include <vendorcode/google/chromeos/chromeos.h>
Patrick Rudolph8b56c8c2020-02-19 12:57:00 +010021#include <framebuffer_info.h>
Koro Chen9733ba52015-07-31 17:11:04 +080022
henryc.chen316ded82016-03-11 14:55:30 +080023enum {
24 CODEC_I2C_BUS = 0,
25 EXT_BUCK_I2C_BUS = 1,
26};
27
28static void configure_ext_buck(void)
Jimmy Huang27eba672015-07-31 17:11:00 +080029{
henryc.chen316ded82016-03-11 14:55:30 +080030 mtk_i2c_bus_init(EXT_BUCK_I2C_BUS);
jun.gaof059e972015-12-17 16:59:55 +080031
Julius Werner9a570952016-03-14 20:12:18 -070032 switch (board_id() + CONFIG_BOARD_ID_ADJUSTMENT) {
henryc.chen70b30442015-12-23 11:45:29 +080033 case 3:
34 case 4:
Jimmy Huang27eba672015-07-31 17:11:00 +080035 /* rev-3 and rev-4 use mt6311 as external buck */
Tristan Shieh71d227b2018-07-09 18:59:32 +080036 gpio_output(GPIO(EINT15), 1);
henryc.chen316ded82016-03-11 14:55:30 +080037 udelay(500);
38 mt6311_probe(EXT_BUCK_I2C_BUS);
Jimmy Huang27eba672015-07-31 17:11:00 +080039 break;
henryc.chen70b30442015-12-23 11:45:29 +080040 case 2:
41 default:
42 /* rev-2 and rev-5 use da9212 as external buck */
henryc.chen316ded82016-03-11 14:55:30 +080043 mt6391_gpio_output(MT6391_KP_ROW3, 1); /* DA9212_IC_EN */
44 mt6391_gpio_output(MT6391_KP_ROW4, 1); /* DA9212_EN_A */
45 udelay(500); /* add 500us delay for powering on da9212 */
46 da9212_probe(EXT_BUCK_I2C_BUS);
henryc.chen70b30442015-12-23 11:45:29 +080047 break;
Jimmy Huang27eba672015-07-31 17:11:00 +080048 }
49}
50
YH Huang5d687ad2016-07-14 11:49:01 +080051static void configure_touchscreen(void)
52{
53 /* Pull low reset gpio for 500us and then pull high */
54 if (board_id() + CONFIG_BOARD_ID_ADJUSTMENT >= 7) {
Tristan Shieh71d227b2018-07-09 18:59:32 +080055 gpio_output(GPIO(PCM_SYNC), 0);
YH Huang5d687ad2016-07-14 11:49:01 +080056 udelay(500);
Tristan Shieh71d227b2018-07-09 18:59:32 +080057 gpio_output(GPIO(PCM_SYNC), 1);
YH Huang5d687ad2016-07-14 11:49:01 +080058 }
59}
60
Koro Chen9733ba52015-07-31 17:11:04 +080061static void configure_audio(void)
62{
63 mtcmos_audio_power_on();
64
Koro Chen603cb852015-12-30 17:50:56 +080065 /* vgp1 set to 1.8V */
66 mt6391_configure_ldo(LDO_VCAMD, LDO_1P8);
67 /* delay 1ms for realtek's power sequence request */
68 mdelay(1);
69 /* vcama set to 1.8V */
70 mt6391_configure_ldo(LDO_VCAMA, LDO_1P8);
Koro Chen9733ba52015-07-31 17:11:04 +080071
72 /* reset ALC5676 */
Julius Werner9a570952016-03-14 20:12:18 -070073 if (board_id() + CONFIG_BOARD_ID_ADJUSTMENT < 5)
Tristan Shieh71d227b2018-07-09 18:59:32 +080074 gpio_output(GPIO(LCM_RST), 1);
Koro Chen9733ba52015-07-31 17:11:04 +080075
76 /* SoC I2S */
Tristan Shieh71d227b2018-07-09 18:59:32 +080077 gpio_set_mode(GPIO(I2S0_LRCK), PAD_I2S0_LRCK_FUNC_I2S1_WS);
78 gpio_set_mode(GPIO(I2S0_BCK), PAD_I2S0_BCK_FUNC_I2S1_BCK);
79 gpio_set_mode(GPIO(I2S0_MCK), PAD_I2S0_MCK_FUNC_I2S1_MCK);
80 gpio_set_mode(GPIO(I2S0_DATA0), PAD_I2S0_DATA0_FUNC_I2S1_DO_1);
81 gpio_set_mode(GPIO(I2S0_DATA1), PAD_I2S0_DATA1_FUNC_I2S2_DI_2);
Koro Chen9733ba52015-07-31 17:11:04 +080082 /* codec ext MCLK ON */
83 mt6391_gpio_output(MT6391_KP_COL4, 1);
Yidi Lin19318dd2016-03-16 16:59:17 +080084
85 switch (board_id() + CONFIG_BOARD_ID_ADJUSTMENT) {
86 case 2:
87 case 3:
88 case 4:
89 mt6391_gpio_output(MT6391_KP_COL5, 1);
90 break;
91 case 5:
92 case 6:
Tristan Shieh71d227b2018-07-09 18:59:32 +080093 gpio_set_mode(GPIO(UCTS0), PAD_UCTS0_FUNC_I2S2_DI_1);
Yidi Lin19318dd2016-03-16 16:59:17 +080094 mt6391_gpio_output(MT6391_KP_COL5, 1);
95 break;
96 default:
97 break;
98 }
Koro Chen9733ba52015-07-31 17:11:04 +080099
jun.gaof059e972015-12-17 16:59:55 +0800100 /* Init i2c bus Timing register for audio codecs */
henryc.chen316ded82016-03-11 14:55:30 +0800101 mtk_i2c_bus_init(CODEC_I2C_BUS);
jun.gaof059e972015-12-17 16:59:55 +0800102
Koro Chen9733ba52015-07-31 17:11:04 +0800103 /* set I2S clock to 48KHz */
104 mt_pll_set_aud_div(48 * KHz);
105}
106
Ben Loka7379402015-07-31 17:11:11 +0800107static void configure_usb(void)
108{
109 setup_usb_host();
110
Julius Werner9a570952016-03-14 20:12:18 -0700111 if (board_id() + CONFIG_BOARD_ID_ADJUSTMENT > 3) {
Yidi Lin57debca2017-02-17 15:59:17 +0800112 /* Type C port 0 Over current alert pin */
Tristan Shieh71d227b2018-07-09 18:59:32 +0800113 gpio_input_pullup(GPIO(MSDC3_DSL));
Evan Green0aa1f9e2019-03-26 11:37:30 -0700114 /* Enable USB3 type A port 0 5V load switch */
115 gpio_output(GPIO(CM2MCLK), 1);
116 /* USB3 Type A port 0 power over current alert pin */
117 gpio_input_pullup(GPIO(CMPCLK));
Yidi Lin57debca2017-02-17 15:59:17 +0800118 /* Type C port 1 over current alert pin */
Yidi Lin19318dd2016-03-16 16:59:17 +0800119 if (board_id() + CONFIG_BOARD_ID_ADJUSTMENT < 7)
Tristan Shieh71d227b2018-07-09 18:59:32 +0800120 gpio_input_pullup(GPIO(PCM_SYNC));
Yidi Lin358f66a2016-01-11 10:05:46 +0800121 }
122
Yidi Lin19318dd2016-03-16 16:59:17 +0800123 if (board_id() + CONFIG_BOARD_ID_ADJUSTMENT > 4 &&
124 board_id() + CONFIG_BOARD_ID_ADJUSTMENT < 7)
125 {
Yidi Lin358f66a2016-01-11 10:05:46 +0800126 /* USB 2.0 type A port over current interrupt pin(low active) */
Tristan Shieh71d227b2018-07-09 18:59:32 +0800127 gpio_input_pullup(GPIO(UCTS2));
Yidi Lin358f66a2016-01-11 10:05:46 +0800128 /* USB 2.0 type A port BC1.2 STATUS(low active) */
Tristan Shieh71d227b2018-07-09 18:59:32 +0800129 gpio_input_pullup(GPIO(AUD_DAT_MISO));
Yidi Lin358f66a2016-01-11 10:05:46 +0800130 }
Ben Loka7379402015-07-31 17:11:11 +0800131}
132
Ben Lok7d7dc202016-01-08 13:10:34 +0800133static void configure_usb_hub(void)
134{
Elyes HAOUAS44f558e2020-02-24 13:26:04 +0100135 /* set USB hub reset pin (low active) to high */
Julius Werner9a570952016-03-14 20:12:18 -0700136 if (board_id() + CONFIG_BOARD_ID_ADJUSTMENT > 4)
Tristan Shieh71d227b2018-07-09 18:59:32 +0800137 gpio_output(GPIO(UTXD3), 1);
Ben Lok7d7dc202016-01-08 13:10:34 +0800138}
139
YH Huang1fcee362015-07-31 17:11:07 +0800140/* Setup backlight control pins as output pin and power-off by default */
141static void configure_backlight(void)
142{
Yidi Lin0443ecc2015-12-28 16:40:54 +0800143 /* Configure PANEL_LCD_POWER_EN */
Julius Werner9a570952016-03-14 20:12:18 -0700144 switch (board_id() + CONFIG_BOARD_ID_ADJUSTMENT) {
YH Huang1fcee362015-07-31 17:11:07 +0800145 case 3:
Tristan Shieh71d227b2018-07-09 18:59:32 +0800146 gpio_output(GPIO(UCTS2), 0);
YH Huang1fcee362015-07-31 17:11:07 +0800147 break;
148 case 4:
Tristan Shieh71d227b2018-07-09 18:59:32 +0800149 gpio_output(GPIO(SRCLKENAI), 0);
Yidi Lin0443ecc2015-12-28 16:40:54 +0800150 break;
YH Huang1fcee362015-07-31 17:11:07 +0800151 default:
Tristan Shieh71d227b2018-07-09 18:59:32 +0800152 gpio_output(GPIO(UTXD2), 0);
YH Huang1fcee362015-07-31 17:11:07 +0800153 break;
154 }
Yidi Lin0443ecc2015-12-28 16:40:54 +0800155
Tristan Shieh71d227b2018-07-09 18:59:32 +0800156 gpio_output(GPIO(DISP_PWM0), 0); /* DISP_PWM0 */
157 gpio_output(GPIO(PCM_TX), 0); /* PANEL_POWER_EN */
YH Huang1fcee362015-07-31 17:11:07 +0800158}
159
Jitao Shi8ea218b2016-01-11 19:24:37 +0800160static void configure_display(void)
161{
Yidi Lin19318dd2016-03-16 16:59:17 +0800162 /* board from Rev2 */
Tristan Shieh71d227b2018-07-09 18:59:32 +0800163 gpio_output(GPIO(CMMCLK), 1); /* PANEL_3V3_ENABLE */
Yidi Lin19318dd2016-03-16 16:59:17 +0800164 /* vgp2 set to 3.3V for ps8640 */
165 mt6391_configure_ldo(LDO_VGP2, LDO_3P3);
Tristan Shieh71d227b2018-07-09 18:59:32 +0800166 gpio_output(GPIO(URTS0), 0); /* PS8640_SYSRSTN */
Yidi Lin19318dd2016-03-16 16:59:17 +0800167 /* PS8640_1V2_ENABLE */
168 if (board_id() + CONFIG_BOARD_ID_ADJUSTMENT == 4)
Tristan Shieh71d227b2018-07-09 18:59:32 +0800169 gpio_output(GPIO(SRCLKENAI2), 1);
Yidi Lin19318dd2016-03-16 16:59:17 +0800170 else
Tristan Shieh71d227b2018-07-09 18:59:32 +0800171 gpio_output(GPIO(URTS2), 1);
Yidi Lin19318dd2016-03-16 16:59:17 +0800172 /* delay 2ms for vgp2 and PS8640_1V2_ENABLE stable */
173 mdelay(2);
174 /* PS8640_PDN */
175 if (board_id() + CONFIG_BOARD_ID_ADJUSTMENT > 4)
Tristan Shieh71d227b2018-07-09 18:59:32 +0800176 gpio_output(GPIO(LCM_RST), 1);
Yidi Lin19318dd2016-03-16 16:59:17 +0800177 else
Tristan Shieh71d227b2018-07-09 18:59:32 +0800178 gpio_output(GPIO(UCTS0), 1);
179 gpio_output(GPIO(PCM_CLK), 1); /* PS8640_MODE_CONF */
180 gpio_output(GPIO(URTS0), 1); /* PS8640_SYSRSTN */
Yidi Lin19318dd2016-03-16 16:59:17 +0800181 /* for level shift(1.8V to 3.3V) on */
182 udelay(100);
Jitao Shi8ea218b2016-01-11 19:24:37 +0800183}
184
Daniel Kurtz8e055f82017-04-20 15:31:33 +0800185static int read_edid_from_ps8640(struct edid *edid)
186{
Yidi Lin19318dd2016-03-16 16:59:17 +0800187 u8 i2c_bus, i2c_addr;
Jitao Shi4a04a7b2016-01-08 16:02:13 +0800188
Yidi Lin19318dd2016-03-16 16:59:17 +0800189 if (board_id() + CONFIG_BOARD_ID_ADJUSTMENT > 6) {
190 i2c_bus = 0;
191 i2c_addr = 0x8;
192 } else {
Jitao Shi4a04a7b2016-01-08 16:02:13 +0800193 i2c_bus = 4;
Yidi Lin19318dd2016-03-16 16:59:17 +0800194 i2c_addr = 0x18;
Jitao Shi4a04a7b2016-01-08 16:02:13 +0800195 }
Yidi Lin19318dd2016-03-16 16:59:17 +0800196
Jitao Shi4a04a7b2016-01-08 16:02:13 +0800197 mtk_i2c_bus_init(i2c_bus);
198
Yidi Lin19318dd2016-03-16 16:59:17 +0800199 ps8640_init(i2c_bus, i2c_addr);
Daniel Kurtz8e055f82017-04-20 15:31:33 +0800200 if (ps8640_get_edid(i2c_bus, i2c_addr, edid)) {
Jitao Shi4a04a7b2016-01-08 16:02:13 +0800201 printk(BIOS_ERR, "Can't get panel's edid\n");
Daniel Kurtz8e055f82017-04-20 15:31:33 +0800202 return -1;
203 }
204
205 return 0;
206}
207
208static void display_startup(void)
209{
210 struct edid edid;
211 int ret;
212 u32 mipi_dsi_flags;
Daniel Kurtz8e055f82017-04-20 15:31:33 +0800213
Evan Green0aa1f9e2019-03-26 11:37:30 -0700214 if (read_edid_from_ps8640(&edid) < 0)
215 return;
Daniel Kurtz8e055f82017-04-20 15:31:33 +0800216
Evan Green0aa1f9e2019-03-26 11:37:30 -0700217 mipi_dsi_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
Daniel Kurtz2332ada2017-04-20 12:30:00 +0800218 edid_set_framebuffer_bits_per_pixel(&edid, 32, 0);
Jitao Shi4a04a7b2016-01-08 16:02:13 +0800219
Hung-Te Lin1c6e5a62019-08-05 14:38:30 +0800220 mtk_ddp_init();
Hung-Te Lin75e43142019-08-07 10:31:27 +0800221 ret = mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, 4, &edid, NULL);
Jitao Shi4a04a7b2016-01-08 16:02:13 +0800222 if (ret < 0) {
223 printk(BIOS_ERR, "dsi init fail\n");
224 return;
225 }
226
Hung-Te Lin1c6e5a62019-08-05 14:38:30 +0800227 mtk_ddp_mode_set(&edid);
Patrick Rudolph8b56c8c2020-02-19 12:57:00 +0100228 fb_new_framebuffer_info_from_edid(&edid, (uintptr_t)0);
Jitao Shi4a04a7b2016-01-08 16:02:13 +0800229}
230
Elyes HAOUASd129d432018-05-04 20:23:33 +0200231static void mainboard_init(struct device *dev)
Yidi Lin3d7b6062015-07-31 17:10:40 +0800232{
Ben Loka7379402015-07-31 17:11:11 +0800233 /* TP_SHIFT_EN: Enables the level shifter for I2C bus 4 (TPAD), which
Martin Roth50863da2021-10-01 14:37:30 -0600234 * also contains the PS8640 eDP bridge and the USB hub.
Ben Loka7379402015-07-31 17:11:11 +0800235 */
Julius Werner9a570952016-03-14 20:12:18 -0700236 if (board_id() + CONFIG_BOARD_ID_ADJUSTMENT < 5)
Yidi Lincd6aac12015-12-28 17:22:33 +0800237 mt6391_gpio_output(MT6391_KP_ROW2, 1);
Ben Loka7379402015-07-31 17:11:11 +0800238
Yidi Linb9b2c6f2015-11-13 16:21:48 +0800239 /* Config SD card detection pin */
Tristan Shieh71d227b2018-07-09 18:59:32 +0800240 gpio_input_pullup(GPIO(EINT1)); /* SD_DET */
Yidi Linb9b2c6f2015-11-13 16:21:48 +0800241
Koro Chen9733ba52015-07-31 17:11:04 +0800242 configure_audio();
Martin Rothc7dfbe22016-07-22 11:15:12 -0600243
244 /* fix dsi lp mode is half voltage attenuation */
245 mtk_dsi_pin_drv_ctrl();
246
Jitao Shi4a04a7b2016-01-08 16:02:13 +0800247 if (display_init_required()) {
Daniel Kurtz8e055f82017-04-20 15:31:33 +0800248 mtcmos_display_power_on();
Evan Green0aa1f9e2019-03-26 11:37:30 -0700249 configure_backlight();
250 configure_display();
Daniel Kurtz8e055f82017-04-20 15:31:33 +0800251 display_startup();
Jitao Shi4a04a7b2016-01-08 16:02:13 +0800252 } else {
253 printk(BIOS_INFO, "Skipping display init.\n");
254 }
Ben Loka7379402015-07-31 17:11:11 +0800255 configure_usb();
Ben Lok7d7dc202016-01-08 13:10:34 +0800256 configure_usb_hub();
henryc.chen316ded82016-03-11 14:55:30 +0800257 configure_ext_buck();
YH Huang5d687ad2016-07-14 11:49:01 +0800258 configure_touchscreen();
Yidi Lin3d7b6062015-07-31 17:10:40 +0800259}
260
Elyes HAOUASd129d432018-05-04 20:23:33 +0200261static void mainboard_enable(struct device *dev)
Yidi Lin3d7b6062015-07-31 17:10:40 +0800262{
263 dev->ops->init = &mainboard_init;
264}
265
266struct chip_operations mainboard_ops = {
Yidi Lin3d7b6062015-07-31 17:10:40 +0800267 .enable_dev = mainboard_enable,
268};