]>
Commit | Line | Data |
---|---|---|
3012a840 KY |
1 | /* |
2 | * (C) Copyright 2016 Rockchip Electronics Co., Ltd | |
cbe18f10 | 3 | * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH |
3012a840 KY |
4 | * |
5 | * SPDX-License-Identifier: GPL-2.0+ | |
6 | */ | |
7 | ||
8 | #include <common.h> | |
cbe18f10 | 9 | #include <asm/arch/bootrom.h> |
3012a840 | 10 | #include <asm/arch/clock.h> |
ba165733 | 11 | #include <asm/arch/grf_rk3399.h> |
3012a840 KY |
12 | #include <asm/arch/hardware.h> |
13 | #include <asm/arch/periph.h> | |
ba165733 PT |
14 | #include <asm/io.h> |
15 | #include <debug_uart.h> | |
16 | #include <dm.h> | |
3012a840 | 17 | #include <dm/pinctrl.h> |
ba165733 PT |
18 | #include <ram.h> |
19 | #include <spl.h> | |
20 | #include <syscon.h> | |
3012a840 KY |
21 | |
22 | DECLARE_GLOBAL_DATA_PTR; | |
23 | ||
cbe18f10 PT |
24 | void board_return_to_bootrom(void) |
25 | { | |
b82bd1f8 | 26 | back_to_bootrom(BROM_BOOT_NEXTSTAGE); |
cbe18f10 PT |
27 | } |
28 | ||
c55addd3 PT |
29 | static const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { |
30 | [BROM_BOOTSOURCE_EMMC] = "/sdhci@fe330000", | |
31 | [BROM_BOOTSOURCE_SPINOR] = "/spi@ff1d0000", | |
32 | [BROM_BOOTSOURCE_SD] = "/dwmmc@fe320000", | |
33 | }; | |
34 | ||
35 | const char *board_spl_was_booted_from(void) | |
36 | { | |
37 | u32 bootdevice_brom_id = readl(RK3399_BROM_BOOTSOURCE_ID_ADDR); | |
38 | const char *bootdevice_ofpath = NULL; | |
39 | ||
40 | if (bootdevice_brom_id < ARRAY_SIZE(boot_devices)) | |
41 | bootdevice_ofpath = boot_devices[bootdevice_brom_id]; | |
42 | ||
43 | if (bootdevice_ofpath) | |
44 | debug("%s: brom_bootdevice_id %x maps to '%s'\n", | |
45 | __func__, bootdevice_brom_id, bootdevice_ofpath); | |
46 | else | |
47 | debug("%s: failed to resolve brom_bootdevice_id %x\n", | |
48 | __func__, bootdevice_brom_id); | |
49 | ||
50 | return bootdevice_ofpath; | |
51 | } | |
52 | ||
3012a840 KY |
53 | u32 spl_boot_device(void) |
54 | { | |
cbe18f10 PT |
55 | u32 boot_device = BOOT_DEVICE_MMC1; |
56 | ||
57 | if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)) | |
58 | return BOOT_DEVICE_BOOTROM; | |
59 | ||
60 | return boot_device; | |
3012a840 KY |
61 | } |
62 | ||
63 | u32 spl_boot_mode(const u32 boot_device) | |
64 | { | |
65 | return MMCSD_MODE_RAW; | |
66 | } | |
67 | ||
68 | #define TIMER_CHN10_BASE 0xff8680a0 | |
69 | #define TIMER_END_COUNT_L 0x00 | |
70 | #define TIMER_END_COUNT_H 0x04 | |
71 | #define TIMER_INIT_COUNT_L 0x10 | |
72 | #define TIMER_INIT_COUNT_H 0x14 | |
73 | #define TIMER_CONTROL_REG 0x1c | |
74 | ||
75 | #define TIMER_EN 0x1 | |
76 | #define TIMER_FMODE (0 << 1) | |
77 | #define TIMER_RMODE (1 << 1) | |
78 | ||
79 | void secure_timer_init(void) | |
80 | { | |
81 | writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_L); | |
82 | writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_H); | |
83 | writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_L); | |
84 | writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_H); | |
85 | writel(TIMER_EN | TIMER_FMODE, TIMER_CHN10_BASE + TIMER_CONTROL_REG); | |
86 | } | |
87 | ||
7ee16de5 PT |
88 | void board_debug_uart_init(void) |
89 | { | |
3012a840 KY |
90 | #define GRF_BASE 0xff770000 |
91 | struct rk3399_grf_regs * const grf = (void *)GRF_BASE; | |
92 | ||
7ee16de5 PT |
93 | #if defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff180000) |
94 | /* Enable early UART0 on the RK3399 */ | |
95 | rk_clrsetreg(&grf->gpio2c_iomux, | |
96 | GRF_GPIO2C0_SEL_MASK, | |
97 | GRF_UART0BT_SIN << GRF_GPIO2C0_SEL_SHIFT); | |
98 | rk_clrsetreg(&grf->gpio2c_iomux, | |
99 | GRF_GPIO2C1_SEL_MASK, | |
100 | GRF_UART0BT_SOUT << GRF_GPIO2C1_SEL_SHIFT); | |
101 | #else | |
102 | /* Enable early UART2 channel C on the RK3399 */ | |
3012a840 KY |
103 | rk_clrsetreg(&grf->gpio4c_iomux, |
104 | GRF_GPIO4C3_SEL_MASK, | |
105 | GRF_UART2DGBC_SIN << GRF_GPIO4C3_SEL_SHIFT); | |
106 | rk_clrsetreg(&grf->gpio4c_iomux, | |
107 | GRF_GPIO4C4_SEL_MASK, | |
108 | GRF_UART2DBGC_SOUT << GRF_GPIO4C4_SEL_SHIFT); | |
109 | /* Set channel C as UART2 input */ | |
110 | rk_clrsetreg(&grf->soc_con7, | |
111 | GRF_UART_DBG_SEL_MASK, | |
112 | GRF_UART_DBG_SEL_C << GRF_UART_DBG_SEL_SHIFT); | |
7ee16de5 PT |
113 | #endif |
114 | } | |
115 | ||
7ee16de5 PT |
116 | void board_init_f(ulong dummy) |
117 | { | |
118 | struct udevice *pinctrl; | |
119 | struct udevice *dev; | |
ba165733 PT |
120 | struct rk3399_pmusgrf_regs *sgrf; |
121 | struct rk3399_grf_regs *grf; | |
7ee16de5 PT |
122 | int ret; |
123 | ||
3012a840 KY |
124 | #define EARLY_UART |
125 | #ifdef EARLY_UART | |
126 | /* | |
127 | * Debug UART can be used from here if required: | |
128 | * | |
129 | * debug_uart_init(); | |
130 | * printch('a'); | |
131 | * printhex8(0x1234); | |
132 | * printascii("string"); | |
133 | */ | |
134 | debug_uart_init(); | |
135 | printascii("U-Boot SPL board init"); | |
136 | #endif | |
c4a92151 | 137 | |
232cf962 | 138 | ret = spl_early_init(); |
3012a840 | 139 | if (ret) { |
232cf962 | 140 | debug("spl_early_init() failed: %d\n", ret); |
3012a840 KY |
141 | hang(); |
142 | } | |
143 | ||
504b9f1a | 144 | /* |
c4a92151 | 145 | * Disable DDR and SRAM security regions. |
504b9f1a PT |
146 | * |
147 | * As we are entered from the BootROM, the region from | |
148 | * 0x0 through 0xfffff (i.e. the first MB of memory) will | |
149 | * be protected. This will cause issues with the DW_MMC | |
150 | * driver, which tries to DMA from/to the stack (likely) | |
151 | * located in this range. | |
152 | */ | |
ba165733 PT |
153 | sgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF); |
154 | rk_clrsetreg(&sgrf->ddr_rgn_con[16], 0x1ff, 0); | |
155 | rk_clrreg(&sgrf->slv_secure_con4, 0x2000); | |
156 | ||
157 | /* eMMC clock generator: disable the clock multipilier */ | |
158 | grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); | |
159 | rk_clrreg(&grf->emmccore_con[11], 0x0ff); | |
504b9f1a | 160 | |
3012a840 KY |
161 | secure_timer_init(); |
162 | ||
163 | ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); | |
164 | if (ret) { | |
165 | debug("Pinctrl init failed: %d\n", ret); | |
166 | return; | |
167 | } | |
168 | ||
169 | ret = uclass_get_device(UCLASS_RAM, 0, &dev); | |
170 | if (ret) { | |
171 | debug("DRAM init failed: %d\n", ret); | |
172 | return; | |
173 | } | |
174 | } | |
175 | ||
3012a840 KY |
176 | #ifdef CONFIG_SPL_LOAD_FIT |
177 | int board_fit_config_name_match(const char *name) | |
178 | { | |
179 | /* Just empty function now - can't decide what to choose */ | |
180 | debug("%s: %s\n", __func__, name); | |
181 | ||
182 | return 0; | |
183 | } | |
184 | #endif |