1 /*
2  * Copyright (C) 2012-2015 Panasonic Corporation
3  * Copyright (C) 2015-2016 Socionext Inc.
4  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  */
8 
9 #include <common.h>
10 #include <libfdt.h>
11 #include <linux/io.h>
12 
13 #include "init.h"
14 #include "micro-support-card.h"
15 #include "sg-regs.h"
16 #include "soc-info.h"
17 
18 DECLARE_GLOBAL_DATA_PTR;
19 
20 #ifdef CONFIG_ARCH_UNIPHIER_LD20
21 static void uniphier_ld20_misc_init(void)
22 {
23 	/* ES1 errata: increase VDD09 supply to suppress VBO noise */
24 	if (uniphier_get_soc_revision() == 1) {
25 		writel(0x00000003, 0x6184e004);
26 		writel(0x00000100, 0x6184e040);
27 		writel(0x0000b500, 0x6184e024);
28 		writel(0x00000001, 0x6184e000);
29 	}
30 }
31 #endif
32 
33 struct uniphier_initdata {
34 	unsigned int soc_id;
35 	void (*sbc_init)(void);
36 	void (*pll_init)(void);
37 	void (*clk_init)(void);
38 	void (*misc_init)(void);
39 };
40 
41 static const struct uniphier_initdata uniphier_initdata[] = {
42 #if defined(CONFIG_ARCH_UNIPHIER_LD4)
43 	{
44 		.soc_id = UNIPHIER_LD4_ID,
45 		.sbc_init = uniphier_ld4_sbc_init,
46 		.pll_init = uniphier_ld4_pll_init,
47 		.clk_init = uniphier_ld4_clk_init,
48 	},
49 #endif
50 #if defined(CONFIG_ARCH_UNIPHIER_PRO4)
51 	{
52 		.soc_id = UNIPHIER_PRO4_ID,
53 		.sbc_init = uniphier_sbc_init_savepin,
54 		.pll_init = uniphier_pro4_pll_init,
55 		.clk_init = uniphier_pro4_clk_init,
56 	},
57 #endif
58 #if defined(CONFIG_ARCH_UNIPHIER_SLD8)
59 	{
60 		.soc_id = UNIPHIER_SLD8_ID,
61 		.sbc_init = uniphier_ld4_sbc_init,
62 		.pll_init = uniphier_ld4_pll_init,
63 		.clk_init = uniphier_ld4_clk_init,
64 	},
65 #endif
66 #if defined(CONFIG_ARCH_UNIPHIER_PRO5)
67 	{
68 		.soc_id = UNIPHIER_PRO5_ID,
69 		.sbc_init = uniphier_sbc_init_savepin,
70 		.clk_init = uniphier_pro5_clk_init,
71 	},
72 #endif
73 #if defined(CONFIG_ARCH_UNIPHIER_PXS2)
74 	{
75 		.soc_id = UNIPHIER_PXS2_ID,
76 		.sbc_init = uniphier_pxs2_sbc_init,
77 		.clk_init = uniphier_pxs2_clk_init,
78 	},
79 #endif
80 #if defined(CONFIG_ARCH_UNIPHIER_LD6B)
81 	{
82 		.soc_id = UNIPHIER_LD6B_ID,
83 		.sbc_init = uniphier_pxs2_sbc_init,
84 		.clk_init = uniphier_pxs2_clk_init,
85 	},
86 #endif
87 #if defined(CONFIG_ARCH_UNIPHIER_LD11)
88 	{
89 		.soc_id = UNIPHIER_LD11_ID,
90 		.sbc_init = uniphier_ld11_sbc_init,
91 		.pll_init = uniphier_ld11_pll_init,
92 		.clk_init = uniphier_ld11_clk_init,
93 	},
94 #endif
95 #if defined(CONFIG_ARCH_UNIPHIER_LD20)
96 	{
97 		.soc_id = UNIPHIER_LD20_ID,
98 		.sbc_init = uniphier_ld11_sbc_init,
99 		.pll_init = uniphier_ld20_pll_init,
100 		.clk_init = uniphier_ld20_clk_init,
101 		.misc_init = uniphier_ld20_misc_init,
102 	},
103 #endif
104 #if defined(CONFIG_ARCH_UNIPHIER_PXS3)
105 	{
106 		.soc_id = UNIPHIER_PXS3_ID,
107 		.sbc_init = uniphier_pxs2_sbc_init,
108 		.pll_init = uniphier_pxs3_pll_init,
109 		.clk_init = uniphier_pxs3_clk_init,
110 	},
111 #endif
112 };
113 UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_initdata, uniphier_initdata)
114 
115 int board_init(void)
116 {
117 	const struct uniphier_initdata *initdata;
118 
119 	led_puts("U0");
120 
121 	initdata = uniphier_get_initdata();
122 	if (!initdata) {
123 		pr_err("unsupported SoC\n");
124 		return -EINVAL;
125 	}
126 
127 	initdata->sbc_init();
128 
129 	support_card_init();
130 
131 	led_puts("U0");
132 
133 	if (initdata->pll_init)
134 		initdata->pll_init();
135 
136 	led_puts("U1");
137 
138 	if (initdata->clk_init)
139 		initdata->clk_init();
140 
141 	led_puts("U2");
142 
143 	if (initdata->misc_init)
144 		initdata->misc_init();
145 
146 	led_puts("U3");
147 
148 	support_card_late_init();
149 
150 	led_puts("Uboo");
151 
152 	return 0;
153 }
154