blob: 1c823f3e7c8b618ea46de3711fd9080882c291a4 [file] [log] [blame]
huang lina6dbfb52016-03-02 18:38:40 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2016 Rockchip Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
Vadim Bendebury8e8a00c2016-04-22 12:25:07 -070017#include <boardid.h>
Julius Wernerc49782c2016-11-21 20:14:18 -080018#include <console/console.h>
Lin Huangb497b482016-03-31 18:44:13 +080019#include <delay.h>
huang lina6dbfb52016-03-02 18:38:40 +080020#include <device/device.h>
Lin Huangb497b482016-03-31 18:44:13 +080021#include <device/i2c.h>
Julius Wernerc49782c2016-11-21 20:14:18 -080022#include <ec/google/chromeec/ec.h>
Vadim Bendebury1e80ab32016-03-28 00:44:54 -070023#include <gpio.h>
Lin Huang5a4be8a2016-05-17 15:45:53 +080024#include <soc/bl31_plat_params.h>
Vadim Bendebury1e80ab32016-03-28 00:44:54 -070025#include <soc/clock.h>
Lin Huangb497b482016-03-31 18:44:13 +080026#include <soc/display.h>
Vadim Bendebury1e80ab32016-03-28 00:44:54 -070027#include <soc/grf.h>
Lin Huangb497b482016-03-31 18:44:13 +080028#include <soc/i2c.h>
Liangfeng Wu76655cb2016-05-26 16:06:58 +080029#include <soc/usb.h>
Simon Glassbc679bc2016-06-19 16:09:21 -060030#include <vendorcode/google/chromeos/chromeos.h>
Vadim Bendebury1e80ab32016-03-28 00:44:54 -070031
Vadim Bendebury993dbe12016-05-22 15:53:37 -070032#include "board.h"
33
Brian Norrise06a1b82016-09-21 18:16:54 -070034/*
35 * Wifi's PDN/RST line is pulled down by its (unpowered) voltage rails, but
36 * this reset pin is pulled up by default. Let's drive it low as early as we
37 * can.
38 */
39static void deassert_wifi_power(void)
40{
41 gpio_output(GPIO(1, B, 3), 0); /* Assert WLAN_MODULE_RST# */
42}
43
Lin Huang2f7ed8d2016-04-08 18:56:20 +080044static void configure_emmc(void)
45{
46 /* Host controller does not support programmable clock generator.
47 * If we don't do this setting, when we use phy to control the
48 * emmc clock(when clock exceed 50MHz), it will get wrong clock.
49 *
50 * Refer to TRM V0.3 Part 1 Chapter 15 PAGE 782 for this register.
51 * Please search "_CON11[7:0]" to locate register description.
52 */
53 write32(&rk3399_grf->emmccore_con[11], RK_CLRSETBITS(0xff, 0));
54
55 rkclk_configure_emmc();
56}
57
Lin Huangc9fea5c2016-08-30 15:34:42 -070058static void register_apio_suspend(void)
59{
60 static struct bl31_apio_param param_apio = {
61 .h = {
62 .type = PARAM_SUSPEND_APIO,
63 },
64 .apio = {
65 .apio1 = 1,
66 .apio2 = 1,
67 .apio3 = 1,
68 .apio4 = 1,
69 .apio5 = 1,
70 },
71 };
72 register_bl31_param(&param_apio.h);
73}
74
Lin Huang7d8ccfb2016-08-22 17:35:40 -070075static void register_gpio_suspend(void)
76{
77 /*
78 * These three GPIO params are used to shut down the 1.5V, 1.8V and
79 * 3.3V power rails, which need to be shut down ordered by voltage,
80 * with highest voltage first.
81 * Since register_bl31() appends to the front of the list, we need to
82 * register them backwards, with 1.5V coming first.
83 */
84 static struct bl31_gpio_param param_p15_en = {
85 .h = {
86 .type = PARAM_SUSPEND_GPIO,
87 },
88 .gpio = {
89 .polarity = BL31_GPIO_LEVEL_LOW,
90 },
91 };
92 param_p15_en.gpio.index = GET_GPIO_NUM(GPIO_P15V_EN);
93 register_bl31_param(&param_p15_en.h);
94
95 static struct bl31_gpio_param param_p18_audio_en = {
96 .h = {
97 .type = PARAM_SUSPEND_GPIO,
98 },
99 .gpio = {
100 .polarity = BL31_GPIO_LEVEL_LOW,
101 },
102 };
103 param_p18_audio_en.gpio.index = GET_GPIO_NUM(GPIO_P18V_AUDIO_PWREN);
104 register_bl31_param(&param_p18_audio_en.h);
105
106 static struct bl31_gpio_param param_p30_en = {
107 .h = {
108 .type = PARAM_SUSPEND_GPIO,
109 },
110 .gpio = {
111 .polarity = BL31_GPIO_LEVEL_LOW,
112 },
113 };
114 param_p30_en.gpio.index = GET_GPIO_NUM(GPIO_P30V_EN);
115 register_bl31_param(&param_p30_en.h);
116}
117
Lin Huang5a4be8a2016-05-17 15:45:53 +0800118static void register_reset_to_bl31(void)
119{
120 static struct bl31_gpio_param param_reset = {
121 .h = {
122 .type = PARAM_RESET,
123 },
124 .gpio = {
125 .polarity = 1,
126 },
127 };
128
129 /* gru/kevin reset pin: gpio0b3 */
130 param_reset.gpio.index = GET_GPIO_NUM(GPIO_RESET),
131
132 register_bl31_param(&param_reset.h);
133}
134
Lin Huang9a5c4fe2016-05-19 11:11:23 +0800135static void register_poweroff_to_bl31(void)
136{
137 static struct bl31_gpio_param param_poweroff = {
138 .h = {
139 .type = PARAM_POWEROFF,
140 },
141 .gpio = {
142 .polarity = 1,
143 },
144 };
145
146 /*
147 * gru/kevin power off pin: gpio1a6,
148 * reuse with tsadc int pin, so iomux need set back to
149 * gpio in BL31 and depthcharge before you setting this gpio
150 */
151 param_poweroff.gpio.index = GET_GPIO_NUM(GPIO_POWEROFF),
152
153 register_bl31_param(&param_poweroff.h);
154}
155
Vadim Bendebury1e80ab32016-03-28 00:44:54 -0700156static void configure_sdmmc(void)
157{
158 gpio_output(GPIO(4, D, 5), 1); /* SDMMC_PWR_EN */
159 gpio_output(GPIO(2, A, 2), 1); /* SDMMC_SDIO_PWR_EN */
Vadim Bendebury2832c412016-05-11 15:03:44 +0800160
161 /* SDMMC_DET_L is different on Kevin board revision 0. */
162 if (IS_ENABLED(CONFIG_BOARD_GOOGLE_KEVIN) && (board_id() == 0))
Vadim Bendebury8e8a00c2016-04-22 12:25:07 -0700163 gpio_input(GPIO(4, D, 2));
Vadim Bendebury2832c412016-05-11 15:03:44 +0800164 else
Vadim Bendebury8e8a00c2016-04-22 12:25:07 -0700165 gpio_input(GPIO(4, D, 0));
Vadim Bendebury2832c412016-05-11 15:03:44 +0800166
Vadim Bendebury1e80ab32016-03-28 00:44:54 -0700167 gpio_output(GPIO(2, D, 4), 0); /* Keep the max voltage */
Vadim Bendebury8e8a00c2016-04-22 12:25:07 -0700168
Julius Werner7feb86b2016-09-02 11:25:56 -0700169 gpio_input(GPIO(4, B, 0)); /* SDMMC0_D0 remove pull-up */
170 gpio_input(GPIO(4, B, 1)); /* SDMMC0_D1 remove pull-up */
171 gpio_input(GPIO(4, B, 2)); /* SDMMC0_D2 remove pull-up */
172 gpio_input(GPIO(4, B, 3)); /* SDMMC0_D3 remove pull-up */
173 gpio_input(GPIO(4, B, 4)); /* SDMMC0_CLK remove pull-down */
174 gpio_input(GPIO(4, B, 5)); /* SDMMC0_CMD remove pull-up */
175
Vadim Bendeburyad6ee022016-05-12 16:54:00 +0800176 write32(&rk3399_grf->gpio2_p[2][1], RK_CLRSETBITS(0xfff, 0));
177
178 /*
179 * Set all outputs' drive strength to 8 mA. Group 4 bank B driver
180 * strength requires three bits per pin. Value of 2 written in that
181 * three bit field means '8 mA', as deduced from the kernel code.
182 *
183 * Thus the six pins involved in SDMMC interface require 18 bits to
184 * configure drive strength, but each 32 bit register provides only 16
185 * bits for this setting, this covers 5 pins fully and one bit from
186 * the 6th pin. Two more bits spill over to the next register. This is
187 * described on page 378 of rk3399 TRM Version 0.3 Part 1.
188 */
189 write32(&rk3399_grf->gpio4b_e01,
190 RK_CLRSETBITS(0xffff,
191 (2 << 0) | (2 << 3) |
192 (2 << 6) | (2 << 9) | (2 << 12)));
193 write32(&rk3399_grf->gpio4b_e2, RK_CLRSETBITS(3, 1));
194
195 /* And now set the multiplexor to enable SDMMC0. */
Vadim Bendebury1e80ab32016-03-28 00:44:54 -0700196 write32(&rk3399_grf->iomux_sdmmc, IOMUX_SDMMC);
197}
huang lina6dbfb52016-03-02 18:38:40 +0800198
Xing Zheng96fbc312016-05-19 11:39:20 +0800199static void configure_codec(void)
200{
Julius Werner7feb86b2016-09-02 11:25:56 -0700201 gpio_input(GPIO(3, D, 0)); /* I2S0_SCLK remove pull-up */
202 gpio_input(GPIO(3, D, 1)); /* I2S0_RX remove pull-up */
203 gpio_input(GPIO(3, D, 2)); /* I2S0_TX remove pull-up */
204 gpio_input(GPIO(3, D, 3)); /* I2S0_SDI0 remove pull-up */
205 gpio_input(GPIO(3, D, 4)); /* I2S0_SDI1 remove pull-up */
206 /* GPIO3_D5 (I2S0_SDI2SDO2) not connected */
207 gpio_input(GPIO(3, D, 6)); /* I2S0_SDO1 remove pull-up */
208 gpio_input(GPIO(3, D, 7)); /* I2S0_SDO0 remove pull-up */
209 gpio_input(GPIO(4, A, 0)); /* I2S0_MCLK remove pull-up */
210
Xing Zheng96fbc312016-05-19 11:39:20 +0800211 write32(&rk3399_grf->iomux_i2s0, IOMUX_I2S0);
212 write32(&rk3399_grf->iomux_i2sclk, IOMUX_I2SCLK);
213
214 /* AUDIO IO domain 1.8V voltage selection */
215 write32(&rk3399_grf->io_vsel, RK_SETBITS(1 << 1));
216
217 /* CPU1_P1.8V_AUDIO_PWREN for P1.8_AUDIO */
218 gpio_output(GPIO(0, A, 2), 1);
219
220 /* set CPU1_SPK_PA_EN output */
221 gpio_output(GPIO(1, A, 2), 0);
222
223 rkclk_configure_i2s(12288000);
224}
225
Lin Huangb497b482016-03-31 18:44:13 +0800226static void configure_display(void)
227{
228 /* set pinmux for edp HPD*/
229 gpio_input_pulldown(GPIO(4, C, 7));
230 write32(&rk3399_grf->iomux_edp_hotplug, IOMUX_EDP_HOTPLUG);
231
232 gpio_output(GPIO(4, D, 3), 1); /* CPU3_EDP_VDDEN for P3.3V_DISP */
233}
234
Julius Wernerc49782c2016-11-21 20:14:18 -0800235static void usb_power_cycle(int port)
236{
237 if (google_chromeec_set_usb_pd_role(port, USB_PD_CTRL_ROLE_FORCE_SINK))
238 printk(BIOS_ERR, "ERROR: Cannot force USB%d PD sink\n", port);
239
240 mdelay(10); /* Make sure USB stick is fully depowered. */
241
242 if (google_chromeec_set_usb_pd_role(port, USB_PD_CTRL_ROLE_TOGGLE_ON))
243 printk(BIOS_ERR, "ERROR: Cannot restore USB%d PD mode\n", port);
244}
245
Liangfeng Wu76655cb2016-05-26 16:06:58 +0800246static void setup_usb(void)
247{
William wu605a87c2017-01-09 19:02:39 +0800248 /*
249 * A few magic PHY tuning values that improve eye diagram amplitude
250 * and make it extra sure we get reliable communication in firmware
251 * Set max ODT compensation voltage and current tuning reference.
252 */
William wu9f470b12016-11-10 19:34:45 +0800253 write32(&rk3399_grf->usbphy0_ctrl[3], RK_CLRSETBITS(0xfff, 0x2e3));
254 write32(&rk3399_grf->usbphy1_ctrl[3], RK_CLRSETBITS(0xfff, 0x2e3));
255
Caesar Wang9e588002017-02-10 11:16:13 +0800256 /* Set max pre-emphasis level on PHY0 and PHY1. */
257 write32(&rk3399_grf->usbphy0_ctrl[12],
258 RK_CLRSETBITS(0xffff, 0xa7));
259 write32(&rk3399_grf->usbphy1_ctrl[12],
260 RK_CLRSETBITS(0xffff, 0xa7));
William wu9f470b12016-11-10 19:34:45 +0800261
Caesar Wang9e588002017-02-10 11:16:13 +0800262 /*
William wuebbdd282017-01-23 20:54:22 +0800263 * 1. Disable the pre-emphasize in eop state and chirp
Caesar Wang9e588002017-02-10 11:16:13 +0800264 * state to avoid mis-trigger the disconnect detection
265 * and also avoid high-speed handshake fail for PHY0
266 * and PHY1 consist of otg-port and host-port.
William wuebbdd282017-01-23 20:54:22 +0800267 *
268 * 2. Configure PHY0 and PHY1 otg-ports squelch detection
269 * threshold to 125mV (default is 150mV).
Caesar Wang9e588002017-02-10 11:16:13 +0800270 */
William wuebbdd282017-01-23 20:54:22 +0800271 write32(&rk3399_grf->usbphy0_ctrl[0],
272 RK_CLRSETBITS(7 << 13 | 3 << 0, 6 << 13));
273 write32(&rk3399_grf->usbphy1_ctrl[0],
274 RK_CLRSETBITS(7 << 13 | 3 << 0, 6 << 13));
275 write32(&rk3399_grf->usbphy0_ctrl[13], RK_CLRBITS(3 << 0));
276 write32(&rk3399_grf->usbphy1_ctrl[13], RK_CLRBITS(3 << 0));
William wu9f470b12016-11-10 19:34:45 +0800277
Caesar Wang9e588002017-02-10 11:16:13 +0800278 /*
279 * ODT auto compensation bypass, and set max driver
280 * strength only for PHY0 and PHY1 otg-port.
281 */
282 write32(&rk3399_grf->usbphy0_ctrl[2],
283 RK_CLRSETBITS(0x7e << 4, 0x60 << 4));
284 write32(&rk3399_grf->usbphy1_ctrl[2],
285 RK_CLRSETBITS(0x7e << 4, 0x60 << 4));
William wu9f470b12016-11-10 19:34:45 +0800286
Caesar Wang9e588002017-02-10 11:16:13 +0800287 /*
288 * ODT auto refresh bypass, and set the max bias current
289 * tuning reference only for PHY0 and PHY1 otg-port.
290 */
291 write32(&rk3399_grf->usbphy0_ctrl[3],
292 RK_CLRSETBITS(0x21c, 1 << 4));
293 write32(&rk3399_grf->usbphy1_ctrl[3],
294 RK_CLRSETBITS(0x21c, 1 << 4));
William wu605a87c2017-01-09 19:02:39 +0800295
Caesar Wang9e588002017-02-10 11:16:13 +0800296 /*
297 * ODT auto compensation bypass, and set default driver
298 * strength only for PHY0 and PHY1 host-port.
299 */
300 write32(&rk3399_grf->usbphy0_ctrl[15], RK_SETBITS(1 << 10));
301 write32(&rk3399_grf->usbphy1_ctrl[15], RK_SETBITS(1 << 10));
William wu605a87c2017-01-09 19:02:39 +0800302
Caesar Wang9e588002017-02-10 11:16:13 +0800303 /* ODT auto refresh bypass only for PHY0 and PHY1 host-port. */
304 write32(&rk3399_grf->usbphy0_ctrl[16], RK_CLRBITS(1 << 9));
305 write32(&rk3399_grf->usbphy1_ctrl[16], RK_CLRBITS(1 << 9));
Julius Werner1c8491c2016-08-15 17:58:05 -0700306
Julius Werner785ff1b2016-08-03 19:18:39 -0700307 setup_usb_otg0();
308 setup_usb_otg1();
Julius Wernerc49782c2016-11-21 20:14:18 -0800309
310 /*
311 * Need to power-cycle USB ports for use in firmware, since some devices
312 * can't fall back to USB 2.0 after they saw SuperSpeed terminations.
313 * This takes about a dozen milliseconds, so only do it in boot modes
314 * that have firmware UI (which one could select USB boot from).
315 */
316 if (display_init_required()) {
317 usb_power_cycle(0);
318 usb_power_cycle(1);
319 }
Liangfeng Wu76655cb2016-05-26 16:06:58 +0800320}
321
huang lina6dbfb52016-03-02 18:38:40 +0800322static void mainboard_init(device_t dev)
323{
Brian Norrise06a1b82016-09-21 18:16:54 -0700324 deassert_wifi_power();
Vadim Bendebury1e80ab32016-03-28 00:44:54 -0700325 configure_sdmmc();
Lin Huang2f7ed8d2016-04-08 18:56:20 +0800326 configure_emmc();
Xing Zheng96fbc312016-05-19 11:39:20 +0800327 configure_codec();
Lin Huangb497b482016-03-31 18:44:13 +0800328 configure_display();
Liangfeng Wu76655cb2016-05-26 16:06:58 +0800329 setup_usb();
Lin Huang5a4be8a2016-05-17 15:45:53 +0800330 register_reset_to_bl31();
Lin Huang9a5c4fe2016-05-19 11:11:23 +0800331 register_poweroff_to_bl31();
Lin Huang7d8ccfb2016-08-22 17:35:40 -0700332 register_gpio_suspend();
Lin Huangc9fea5c2016-08-30 15:34:42 -0700333 register_apio_suspend();
Lin Huangb497b482016-03-31 18:44:13 +0800334}
335
Philip Chena304b692017-04-06 10:17:08 -0700336static void prepare_backlight_i2c(void)
Lin Huangb497b482016-03-31 18:44:13 +0800337{
Julius Werner7feb86b2016-09-02 11:25:56 -0700338 gpio_input(GPIO(1, B, 7)); /* I2C0_SDA remove pull_up */
339 gpio_input(GPIO(1, C, 0)); /* I2C0_SCL remove pull_up */
340
341 i2c_init(0, 100*KHz);
342
Lin Huangb497b482016-03-31 18:44:13 +0800343 write32(&rk3399_pmugrf->iomux_i2c0_sda, IOMUX_I2C0_SDA);
344 write32(&rk3399_pmugrf->iomux_i2c0_scl, IOMUX_I2C0_SCL);
Lin Huangb497b482016-03-31 18:44:13 +0800345}
346
347void mainboard_power_on_backlight(void)
348{
Vadim Bendeburyf1343df2016-05-22 15:53:37 -0700349 gpio_output(GPIO_BACKLIGHT, 1); /* BL_EN */
Lin Huangb497b482016-03-31 18:44:13 +0800350
Philip Chena304b692017-04-06 10:17:08 -0700351 if (IS_ENABLED(CONFIG_BOARD_GOOGLE_GRU))
352 prepare_backlight_i2c();
huang lina6dbfb52016-03-02 18:38:40 +0800353}
354
355static void mainboard_enable(device_t dev)
356{
357 dev->ops->init = &mainboard_init;
358}
359
360struct chip_operations mainboard_ops = {
361 .name = CONFIG_MAINBOARD_PART_NUMBER,
362 .enable_dev = mainboard_enable,
363};