1 /*
2 * Copyright (c) 2016 Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6 #include <common.h>
7 #include <clk.h>
8 #include <dm.h>
9 #include <asm/armv7.h>
10 #include <asm/io.h>
11 #include <asm/arch/bootrom.h>
12 #include <asm/arch/clock.h>
13 #include <asm/arch/cpu.h>
14 #include <asm/arch/hardware.h>
15 #include <asm/arch/periph.h>
16 #include <asm/arch/cru_rk3288.h>
17 #include <asm/arch/grf_rk3288.h>
18 #include <asm/arch/pmu_rk3288.h>
19 #include <asm/arch/qos_rk3288.h>
20 #include <asm/arch/sys_proto.h>
21 #include <asm/gpio.h>
22 #include <dm/pinctrl.h>
23 #include <dt-bindings/clock/rk3288-cru.h>
24 #include <power/regulator.h>
25
26 #define GRF_BASE 0xff770000
27
28 #define VIO0_VOP_QOS_BASE 0xffad0408
29 #define VIO1_VOP_QOS_BASE 0xffad0008
30 #define BUS_MSCH0_QOS_BASE 0xffac0014
31 #define BUS_MSCH1_QOS_BASE 0xffac0094
32
33 #define READLATENCY_VAL 0x34
34 #define CRU_CLKSEL_CON28 0Xff7600d0
35
36 #define CPU_AXI_QOS_PRIORITY_LEVEL(h, l) \
37 ((((h) & 3) << 8) | (((h) & 3) << 2) | ((l) & 3))
38
39 const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
40 [BROM_BOOTSOURCE_EMMC] = "/dwmmc@ff0f0000",
41 [BROM_BOOTSOURCE_SD] = "/dwmmc@ff0c0000",
42 };
43
44 #ifndef CONFIG_TPL_BUILD
45 #ifdef CONFIG_SPL_BUILD
configure_l2ctlr(void)46 static void configure_l2ctlr(void)
47 {
48 uint32_t l2ctlr;
49
50 l2ctlr = read_l2ctlr();
51 l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
52
53 /*
54 * Data RAM write latency: 2 cycles
55 * Data RAM read latency: 2 cycles
56 * Data RAM setup latency: 1 cycle
57 * Tag RAM write latency: 1 cycle
58 * Tag RAM read latency: 1 cycle
59 * Tag RAM setup latency: 1 cycle
60 */
61 l2ctlr |= (1 << 3 | 1 << 0);
62 write_l2ctlr(l2ctlr);
63 }
64 #endif
65
arch_cpu_init(void)66 int arch_cpu_init(void)
67 {
68 /* We do some SoC one time setting here. */
69 #ifdef CONFIG_SPL_BUILD
70 configure_l2ctlr();
71 #else
72 struct rk3288_grf * const grf = (void *)GRF_BASE;
73
74 /* Use rkpwm by default */
75 rk_setreg(&grf->soc_con2, 1 << 0);
76
77 /* Disable LVDS phy */
78 rk_setreg(&grf->soc_con7, 1 << 15);
79
80 /* Select EDP clock source 24M */
81 rk_setreg(CRU_CLKSEL_CON28, 1 << 15);
82
83 /* Read latency configure */
84 writel(READLATENCY_VAL, BUS_MSCH0_QOS_BASE);
85 writel(READLATENCY_VAL, BUS_MSCH1_QOS_BASE);
86
87 /* Set vop qos to highest priority */
88 writel(CPU_AXI_QOS_PRIORITY_LEVEL(2, 2), VIO0_VOP_QOS_BASE);
89 writel(CPU_AXI_QOS_PRIORITY_LEVEL(2, 2), VIO1_VOP_QOS_BASE);
90 #endif
91 return 0;
92 }
93 #endif
94
board_debug_uart_init(void)95 void board_debug_uart_init(void)
96 {
97 struct rk3288_grf * const grf = (void *)GRF_BASE;
98
99 rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT |
100 GPIO7C6_MASK << GPIO7C6_SHIFT,
101 GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
102 GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
103 }
104
105 #if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
106 #ifdef CONFIG_SPL_MMC_SUPPORT
configure_emmc(void)107 static int configure_emmc(void)
108 {
109 #if defined(CONFIG_TARGET_CHROMEBOOK_JERRY)
110
111 struct gpio_desc desc;
112 int ret;
113 struct udevice *pinctrl;
114
115 pinctrl_request_noflags(pinctrl, PERIPH_ID_EMMC);
116
117 /*
118 * TODO(sjg@chromium.org): Pick this up from device tree or perhaps
119 * use the EMMC_PWREN setting.
120 */
121 ret = dm_gpio_lookup_name("D9", &desc);
122 if (ret) {
123 debug("gpio ret=%d\n", ret);
124 return ret;
125 }
126 ret = dm_gpio_request(&desc, "emmc_pwren");
127 if (ret) {
128 debug("gpio_request ret=%d\n", ret);
129 return ret;
130 }
131 ret = dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT);
132 if (ret) {
133 debug("gpio dir ret=%d\n", ret);
134 return ret;
135 }
136 ret = dm_gpio_set_value(&desc, 1);
137 if (ret) {
138 debug("gpio value ret=%d\n", ret);
139 return ret;
140 }
141 #endif
142 return 0;
143 }
144
rk_spl_board_init(void)145 int rk_spl_board_init(void)
146 {
147 struct udevice *pinctrl;
148 int ret = 0;
149
150 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
151 if (ret) {
152 debug("%s: Cannot find pinctrl device\n", __func__);
153 goto err;
154 }
155 /* TODO: we may need to check boot device first */
156 #ifdef CONFIG_SPL_MMC_SUPPORT
157 ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
158 if (ret) {
159 debug("%s: Failed to set up SD card\n", __func__);
160 goto err;
161 }
162 #endif
163
164 ret = configure_emmc();
165 if (ret) {
166 debug("%s: Failed to set up eMMC\n", __func__);
167 }
168
169 err:
170 return ret;
171 }
172 #endif
173 #endif
174
rk3288_qos_init(void)175 int rk3288_qos_init(void)
176 {
177 int val = 2 << PRIORITY_HIGH_SHIFT | 2 << PRIORITY_LOW_SHIFT;
178 /* set vop qos to higher priority */
179 writel(val, CPU_AXI_QOS_PRIORITY + VIO0_VOP_QOS);
180 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_VOP_QOS);
181
182 if (!fdt_node_check_compatible(gd->fdt_blob, 0,
183 "rockchip,rk3288-tinker"))
184 {
185 /* set isp qos to higher priority */
186 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_R_QOS);
187 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W0_QOS);
188 writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W1_QOS);
189 }
190 return 0;
191 }
192
rk3288_detect_reset_reason(void)193 static void rk3288_detect_reset_reason(void)
194 {
195 struct rk3288_cru *cru = rockchip_get_cru();
196 const char *reason;
197
198 if (IS_ERR(cru))
199 return;
200
201 switch (cru->cru_glb_rst_st) {
202 case GLB_POR_RST:
203 reason = "POR";
204 break;
205 case FST_GLB_RST_ST:
206 case SND_GLB_RST_ST:
207 reason = "RST";
208 break;
209 case FST_GLB_TSADC_RST_ST:
210 case SND_GLB_TSADC_RST_ST:
211 reason = "THERMAL";
212 break;
213 case FST_GLB_WDT_RST_ST:
214 case SND_GLB_WDT_RST_ST:
215 reason = "WDOG";
216 break;
217 default:
218 reason = "unknown reset";
219 }
220
221 env_set("reset_reason", reason);
222
223 /*
224 * Clear cru_glb_rst_st, so we can determine the last reset cause
225 * for following resets.
226 */
227 rk_clrreg(&cru->cru_glb_rst_st, GLB_RST_ST_MASK);
228 }
229
rk3288_board_late_init(void)230 __weak int rk3288_board_late_init(void)
231 {
232 return 0;
233 }
234
rk_board_late_init(void)235 int rk_board_late_init(void)
236 {
237 rk3288_qos_init();
238 rk3288_detect_reset_reason();
239
240 return rk3288_board_late_init();
241 }
242
243 #if !CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
veyron_init(void)244 static int veyron_init(void)
245 {
246 struct udevice *dev;
247 struct clk clk;
248 int ret;
249
250 ret = regulator_get_by_platname("vdd_arm", &dev);
251 if (ret) {
252 debug("Cannot set regulator name\n");
253 return ret;
254 }
255
256 /* Slowly raise to max CPU voltage to prevent overshoot */
257 ret = regulator_set_value(dev, 1200000);
258 if (ret)
259 return ret;
260 udelay(175); /* Must wait for voltage to stabilize, 2mV/us */
261 ret = regulator_set_value(dev, 1400000);
262 if (ret)
263 return ret;
264 udelay(100); /* Must wait for voltage to stabilize, 2mV/us */
265
266 ret = rockchip_get_clk(&clk.dev);
267 if (ret)
268 return ret;
269 clk.id = PLL_APLL;
270 ret = clk_set_rate(&clk, 1800000000);
271 if (IS_ERR_VALUE(ret))
272 return ret;
273
274 return 0;
275 }
276
rk_board_init(void)277 int rk_board_init(void)
278 {
279 int ret;
280
281 /* We do some SoC one time setting here */
282 if (!fdt_node_check_compatible(gd->fdt_blob, 0, "google,veyron")) {
283 ret = veyron_init();
284 if (ret)
285 return ret;
286 }
287
288 return 0;
289 }
290 #endif
291
do_clock(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])292 static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc,
293 char * const argv[])
294 {
295 static const struct {
296 char *name;
297 int id;
298 } clks[] = {
299 { "osc", CLK_OSC },
300 { "apll", CLK_ARM },
301 { "dpll", CLK_DDR },
302 { "cpll", CLK_CODEC },
303 { "gpll", CLK_GENERAL },
304 #ifdef CONFIG_ROCKCHIP_RK3036
305 { "mpll", CLK_NEW },
306 #else
307 { "npll", CLK_NEW },
308 #endif
309 };
310 int ret, i;
311 struct udevice *dev;
312
313 ret = rockchip_get_clk(&dev);
314 if (ret) {
315 printf("clk-uclass not found\n");
316 return 0;
317 }
318
319 for (i = 0; i < ARRAY_SIZE(clks); i++) {
320 struct clk clk;
321 ulong rate;
322
323 clk.id = clks[i].id;
324 ret = clk_request(dev, &clk);
325 if (ret < 0)
326 continue;
327
328 rate = clk_get_rate(&clk);
329 printf("%s: %lu\n", clks[i].name, rate);
330
331 clk_free(&clk);
332 }
333
334 return 0;
335 }
336
337 U_BOOT_CMD(
338 clock, 2, 1, do_clock,
339 "display information about clocks",
340 ""
341 );
342
343 #define GRF_SOC_CON2 0xff77024c
344
board_early_init_f(void)345 int board_early_init_f(void)
346 {
347 struct udevice *pinctrl;
348 struct udevice *dev;
349 int ret;
350
351 /*
352 * This init is done in SPL, but when chain-loading U-Boot SPL will
353 * have been skipped. Allow the clock driver to check if it needs
354 * setting up.
355 */
356 ret = rockchip_get_clk(&dev);
357 if (ret) {
358 debug("CLK init failed: %d\n", ret);
359 return ret;
360 }
361 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
362 if (ret) {
363 debug("%s: Cannot find pinctrl device\n", __func__);
364 return ret;
365 }
366
367 /* Enable debug UART */
368 ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG);
369 if (ret) {
370 debug("%s: Failed to set up console UART\n", __func__);
371 return ret;
372 }
373 rk_setreg(GRF_SOC_CON2, 1 << 0);
374
375 return 0;
376 }
377
378 #ifndef CONFIG_SPL_BUILD
rk_board_fdt_fixup(void * blob)379 int rk_board_fdt_fixup(void *blob)
380 {
381 /* RK3288: Recognize RK3288W by HDMI Revision ID is 0x1A; */
382 if (soc_is_rk3288w()) {
383 if (fdt_setprop_string(blob, 0,
384 "compatible", "rockchip,rk3288w"))
385 printf("RK3288w set compatible failed!\n");
386 }
387
388 return 0;
389 }
390 #endif
391