]>
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 | } | |
76 | ||
77 | cci500_init(2); | |
78 | } | |
79 | #endif | |
80 | ||
81 | struct uniphier_initdata { | |
82 | enum uniphier_soc_id soc_id; | |
83 | bool nand_2cs; | |
84 | void (*pll_init)(void); | |
85 | void (*clk_init)(void); | |
86 | void (*misc_init)(void); | |
87 | }; | |
84ccd791 | 88 | |
b61664e2 | 89 | struct uniphier_initdata uniphier_initdata[] = { |
ea65c980 | 90 | #if defined(CONFIG_ARCH_UNIPHIER_SLD3) |
b61664e2 MY |
91 | { |
92 | .soc_id = SOC_UNIPHIER_SLD3, | |
93 | .nand_2cs = true, | |
94 | .pll_init = uniphier_sld3_pll_init, | |
95 | .clk_init = uniphier_ld4_clk_init, | |
96 | }, | |
323d1f9d | 97 | #endif |
ea65c980 | 98 | #if defined(CONFIG_ARCH_UNIPHIER_LD4) |
b61664e2 MY |
99 | { |
100 | .soc_id = SOC_UNIPHIER_LD4, | |
101 | .nand_2cs = true, | |
102 | .pll_init = uniphier_ld4_pll_init, | |
103 | .clk_init = uniphier_ld4_clk_init, | |
104 | }, | |
323d1f9d | 105 | #endif |
ea65c980 | 106 | #if defined(CONFIG_ARCH_UNIPHIER_PRO4) |
b61664e2 MY |
107 | { |
108 | .soc_id = SOC_UNIPHIER_PRO4, | |
109 | .nand_2cs = false, | |
110 | .pll_init = uniphier_pro4_pll_init, | |
111 | .clk_init = uniphier_pro4_clk_init, | |
112 | }, | |
323d1f9d | 113 | #endif |
ea65c980 | 114 | #if defined(CONFIG_ARCH_UNIPHIER_SLD8) |
b61664e2 MY |
115 | { |
116 | .soc_id = SOC_UNIPHIER_SLD8, | |
117 | .nand_2cs = true, | |
118 | .pll_init = uniphier_ld4_pll_init, | |
119 | .clk_init = uniphier_ld4_clk_init, | |
120 | }, | |
28f40d4a | 121 | #endif |
ea65c980 | 122 | #if defined(CONFIG_ARCH_UNIPHIER_PRO5) |
b61664e2 MY |
123 | { |
124 | .soc_id = SOC_UNIPHIER_PRO5, | |
125 | .nand_2cs = true, | |
126 | .clk_init = uniphier_pro5_clk_init, | |
127 | }, | |
019df879 | 128 | #endif |
ea65c980 | 129 | #if defined(CONFIG_ARCH_UNIPHIER_PXS2) |
b61664e2 MY |
130 | { |
131 | .soc_id = SOC_UNIPHIER_PXS2, | |
132 | .nand_2cs = true, | |
133 | .clk_init = uniphier_pxs2_clk_init, | |
134 | }, | |
019df879 | 135 | #endif |
ea65c980 | 136 | #if defined(CONFIG_ARCH_UNIPHIER_LD6B) |
b61664e2 MY |
137 | { |
138 | .soc_id = SOC_UNIPHIER_LD6B, | |
139 | .nand_2cs = true, | |
140 | .clk_init = uniphier_pxs2_clk_init, | |
141 | }, | |
9d0c2ceb | 142 | #endif |
667dbcd0 | 143 | #if defined(CONFIG_ARCH_UNIPHIER_LD11) |
b61664e2 MY |
144 | { |
145 | .soc_id = SOC_UNIPHIER_LD11, | |
146 | .nand_2cs = false, | |
147 | .pll_init = uniphier_ld11_pll_init, | |
148 | .clk_init = uniphier_ld11_clk_init, | |
149 | .misc_init = uniphier_ld11_misc_init, | |
150 | }, | |
667dbcd0 | 151 | #endif |
9d0c2ceb | 152 | #if defined(CONFIG_ARCH_UNIPHIER_LD20) |
b61664e2 MY |
153 | { |
154 | .soc_id = SOC_UNIPHIER_LD20, | |
155 | .nand_2cs = false, | |
156 | .pll_init = uniphier_ld20_pll_init, | |
157 | .misc_init = uniphier_ld20_misc_init, | |
158 | }, | |
323d1f9d | 159 | #endif |
b61664e2 MY |
160 | }; |
161 | ||
162 | static struct uniphier_initdata *uniphier_get_initdata( | |
163 | enum uniphier_soc_id soc_id) | |
164 | { | |
165 | int i; | |
166 | ||
167 | for (i = 0; i < ARRAY_SIZE(uniphier_initdata); i++) { | |
168 | if (uniphier_initdata[i].soc_id == soc_id) | |
169 | return &uniphier_initdata[i]; | |
323d1f9d | 170 | } |
198a97a6 | 171 | |
b61664e2 MY |
172 | return NULL; |
173 | } | |
174 | ||
175 | int board_init(void) | |
176 | { | |
177 | struct uniphier_initdata *initdata; | |
178 | enum uniphier_soc_id soc_id; | |
179 | int ret; | |
180 | ||
181 | led_puts("U0"); | |
182 | ||
183 | soc_id = uniphier_get_soc_type(); | |
184 | initdata = uniphier_get_initdata(soc_id); | |
185 | if (!initdata) { | |
186 | pr_err("unsupported board\n"); | |
187 | return -EINVAL; | |
188 | } | |
189 | ||
190 | if (IS_ENABLED(CONFIG_NAND_DENALI)) { | |
191 | ret = uniphier_pin_init(initdata->nand_2cs ? | |
192 | "nand2cs_grp" : "nand_grp"); | |
193 | if (ret) | |
194 | pr_err("failed to init NAND pins\n"); | |
195 | } | |
196 | ||
197 | led_puts("U1"); | |
198 | ||
199 | if (initdata->pll_init) | |
200 | initdata->pll_init(); | |
e64a6b11 | 201 | |
8469700b | 202 | led_puts("U2"); |
198a97a6 | 203 | |
b61664e2 MY |
204 | if (initdata->clk_init) |
205 | initdata->clk_init(); | |
b2916712 MY |
206 | |
207 | led_puts("U3"); | |
208 | ||
b61664e2 MY |
209 | if (initdata->misc_init) |
210 | initdata->misc_init(); | |
211 | ||
212 | led_puts("U4"); | |
213 | ||
214 | uniphier_setup_xirq(); | |
215 | ||
216 | led_puts("U5"); | |
217 | ||
218 | support_card_late_init(); | |
219 | ||
220 | led_puts("U6"); | |
221 | ||
b2916712 MY |
222 | #ifdef CONFIG_ARM64 |
223 | uniphier_smp_kick_all_cpus(); | |
224 | #endif | |
225 | ||
226 | led_puts("Uboo"); | |
227 | ||
84ccd791 MY |
228 | return 0; |
229 | } |