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