]>
Commit | Line | Data |
---|---|---|
84ccd791 | 1 | /* |
b2916712 MY |
2 | * Copyright (C) 2012-2015 Panasonic Corporation |
3 | * Copyright (C) 2015-2016 Socionext Inc. | |
4 | * Author: Masahiro Yamada <yamada.masahiro@socionext.com> | |
84ccd791 MY |
5 | * |
6 | * SPDX-License-Identifier: GPL-2.0+ | |
7 | */ | |
8 | ||
e64a6b11 MY |
9 | #include <common.h> |
10 | #include <libfdt.h> | |
11 | #include <linux/io.h> | |
12 | ||
107b3fb4 MY |
13 | #include "init.h" |
14 | #include "micro-support-card.h" | |
b78ffc53 | 15 | #include "sg-regs.h" |
107b3fb4 | 16 | #include "soc-info.h" |
84ccd791 | 17 | |
e64a6b11 MY |
18 | DECLARE_GLOBAL_DATA_PTR; |
19 | ||
20 | static void uniphier_setup_xirq(void) | |
21 | { | |
22 | const void *fdt = gd->fdt_blob; | |
23 | int soc_node, aidet_node; | |
24 | const u32 *val; | |
25 | unsigned long aidet_base; | |
26 | u32 tmp; | |
27 | ||
28 | soc_node = fdt_path_offset(fdt, "/soc"); | |
29 | if (soc_node < 0) | |
30 | return; | |
31 | ||
32 | aidet_node = fdt_subnode_offset_namelen(fdt, soc_node, "aidet", 5); | |
33 | if (aidet_node < 0) | |
34 | return; | |
35 | ||
36 | val = fdt_getprop(fdt, aidet_node, "reg", NULL); | |
37 | if (!val) | |
38 | return; | |
39 | ||
40 | aidet_base = fdt32_to_cpu(*val); | |
41 | ||
42 | tmp = readl(aidet_base + 8); /* AIDET DETCONFR2 */ | |
43 | tmp |= 0x00ff0000; /* Set XIRQ0-7 low active */ | |
44 | writel(tmp, aidet_base + 8); | |
45 | ||
46 | tmp = readl(0x55000090); /* IRQCTL */ | |
47 | tmp |= 0x000000ff; | |
48 | writel(tmp, 0x55000090); | |
49 | } | |
50 | ||
b61664e2 MY |
51 | #ifdef CONFIG_ARCH_UNIPHIER_LD11 |
52 | static void uniphier_ld11_misc_init(void) | |
5ac9dfbe | 53 | { |
b61664e2 MY |
54 | sg_set_pinsel(149, 14, 8, 4); /* XIRQ0 -> XIRQ0 */ |
55 | sg_set_iectrl(149); | |
56 | sg_set_pinsel(153, 14, 8, 4); /* XIRQ4 -> XIRQ4 */ | |
57 | sg_set_iectrl(153); | |
5ac9dfbe | 58 | } |
b61664e2 | 59 | #endif |
5ac9dfbe | 60 | |
b61664e2 MY |
61 | #ifdef CONFIG_ARCH_UNIPHIER_LD20 |
62 | static void uniphier_ld20_misc_init(void) | |
84ccd791 | 63 | { |
b61664e2 MY |
64 | sg_set_pinsel(149, 14, 8, 4); /* XIRQ0 -> XIRQ0 */ |
65 | sg_set_iectrl(149); | |
66 | sg_set_pinsel(153, 14, 8, 4); /* XIRQ4 -> XIRQ4 */ | |
67 | sg_set_iectrl(153); | |
68 | ||
69 | /* ES1 errata: increase VDD09 supply to suppress VBO noise */ | |
70 | if (uniphier_get_soc_revision() == 1) { | |
71 | writel(0x00000003, 0x6184e004); | |
72 | writel(0x00000100, 0x6184e040); | |
73 | writel(0x0000b500, 0x6184e024); | |
74 | writel(0x00000001, 0x6184e000); | |
75 | } | |
561ca649 | 76 | #ifdef CONFIG_ARMV8_MULTIENTRY |
b61664e2 | 77 | cci500_init(2); |
561ca649 | 78 | #endif |
b61664e2 MY |
79 | } |
80 | #endif | |
81 | ||
82 | struct uniphier_initdata { | |
83 | enum uniphier_soc_id soc_id; | |
84 | bool nand_2cs; | |
26b09c02 | 85 | void (*sbc_init)(void); |
b61664e2 MY |
86 | void (*pll_init)(void); |
87 | void (*clk_init)(void); | |
88 | void (*misc_init)(void); | |
89 | }; | |
84ccd791 | 90 | |
7a37bd64 | 91 | static const struct uniphier_initdata uniphier_initdata[] = { |
ea65c980 | 92 | #if defined(CONFIG_ARCH_UNIPHIER_SLD3) |
b61664e2 MY |
93 | { |
94 | .soc_id = SOC_UNIPHIER_SLD3, | |
95 | .nand_2cs = true, | |
26b09c02 | 96 | .sbc_init = uniphier_sbc_init_admulti, |
b61664e2 MY |
97 | .pll_init = uniphier_sld3_pll_init, |
98 | .clk_init = uniphier_ld4_clk_init, | |
99 | }, | |
323d1f9d | 100 | #endif |
ea65c980 | 101 | #if defined(CONFIG_ARCH_UNIPHIER_LD4) |
b61664e2 MY |
102 | { |
103 | .soc_id = SOC_UNIPHIER_LD4, | |
104 | .nand_2cs = true, | |
26b09c02 | 105 | .sbc_init = uniphier_ld4_sbc_init, |
b61664e2 MY |
106 | .pll_init = uniphier_ld4_pll_init, |
107 | .clk_init = uniphier_ld4_clk_init, | |
108 | }, | |
323d1f9d | 109 | #endif |
ea65c980 | 110 | #if defined(CONFIG_ARCH_UNIPHIER_PRO4) |
b61664e2 MY |
111 | { |
112 | .soc_id = SOC_UNIPHIER_PRO4, | |
113 | .nand_2cs = false, | |
26b09c02 | 114 | .sbc_init = uniphier_sbc_init_savepin, |
b61664e2 MY |
115 | .pll_init = uniphier_pro4_pll_init, |
116 | .clk_init = uniphier_pro4_clk_init, | |
117 | }, | |
323d1f9d | 118 | #endif |
ea65c980 | 119 | #if defined(CONFIG_ARCH_UNIPHIER_SLD8) |
b61664e2 MY |
120 | { |
121 | .soc_id = SOC_UNIPHIER_SLD8, | |
122 | .nand_2cs = true, | |
26b09c02 | 123 | .sbc_init = uniphier_ld4_sbc_init, |
b61664e2 MY |
124 | .pll_init = uniphier_ld4_pll_init, |
125 | .clk_init = uniphier_ld4_clk_init, | |
126 | }, | |
28f40d4a | 127 | #endif |
ea65c980 | 128 | #if defined(CONFIG_ARCH_UNIPHIER_PRO5) |
b61664e2 MY |
129 | { |
130 | .soc_id = SOC_UNIPHIER_PRO5, | |
131 | .nand_2cs = true, | |
26b09c02 | 132 | .sbc_init = uniphier_sbc_init_savepin, |
b61664e2 MY |
133 | .clk_init = uniphier_pro5_clk_init, |
134 | }, | |
019df879 | 135 | #endif |
ea65c980 | 136 | #if defined(CONFIG_ARCH_UNIPHIER_PXS2) |
b61664e2 MY |
137 | { |
138 | .soc_id = SOC_UNIPHIER_PXS2, | |
139 | .nand_2cs = true, | |
26b09c02 | 140 | .sbc_init = uniphier_pxs2_sbc_init, |
b61664e2 MY |
141 | .clk_init = uniphier_pxs2_clk_init, |
142 | }, | |
019df879 | 143 | #endif |
ea65c980 | 144 | #if defined(CONFIG_ARCH_UNIPHIER_LD6B) |
b61664e2 MY |
145 | { |
146 | .soc_id = SOC_UNIPHIER_LD6B, | |
147 | .nand_2cs = true, | |
26b09c02 | 148 | .sbc_init = uniphier_pxs2_sbc_init, |
b61664e2 MY |
149 | .clk_init = uniphier_pxs2_clk_init, |
150 | }, | |
9d0c2ceb | 151 | #endif |
667dbcd0 | 152 | #if defined(CONFIG_ARCH_UNIPHIER_LD11) |
b61664e2 MY |
153 | { |
154 | .soc_id = SOC_UNIPHIER_LD11, | |
155 | .nand_2cs = false, | |
26b09c02 | 156 | .sbc_init = uniphier_ld11_sbc_init, |
b61664e2 MY |
157 | .pll_init = uniphier_ld11_pll_init, |
158 | .clk_init = uniphier_ld11_clk_init, | |
159 | .misc_init = uniphier_ld11_misc_init, | |
160 | }, | |
667dbcd0 | 161 | #endif |
9d0c2ceb | 162 | #if defined(CONFIG_ARCH_UNIPHIER_LD20) |
b61664e2 MY |
163 | { |
164 | .soc_id = SOC_UNIPHIER_LD20, | |
165 | .nand_2cs = false, | |
26b09c02 | 166 | .sbc_init = uniphier_ld11_sbc_init, |
b61664e2 MY |
167 | .pll_init = uniphier_ld20_pll_init, |
168 | .misc_init = uniphier_ld20_misc_init, | |
169 | }, | |
323d1f9d | 170 | #endif |
b61664e2 MY |
171 | }; |
172 | ||
7a37bd64 | 173 | static const struct uniphier_initdata *uniphier_get_initdata( |
b61664e2 MY |
174 | enum uniphier_soc_id soc_id) |
175 | { | |
176 | int i; | |
177 | ||
178 | for (i = 0; i < ARRAY_SIZE(uniphier_initdata); i++) { | |
179 | if (uniphier_initdata[i].soc_id == soc_id) | |
180 | return &uniphier_initdata[i]; | |
323d1f9d | 181 | } |
198a97a6 | 182 | |
b61664e2 MY |
183 | return NULL; |
184 | } | |
185 | ||
186 | int board_init(void) | |
187 | { | |
7a37bd64 | 188 | const struct uniphier_initdata *initdata; |
b61664e2 MY |
189 | enum uniphier_soc_id soc_id; |
190 | int ret; | |
191 | ||
192 | led_puts("U0"); | |
193 | ||
194 | soc_id = uniphier_get_soc_type(); | |
195 | initdata = uniphier_get_initdata(soc_id); | |
196 | if (!initdata) { | |
197 | pr_err("unsupported board\n"); | |
198 | return -EINVAL; | |
199 | } | |
200 | ||
26b09c02 MY |
201 | initdata->sbc_init(); |
202 | ||
203 | support_card_init(); | |
204 | ||
205 | led_puts("U0"); | |
206 | ||
b61664e2 MY |
207 | if (IS_ENABLED(CONFIG_NAND_DENALI)) { |
208 | ret = uniphier_pin_init(initdata->nand_2cs ? | |
209 | "nand2cs_grp" : "nand_grp"); | |
210 | if (ret) | |
211 | pr_err("failed to init NAND pins\n"); | |
212 | } | |
213 | ||
214 | led_puts("U1"); | |
215 | ||
216 | if (initdata->pll_init) | |
217 | initdata->pll_init(); | |
e64a6b11 | 218 | |
8469700b | 219 | led_puts("U2"); |
198a97a6 | 220 | |
b61664e2 MY |
221 | if (initdata->clk_init) |
222 | initdata->clk_init(); | |
b2916712 MY |
223 | |
224 | led_puts("U3"); | |
225 | ||
b61664e2 MY |
226 | if (initdata->misc_init) |
227 | initdata->misc_init(); | |
228 | ||
229 | led_puts("U4"); | |
230 | ||
231 | uniphier_setup_xirq(); | |
232 | ||
233 | led_puts("U5"); | |
234 | ||
235 | support_card_late_init(); | |
236 | ||
237 | led_puts("U6"); | |
238 | ||
561ca649 | 239 | #ifdef CONFIG_ARMV8_MULTIENTRY |
b2916712 MY |
240 | uniphier_smp_kick_all_cpus(); |
241 | #endif | |
242 | ||
243 | led_puts("Uboo"); | |
244 | ||
84ccd791 MY |
245 | return 0; |
246 | } |