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 #define CRU_CLKGATE_CON10 0x0328
191 #define CRU_CLKGATE_CON11 0x032c
192 #define CRU_CLKGATE_CON12 0x0330
193
194 enum {
195 IOVSEL4_SHIFT = 4,
196 IOVSEL4_MASK = BIT(4),
197 VCCIO4_3V3 = 0,
198 VCCIO4_1V8,
199 };
200
arch_cpu_init(void)201 int arch_cpu_init(void)
202 {
203 #ifndef CONFIG_TPL_BUILD
204 #ifdef CONFIG_SPL_BUILD
205 static struct rk3308_sgrf * const sgrf = (void *)SGRF_BASE;
206
207 /* Set CRYPTO SDMMC EMMC NAND SFC USB master bus to be secure access */
208 rk_clrreg(&sgrf->con_secure0, 0x2b83);
209 #else /* uboot */
210
211 /*
212 * Gate I2Sx_MCLK default
213 *
214 * It's safe to gate mclk default to avoid high freq glitch
215 * which may make devices work unexpected. And then enabled by
216 * kernel stage or any state where user use it.
217 */
218 writel(0x80008000, CRU_BASE + CRU_CLKGATE_CON10);
219 writel(0x88888888, CRU_BASE + CRU_CLKGATE_CON11);
220 writel(0x88888888, CRU_BASE + CRU_CLKGATE_CON12);
221 #endif
222 #else /* defined(CONFIG_TPL_BUILD) */
223 static struct rk3308_cru * const cru = (void *)CRU_BASE;
224 static struct rk3308_grf * const grf = (void *)GRF_BASE;
225 u32 glb_rst_st;
226
227 /*
228 * RK3308 internally default select 1.8v for VCCIO4 on reset state,
229 * but some boards may give a 3.3V power supply for VCCIO4, this may
230 * bring a risk of chip damage through overvoltage. So we internally
231 * select 3.3V for VCCIO4 as early as possiple to reduces this risk.
232 */
233 rk_clrsetreg(&grf->soc_con0, IOVSEL4_MASK, VCCIO4_3V3 << IOVSEL4_SHIFT);
234
235 /*
236 * write BOOT_WATCHDOG to boot mode register, if we are reset by wdt
237 */
238 glb_rst_st = readl(&cru->glb_rst_st);
239 writel(FST_GLB_WDT_RST | SND_GLB_WDT_RST, &cru->glb_rst_st);
240 if (glb_rst_st & (FST_GLB_WDT_RST | SND_GLB_WDT_RST))
241 writel(BOOT_WATCHDOG, CONFIG_ROCKCHIP_BOOT_MODE_REG);
242
243 /* set wdt tsadc first global reset*/
244 writel(WDT_GLB_SRST_CTRL << WDT_GLB_SRST_CTRL_SHIFT |
245 TSADC_GLB_SRST_CTRL << TSADC_GLB_SRST_CTRL_SHIFT,
246 &cru->glb_rst_con);
247
248 /* Set qos priority level */
249 writel(QOS_PRIORITY_P1_P0(1, 1),
250 SERVICE_CPU_ADDR + DOS_PRIORITY_OFFSET);
251 writel(QOS_PRIORITY_P1_P0(3, 3),
252 SERVICE_VOP_ADDR + DOS_PRIORITY_OFFSET);
253 writel(QOS_PRIORITY_P1_P0(2, 2),
254 SERVICE_DMAC0_ADDR + DOS_PRIORITY_OFFSET);
255 writel(QOS_PRIORITY_P1_P0(2, 2),
256 SERVICE_DMAC1_ADDR + DOS_PRIORITY_OFFSET);
257 writel(QOS_PRIORITY_P1_P0(2, 2),
258 SERVICE_CRYPTO_ADDR + DOS_PRIORITY_OFFSET);
259 writel(QOS_PRIORITY_P1_P0(3, 3),
260 SERVICE_VAD_ADDR + DOS_PRIORITY_OFFSET);
261 writel(QOS_PRIORITY_P1_P0(2, 2),
262 SERVICE_EMMC_ADDR + DOS_PRIORITY_OFFSET);
263 writel(QOS_PRIORITY_P1_P0(2, 2),
264 SERVICE_GMAC_ADDR + DOS_PRIORITY_OFFSET);
265 writel(QOS_PRIORITY_P1_P0(2, 2),
266 SERVICE_NAND_ADDR + DOS_PRIORITY_OFFSET);
267 writel(QOS_PRIORITY_P1_P0(2, 2),
268 SERVICE_SDIO_ADDR + DOS_PRIORITY_OFFSET);
269 writel(QOS_PRIORITY_P1_P0(2, 2),
270 SERVICE_SDMMC_ADDR + DOS_PRIORITY_OFFSET);
271 writel(QOS_PRIORITY_P1_P0(2, 2),
272 SERVICE_SFC_ADDR + DOS_PRIORITY_OFFSET);
273 writel(QOS_PRIORITY_P1_P0(2, 2),
274 SERVICE_USB_HOST_ADDR + DOS_PRIORITY_OFFSET);
275 writel(QOS_PRIORITY_P1_P0(2, 2),
276 SERVICE_USB_OTG_ADDR + DOS_PRIORITY_OFFSET);
277 #endif
278 return 0;
279 }
280
281 #ifdef CONFIG_SPL_BUILD
rk_board_init_f(void)282 int rk_board_init_f(void)
283 {
284 static struct rk3308_grf * const grf = (void *)GRF_BASE;
285 unsigned long mask;
286 unsigned long value;
287
288 mask = GPIO3B2_SEL_PLUS_MASK | GPIO3B2_SEL_SRC_CTRL_MASK |
289 GPIO3B3_SEL_PLUS_MASK | GPIO3B3_SEL_SRC_CTRL_MASK;
290 value = (GPIO3B2_SEL_PLUS_FLASH_RDN << GPIO3B2_SEL_PLUS_SHIFT) |
291 (GPIO3B2_SEL_SRC_CTRL_SEL_PLUS << GPIO3B2_SEL_SRC_CTRL_SHIFT) |
292 (GPIO3B3_SEL_PLUS_FLASH_ALE << GPIO3B3_SEL_PLUS_SHIFT) |
293 (GPIO3B3_SEL_SRC_CTRL_SEL_PLUS << GPIO3B3_SEL_SRC_CTRL_SHIFT);
294
295 if (get_bootdev_by_brom_bootsource() == BOOT_TYPE_NAND) {
296 if (soc_is_rk3308b() || soc_is_rk3308bs())
297 rk_clrsetreg(&grf->soc_con15, mask, value);
298 }
299
300 return 0;
301 }
302 #endif
303
board_debug_uart_init(void)304 void board_debug_uart_init(void)
305 {
306 static struct rk3308_cru * const cru = (void *)CRU_BASE;
307 static struct rk3308_grf * const grf = (void *)GRF_BASE;
308
309 #if defined(CONFIG_DEBUG_UART_BASE)
310 #if (CONFIG_DEBUG_UART_BASE == 0xFF0C0000)
311 /*select 24M clock to UART2 */
312 rk_clrsetreg(&cru->clksel_con[16],
313 CLK_UART2_PLL_SEL_MASK | CLK_UART2_DIV_CON_MASK,
314 CLK_UART2_PLL_SEL_XIN_OSC0 << CLK_UART2_PLL_SEL_SHIFT |
315 CLK_UART2_DIV_CON << CLK_UART2_DIV_CON_SHIFT);
316
317 #if (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0)
318 /* Enable early UART2 channel m0 on the rk3308 */
319 rk_clrsetreg(&grf->soc_con5, UART2_IO_SEL_MASK,
320 UART2_IO_SEL_M0 << UART2_IO_SEL_SHIFT);
321 rk_clrsetreg(&grf->gpio1ch_iomux, GPIO1C7_MASK | GPIO1C6_MASK,
322 GPIO1C7_UART2_TX_M0 << GPIO1C7_SHIFT |
323 GPIO1C6_UART2_RX_M0 << GPIO1C6_SHIFT);
324
325 #elif (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1)
326 /* Enable early UART2 channel m1 on the rk3308 */
327 rk_clrsetreg(&grf->soc_con5, UART2_IO_SEL_MASK,
328 UART2_IO_SEL_M1 << UART2_IO_SEL_SHIFT);
329 if (readl(BROM_BOOTSOURCE_ID_ADDR) != BROM_BOOTSOURCE_SD)
330 rk_clrsetreg(&grf->gpio4d_iomux,
331 GPIO4D3_MASK | GPIO4D2_MASK,
332 GPIO4D2_UART2_RX_M1 << GPIO4D2_SHIFT |
333 GPIO4D3_UART2_TX_M1 << GPIO4D3_SHIFT);
334 #else
335 #error "Please select M0 or M1 for uart2 !!!"
336 #endif
337
338 #elif (CONFIG_DEBUG_UART_BASE == 0xFF0E0000)
339 /*select 24M clock to UART4 */
340 rk_clrsetreg(&cru->clksel_con[22],
341 CLK_UART4_PLL_SEL_MASK | CLK_UART4_DIV_CON_MASK,
342 CLK_UART4_PLL_SEL_XIN_OSC0 << CLK_UART4_PLL_SEL_SHIFT |
343 CLK_UART4_DIV_CON << CLK_UART4_DIV_CON_SHIFT);
344
345 rk_clrsetreg(&grf->gpio4b_iomux,
346 GPIO4B1_SEL_MASK | GPIO4B0_SEL_MASK,
347 GPIO4B1_SEL_UART4_TX << GPIO4B1_SEL_SHIFT |
348 GPIO4B0_SEL_UART4_RX << GPIO4B0_SEL_SHIFT);
349 #elif (CONFIG_DEBUG_UART_BASE == 0xFF0A0000)
350 /*select 24M clock to UART0 */
351 rk_clrsetreg(&cru->clksel_con[10],
352 CLK_UART0_PLL_SEL_MASK | CLK_UART0_DIV_CON_MASK,
353 CLK_UART0_PLL_SEL_XIN_OSC0 << CLK_UART0_PLL_SEL_SHIFT |
354 CLK_UART0_DIV_CON << CLK_UART0_DIV_CON_SHIFT);
355
356 rk_clrsetreg(&grf->gpio2a_iomux,
357 GPIO2A1_SEL_MASK | GPIO2A0_SEL_MASK,
358 GPIO2A1_SEL_UART0_TX << GPIO2A1_SEL_SHIFT |
359 GPIO2A0_SEL_UART0_RX << GPIO2A0_SEL_SHIFT);
360 #elif (CONFIG_DEBUG_UART_BASE == 0xFF0B0000)
361 /*select 24M clock to UART1 */
362 rk_clrsetreg(&cru->clksel_con[13],
363 CLK_UART1_PLL_SEL_MASK | CLK_UART1_DIV_CON_MASK,
364 CLK_UART1_PLL_SEL_XIN_OSC0 << CLK_UART1_PLL_SEL_SHIFT |
365 CLK_UART1_DIV_CON << CLK_UART1_DIV_CON_SHIFT);
366
367 rk_clrsetreg(&grf->gpio1d_iomux,
368 GPIO1D1_SEL_MASK | GPIO1D0_SEL_MASK,
369 GPIO1D1_SEL_UART1_TX << GPIO1D1_SEL_SHIFT |
370 GPIO1D1_SEL_UART1_RX << GPIO1D0_SEL_SHIFT);
371 #elif (CONFIG_DEBUG_UART_BASE == 0xFF0D0000)
372 /*select 24M clock to UART3 */
373 rk_clrsetreg(&cru->clksel_con[19],
374 CLK_UART3_PLL_SEL_MASK | CLK_UART3_DIV_CON_MASK,
375 CLK_UART3_PLL_SEL_XIN_OSC0 << CLK_UART3_PLL_SEL_SHIFT |
376 CLK_UART3_DIV_CON << CLK_UART3_DIV_CON_SHIFT);
377
378 rk_clrsetreg(&grf->gpio3b_iomux,
379 GPIO3B5_SEL_MASK | GPIO3B4_SEL_MASK,
380 GPIO3B5_SEL_UART3_TX << GPIO3B5_SEL_SHIFT |
381 GPIO3B4_SEL_UART3_RX << GPIO3B4_SEL_SHIFT);
382 #else
383 #error "Please select proper uart as debug uart !!!"
384 #endif
385 #endif /* defined(CONFIG_DEBUG_UART_BASE) */
386 }
387
fdt_fixup_cpu_idle(const void * blob)388 static int fdt_fixup_cpu_idle(const void *blob)
389 {
390 int cpu_node, sub_node, len;
391 u32 *pp;
392
393 cpu_node = fdt_path_offset(blob, "/cpus");
394 if (cpu_node < 0) {
395 printf("Failed to get cpus node\n");
396 return -EINVAL;
397 }
398
399 fdt_for_each_subnode(sub_node, blob, cpu_node) {
400 pp = (u32 *)fdt_getprop(blob, sub_node, "cpu-idle-states",
401 &len);
402 if (!pp)
403 continue;
404 if (fdt_delprop((void *)blob, sub_node, "cpu-idle-states") < 0)
405 printf("Failed to del cpu-idle-states prop\n");
406 }
407
408 return 0;
409 }
410
fdt_fixup_cpu_opp_table(const void * blob)411 static int fdt_fixup_cpu_opp_table(const void *blob)
412 {
413 int opp_node, cpu_node, sub_node;
414 int len;
415 u32 phandle;
416 u32 *pp;
417
418 /* Replace opp table */
419 opp_node = fdt_path_offset(blob, "/rk3308bs-cpu0-opp-table");
420 if (opp_node < 0) {
421 printf("Failed to get rk3308bs-cpu0-opp-table node\n");
422 return -EINVAL;
423 }
424
425 phandle = fdt_get_phandle(blob, opp_node);
426 if (!phandle) {
427 printf("Failed to get cpu opp table phandle\n");
428 return -EINVAL;
429 }
430
431 cpu_node = fdt_path_offset(blob, "/cpus");
432 if (cpu_node < 0) {
433 printf("Failed to get cpus node\n");
434 return -EINVAL;
435 }
436
437 fdt_for_each_subnode(sub_node, blob, cpu_node) {
438 pp = (u32 *)fdt_getprop(blob, sub_node, "operating-points-v2",
439 &len);
440 if (!pp)
441 continue;
442 pp[0] = cpu_to_fdt32(phandle);
443 }
444
445 return 0;
446 }
447
fdt_fixup_dmc_opp_table(const void * blob)448 static int fdt_fixup_dmc_opp_table(const void *blob)
449 {
450 int opp_node, dmc_node;
451 int len;
452 u32 phandle;
453 u32 *pp;
454
455 opp_node = fdt_path_offset(blob, "/rk3308bs-dmc-opp-table");
456 if (opp_node < 0) {
457 printf("Failed to get rk3308bs-dmc-opp-table node\n");
458 return -EINVAL;
459 }
460
461 phandle = fdt_get_phandle(blob, opp_node);
462 if (!phandle) {
463 printf("Failed to get dmc opp table phandle\n");
464 return -EINVAL;
465 }
466
467 dmc_node = fdt_path_offset(blob, "/dmc");
468 if (dmc_node < 0) {
469 printf("Failed to get dmc node\n");
470 return -EINVAL;
471 }
472
473 pp = (u32 *)fdt_getprop(blob, dmc_node, "operating-points-v2", &len);
474 if (!pp)
475 return 0;
476 pp[0] = cpu_to_fdt32(phandle);
477
478 return 0;
479 }
480
fixup_pcfg_drive_strength(const void * blob,int noffset)481 static void fixup_pcfg_drive_strength(const void *blob, int noffset)
482 {
483 u32 *ds, *dss;
484 u32 val;
485
486 dss = (u32 *)fdt_getprop(blob, noffset, "drive-strength-s", NULL);
487 if (!dss)
488 return;
489
490 val = dss[0];
491 ds = (u32 *)fdt_getprop(blob, noffset, "drive-strength", NULL);
492 if (ds) {
493 ds[0] = val;
494 } else {
495 if (fdt_setprop((void *)blob, noffset,
496 "drive-strength", &val, 4) < 0)
497 printf("Failed to add drive-strength prop\n");
498 }
499 }
500
fdt_fixup_pcfg(const void * blob)501 static int fdt_fixup_pcfg(const void *blob)
502 {
503 int depth1_node;
504 int depth2_node;
505 int root_node, i;
506 const char *path[] = { "/", "/pinctrl" };
507
508 for (i = 0; i < ARRAY_SIZE(path); i++) {
509 root_node = fdt_path_offset(blob, path[i]);
510 if (root_node < 0)
511 return root_node;
512
513 fdt_for_each_subnode(depth1_node, blob, root_node) {
514 debug("depth1: %s\n", fdt_get_name(blob, depth1_node, NULL));
515 fixup_pcfg_drive_strength(blob, depth1_node);
516 fdt_for_each_subnode(depth2_node, blob, depth1_node) {
517 debug(" depth2: %s\n",
518 fdt_get_name(blob, depth2_node, NULL));
519 fixup_pcfg_drive_strength(blob, depth2_node);
520 }
521 }
522 }
523 return 0;
524 }
525
fdt_fixup_thermal_zones(const void * blob)526 static int fdt_fixup_thermal_zones(const void *blob)
527 {
528 int thermal_node;
529 int len;
530 u32 *pp;
531 u32 val;
532
533 thermal_node = fdt_path_offset(blob, "/thermal-zones/soc-thermal");
534 if (thermal_node < 0) {
535 printf("Failed to get soc thermal node\n");
536 return -EINVAL;
537 }
538
539 pp = (u32 *)fdt_getprop(blob, thermal_node,
540 "rk3308bs-sustainable-power", &len);
541 if (pp) {
542 val = fdt32_to_cpu(*pp);
543 pp = (u32 *)fdt_getprop(blob, thermal_node,
544 "sustainable-power", &len);
545 if (pp)
546 pp[0] = cpu_to_fdt32(val);
547 }
548
549 return 0;
550 }
551
rk_board_fdt_fixup(const void * blob)552 int rk_board_fdt_fixup(const void *blob)
553 {
554 if (soc_is_rk3308bs()) {
555 fdt_increase_size((void *)blob, SZ_8K);
556 fdt_fixup_cpu_idle(blob);
557 fdt_fixup_cpu_opp_table(blob);
558 fdt_fixup_dmc_opp_table(blob);
559 fdt_fixup_pcfg(blob);
560 fdt_fixup_thermal_zones(blob);
561 }
562
563 return 0;
564 }
565
rk_board_early_fdt_fixup(const void * blob)566 int rk_board_early_fdt_fixup(const void *blob)
567 {
568 rk_board_fdt_fixup(blob);
569
570 return 0;
571 }
572
573