]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
df9041ec HS |
2 | /* |
3 | * (C) Copyright 2015 Google, Inc | |
df9041ec HS |
4 | */ |
5 | ||
f4f57c58 | 6 | #include <clk.h> |
df9041ec HS |
7 | #include <common.h> |
8 | #include <debug_uart.h> | |
9 | #include <dm.h> | |
10 | #include <fdtdec.h> | |
11 | #include <led.h> | |
12 | #include <malloc.h> | |
13 | #include <ram.h> | |
14 | #include <spl.h> | |
15 | #include <asm/gpio.h> | |
16 | #include <asm/io.h> | |
17 | #include <asm/arch/bootrom.h> | |
18 | #include <asm/arch/clock.h> | |
5b5ca4c0 | 19 | #include <asm/arch/grf_rk3188.h> |
df9041ec HS |
20 | #include <asm/arch/hardware.h> |
21 | #include <asm/arch/periph.h> | |
22 | #include <asm/arch/pmu_rk3188.h> | |
23 | #include <asm/arch/sdram.h> | |
24 | #include <asm/arch/timer.h> | |
25 | #include <dm/pinctrl.h> | |
26 | #include <dm/root.h> | |
27 | #include <dm/test.h> | |
28 | #include <dm/util.h> | |
29 | #include <power/regulator.h> | |
30 | #include <syscon.h> | |
31 | ||
32 | DECLARE_GLOBAL_DATA_PTR; | |
33 | ||
34 | u32 spl_boot_device(void) | |
35 | { | |
36 | #if !CONFIG_IS_ENABLED(OF_PLATDATA) | |
37 | const void *blob = gd->fdt_blob; | |
38 | struct udevice *dev; | |
39 | const char *bootdev; | |
40 | int node; | |
41 | int ret; | |
42 | ||
43 | bootdev = fdtdec_get_config_string(blob, "u-boot,boot0"); | |
44 | debug("Boot device %s\n", bootdev); | |
45 | if (!bootdev) | |
46 | goto fallback; | |
47 | ||
48 | node = fdt_path_offset(blob, bootdev); | |
49 | if (node < 0) { | |
50 | debug("node=%d\n", node); | |
51 | goto fallback; | |
52 | } | |
7ec9181d | 53 | ret = device_get_global_by_ofnode(offset_to_ofnode(node), &dev); |
df9041ec HS |
54 | if (ret) { |
55 | debug("device at node %s/%d not found: %d\n", bootdev, node, | |
56 | ret); | |
57 | goto fallback; | |
58 | } | |
59 | debug("Found device %s\n", dev->name); | |
60 | switch (device_get_uclass_id(dev)) { | |
61 | case UCLASS_SPI_FLASH: | |
62 | return BOOT_DEVICE_SPI; | |
63 | case UCLASS_MMC: | |
64 | return BOOT_DEVICE_MMC1; | |
65 | default: | |
66 | debug("Booting from device uclass '%s' not supported\n", | |
67 | dev_get_uclass_name(dev)); | |
68 | } | |
69 | ||
70 | fallback: | |
71 | #endif | |
72 | return BOOT_DEVICE_MMC1; | |
73 | } | |
74 | ||
f4f57c58 HS |
75 | static int setup_arm_clock(void) |
76 | { | |
77 | struct udevice *dev; | |
78 | struct clk clk; | |
79 | int ret; | |
80 | ||
81 | ret = rockchip_get_clk(&dev); | |
82 | if (ret) | |
83 | return ret; | |
84 | ||
85 | clk.id = CLK_ARM; | |
86 | ret = clk_request(dev, &clk); | |
87 | if (ret < 0) | |
88 | return ret; | |
89 | ||
90 | ret = clk_set_rate(&clk, 600000000); | |
91 | ||
92 | clk_free(&clk); | |
93 | return ret; | |
94 | } | |
95 | ||
5b5ca4c0 HS |
96 | #define GRF_BASE 0x20008000 |
97 | ||
df9041ec HS |
98 | void board_init_f(ulong dummy) |
99 | { | |
5b5ca4c0 | 100 | __maybe_unused struct rk3188_grf * const grf = (void *)GRF_BASE; |
df9041ec | 101 | struct udevice *pinctrl, *dev; |
df9041ec HS |
102 | int ret; |
103 | ||
104 | /* Example code showing how to enable the debug UART on RK3188 */ | |
105 | #ifdef EARLY_UART | |
6c69ed19 HS |
106 | enum { |
107 | GPIO1B1_SHIFT = 2, | |
108 | GPIO1B1_MASK = 3, | |
109 | GPIO1B1_UART2_SOUT = 1, | |
110 | ||
111 | GPIO1B0_SHIFT = 0, | |
112 | GPIO1B0_MASK = 3, | |
113 | GPIO1B0_UART2_SIN = 1, | |
114 | }; | |
115 | ||
df9041ec | 116 | /* Enable early UART on the RK3188 */ |
df9041ec HS |
117 | rk_clrsetreg(&grf->gpio1b_iomux, |
118 | GPIO1B1_MASK << GPIO1B1_SHIFT | | |
119 | GPIO1B0_MASK << GPIO1B0_SHIFT, | |
120 | GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT | | |
121 | GPIO1B0_UART2_SIN << GPIO1B0_SHIFT); | |
122 | /* | |
123 | * Debug UART can be used from here if required: | |
124 | * | |
125 | * debug_uart_init(); | |
126 | * printch('a'); | |
127 | * printhex8(0x1234); | |
128 | * printascii("string"); | |
129 | */ | |
130 | debug_uart_init(); | |
131 | printch('s'); | |
132 | printch('p'); | |
133 | printch('l'); | |
134 | printch('\n'); | |
135 | #endif | |
136 | ||
5b5ca4c0 HS |
137 | #ifdef CONFIG_ROCKCHIP_USB_UART |
138 | rk_clrsetreg(&grf->uoc0_con[0], | |
139 | SIDDQ_MASK | UOC_DISABLE_MASK | COMMON_ON_N_MASK, | |
140 | 1 << SIDDQ_SHIFT | 1 << UOC_DISABLE_SHIFT | | |
141 | 1 << COMMON_ON_N_SHIFT); | |
142 | rk_clrsetreg(&grf->uoc0_con[2], | |
143 | SOFT_CON_SEL_MASK, 1 << SOFT_CON_SEL_SHIFT); | |
144 | rk_clrsetreg(&grf->uoc0_con[3], | |
145 | OPMODE_MASK | XCVRSELECT_MASK | | |
146 | TERMSEL_FULLSPEED_MASK | SUSPENDN_MASK, | |
147 | OPMODE_NODRIVING << OPMODE_SHIFT | | |
148 | XCVRSELECT_FSTRANSC << XCVRSELECT_SHIFT | | |
149 | 1 << TERMSEL_FULLSPEED_SHIFT | | |
150 | 1 << SUSPENDN_SHIFT); | |
151 | rk_clrsetreg(&grf->uoc0_con[0], | |
152 | BYPASSSEL_MASK | BYPASSDMEN_MASK, | |
153 | 1 << BYPASSSEL_SHIFT | 1 << BYPASSDMEN_SHIFT); | |
154 | #endif | |
155 | ||
232cf962 | 156 | ret = spl_early_init(); |
df9041ec | 157 | if (ret) { |
232cf962 | 158 | debug("spl_early_init() failed: %d\n", ret); |
df9041ec HS |
159 | hang(); |
160 | } | |
161 | ||
df9041ec HS |
162 | ret = rockchip_get_clk(&dev); |
163 | if (ret) { | |
164 | debug("CLK init failed: %d\n", ret); | |
165 | return; | |
166 | } | |
167 | ||
df9041ec HS |
168 | ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); |
169 | if (ret) { | |
170 | debug("Pinctrl init failed: %d\n", ret); | |
171 | return; | |
172 | } | |
173 | ||
174 | ret = uclass_get_device(UCLASS_RAM, 0, &dev); | |
175 | if (ret) { | |
176 | debug("DRAM init failed: %d\n", ret); | |
177 | return; | |
178 | } | |
179 | ||
f4f57c58 | 180 | setup_arm_clock(); |
ee14d29d | 181 | #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT) |
b82bd1f8 | 182 | back_to_bootrom(BROM_BOOT_NEXTSTAGE); |
df9041ec HS |
183 | #endif |
184 | } | |
185 | ||
186 | static int setup_led(void) | |
187 | { | |
188 | #ifdef CONFIG_SPL_LED | |
189 | struct udevice *dev; | |
190 | char *led_name; | |
191 | int ret; | |
192 | ||
193 | led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led"); | |
194 | if (!led_name) | |
195 | return 0; | |
196 | ret = led_get_by_label(led_name, &dev); | |
197 | if (ret) { | |
198 | debug("%s: get=%d\n", __func__, ret); | |
199 | return ret; | |
200 | } | |
201 | ret = led_set_on(dev, 1); | |
202 | if (ret) | |
203 | return ret; | |
204 | #endif | |
205 | ||
206 | return 0; | |
207 | } | |
208 | ||
209 | void spl_board_init(void) | |
210 | { | |
211 | struct udevice *pinctrl; | |
212 | int ret; | |
213 | ||
214 | ret = setup_led(); | |
215 | if (ret) { | |
216 | debug("LED ret=%d\n", ret); | |
217 | hang(); | |
218 | } | |
219 | ||
220 | ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); | |
221 | if (ret) { | |
222 | debug("%s: Cannot find pinctrl device\n", __func__); | |
223 | goto err; | |
224 | } | |
225 | ||
226 | #ifdef CONFIG_SPL_MMC_SUPPORT | |
227 | ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD); | |
228 | if (ret) { | |
229 | debug("%s: Failed to set up SD card\n", __func__); | |
230 | goto err; | |
231 | } | |
232 | #endif | |
233 | ||
234 | /* Enable debug UART */ | |
235 | ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG); | |
236 | if (ret) { | |
237 | debug("%s: Failed to set up console UART\n", __func__); | |
238 | goto err; | |
239 | } | |
240 | ||
241 | preloader_console_init(); | |
ee14d29d | 242 | #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) |
b82bd1f8 | 243 | back_to_bootrom(BROM_BOOT_NEXTSTAGE); |
df9041ec HS |
244 | #endif |
245 | return; | |
246 | ||
247 | err: | |
248 | printf("spl_board_init: Error %d\n", ret); | |
249 | ||
250 | /* No way to report error here */ | |
251 | hang(); | |
252 | } |