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