1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2020 Rockchip Electronics Co., Ltd
4 */
5
6 #include <common.h>
7 #include <fdt_support.h>
8 #include <ram.h>
9 #include <asm/io.h>
10 #include <asm/arch/boot_mode.h>
11 #include <asm/arch/bootrom.h>
12 #include <asm/arch/cru_rk3308.h>
13 #include <asm/arch/cpu.h>
14 #include <asm/arch/grf_rk3308.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/arch/rk_atags.h>
17 #include <asm/gpio.h>
18 #include <asm/arch/sdram_common.h>
19 #include <debug_uart.h>
20
21 DECLARE_GLOBAL_DATA_PTR;
22
23 #ifdef CONFIG_ARM64
24 #include <asm/armv8/mmu.h>
25 static struct mm_region rk3308_mem_map[] = {
26 {
27 .virt = 0x0UL,
28 .phys = 0x0UL,
29 .size = 0xff000000UL,
30 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
31 PTE_BLOCK_INNER_SHARE
32 }, {
33 .virt = 0xff000000UL,
34 .phys = 0xff000000UL,
35 .size = 0x01000000UL,
36 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
37 PTE_BLOCK_NON_SHARE |
38 PTE_BLOCK_PXN | PTE_BLOCK_UXN
39 }, {
40 /* List terminator */
41 0,
42 }
43 };
44
45 struct mm_region *mem_map = rk3308_mem_map;
46 #endif
47
48 #define GRF_BASE 0xff000000
49 #define SGRF_BASE 0xff2b0000
50 #define CRU_BASE 0xff500000
51
52 enum {
53 GPIO1C7_SHIFT = 8,
54 GPIO1C7_MASK = GENMASK(11, 8),
55 GPIO1C7_GPIO = 0,
56 GPIO1C7_UART1_RTSN,
57 GPIO1C7_UART2_TX_M0,
58 GPIO1C7_SPI2_MOSI,
59 GPIO1C7_JTAG_TMS,
60
61 GPIO1C6_SHIFT = 4,
62 GPIO1C6_MASK = GENMASK(7, 4),
63 GPIO1C6_GPIO = 0,
64 GPIO1C6_UART1_CTSN,
65 GPIO1C6_UART2_RX_M0,
66 GPIO1C6_SPI2_MISO,
67 GPIO1C6_JTAG_TCLK,
68
69 GPIO4D3_SHIFT = 6,
70 GPIO4D3_MASK = GENMASK(7, 6),
71 GPIO4D3_GPIO = 0,
72 GPIO4D3_SDMMC_D3,
73 GPIO4D3_UART2_TX_M1,
74
75 GPIO4D2_SHIFT = 4,
76 GPIO4D2_MASK = GENMASK(5, 4),
77 GPIO4D2_GPIO = 0,
78 GPIO4D2_SDMMC_D2,
79 GPIO4D2_UART2_RX_M1,
80
81 UART2_IO_SEL_SHIFT = 2,
82 UART2_IO_SEL_MASK = GENMASK(3, 2),
83 UART2_IO_SEL_M0 = 0,
84 UART2_IO_SEL_M1,
85 UART2_IO_SEL_USB,
86
87 GPIO3B3_SEL_SRC_CTRL_SHIFT = 7,
88 GPIO3B3_SEL_SRC_CTRL_MASK = BIT(7),
89 GPIO3B3_SEL_SRC_CTRL_IOMUX = 0,
90 GPIO3B3_SEL_SRC_CTRL_SEL_PLUS,
91
92 GPIO3B3_SEL_PLUS_SHIFT = 4,
93 GPIO3B3_SEL_PLUS_MASK = GENMASK(6, 4),
94 GPIO3B3_SEL_PLUS_GPIO3_B3 = 0,
95 GPIO3B3_SEL_PLUS_FLASH_ALE,
96 GPIO3B3_SEL_PLUS_EMMC_PWREN,
97 GPIO3B3_SEL_PLUS_SPI1_CLK,
98 GPIO3B3_SEL_PLUS_LCDC_D23_M1,
99
100 GPIO3B2_SEL_SRC_CTRL_SHIFT = 3,
101 GPIO3B2_SEL_SRC_CTRL_MASK = BIT(3),
102 GPIO3B2_SEL_SRC_CTRL_IOMUX = 0,
103 GPIO3B2_SEL_SRC_CTRL_SEL_PLUS,
104
105 GPIO3B2_SEL_PLUS_SHIFT = 0,
106 GPIO3B2_SEL_PLUS_MASK = GENMASK(2, 0),
107 GPIO3B2_SEL_PLUS_GPIO3_B2 = 0,
108 GPIO3B2_SEL_PLUS_FLASH_RDN,
109 GPIO3B2_SEL_PLUS_EMMC_RSTN,
110 GPIO3B2_SEL_PLUS_SPI1_MISO,
111 GPIO3B2_SEL_PLUS_LCDC_D22_M1,
112 };
113
114 enum {
115 IOVSEL3_CTRL_SHIFT = 8,
116 IOVSEL3_CTRL_MASK = BIT(8),
117 VCCIO3_SEL_BY_GPIO = 0,
118 VCCIO3_SEL_BY_IOVSEL3,
119
120 IOVSEL3_SHIFT = 3,
121 IOVSEL3_MASK = BIT(3),
122 VCCIO3_3V3 = 0,
123 VCCIO3_1V8,
124 };
125
126 enum {
127 SND_GLB_WDT_RST = BIT(3),
128 FST_GLB_WDT_RST = BIT(2),
129 };
130
131 /*
132 * The voltage of VCCIO3(which is the voltage domain of emmc/flash/sfc
133 * interface) can indicated by GPIO0_A4 or io_vsel3. The SOC defaults
134 * use GPIO0_A4 to indicate power supply voltage for VCCIO3 by hardware,
135 * then we can switch to io_vsel3 after system power on, and release GPIO0_A4
136 * for other usage.
137 */
138
139 #define GPIO0_A4 4
140
rk_board_init(void)141 int rk_board_init(void)
142 {
143 static struct rk3308_grf * const grf = (void *)GRF_BASE;
144 u32 val;
145 int ret;
146
147 ret = gpio_request(GPIO0_A4, "gpio0_a4");
148 if (ret < 0) {
149 printf("request for gpio0_a4 failed:%d\n", ret);
150 return 0;
151 }
152
153 gpio_direction_input(GPIO0_A4);
154
155 if (gpio_get_value(GPIO0_A4))
156 val = VCCIO3_SEL_BY_IOVSEL3 << IOVSEL3_CTRL_SHIFT |
157 VCCIO3_1V8 << IOVSEL3_SHIFT;
158 else
159 val = VCCIO3_SEL_BY_IOVSEL3 << IOVSEL3_CTRL_SHIFT |
160 VCCIO3_3V3 << IOVSEL3_SHIFT;
161 rk_clrsetreg(&grf->soc_con0, IOVSEL3_CTRL_MASK | IOVSEL3_MASK, val);
162
163 gpio_free(GPIO0_A4);
164 return 0;
165 }
166
167 #define SERVICE_CPU_BASE 0xff5c0000
168 #define SERVICE_VOICE_BASE 0xff5d0000
169 #define SERVICE_LOGIC_BASE 0xff5d8000
170 #define SERVICE_PERI_BASE 0xff5e0000
171 #define SERVICE_CPU_ADDR (SERVICE_CPU_BASE + 0x80)
172 #define SERVICE_VOP_ADDR (SERVICE_LOGIC_BASE + 0x100)
173 #define SERVICE_DMAC0_ADDR (SERVICE_LOGIC_BASE + 0x0)
174 #define SERVICE_DMAC1_ADDR (SERVICE_LOGIC_BASE + 0x80)
175 #define SERVICE_CRYPTO_ADDR (SERVICE_LOGIC_BASE + 0x180)
176 #define SERVICE_VAD_ADDR (SERVICE_VOICE_BASE + 0x80)
177 #define SERVICE_EMMC_ADDR (SERVICE_PERI_BASE + 0x80)
178 #define SERVICE_GMAC_ADDR (SERVICE_PERI_BASE + 0x100)
179 #define SERVICE_NAND_ADDR (SERVICE_PERI_BASE + 0x180)
180 #define SERVICE_SDIO_ADDR (SERVICE_PERI_BASE + 0x200)
181 #define SERVICE_SDMMC_ADDR (SERVICE_PERI_BASE + 0x280)
182 #define SERVICE_SFC_ADDR (SERVICE_PERI_BASE + 0x300)
183 #define SERVICE_USB_HOST_ADDR (SERVICE_PERI_BASE + 0x380)
184 #define SERVICE_USB_OTG_ADDR (SERVICE_PERI_BASE + 0x400)
185
186 #define DOS_PRIORITY_OFFSET 0x8
187 #define QOS_PRIORITY_P1_P0(p1, p0) ((((p1) & 0x3) << 8) |\
188 (((p0) & 0x3) << 0))
189
190 enum {
191 IOVSEL4_SHIFT = 4,
192 IOVSEL4_MASK = BIT(4),
193 VCCIO4_3V3 = 0,
194 VCCIO4_1V8,
195 };
196
arch_cpu_init(void)197 int arch_cpu_init(void)
198 {
199 #ifndef CONFIG_TPL_BUILD
200 #ifdef CONFIG_SPL_BUILD
201 static struct rk3308_sgrf * const sgrf = (void *)SGRF_BASE;
202
203 /* Set CRYPTO SDMMC EMMC NAND SFC USB master bus to be secure access */
204 rk_clrreg(&sgrf->con_secure0, 0x2b83);
205 #endif
206 #else /* defined(CONFIG_TPL_BUILD) */
207 static struct rk3308_cru * const cru = (void *)CRU_BASE;
208 static struct rk3308_grf * const grf = (void *)GRF_BASE;
209 u32 glb_rst_st;
210
211 /*
212 * RK3308 internally default select 1.8v for VCCIO4 on reset state,
213 * but some boards may give a 3.3V power supply for VCCIO4, this may
214 * bring a risk of chip damage through overvoltage. So we internally
215 * select 3.3V for VCCIO4 as early as possiple to reduces this risk.
216 */
217 rk_clrsetreg(&grf->soc_con0, IOVSEL4_MASK, VCCIO4_3V3 << IOVSEL4_SHIFT);
218
219 /*
220 * write BOOT_WATCHDOG to boot mode register, if we are reset by wdt
221 */
222 glb_rst_st = readl(&cru->glb_rst_st);
223 writel(FST_GLB_WDT_RST | SND_GLB_WDT_RST, &cru->glb_rst_st);
224 if (glb_rst_st & (FST_GLB_WDT_RST | SND_GLB_WDT_RST))
225 writel(BOOT_WATCHDOG, CONFIG_ROCKCHIP_BOOT_MODE_REG);
226
227 /* set wdt tsadc first global reset*/
228 writel(WDT_GLB_SRST_CTRL << WDT_GLB_SRST_CTRL_SHIFT |
229 TSADC_GLB_SRST_CTRL << TSADC_GLB_SRST_CTRL_SHIFT,
230 &cru->glb_rst_con);
231
232 /* Set qos priority level */
233 writel(QOS_PRIORITY_P1_P0(1, 1),
234 SERVICE_CPU_ADDR + DOS_PRIORITY_OFFSET);
235 writel(QOS_PRIORITY_P1_P0(3, 3),
236 SERVICE_VOP_ADDR + DOS_PRIORITY_OFFSET);
237 writel(QOS_PRIORITY_P1_P0(2, 2),
238 SERVICE_DMAC0_ADDR + DOS_PRIORITY_OFFSET);
239 writel(QOS_PRIORITY_P1_P0(2, 2),
240 SERVICE_DMAC1_ADDR + DOS_PRIORITY_OFFSET);
241 writel(QOS_PRIORITY_P1_P0(2, 2),
242 SERVICE_CRYPTO_ADDR + DOS_PRIORITY_OFFSET);
243 writel(QOS_PRIORITY_P1_P0(3, 3),
244 SERVICE_VAD_ADDR + DOS_PRIORITY_OFFSET);
245 writel(QOS_PRIORITY_P1_P0(2, 2),
246 SERVICE_EMMC_ADDR + DOS_PRIORITY_OFFSET);
247 writel(QOS_PRIORITY_P1_P0(2, 2),
248 SERVICE_GMAC_ADDR + DOS_PRIORITY_OFFSET);
249 writel(QOS_PRIORITY_P1_P0(2, 2),
250 SERVICE_NAND_ADDR + DOS_PRIORITY_OFFSET);
251 writel(QOS_PRIORITY_P1_P0(2, 2),
252 SERVICE_SDIO_ADDR + DOS_PRIORITY_OFFSET);
253 writel(QOS_PRIORITY_P1_P0(2, 2),
254 SERVICE_SDMMC_ADDR + DOS_PRIORITY_OFFSET);
255 writel(QOS_PRIORITY_P1_P0(2, 2),
256 SERVICE_SFC_ADDR + DOS_PRIORITY_OFFSET);
257 writel(QOS_PRIORITY_P1_P0(2, 2),
258 SERVICE_USB_HOST_ADDR + DOS_PRIORITY_OFFSET);
259 writel(QOS_PRIORITY_P1_P0(2, 2),
260 SERVICE_USB_OTG_ADDR + DOS_PRIORITY_OFFSET);
261 #endif
262 return 0;
263 }
264
265 #ifdef CONFIG_SPL_BUILD
rk_board_init_f(void)266 int rk_board_init_f(void)
267 {
268 static struct rk3308_grf * const grf = (void *)GRF_BASE;
269 unsigned long mask;
270 unsigned long value;
271
272 mask = GPIO3B2_SEL_PLUS_MASK | GPIO3B2_SEL_SRC_CTRL_MASK |
273 GPIO3B3_SEL_PLUS_MASK | GPIO3B3_SEL_SRC_CTRL_MASK;
274 value = (GPIO3B2_SEL_PLUS_FLASH_RDN << GPIO3B2_SEL_PLUS_SHIFT) |
275 (GPIO3B2_SEL_SRC_CTRL_SEL_PLUS << GPIO3B2_SEL_SRC_CTRL_SHIFT) |
276 (GPIO3B3_SEL_PLUS_FLASH_ALE << GPIO3B3_SEL_PLUS_SHIFT) |
277 (GPIO3B3_SEL_SRC_CTRL_SEL_PLUS << GPIO3B3_SEL_SRC_CTRL_SHIFT);
278
279 if (get_bootdev_by_brom_bootsource() == BOOT_TYPE_NAND) {
280 if (soc_is_rk3308b() || soc_is_rk3308bs())
281 rk_clrsetreg(&grf->soc_con15, mask, value);
282 }
283
284 return 0;
285 }
286 #endif
287
board_debug_uart_init(void)288 void board_debug_uart_init(void)
289 {
290 static struct rk3308_cru * const cru = (void *)CRU_BASE;
291 static struct rk3308_grf * const grf = (void *)GRF_BASE;
292
293 #if defined(CONFIG_DEBUG_UART_BASE)
294 #if (CONFIG_DEBUG_UART_BASE == 0xFF0C0000)
295 /*select 24M clock to UART2 */
296 rk_clrsetreg(&cru->clksel_con[16],
297 CLK_UART2_PLL_SEL_MASK | CLK_UART2_DIV_CON_MASK,
298 CLK_UART2_PLL_SEL_XIN_OSC0 << CLK_UART2_PLL_SEL_SHIFT |
299 CLK_UART2_DIV_CON << CLK_UART2_DIV_CON_SHIFT);
300
301 #if (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0)
302 /* Enable early UART2 channel m0 on the rk3308 */
303 rk_clrsetreg(&grf->soc_con5, UART2_IO_SEL_MASK,
304 UART2_IO_SEL_M0 << UART2_IO_SEL_SHIFT);
305 rk_clrsetreg(&grf->gpio1ch_iomux, GPIO1C7_MASK | GPIO1C6_MASK,
306 GPIO1C7_UART2_TX_M0 << GPIO1C7_SHIFT |
307 GPIO1C6_UART2_RX_M0 << GPIO1C6_SHIFT);
308
309 #elif (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1)
310 /* Enable early UART2 channel m1 on the rk3308 */
311 rk_clrsetreg(&grf->soc_con5, UART2_IO_SEL_MASK,
312 UART2_IO_SEL_M1 << UART2_IO_SEL_SHIFT);
313 if (readl(BROM_BOOTSOURCE_ID_ADDR) != BROM_BOOTSOURCE_SD)
314 rk_clrsetreg(&grf->gpio4d_iomux,
315 GPIO4D3_MASK | GPIO4D2_MASK,
316 GPIO4D2_UART2_RX_M1 << GPIO4D2_SHIFT |
317 GPIO4D3_UART2_TX_M1 << GPIO4D3_SHIFT);
318 #else
319 #error "Please select M0 or M1 for uart2 !!!"
320 #endif
321
322 #elif (CONFIG_DEBUG_UART_BASE == 0xFF0E0000)
323 /*select 24M clock to UART4 */
324 rk_clrsetreg(&cru->clksel_con[22],
325 CLK_UART4_PLL_SEL_MASK | CLK_UART4_DIV_CON_MASK,
326 CLK_UART4_PLL_SEL_XIN_OSC0 << CLK_UART4_PLL_SEL_SHIFT |
327 CLK_UART4_DIV_CON << CLK_UART4_DIV_CON_SHIFT);
328
329 rk_clrsetreg(&grf->gpio4b_iomux,
330 GPIO4B1_SEL_MASK | GPIO4B0_SEL_MASK,
331 GPIO4B1_SEL_UART4_TX << GPIO4B1_SEL_SHIFT |
332 GPIO4B0_SEL_UART4_RX << GPIO4B0_SEL_SHIFT);
333 #elif (CONFIG_DEBUG_UART_BASE == 0xFF0A0000)
334 /*select 24M clock to UART0 */
335 rk_clrsetreg(&cru->clksel_con[10],
336 CLK_UART0_PLL_SEL_MASK | CLK_UART0_DIV_CON_MASK,
337 CLK_UART0_PLL_SEL_XIN_OSC0 << CLK_UART0_PLL_SEL_SHIFT |
338 CLK_UART0_DIV_CON << CLK_UART0_DIV_CON_SHIFT);
339
340 rk_clrsetreg(&grf->gpio2a_iomux,
341 GPIO2A1_SEL_MASK | GPIO2A0_SEL_MASK,
342 GPIO2A1_SEL_UART0_TX << GPIO2A1_SEL_SHIFT |
343 GPIO2A0_SEL_UART0_RX << GPIO2A0_SEL_SHIFT);
344 #elif (CONFIG_DEBUG_UART_BASE == 0xFF0B0000)
345 /*select 24M clock to UART1 */
346 rk_clrsetreg(&cru->clksel_con[13],
347 CLK_UART1_PLL_SEL_MASK | CLK_UART1_DIV_CON_MASK,
348 CLK_UART1_PLL_SEL_XIN_OSC0 << CLK_UART1_PLL_SEL_SHIFT |
349 CLK_UART1_DIV_CON << CLK_UART1_DIV_CON_SHIFT);
350
351 rk_clrsetreg(&grf->gpio1d_iomux,
352 GPIO1D1_SEL_MASK | GPIO1D0_SEL_MASK,
353 GPIO1D1_SEL_UART1_TX << GPIO1D1_SEL_SHIFT |
354 GPIO1D1_SEL_UART1_RX << GPIO1D0_SEL_SHIFT);
355 #elif (CONFIG_DEBUG_UART_BASE == 0xFF0D0000)
356 /*select 24M clock to UART3 */
357 rk_clrsetreg(&cru->clksel_con[19],
358 CLK_UART3_PLL_SEL_MASK | CLK_UART3_DIV_CON_MASK,
359 CLK_UART3_PLL_SEL_XIN_OSC0 << CLK_UART3_PLL_SEL_SHIFT |
360 CLK_UART3_DIV_CON << CLK_UART3_DIV_CON_SHIFT);
361
362 rk_clrsetreg(&grf->gpio3b_iomux,
363 GPIO3B5_SEL_MASK | GPIO3B4_SEL_MASK,
364 GPIO3B5_SEL_UART3_TX << GPIO3B5_SEL_SHIFT |
365 GPIO3B4_SEL_UART3_RX << GPIO3B4_SEL_SHIFT);
366 #else
367 #error "Please select proper uart as debug uart !!!"
368 #endif
369 #endif /* defined(CONFIG_DEBUG_UART_BASE) */
370 }
371
fdt_fixup_cpu_idle(const void * blob)372 static int fdt_fixup_cpu_idle(const void *blob)
373 {
374 int cpu_node, sub_node, len;
375 u32 *pp;
376
377 cpu_node = fdt_path_offset(blob, "/cpus");
378 if (cpu_node < 0) {
379 printf("Failed to get cpus node\n");
380 return -EINVAL;
381 }
382
383 fdt_for_each_subnode(sub_node, blob, cpu_node) {
384 pp = (u32 *)fdt_getprop(blob, sub_node, "cpu-idle-states",
385 &len);
386 if (!pp)
387 continue;
388 if (fdt_delprop((void *)blob, sub_node, "cpu-idle-states") < 0)
389 printf("Failed to del cpu-idle-states prop\n");
390 }
391
392 return 0;
393 }
394
fdt_fixup_cpu_opp_table(const void * blob)395 static int fdt_fixup_cpu_opp_table(const void *blob)
396 {
397 int opp_node, cpu_node, sub_node;
398 int len;
399 u32 phandle;
400 u32 *pp;
401
402 /* Replace opp table */
403 opp_node = fdt_path_offset(blob, "/rk3308bs-cpu0-opp-table");
404 if (opp_node < 0) {
405 printf("Failed to get rk3308bs-cpu0-opp-table node\n");
406 return -EINVAL;
407 }
408
409 phandle = fdt_get_phandle(blob, opp_node);
410 if (!phandle) {
411 printf("Failed to get cpu opp table phandle\n");
412 return -EINVAL;
413 }
414
415 cpu_node = fdt_path_offset(blob, "/cpus");
416 if (cpu_node < 0) {
417 printf("Failed to get cpus node\n");
418 return -EINVAL;
419 }
420
421 fdt_for_each_subnode(sub_node, blob, cpu_node) {
422 pp = (u32 *)fdt_getprop(blob, sub_node, "operating-points-v2",
423 &len);
424 if (!pp)
425 continue;
426 pp[0] = cpu_to_fdt32(phandle);
427 }
428
429 return 0;
430 }
431
fdt_fixup_dmc_opp_table(const void * blob)432 static int fdt_fixup_dmc_opp_table(const void *blob)
433 {
434 int opp_node, dmc_node;
435 int len;
436 u32 phandle;
437 u32 *pp;
438
439 opp_node = fdt_path_offset(blob, "/rk3308bs-dmc-opp-table");
440 if (opp_node < 0) {
441 printf("Failed to get rk3308bs-dmc-opp-table node\n");
442 return -EINVAL;
443 }
444
445 phandle = fdt_get_phandle(blob, opp_node);
446 if (!phandle) {
447 printf("Failed to get dmc opp table phandle\n");
448 return -EINVAL;
449 }
450
451 dmc_node = fdt_path_offset(blob, "/dmc");
452 if (dmc_node < 0) {
453 printf("Failed to get dmc node\n");
454 return -EINVAL;
455 }
456
457 pp = (u32 *)fdt_getprop(blob, dmc_node, "operating-points-v2", &len);
458 if (!pp)
459 return 0;
460 pp[0] = cpu_to_fdt32(phandle);
461
462 return 0;
463 }
464
fixup_pcfg_drive_strength(const void * blob,int noffset)465 static void fixup_pcfg_drive_strength(const void *blob, int noffset)
466 {
467 u32 *ds, *dss;
468 u32 val;
469
470 dss = (u32 *)fdt_getprop(blob, noffset, "drive-strength-s", NULL);
471 if (!dss)
472 return;
473
474 val = dss[0];
475 ds = (u32 *)fdt_getprop(blob, noffset, "drive-strength", NULL);
476 if (ds) {
477 ds[0] = val;
478 } else {
479 if (fdt_setprop((void *)blob, noffset,
480 "drive-strength", &val, 4) < 0)
481 printf("Failed to add drive-strength prop\n");
482 }
483 }
484
fdt_fixup_pcfg(const void * blob)485 static int fdt_fixup_pcfg(const void *blob)
486 {
487 int depth1_node;
488 int depth2_node;
489 int root_node, i;
490 const char *path[] = { "/", "/pinctrl" };
491
492 for (i = 0; i < ARRAY_SIZE(path); i++) {
493 root_node = fdt_path_offset(blob, path[i]);
494 if (root_node < 0)
495 return root_node;
496
497 fdt_for_each_subnode(depth1_node, blob, root_node) {
498 debug("depth1: %s\n", fdt_get_name(blob, depth1_node, NULL));
499 fixup_pcfg_drive_strength(blob, depth1_node);
500 fdt_for_each_subnode(depth2_node, blob, depth1_node) {
501 debug(" depth2: %s\n",
502 fdt_get_name(blob, depth2_node, NULL));
503 fixup_pcfg_drive_strength(blob, depth2_node);
504 }
505 }
506 }
507 return 0;
508 }
509
fdt_fixup_thermal_zones(const void * blob)510 static int fdt_fixup_thermal_zones(const void *blob)
511 {
512 int thermal_node;
513 int len;
514 u32 *pp;
515 u32 val;
516
517 thermal_node = fdt_path_offset(blob, "/thermal-zones/soc-thermal");
518 if (thermal_node < 0) {
519 printf("Failed to get soc thermal node\n");
520 return -EINVAL;
521 }
522
523 pp = (u32 *)fdt_getprop(blob, thermal_node,
524 "rk3308bs-sustainable-power", &len);
525 if (pp) {
526 val = fdt32_to_cpu(*pp);
527 pp = (u32 *)fdt_getprop(blob, thermal_node,
528 "sustainable-power", &len);
529 if (pp)
530 pp[0] = cpu_to_fdt32(val);
531 }
532
533 return 0;
534 }
535
rk_board_fdt_fixup(const void * blob)536 int rk_board_fdt_fixup(const void *blob)
537 {
538 if (soc_is_rk3308bs()) {
539 fdt_increase_size((void *)blob, SZ_8K);
540 fdt_fixup_cpu_idle(blob);
541 fdt_fixup_cpu_opp_table(blob);
542 fdt_fixup_dmc_opp_table(blob);
543 fdt_fixup_pcfg(blob);
544 fdt_fixup_thermal_zones(blob);
545 }
546
547 return 0;
548 }
549
rk_board_early_fdt_fixup(const void * blob)550 int rk_board_early_fdt_fixup(const void *blob)
551 {
552 rk_board_fdt_fixup(blob);
553
554 return 0;
555 }
556
557