1b2916712SMasahiro Yamada /*
2b2916712SMasahiro Yamada * Copyright (C) 2012-2015 Panasonic Corporation
3b2916712SMasahiro Yamada * Copyright (C) 2015-2016 Socionext Inc.
4b2916712SMasahiro Yamada * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
5b2916712SMasahiro Yamada *
6b2916712SMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+
7b2916712SMasahiro Yamada */
8b2916712SMasahiro Yamada
9b2916712SMasahiro Yamada #include <common.h>
10b2916712SMasahiro Yamada #include <libfdt.h>
11b2916712SMasahiro Yamada #include <linux/io.h>
12b2916712SMasahiro Yamada
13b2916712SMasahiro Yamada #include "init.h"
14b2916712SMasahiro Yamada #include "micro-support-card.h"
15b78ffc53SMasahiro Yamada #include "sg-regs.h"
16b2916712SMasahiro Yamada #include "soc-info.h"
17b2916712SMasahiro Yamada
18b2916712SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR;
19b2916712SMasahiro Yamada
uniphier_setup_xirq(void)20b2916712SMasahiro Yamada static void uniphier_setup_xirq(void)
21b2916712SMasahiro Yamada {
22b2916712SMasahiro Yamada const void *fdt = gd->fdt_blob;
23b2916712SMasahiro Yamada int soc_node, aidet_node;
241d21e1b9SMasahiro Yamada const fdt32_t *val;
25b2916712SMasahiro Yamada unsigned long aidet_base;
26b2916712SMasahiro Yamada u32 tmp;
27b2916712SMasahiro Yamada
28b2916712SMasahiro Yamada soc_node = fdt_path_offset(fdt, "/soc");
29b2916712SMasahiro Yamada if (soc_node < 0)
30b2916712SMasahiro Yamada return;
31b2916712SMasahiro Yamada
32b2916712SMasahiro Yamada aidet_node = fdt_subnode_offset_namelen(fdt, soc_node, "aidet", 5);
33b2916712SMasahiro Yamada if (aidet_node < 0)
34b2916712SMasahiro Yamada return;
35b2916712SMasahiro Yamada
36b2916712SMasahiro Yamada val = fdt_getprop(fdt, aidet_node, "reg", NULL);
37b2916712SMasahiro Yamada if (!val)
38b2916712SMasahiro Yamada return;
39b2916712SMasahiro Yamada
40b2916712SMasahiro Yamada aidet_base = fdt32_to_cpu(*val);
41b2916712SMasahiro Yamada
42b2916712SMasahiro Yamada tmp = readl(aidet_base + 8); /* AIDET DETCONFR2 */
43b2916712SMasahiro Yamada tmp |= 0x00ff0000; /* Set XIRQ0-7 low active */
44b2916712SMasahiro Yamada writel(tmp, aidet_base + 8);
45b2916712SMasahiro Yamada
46b2916712SMasahiro Yamada tmp = readl(0x55000090); /* IRQCTL */
47b2916712SMasahiro Yamada tmp |= 0x000000ff;
48b2916712SMasahiro Yamada writel(tmp, 0x55000090);
49b2916712SMasahiro Yamada }
50b2916712SMasahiro Yamada
51b61664e2SMasahiro Yamada #ifdef CONFIG_ARCH_UNIPHIER_LD11
uniphier_ld11_misc_init(void)52b61664e2SMasahiro Yamada static void uniphier_ld11_misc_init(void)
535ac9dfbeSMasahiro Yamada {
54b78ffc53SMasahiro Yamada sg_set_pinsel(149, 14, 8, 4); /* XIRQ0 -> XIRQ0 */
55b78ffc53SMasahiro Yamada sg_set_iectrl(149);
56b78ffc53SMasahiro Yamada sg_set_pinsel(153, 14, 8, 4); /* XIRQ4 -> XIRQ4 */
57b78ffc53SMasahiro Yamada sg_set_iectrl(153);
58b61664e2SMasahiro Yamada }
59b2916712SMasahiro Yamada #endif
60b61664e2SMasahiro Yamada
61b61664e2SMasahiro Yamada #ifdef CONFIG_ARCH_UNIPHIER_LD20
uniphier_ld20_misc_init(void)62b61664e2SMasahiro Yamada static void uniphier_ld20_misc_init(void)
63b61664e2SMasahiro Yamada {
64b61664e2SMasahiro Yamada sg_set_pinsel(149, 14, 8, 4); /* XIRQ0 -> XIRQ0 */
65b61664e2SMasahiro Yamada sg_set_iectrl(149);
66b61664e2SMasahiro Yamada sg_set_pinsel(153, 14, 8, 4); /* XIRQ4 -> XIRQ4 */
67b61664e2SMasahiro Yamada sg_set_iectrl(153);
68b61664e2SMasahiro Yamada
69baaafaaaSMasahiro Yamada /* ES1 errata: increase VDD09 supply to suppress VBO noise */
70baaafaaaSMasahiro Yamada if (uniphier_get_soc_revision() == 1) {
71baaafaaaSMasahiro Yamada writel(0x00000003, 0x6184e004);
72baaafaaaSMasahiro Yamada writel(0x00000100, 0x6184e040);
73baaafaaaSMasahiro Yamada writel(0x0000b500, 0x6184e024);
74baaafaaaSMasahiro Yamada writel(0x00000001, 0x6184e000);
75baaafaaaSMasahiro Yamada }
76b61664e2SMasahiro Yamada }
77b2916712SMasahiro Yamada #endif
78b61664e2SMasahiro Yamada
79b61664e2SMasahiro Yamada struct uniphier_initdata {
80e27d6c7dSMasahiro Yamada unsigned int soc_id;
8126b09c02SMasahiro Yamada void (*sbc_init)(void);
82b61664e2SMasahiro Yamada void (*pll_init)(void);
83b61664e2SMasahiro Yamada void (*clk_init)(void);
84b61664e2SMasahiro Yamada void (*misc_init)(void);
85b61664e2SMasahiro Yamada };
86b61664e2SMasahiro Yamada
877a37bd64SMasahiro Yamada static const struct uniphier_initdata uniphier_initdata[] = {
88b61664e2SMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD4)
89b61664e2SMasahiro Yamada {
90e27d6c7dSMasahiro Yamada .soc_id = UNIPHIER_LD4_ID,
9126b09c02SMasahiro Yamada .sbc_init = uniphier_ld4_sbc_init,
92b61664e2SMasahiro Yamada .pll_init = uniphier_ld4_pll_init,
93b61664e2SMasahiro Yamada .clk_init = uniphier_ld4_clk_init,
94b61664e2SMasahiro Yamada },
95b61664e2SMasahiro Yamada #endif
96b61664e2SMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_PRO4)
97b61664e2SMasahiro Yamada {
98e27d6c7dSMasahiro Yamada .soc_id = UNIPHIER_PRO4_ID,
9926b09c02SMasahiro Yamada .sbc_init = uniphier_sbc_init_savepin,
100b61664e2SMasahiro Yamada .pll_init = uniphier_pro4_pll_init,
101b61664e2SMasahiro Yamada .clk_init = uniphier_pro4_clk_init,
102b61664e2SMasahiro Yamada },
103b61664e2SMasahiro Yamada #endif
104b61664e2SMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_SLD8)
105b61664e2SMasahiro Yamada {
106e27d6c7dSMasahiro Yamada .soc_id = UNIPHIER_SLD8_ID,
10726b09c02SMasahiro Yamada .sbc_init = uniphier_ld4_sbc_init,
108b61664e2SMasahiro Yamada .pll_init = uniphier_ld4_pll_init,
109b61664e2SMasahiro Yamada .clk_init = uniphier_ld4_clk_init,
110b61664e2SMasahiro Yamada },
111b61664e2SMasahiro Yamada #endif
112b61664e2SMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_PRO5)
113b61664e2SMasahiro Yamada {
114e27d6c7dSMasahiro Yamada .soc_id = UNIPHIER_PRO5_ID,
11526b09c02SMasahiro Yamada .sbc_init = uniphier_sbc_init_savepin,
116b61664e2SMasahiro Yamada .clk_init = uniphier_pro5_clk_init,
117b61664e2SMasahiro Yamada },
118b61664e2SMasahiro Yamada #endif
119b61664e2SMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_PXS2)
120b61664e2SMasahiro Yamada {
121e27d6c7dSMasahiro Yamada .soc_id = UNIPHIER_PXS2_ID,
12226b09c02SMasahiro Yamada .sbc_init = uniphier_pxs2_sbc_init,
123b61664e2SMasahiro Yamada .clk_init = uniphier_pxs2_clk_init,
124b61664e2SMasahiro Yamada },
125b61664e2SMasahiro Yamada #endif
126b61664e2SMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD6B)
127b61664e2SMasahiro Yamada {
128e27d6c7dSMasahiro Yamada .soc_id = UNIPHIER_LD6B_ID,
12926b09c02SMasahiro Yamada .sbc_init = uniphier_pxs2_sbc_init,
130b61664e2SMasahiro Yamada .clk_init = uniphier_pxs2_clk_init,
131b61664e2SMasahiro Yamada },
132b61664e2SMasahiro Yamada #endif
133b61664e2SMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD11)
134b61664e2SMasahiro Yamada {
135e27d6c7dSMasahiro Yamada .soc_id = UNIPHIER_LD11_ID,
13626b09c02SMasahiro Yamada .sbc_init = uniphier_ld11_sbc_init,
137b61664e2SMasahiro Yamada .pll_init = uniphier_ld11_pll_init,
138b61664e2SMasahiro Yamada .clk_init = uniphier_ld11_clk_init,
139b61664e2SMasahiro Yamada .misc_init = uniphier_ld11_misc_init,
140b61664e2SMasahiro Yamada },
141b61664e2SMasahiro Yamada #endif
142b61664e2SMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD20)
143b61664e2SMasahiro Yamada {
144e27d6c7dSMasahiro Yamada .soc_id = UNIPHIER_LD20_ID,
14526b09c02SMasahiro Yamada .sbc_init = uniphier_ld11_sbc_init,
146b61664e2SMasahiro Yamada .pll_init = uniphier_ld20_pll_init,
147c21f5854SMasahiro Yamada .clk_init = uniphier_ld20_clk_init,
148b61664e2SMasahiro Yamada .misc_init = uniphier_ld20_misc_init,
149b61664e2SMasahiro Yamada },
150b61664e2SMasahiro Yamada #endif
1512c2ab3d4SMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_PXS3)
1522c2ab3d4SMasahiro Yamada {
1532c2ab3d4SMasahiro Yamada .soc_id = UNIPHIER_PXS3_ID,
1542c2ab3d4SMasahiro Yamada .sbc_init = uniphier_pxs2_sbc_init,
1552c2ab3d4SMasahiro Yamada .pll_init = uniphier_pxs3_pll_init,
15681afa9c9SMasahiro Yamada .clk_init = uniphier_pxs3_clk_init,
1572c2ab3d4SMasahiro Yamada },
1582c2ab3d4SMasahiro Yamada #endif
159b61664e2SMasahiro Yamada };
UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_initdata,uniphier_initdata)160ee8ef5afSMasahiro Yamada UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_initdata, uniphier_initdata)
161b61664e2SMasahiro Yamada
162b61664e2SMasahiro Yamada int board_init(void)
163b61664e2SMasahiro Yamada {
1647a37bd64SMasahiro Yamada const struct uniphier_initdata *initdata;
165b61664e2SMasahiro Yamada
166b61664e2SMasahiro Yamada led_puts("U0");
167b61664e2SMasahiro Yamada
168ee8ef5afSMasahiro Yamada initdata = uniphier_get_initdata();
169b61664e2SMasahiro Yamada if (!initdata) {
170ee8ef5afSMasahiro Yamada pr_err("unsupported SoC\n");
171b61664e2SMasahiro Yamada return -EINVAL;
172b61664e2SMasahiro Yamada }
173b61664e2SMasahiro Yamada
17426b09c02SMasahiro Yamada initdata->sbc_init();
17526b09c02SMasahiro Yamada
17626b09c02SMasahiro Yamada support_card_init();
17726b09c02SMasahiro Yamada
17826b09c02SMasahiro Yamada led_puts("U0");
17926b09c02SMasahiro Yamada
180b61664e2SMasahiro Yamada if (initdata->pll_init)
181b61664e2SMasahiro Yamada initdata->pll_init();
182b2916712SMasahiro Yamada
183*e0daca7dSMasahiro Yamada led_puts("U1");
184b2916712SMasahiro Yamada
185b61664e2SMasahiro Yamada if (initdata->clk_init)
186b61664e2SMasahiro Yamada initdata->clk_init();
187b2916712SMasahiro Yamada
188*e0daca7dSMasahiro Yamada led_puts("U2");
189b2916712SMasahiro Yamada
190b61664e2SMasahiro Yamada if (initdata->misc_init)
191b61664e2SMasahiro Yamada initdata->misc_init();
192b61664e2SMasahiro Yamada
193*e0daca7dSMasahiro Yamada led_puts("U3");
194b61664e2SMasahiro Yamada
195b61664e2SMasahiro Yamada uniphier_setup_xirq();
196b61664e2SMasahiro Yamada
197*e0daca7dSMasahiro Yamada led_puts("U4");
198b61664e2SMasahiro Yamada
199b61664e2SMasahiro Yamada support_card_late_init();
200b61664e2SMasahiro Yamada
201b2916712SMasahiro Yamada led_puts("Uboo");
202b2916712SMasahiro Yamada
203b2916712SMasahiro Yamada return 0;
204b2916712SMasahiro Yamada }
205