xref: /OK3568_Linux_fs/u-boot/arch/arm/mach-rockchip/rk3288/rk3288.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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