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