]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0 |
6f107e4c | 2 | /* |
3 | * board/renesas/blanche/blanche.c | |
4 | * This file is blanche board support. | |
5 | * | |
6 | * Copyright (C) 2016 Renesas Electronics Corporation | |
6f107e4c | 7 | */ |
8 | ||
9a3b4ceb | 9 | #include <cpu_func.h> |
691d719d | 10 | #include <init.h> |
90526e9f | 11 | #include <net.h> |
e9c891ff | 12 | #include <asm/arch/rcar-mstp.h> |
65abdd19 | 13 | #include <asm/arch/renesas.h> |
e9c891ff | 14 | #include <asm/arch/sys_proto.h> |
401d1c4f | 15 | #include <asm/global_data.h> |
e9c891ff MV |
16 | #include <asm/gpio.h> |
17 | #include <asm/io.h> | |
18 | #include <asm/mach-types.h> | |
19 | #include <asm/processor.h> | |
6f107e4c | 20 | #include <dm.h> |
21 | #include <dm/platform_data/serial_sh.h> | |
9fb625ce | 22 | #include <env.h> |
4666521d | 23 | #include <hang.h> |
e9c891ff | 24 | #include <i2c.h> |
cd93d625 | 25 | #include <linux/bitops.h> |
1221ce45 | 26 | #include <linux/errno.h> |
e9c891ff | 27 | #include <malloc.h> |
6f107e4c | 28 | #include <miiphy.h> |
6f107e4c | 29 | #include <mmc.h> |
e9c891ff | 30 | #include <netdev.h> |
6f107e4c | 31 | #include "qos.h" |
32 | ||
33 | DECLARE_GLOBAL_DATA_PTR; | |
34 | ||
6f107e4c | 35 | #define CPG_PLL1CR 0xE6150028 |
36 | #define CPG_PLL3CR 0xE61500DC | |
37 | ||
e9c891ff MV |
38 | #define TMU0_MSTP125 BIT(25) |
39 | #define QSPI_MSTP917 BIT(17) | |
6f107e4c | 40 | |
e9c891ff MV |
41 | struct reg_config { |
42 | u16 off; | |
43 | u32 val; | |
6f107e4c | 44 | }; |
45 | ||
e9c891ff | 46 | static void blanche_init_sys(void) |
6f107e4c | 47 | { |
48 | struct rcar_rwdt *rwdt = (struct rcar_rwdt *)RWDT_BASE; | |
49 | struct rcar_swdt *swdt = (struct rcar_swdt *)SWDT_BASE; | |
50 | u32 cpu_type; | |
51 | ||
6bd3a95b | 52 | cpu_type = renesas_get_cpu_type(); |
6f107e4c | 53 | if (cpu_type == 0x4A) { |
54 | writel(0x4D000000, CPG_PLL1CR); | |
55 | writel(0x4F000000, CPG_PLL3CR); | |
56 | } | |
57 | ||
58 | /* Watchdog init */ | |
59 | writel(0xA5A5A500, &rwdt->rwtcsra); | |
60 | writel(0xA5A5A500, &swdt->swtcsra); | |
e9c891ff | 61 | } |
6f107e4c | 62 | |
e9c891ff MV |
63 | static void blanche_init_pfc(void) |
64 | { | |
65 | static const struct reg_config pfc_with_unlock[] = { | |
66 | { 0x0004, 0x0bffffff }, | |
67 | { 0x0008, 0x002fffff }, | |
68 | { 0x0014, 0x00000fff }, | |
69 | { 0x0018, 0x00010fff }, | |
70 | { 0x001c, 0x00010fff }, | |
71 | { 0x0020, 0x00010fff }, | |
72 | { 0x0024, 0x00010fff }, | |
73 | { 0x0028, 0x00010fff }, | |
74 | { 0x002c, 0x04006000 }, | |
75 | { 0x0030, 0x303fefe0 }, | |
76 | { 0x0058, 0x0002000e }, | |
77 | }; | |
78 | ||
79 | static const struct reg_config pfc_without_unlock[] = { | |
80 | { 0x0108, 0x00000000 }, | |
81 | { 0x010c, 0x0803FF40 }, | |
82 | { 0x0110, 0x0000FFFF }, | |
83 | { 0x0114, 0x00010FFF }, | |
84 | { 0x011c, 0x0001AFFF }, | |
85 | { 0x0124, 0x0001CFFF }, | |
86 | { 0x0128, 0xC0438001 }, | |
87 | { 0x012c, 0x0FC00007 }, | |
88 | }; | |
89 | ||
90 | static const u32 pfc_base = 0xe6060000; | |
91 | ||
92 | unsigned int i; | |
93 | ||
94 | for (i = 0; i < ARRAY_SIZE(pfc_with_unlock); i++) { | |
95 | writel(~pfc_with_unlock[i].val, pfc_base); | |
96 | writel(pfc_with_unlock[i].val, | |
97 | pfc_base | pfc_with_unlock[i].off); | |
98 | } | |
99 | ||
100 | for (i = 0; i < ARRAY_SIZE(pfc_without_unlock); i++) | |
101 | writel(pfc_without_unlock[i].val, | |
102 | pfc_base | pfc_without_unlock[i].off); | |
103 | } | |
6f107e4c | 104 | |
e9c891ff MV |
105 | static void blanche_init_lbsc(void) |
106 | { | |
107 | static const struct reg_config lbsc_config[] = { | |
108 | { 0x00, 0x00000020 }, | |
109 | { 0x08, 0x00002020 }, | |
110 | { 0x30, 0x2a103320 }, | |
111 | { 0x38, 0x19102110 }, | |
112 | }; | |
113 | ||
114 | static const u32 lbsc_base = 0xfec00200; | |
115 | ||
116 | unsigned int i; | |
117 | ||
118 | for (i = 0; i < ARRAY_SIZE(lbsc_config); i++) { | |
119 | writel(lbsc_config[i].val, | |
120 | lbsc_base | lbsc_config[i].off); | |
121 | writel(lbsc_config[i].val, | |
122 | lbsc_base | (lbsc_config[i].off + 4)); | |
123 | } | |
124 | } | |
6f107e4c | 125 | |
e856bdcf | 126 | #if defined(CONFIG_MTD_NOR_FLASH) |
e9c891ff MV |
127 | static void dbsc_wait(u16 reg) |
128 | { | |
129 | static const u32 dbsc3_0_base = DBSC3_0_BASE; | |
6f107e4c | 130 | |
e9c891ff MV |
131 | while (!(readl(dbsc3_0_base + reg) & BIT(0))) |
132 | ; | |
133 | } | |
6f107e4c | 134 | |
e9c891ff MV |
135 | static void blanche_init_dbsc(void) |
136 | { | |
137 | static const struct reg_config dbsc_config1[] = { | |
138 | { 0x0280, 0x0000a55a }, | |
139 | { 0x0018, 0x21000000 }, | |
140 | { 0x0018, 0x11000000 }, | |
141 | { 0x0018, 0x10000000 }, | |
142 | { 0x0290, 0x00000001 }, | |
143 | { 0x02a0, 0x80000000 }, | |
144 | { 0x0290, 0x00000004 }, | |
145 | }; | |
146 | ||
147 | static const struct reg_config dbsc_config2[] = { | |
148 | { 0x0290, 0x00000006 }, | |
149 | { 0x02a0, 0x0001c000 }, | |
150 | }; | |
151 | ||
152 | static const struct reg_config dbsc_config4[] = { | |
153 | { 0x0290, 0x0000000f }, | |
154 | { 0x02a0, 0x00181ee4 }, | |
155 | { 0x0290, 0x00000010 }, | |
156 | { 0x02a0, 0xf00464db }, | |
157 | { 0x0290, 0x00000061 }, | |
158 | { 0x02a0, 0x0000008d }, | |
159 | { 0x0290, 0x00000001 }, | |
160 | { 0x02a0, 0x00000073 }, | |
161 | { 0x0020, 0x00000007 }, | |
162 | { 0x0024, 0x0f030a02 }, | |
163 | { 0x0030, 0x00000001 }, | |
164 | { 0x00b0, 0x00000000 }, | |
165 | { 0x0040, 0x0000000b }, | |
166 | { 0x0044, 0x00000008 }, | |
167 | { 0x0048, 0x00000000 }, | |
168 | { 0x0050, 0x0000000b }, | |
169 | { 0x0054, 0x000c000b }, | |
170 | { 0x0058, 0x00000027 }, | |
171 | { 0x005c, 0x0000001c }, | |
172 | { 0x0060, 0x00000006 }, | |
173 | { 0x0064, 0x00000020 }, | |
174 | { 0x0068, 0x00000008 }, | |
175 | { 0x006c, 0x0000000c }, | |
176 | { 0x0070, 0x00000009 }, | |
177 | { 0x0074, 0x00000012 }, | |
178 | { 0x0078, 0x000000d0 }, | |
179 | { 0x007c, 0x00140005 }, | |
180 | { 0x0080, 0x00050004 }, | |
181 | { 0x0084, 0x70233005 }, | |
182 | { 0x0088, 0x000c0000 }, | |
183 | { 0x008c, 0x00000300 }, | |
184 | { 0x0090, 0x00000040 }, | |
185 | { 0x0100, 0x00000001 }, | |
186 | { 0x00c0, 0x00020001 }, | |
187 | { 0x00c8, 0x20082004 }, | |
188 | { 0x0380, 0x00020002 }, | |
189 | { 0x0390, 0x0000001f }, | |
190 | }; | |
191 | ||
192 | static const struct reg_config dbsc_config5[] = { | |
193 | { 0x0244, 0x00000011 }, | |
194 | { 0x0290, 0x00000003 }, | |
195 | { 0x02a0, 0x0300c4e1 }, | |
196 | { 0x0290, 0x00000023 }, | |
197 | { 0x02a0, 0x00fcdb60 }, | |
198 | { 0x0290, 0x00000011 }, | |
199 | { 0x02a0, 0x1000040b }, | |
200 | { 0x0290, 0x00000012 }, | |
201 | { 0x02a0, 0x9d9cbb66 }, | |
202 | { 0x0290, 0x00000013 }, | |
203 | { 0x02a0, 0x1a868400 }, | |
204 | { 0x0290, 0x00000014 }, | |
205 | { 0x02a0, 0x300214d8 }, | |
206 | { 0x0290, 0x00000015 }, | |
207 | { 0x02a0, 0x00000d70 }, | |
208 | { 0x0290, 0x00000016 }, | |
209 | { 0x02a0, 0x00000004 }, | |
210 | { 0x0290, 0x00000017 }, | |
211 | { 0x02a0, 0x00000018 }, | |
212 | { 0x0290, 0x0000001a }, | |
213 | { 0x02a0, 0x910035c7 }, | |
214 | { 0x0290, 0x00000004 }, | |
215 | }; | |
216 | ||
217 | static const struct reg_config dbsc_config6[] = { | |
218 | { 0x0290, 0x00000001 }, | |
219 | { 0x02a0, 0x00000181 }, | |
220 | { 0x0018, 0x11000000 }, | |
221 | { 0x0290, 0x00000004 }, | |
222 | }; | |
223 | ||
224 | static const struct reg_config dbsc_config7[] = { | |
225 | { 0x0290, 0x00000001 }, | |
226 | { 0x02a0, 0x0000fe01 }, | |
227 | { 0x0304, 0x00000000 }, | |
228 | { 0x00f4, 0x01004c20 }, | |
229 | { 0x00f8, 0x014000aa }, | |
230 | { 0x00e0, 0x00000140 }, | |
231 | { 0x00e4, 0x00081860 }, | |
232 | { 0x00e8, 0x00010000 }, | |
233 | { 0x0290, 0x00000004 }, | |
234 | }; | |
235 | ||
236 | static const struct reg_config dbsc_config8[] = { | |
237 | { 0x0014, 0x00000001 }, | |
238 | { 0x0010, 0x00000001 }, | |
239 | { 0x0280, 0x00000000 }, | |
240 | }; | |
241 | ||
242 | static const u32 dbsc3_0_base = DBSC3_0_BASE; | |
243 | unsigned int i; | |
244 | ||
245 | for (i = 0; i < ARRAY_SIZE(dbsc_config1); i++) | |
246 | writel(dbsc_config1[i].val, dbsc3_0_base | dbsc_config1[i].off); | |
247 | ||
248 | dbsc_wait(0x2a0); | |
249 | ||
250 | for (i = 0; i < ARRAY_SIZE(dbsc_config2); i++) | |
251 | writel(dbsc_config2[i].val, dbsc3_0_base | dbsc_config2[i].off); | |
252 | ||
253 | for (i = 0; i < ARRAY_SIZE(dbsc_config4); i++) | |
254 | writel(dbsc_config4[i].val, dbsc3_0_base | dbsc_config4[i].off); | |
255 | ||
256 | dbsc_wait(0x240); | |
257 | ||
258 | for (i = 0; i < ARRAY_SIZE(dbsc_config5); i++) | |
259 | writel(dbsc_config5[i].val, dbsc3_0_base | dbsc_config5[i].off); | |
260 | ||
261 | dbsc_wait(0x2a0); | |
262 | ||
263 | for (i = 0; i < ARRAY_SIZE(dbsc_config6); i++) | |
264 | writel(dbsc_config6[i].val, dbsc3_0_base | dbsc_config6[i].off); | |
265 | ||
266 | dbsc_wait(0x2a0); | |
267 | ||
268 | for (i = 0; i < ARRAY_SIZE(dbsc_config7); i++) | |
269 | writel(dbsc_config7[i].val, dbsc3_0_base | dbsc_config7[i].off); | |
270 | ||
271 | dbsc_wait(0x2a0); | |
272 | ||
273 | for (i = 0; i < ARRAY_SIZE(dbsc_config8); i++) | |
274 | writel(dbsc_config8[i].val, dbsc3_0_base | dbsc_config8[i].off); | |
6f107e4c | 275 | |
e9c891ff | 276 | } |
6f107e4c | 277 | |
e9c891ff MV |
278 | static void s_init_wait(volatile unsigned int cnt) |
279 | { | |
280 | volatile u32 i = cnt * 0x10000; | |
6f107e4c | 281 | |
e9c891ff MV |
282 | while (i-- > 0) |
283 | ; | |
6f107e4c | 284 | } |
e9c891ff | 285 | #endif |
6f107e4c | 286 | |
e9c891ff MV |
287 | void s_init(void) |
288 | { | |
289 | blanche_init_sys(); | |
290 | qos_init(); | |
291 | blanche_init_pfc(); | |
292 | blanche_init_lbsc(); | |
293 | #if defined(CONFIG_MTD_NOR_FLASH) | |
294 | s_init_wait(10); | |
295 | blanche_init_dbsc(); | |
296 | #endif /* CONFIG_MTD_NOR_FLASH */ | |
297 | } | |
6f107e4c | 298 | |
299 | int board_early_init_f(void) | |
300 | { | |
301 | /* TMU0 */ | |
302 | mstp_clrbits_le32(MSTPSR1, SMSTPCR1, TMU0_MSTP125); | |
6f107e4c | 303 | /* QSPI */ |
304 | mstp_clrbits_le32(MSTPSR9, SMSTPCR9, QSPI_MSTP917); | |
305 | ||
306 | return 0; | |
307 | } | |
308 | ||
6f107e4c | 309 | int board_init(void) |
310 | { | |
311 | /* adress of boot parameters */ | |
aa6e94de | 312 | gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100; |
6f107e4c | 313 | |
6f107e4c | 314 | return 0; |
315 | } | |
316 | ||
e9c891ff | 317 | /* Added for BLANCHE(R-CarV2H board) */ |
264398b2 | 318 | #ifndef CONFIG_DM_ETH |
b75d8dc5 | 319 | int board_eth_init(struct bd_info *bis) |
6f107e4c | 320 | { |
321 | int rc = 0; | |
322 | ||
323 | #ifdef CONFIG_SMC911X | |
6f107e4c | 324 | struct eth_device *dev; |
325 | uchar eth_addr[6]; | |
326 | ||
6e7df1d1 | 327 | rc = smc911x_initialize(0, CFG_SMC911X_BASE); |
6f107e4c | 328 | |
e9c891ff | 329 | if (!eth_env_get_enetaddr("ethaddr", eth_addr)) { |
6f107e4c | 330 | dev = eth_get_dev_by_index(0); |
331 | if (dev) { | |
e9c891ff | 332 | eth_env_set_enetaddr("ethaddr", dev->enetaddr); |
6f107e4c | 333 | } else { |
334 | printf("blanche: Couldn't get eth device\n"); | |
335 | rc = -1; | |
336 | } | |
337 | } | |
338 | ||
339 | #endif | |
340 | ||
341 | return rc; | |
342 | } | |
264398b2 | 343 | #endif |
6f107e4c | 344 | |
e9c891ff | 345 | int dram_init(void) |
6f107e4c | 346 | { |
12308b12 | 347 | if (fdtdec_setup_mem_size_base() != 0) |
e9c891ff | 348 | return -EINVAL; |
6f107e4c | 349 | |
e9c891ff | 350 | return 0; |
6f107e4c | 351 | } |
352 | ||
e9c891ff | 353 | int dram_init_banksize(void) |
6f107e4c | 354 | { |
e9c891ff | 355 | fdtdec_setup_memory_banksize(); |
6f107e4c | 356 | |
357 | return 0; | |
358 | } | |
359 | ||
35b65dd8 | 360 | void reset_cpu(void) |
6f107e4c | 361 | { |
4666521d MV |
362 | struct udevice *dev; |
363 | const u8 pmic_bus = 6; | |
364 | const u8 pmic_addr = 0x58; | |
365 | u8 data; | |
366 | int ret; | |
367 | ||
368 | ret = i2c_get_chip_for_busnum(pmic_bus, pmic_addr, 1, &dev); | |
369 | if (ret) | |
370 | hang(); | |
371 | ||
372 | ret = dm_i2c_read(dev, 0x13, &data, 1); | |
373 | if (ret) | |
374 | hang(); | |
375 | ||
376 | data |= BIT(1); | |
377 | ||
378 | ret = dm_i2c_write(dev, 0x13, &data, 1); | |
379 | if (ret) | |
380 | hang(); | |
6f107e4c | 381 | } |