blob: b25b1331874cf560a3c0879e6c2400fadcb1ff75 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Alexey Brodkin67482f52016-11-25 16:23:43 +03002/*
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +03003 * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
4 * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
Alexey Brodkin67482f52016-11-25 16:23:43 +03005 */
6
7#include <common.h>
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +03008#include <config.h>
Simon Glass9edefc22019-11-14 12:57:37 -07009#include <cpu_func.h>
Simon Glass168068f2019-08-01 09:46:47 -060010#include <env.h>
Simon Glass52559322019-11-14 12:57:46 -070011#include <init.h>
Simon Glass36bf4462019-11-14 12:57:42 -070012#include <irq_func.h>
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +030013#include <linux/printk.h>
14#include <linux/kernel.h>
15#include <linux/io.h>
16#include <asm/arcregs.h>
17#include <fdt_support.h>
Alexey Brodkin67482f52016-11-25 16:23:43 +030018#include <dwmmc.h>
19#include <malloc.h>
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +030020#include <usb.h>
21
22#include "clk-lib.h"
23#include "env-lib.h"
Alexey Brodkin67482f52016-11-25 16:23:43 +030024
25DECLARE_GLOBAL_DATA_PTR;
26
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +030027#define ALL_CPU_MASK GENMASK(NR_CPUS - 1, 0)
28#define MASTER_CPU_ID 0
29#define APERTURE_SHIFT 28
30#define NO_CCM 0x10
31#define SLAVE_CPU_READY 0x12345678
32#define BOOTSTAGE_1 1 /* after SP, FP setup, before HW init */
33#define BOOTSTAGE_2 2 /* after HW init, before self halt */
34#define BOOTSTAGE_3 3 /* after self halt */
35#define BOOTSTAGE_4 4 /* before app launch */
36#define BOOTSTAGE_5 5 /* after app launch, unreachable */
Alexey Brodkin67482f52016-11-25 16:23:43 +030037
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +030038#define RESET_VECTOR_ADDR 0x0
39
40#define CREG_BASE (ARC_PERIPHERAL_BASE + 0x1000)
41#define CREG_CPU_START (CREG_BASE + 0x400)
42#define CREG_CPU_START_MASK 0xF
Eugeniy Paltsev4b4da7f2020-01-16 19:22:32 +030043#define CREG_CPU_START_POL BIT(4)
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +030044
45#define SDIO_BASE (ARC_PERIPHERAL_BASE + 0xA000)
46#define SDIO_UHS_REG_EXT (SDIO_BASE + 0x108)
47#define SDIO_UHS_REG_EXT_DIV_2 (2 << 30)
48
49/* Uncached access macros */
50#define arc_read_uncached_32(ptr) \
51({ \
52 unsigned int __ret; \
53 __asm__ __volatile__( \
54 " ld.di %0, [%1] \n" \
55 : "=r"(__ret) \
56 : "r"(ptr)); \
57 __ret; \
58})
59
60#define arc_write_uncached_32(ptr, data)\
61({ \
62 __asm__ __volatile__( \
63 " st.di %0, [%1] \n" \
64 : \
65 : "r"(data), "r"(ptr)); \
66})
67
68struct hsdk_env_core_ctl {
69 u32_env entry[NR_CPUS];
70 u32_env iccm[NR_CPUS];
71 u32_env dccm[NR_CPUS];
72};
73
74struct hsdk_env_common_ctl {
75 bool halt_on_boot;
76 u32_env core_mask;
77 u32_env cpu_freq;
78 u32_env axi_freq;
79 u32_env tun_freq;
80 u32_env nvlim;
81 u32_env icache;
82 u32_env dcache;
Eugeniy Paltsev1d897d12020-03-23 20:46:35 +030083 u32_env l2_cache;
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +030084};
85
86/*
87 * Uncached cross-cpu structure. All CPUs must access to this structure fields
88 * only with arc_read_uncached_32() / arc_write_uncached_32() accessors (which
89 * implement ld.di / st.di instructions). Simultaneous cached and uncached
90 * access to this area will lead to data loss.
91 * We flush all data caches in board_early_init_r() as we don't want to have
92 * any dirty line in L1d$ or SL$ in this area.
93 */
94struct hsdk_cross_cpu {
95 /* slave CPU ready flag */
96 u32 ready_flag;
97 /* address of the area, which can be used for stack by slave CPU */
98 u32 stack_ptr;
99 /* slave CPU status - bootstage number */
100 s32 status[NR_CPUS];
101
102 /*
103 * Slave CPU data - it is copy of corresponding fields in
104 * hsdk_env_core_ctl and hsdk_env_common_ctl structures which are
105 * required for slave CPUs initialization.
106 * This fields can be populated by copying from hsdk_env_core_ctl
107 * and hsdk_env_common_ctl structures with sync_cross_cpu_data()
108 * function.
109 */
110 u32 entry[NR_CPUS];
111 u32 iccm[NR_CPUS];
112 u32 dccm[NR_CPUS];
113
114 u32 core_mask;
115 u32 icache;
116 u32 dcache;
117
118 u8 cache_padding[ARCH_DMA_MINALIGN];
119} __aligned(ARCH_DMA_MINALIGN);
120
121/* Place for slave CPUs temporary stack */
122static u32 slave_stack[256 * NR_CPUS] __aligned(ARCH_DMA_MINALIGN);
123
124static struct hsdk_env_common_ctl env_common = {};
125static struct hsdk_env_core_ctl env_core = {};
126static struct hsdk_cross_cpu cross_cpu_data;
127
128static const struct env_map_common env_map_common[] = {
129 { "core_mask", ENV_HEX, true, 0x1, 0xF, &env_common.core_mask },
130 { "non_volatile_limit", ENV_HEX, true, 0, 0xF, &env_common.nvlim },
131 { "icache_ena", ENV_HEX, true, 0, 1, &env_common.icache },
132 { "dcache_ena", ENV_HEX, true, 0, 1, &env_common.dcache },
Eugeniy Paltsev1d897d12020-03-23 20:46:35 +0300133#if defined(CONFIG_BOARD_HSDK_4XD)
134 { "l2_cache_ena", ENV_HEX, true, 0, 1, &env_common.l2_cache },
135#endif /* CONFIG_BOARD_HSDK_4XD */
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300136 {}
137};
138
139static const struct env_map_common env_map_clock[] = {
140 { "cpu_freq", ENV_DEC, false, 100, 1000, &env_common.cpu_freq },
141 { "axi_freq", ENV_DEC, false, 200, 800, &env_common.axi_freq },
142 { "tun_freq", ENV_DEC, false, 0, 150, &env_common.tun_freq },
143 {}
144};
145
146static const struct env_map_percpu env_map_core[] = {
147 { "core_iccm", ENV_HEX, true, {NO_CCM, 0, NO_CCM, 0}, {NO_CCM, 0xF, NO_CCM, 0xF}, &env_core.iccm },
148 { "core_dccm", ENV_HEX, true, {NO_CCM, 0, NO_CCM, 0}, {NO_CCM, 0xF, NO_CCM, 0xF}, &env_core.dccm },
149 {}
150};
151
152static const struct env_map_common env_map_mask[] = {
153 { "core_mask", ENV_HEX, false, 0x1, 0xF, &env_common.core_mask },
154 {}
155};
156
157static const struct env_map_percpu env_map_go[] = {
158 { "core_entry", ENV_HEX, true, {0, 0, 0, 0}, {U32_MAX, U32_MAX, U32_MAX, U32_MAX}, &env_core.entry },
159 {}
160};
161
Eugeniy Paltsevf0f84ef2020-04-22 00:33:40 +0300162enum board_type {
163 T_BOARD_NONE,
164 T_BOARD_HSDK,
165 T_BOARD_HSDK_4XD
166};
167
168static inline enum board_type get_board_type_runtime(void)
169{
170 u32 arc_id = read_aux_reg(ARC_AUX_IDENTITY) & 0xFF;
171
172 if (arc_id == 0x52)
173 return T_BOARD_HSDK;
174 else if (arc_id == 0x54)
175 return T_BOARD_HSDK_4XD;
176 else
177 return T_BOARD_NONE;
178}
179
180static inline enum board_type get_board_type_config(void)
181{
182 if (IS_ENABLED(CONFIG_BOARD_HSDK))
183 return T_BOARD_HSDK;
184 else if (IS_ENABLED(CONFIG_BOARD_HSDK_4XD))
185 return T_BOARD_HSDK_4XD;
186 else
187 return T_BOARD_NONE;
188}
189
190static bool is_board_match_runtime(enum board_type type_req)
191{
192 return get_board_type_runtime() == type_req;
193}
194
Eugeniy Paltsev1d897d12020-03-23 20:46:35 +0300195static bool is_board_match_config(enum board_type type_req)
196{
197 return get_board_type_config() == type_req;
198}
199
Eugeniy Paltsevf0f84ef2020-04-22 00:33:40 +0300200static const char * board_name(enum board_type type)
201{
202 switch (type) {
203 case T_BOARD_HSDK:
204 return "ARC HS Development Kit";
205 case T_BOARD_HSDK_4XD:
206 return "ARC HS4x/HS4xD Development Kit";
207 default:
208 return "?";
209 }
210}
211
212static bool board_mismatch(void)
213{
214 return get_board_type_config() != get_board_type_runtime();
215}
216
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300217static void sync_cross_cpu_data(void)
Alexey Brodkin67482f52016-11-25 16:23:43 +0300218{
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300219 u32 value;
Alexey Brodkin67482f52016-11-25 16:23:43 +0300220
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300221 for (u32 i = 0; i < NR_CPUS; i++) {
222 value = env_core.entry[i].val;
223 arc_write_uncached_32(&cross_cpu_data.entry[i], value);
224 }
225
226 for (u32 i = 0; i < NR_CPUS; i++) {
227 value = env_core.iccm[i].val;
228 arc_write_uncached_32(&cross_cpu_data.iccm[i], value);
229 }
230
231 for (u32 i = 0; i < NR_CPUS; i++) {
232 value = env_core.dccm[i].val;
233 arc_write_uncached_32(&cross_cpu_data.dccm[i], value);
234 }
235
236 value = env_common.core_mask.val;
237 arc_write_uncached_32(&cross_cpu_data.core_mask, value);
238
239 value = env_common.icache.val;
240 arc_write_uncached_32(&cross_cpu_data.icache, value);
241
242 value = env_common.dcache.val;
243 arc_write_uncached_32(&cross_cpu_data.dcache, value);
244}
245
246/* Can be used only on master CPU */
247static bool is_cpu_used(u32 cpu_id)
248{
249 return !!(env_common.core_mask.val & BIT(cpu_id));
250}
251
252/* TODO: add ICCM BCR and DCCM BCR runtime check */
253static void init_slave_cpu_func(u32 core)
254{
255 u32 val;
256
257 /* Remap ICCM to another memory region if it exists */
258 val = arc_read_uncached_32(&cross_cpu_data.iccm[core]);
259 if (val != NO_CCM)
260 write_aux_reg(ARC_AUX_ICCM_BASE, val << APERTURE_SHIFT);
261
262 /* Remap DCCM to another memory region if it exists */
263 val = arc_read_uncached_32(&cross_cpu_data.dccm[core]);
264 if (val != NO_CCM)
265 write_aux_reg(ARC_AUX_DCCM_BASE, val << APERTURE_SHIFT);
266
267 if (arc_read_uncached_32(&cross_cpu_data.icache))
268 icache_enable();
269 else
270 icache_disable();
271
272 if (arc_read_uncached_32(&cross_cpu_data.dcache))
273 dcache_enable();
274 else
275 dcache_disable();
276}
277
278static void init_cluster_nvlim(void)
279{
280 u32 val = env_common.nvlim.val << APERTURE_SHIFT;
281
282 flush_dcache_all();
283 write_aux_reg(ARC_AUX_NON_VOLATILE_LIMIT, val);
Eugeniy Paltsevf0f84ef2020-04-22 00:33:40 +0300284 /* AUX_AUX_CACHE_LIMIT reg is missing starting from HS48 */
285 if (is_board_match_runtime(T_BOARD_HSDK))
286 write_aux_reg(AUX_AUX_CACHE_LIMIT, val);
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300287 flush_n_invalidate_dcache_all();
288}
289
Eugeniy Paltsev1d897d12020-03-23 20:46:35 +0300290static void init_cluster_slc(void)
291{
292 /* ARC HS38 doesn't support SLC disabling */
293 if (!is_board_match_config(T_BOARD_HSDK_4XD))
294 return;
295
296 if (env_common.l2_cache.val)
297 slc_enable();
298 else
299 slc_disable();
300}
301
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300302static void init_master_icache(void)
303{
304 if (icache_status()) {
305 /* I$ is enabled - we need to disable it */
306 if (!env_common.icache.val)
307 icache_disable();
308 } else {
309 /* I$ is disabled - we need to enable it */
310 if (env_common.icache.val) {
311 icache_enable();
312
313 /* invalidate I$ right after enable */
314 invalidate_icache_all();
315 }
316 }
317}
318
319static void init_master_dcache(void)
320{
321 if (dcache_status()) {
322 /* D$ is enabled - we need to disable it */
323 if (!env_common.dcache.val)
324 dcache_disable();
325 } else {
326 /* D$ is disabled - we need to enable it */
327 if (env_common.dcache.val)
328 dcache_enable();
329
330 /* TODO: probably we need ti invalidate D$ right after enable */
331 }
332}
333
334static int cleanup_before_go(void)
335{
336 disable_interrupts();
337 sync_n_cleanup_cache_all();
Alexey Brodkin67482f52016-11-25 16:23:43 +0300338
339 return 0;
340}
341
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300342void slave_cpu_set_boot_addr(u32 addr)
343{
344 /* All cores have reset vector pointing to 0 */
345 writel(addr, (void __iomem *)RESET_VECTOR_ADDR);
346
347 /* Make sure other cores see written value in memory */
348 sync_n_cleanup_cache_all();
349}
350
351static inline void halt_this_cpu(void)
352{
353 __builtin_arc_flag(1);
354}
355
Eugeniy Paltsev4b4da7f2020-01-16 19:22:32 +0300356static u32 get_masked_cpu_ctart_reg(void)
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300357{
358 int cmd = readl((void __iomem *)CREG_CPU_START);
359
Eugeniy Paltsev4b4da7f2020-01-16 19:22:32 +0300360 /*
361 * Quirk for HSDK-4xD - due to HW issues HSDK can use any pulse polarity
362 * and HSDK-4xD require active low polarity of cpu_start pulse.
363 */
364 cmd &= ~CREG_CPU_START_POL;
365
366 cmd &= ~CREG_CPU_START_MASK;
367
368 return cmd;
369}
370
371static void smp_kick_cpu_x(u32 cpu_id)
372{
373 int cmd;
374
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300375 if (cpu_id > NR_CPUS)
376 return;
377
Eugeniy Paltsev4b4da7f2020-01-16 19:22:32 +0300378 cmd = get_masked_cpu_ctart_reg();
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300379 cmd |= (1 << cpu_id);
380 writel(cmd, (void __iomem *)CREG_CPU_START);
381}
382
383static u32 prepare_cpu_ctart_reg(void)
384{
Eugeniy Paltsev4b4da7f2020-01-16 19:22:32 +0300385 return get_masked_cpu_ctart_reg() | env_common.core_mask.val;
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300386}
387
388/* slave CPU entry for configuration */
389__attribute__((naked, noreturn, flatten)) noinline void hsdk_core_init_f(void)
390{
391 __asm__ __volatile__(
392 "ld.di r8, [%0]\n"
393 "mov %%sp, r8\n"
394 "mov %%fp, %%sp\n"
395 : /* no output */
396 : "r" (&cross_cpu_data.stack_ptr));
397
398 invalidate_icache_all();
399
400 arc_write_uncached_32(&cross_cpu_data.status[CPU_ID_GET()], BOOTSTAGE_1);
401 init_slave_cpu_func(CPU_ID_GET());
402
403 arc_write_uncached_32(&cross_cpu_data.ready_flag, SLAVE_CPU_READY);
404 arc_write_uncached_32(&cross_cpu_data.status[CPU_ID_GET()], BOOTSTAGE_2);
405
406 /* Halt the processor until the master kick us again */
407 halt_this_cpu();
408
409 /*
410 * 3 NOPs after FLAG 1 instruction are no longer required for ARCv2
411 * cores but we leave them for gebug purposes.
412 */
413 __builtin_arc_nop();
414 __builtin_arc_nop();
415 __builtin_arc_nop();
416
417 arc_write_uncached_32(&cross_cpu_data.status[CPU_ID_GET()], BOOTSTAGE_3);
418
419 /* get the updated entry - invalidate i$ */
420 invalidate_icache_all();
421
422 arc_write_uncached_32(&cross_cpu_data.status[CPU_ID_GET()], BOOTSTAGE_4);
423
424 /* Run our program */
425 ((void (*)(void))(arc_read_uncached_32(&cross_cpu_data.entry[CPU_ID_GET()])))();
426
427 /* This bootstage is unreachable as we don't return from app we launch */
428 arc_write_uncached_32(&cross_cpu_data.status[CPU_ID_GET()], BOOTSTAGE_5);
429
430 /* Something went terribly wrong */
431 while (true)
432 halt_this_cpu();
433}
434
435static void clear_cross_cpu_data(void)
436{
437 arc_write_uncached_32(&cross_cpu_data.ready_flag, 0);
438 arc_write_uncached_32(&cross_cpu_data.stack_ptr, 0);
439
440 for (u32 i = 0; i < NR_CPUS; i++)
441 arc_write_uncached_32(&cross_cpu_data.status[i], 0);
442}
443
444static noinline void do_init_slave_cpu(u32 cpu_id)
445{
446 /* attempts number for check clave CPU ready_flag */
447 u32 attempts = 100;
448 u32 stack_ptr = (u32)(slave_stack + (64 * cpu_id));
449
450 if (cpu_id >= NR_CPUS)
451 return;
452
453 arc_write_uncached_32(&cross_cpu_data.ready_flag, 0);
454
455 /* Use global unique place for each slave cpu stack */
456 arc_write_uncached_32(&cross_cpu_data.stack_ptr, stack_ptr);
457
458 debug("CPU %u: stack pool base: %p\n", cpu_id, slave_stack);
459 debug("CPU %u: current slave stack base: %x\n", cpu_id, stack_ptr);
460 slave_cpu_set_boot_addr((u32)hsdk_core_init_f);
461
462 smp_kick_cpu_x(cpu_id);
463
464 debug("CPU %u: cross-cpu flag: %x [before timeout]\n", cpu_id,
465 arc_read_uncached_32(&cross_cpu_data.ready_flag));
466
467 while (!arc_read_uncached_32(&cross_cpu_data.ready_flag) && attempts--)
468 mdelay(10);
469
470 /* Just to be sure that slave cpu is halted after it set ready_flag */
471 mdelay(20);
472
473 /*
474 * Only print error here if we reach timeout as there is no option to
475 * halt slave cpu (or check that slave cpu is halted)
476 */
477 if (!attempts)
478 pr_err("CPU %u is not responding after init!\n", cpu_id);
479
480 /* Check current stage of slave cpu */
481 if (arc_read_uncached_32(&cross_cpu_data.status[cpu_id]) != BOOTSTAGE_2)
482 pr_err("CPU %u status is unexpected: %d\n", cpu_id,
483 arc_read_uncached_32(&cross_cpu_data.status[cpu_id]));
484
485 debug("CPU %u: cross-cpu flag: %x [after timeout]\n", cpu_id,
486 arc_read_uncached_32(&cross_cpu_data.ready_flag));
487 debug("CPU %u: status: %d [after timeout]\n", cpu_id,
488 arc_read_uncached_32(&cross_cpu_data.status[cpu_id]));
489}
490
491static void do_init_slave_cpus(void)
492{
493 clear_cross_cpu_data();
494 sync_cross_cpu_data();
495
496 debug("cross_cpu_data location: %#x\n", (u32)&cross_cpu_data);
497
498 for (u32 i = MASTER_CPU_ID + 1; i < NR_CPUS; i++)
499 if (is_cpu_used(i))
500 do_init_slave_cpu(i);
501}
502
503static void do_init_master_cpu(void)
504{
505 /*
506 * Setup master caches even if master isn't used as we want to use
507 * same cache configuration on all running CPUs
508 */
509 init_master_icache();
510 init_master_dcache();
511}
512
513enum hsdk_axi_masters {
514 M_HS_CORE = 0,
515 M_HS_RTT,
516 M_AXI_TUN,
517 M_HDMI_VIDEO,
518 M_HDMI_AUDIO,
519 M_USB_HOST,
520 M_ETHERNET,
521 M_SDIO,
522 M_GPU,
523 M_DMAC_0,
524 M_DMAC_1,
525 M_DVFS
526};
527
528#define UPDATE_VAL 1
529
530/*
531 * m master AXI_M_m_SLV0 AXI_M_m_SLV1 AXI_M_m_OFFSET0 AXI_M_m_OFFSET1
532 * 0 HS (CBU) 0x11111111 0x63111111 0xFEDCBA98 0x0E543210
533 * 1 HS (RTT) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
534 * 2 AXI Tunnel 0x88888888 0x88888888 0xFEDCBA98 0x76543210
535 * 3 HDMI-VIDEO 0x77777777 0x77777777 0xFEDCBA98 0x76543210
536 * 4 HDMI-ADUIO 0x77777777 0x77777777 0xFEDCBA98 0x76543210
537 * 5 USB-HOST 0x77777777 0x77999999 0xFEDCBA98 0x76DCBA98
538 * 6 ETHERNET 0x77777777 0x77999999 0xFEDCBA98 0x76DCBA98
539 * 7 SDIO 0x77777777 0x77999999 0xFEDCBA98 0x76DCBA98
540 * 8 GPU 0x77777777 0x77777777 0xFEDCBA98 0x76543210
541 * 9 DMAC (port #1) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
542 * 10 DMAC (port #2) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
543 * 11 DVFS 0x00000000 0x60000000 0x00000000 0x00000000
544 *
545 * Please read ARC HS Development IC Specification, section 17.2 for more
546 * information about apertures configuration.
547 * NOTE: we intentionally modify default settings in U-boot. Default settings
548 * are specified in "Table 111 CREG Address Decoder register reset values".
549 */
550
551#define CREG_AXI_M_SLV0(m) ((void __iomem *)(CREG_BASE + 0x020 * (m)))
552#define CREG_AXI_M_SLV1(m) ((void __iomem *)(CREG_BASE + 0x020 * (m) + 0x004))
553#define CREG_AXI_M_OFT0(m) ((void __iomem *)(CREG_BASE + 0x020 * (m) + 0x008))
554#define CREG_AXI_M_OFT1(m) ((void __iomem *)(CREG_BASE + 0x020 * (m) + 0x00C))
555#define CREG_AXI_M_UPDT(m) ((void __iomem *)(CREG_BASE + 0x020 * (m) + 0x014))
556
557#define CREG_AXI_M_HS_CORE_BOOT ((void __iomem *)(CREG_BASE + 0x010))
558
559#define CREG_PAE ((void __iomem *)(CREG_BASE + 0x180))
560#define CREG_PAE_UPDT ((void __iomem *)(CREG_BASE + 0x194))
561
562void init_memory_bridge(void)
563{
564 u32 reg;
565
566 /*
567 * M_HS_CORE has one unic register - BOOT.
568 * We need to clean boot mirror (BOOT[1:0]) bits in them.
569 */
570 reg = readl(CREG_AXI_M_HS_CORE_BOOT) & (~0x3);
571 writel(reg, CREG_AXI_M_HS_CORE_BOOT);
572 writel(0x11111111, CREG_AXI_M_SLV0(M_HS_CORE));
573 writel(0x63111111, CREG_AXI_M_SLV1(M_HS_CORE));
574 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_CORE));
575 writel(0x0E543210, CREG_AXI_M_OFT1(M_HS_CORE));
576 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_CORE));
577
578 writel(0x77777777, CREG_AXI_M_SLV0(M_HS_RTT));
579 writel(0x77777777, CREG_AXI_M_SLV1(M_HS_RTT));
580 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_RTT));
581 writel(0x76543210, CREG_AXI_M_OFT1(M_HS_RTT));
582 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_RTT));
583
584 writel(0x88888888, CREG_AXI_M_SLV0(M_AXI_TUN));
585 writel(0x88888888, CREG_AXI_M_SLV1(M_AXI_TUN));
586 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_AXI_TUN));
587 writel(0x76543210, CREG_AXI_M_OFT1(M_AXI_TUN));
588 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_AXI_TUN));
589
590 writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_VIDEO));
591 writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_VIDEO));
592 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_VIDEO));
593 writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_VIDEO));
594 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_VIDEO));
595
596 writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_AUDIO));
597 writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_AUDIO));
598 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_AUDIO));
599 writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_AUDIO));
600 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_AUDIO));
601
602 writel(0x77777777, CREG_AXI_M_SLV0(M_USB_HOST));
603 writel(0x77999999, CREG_AXI_M_SLV1(M_USB_HOST));
604 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_USB_HOST));
605 writel(0x76DCBA98, CREG_AXI_M_OFT1(M_USB_HOST));
606 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_USB_HOST));
607
608 writel(0x77777777, CREG_AXI_M_SLV0(M_ETHERNET));
609 writel(0x77999999, CREG_AXI_M_SLV1(M_ETHERNET));
610 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_ETHERNET));
611 writel(0x76DCBA98, CREG_AXI_M_OFT1(M_ETHERNET));
612 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_ETHERNET));
613
614 writel(0x77777777, CREG_AXI_M_SLV0(M_SDIO));
615 writel(0x77999999, CREG_AXI_M_SLV1(M_SDIO));
616 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_SDIO));
617 writel(0x76DCBA98, CREG_AXI_M_OFT1(M_SDIO));
618 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_SDIO));
619
620 writel(0x77777777, CREG_AXI_M_SLV0(M_GPU));
621 writel(0x77777777, CREG_AXI_M_SLV1(M_GPU));
622 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_GPU));
623 writel(0x76543210, CREG_AXI_M_OFT1(M_GPU));
624 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_GPU));
625
626 writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_0));
627 writel(0x77777777, CREG_AXI_M_SLV1(M_DMAC_0));
628 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_0));
629 writel(0x76543210, CREG_AXI_M_OFT1(M_DMAC_0));
630 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_0));
631
632 writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_1));
633 writel(0x77777777, CREG_AXI_M_SLV1(M_DMAC_1));
634 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_1));
635 writel(0x76543210, CREG_AXI_M_OFT1(M_DMAC_1));
636 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_1));
637
638 writel(0x00000000, CREG_AXI_M_SLV0(M_DVFS));
639 writel(0x60000000, CREG_AXI_M_SLV1(M_DVFS));
640 writel(0x00000000, CREG_AXI_M_OFT0(M_DVFS));
641 writel(0x00000000, CREG_AXI_M_OFT1(M_DVFS));
642 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DVFS));
643
644 writel(0x00000000, CREG_PAE);
645 writel(UPDATE_VAL, CREG_PAE_UPDT);
646}
647
648static void setup_clocks(void)
649{
650 ulong rate;
651
652 /* Setup CPU clock */
653 if (env_common.cpu_freq.set) {
654 rate = env_common.cpu_freq.val;
655 soc_clk_ctl("cpu-clk", &rate, CLK_ON | CLK_SET | CLK_MHZ);
656 }
657
658 /* Setup TUN clock */
659 if (env_common.tun_freq.set) {
660 rate = env_common.tun_freq.val;
661 if (rate)
662 soc_clk_ctl("tun-clk", &rate, CLK_ON | CLK_SET | CLK_MHZ);
663 else
664 soc_clk_ctl("tun-clk", NULL, CLK_OFF);
665 }
666
667 if (env_common.axi_freq.set) {
668 rate = env_common.axi_freq.val;
669 soc_clk_ctl("axi-clk", &rate, CLK_SET | CLK_ON | CLK_MHZ);
670 }
671}
672
673static void do_init_cluster(void)
674{
675 /*
676 * A multi-core ARC HS configuration always includes only one
677 * ARC_AUX_NON_VOLATILE_LIMIT register, which is shared by all the
678 * cores.
679 */
680 init_cluster_nvlim();
Eugeniy Paltsev1d897d12020-03-23 20:46:35 +0300681 init_cluster_slc();
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300682}
683
684static int check_master_cpu_id(void)
685{
686 if (CPU_ID_GET() == MASTER_CPU_ID)
687 return 0;
688
689 pr_err("u-boot runs on non-master cpu with id: %lu\n", CPU_ID_GET());
690
691 return -ENOENT;
692}
693
694static noinline int prepare_cpus(void)
695{
696 int ret;
697
698 ret = check_master_cpu_id();
699 if (ret)
700 return ret;
701
702 ret = envs_process_and_validate(env_map_common, env_map_core, is_cpu_used);
703 if (ret)
704 return ret;
705
706 printf("CPU start mask is %#x\n", env_common.core_mask.val);
707
708 do_init_slave_cpus();
709 do_init_master_cpu();
710 do_init_cluster();
711
712 return 0;
713}
714
715static int hsdk_go_run(u32 cpu_start_reg)
716{
717 /* Cleanup caches, disable interrupts */
718 cleanup_before_go();
719
720 if (env_common.halt_on_boot)
721 halt_this_cpu();
722
723 /*
724 * 3 NOPs after FLAG 1 instruction are no longer required for ARCv2
725 * cores but we leave them for gebug purposes.
726 */
727 __builtin_arc_nop();
728 __builtin_arc_nop();
729 __builtin_arc_nop();
730
731 /* Kick chosen slave CPUs */
732 writel(cpu_start_reg, (void __iomem *)CREG_CPU_START);
733
734 if (is_cpu_used(MASTER_CPU_ID))
735 ((void (*)(void))(env_core.entry[MASTER_CPU_ID].val))();
736 else
737 halt_this_cpu();
738
739 pr_err("u-boot still runs on cpu [%ld]\n", CPU_ID_GET());
740
741 /*
742 * We will never return after executing our program if master cpu used
743 * otherwise halt master cpu manually.
744 */
745 while (true)
746 halt_this_cpu();
747
748 return 0;
749}
750
751int board_prep_linux(bootm_headers_t *images)
752{
753 int ret, ofst;
754 char mask[15];
755
756 ret = envs_read_validate_common(env_map_mask);
757 if (ret)
758 return ret;
759
760 /* Rollback to default values */
761 if (!env_common.core_mask.set) {
762 env_common.core_mask.val = ALL_CPU_MASK;
763 env_common.core_mask.set = true;
764 }
765
766 printf("CPU start mask is %#x\n", env_common.core_mask.val);
767
768 if (!is_cpu_used(MASTER_CPU_ID))
769 pr_err("ERR: try to launch linux with CPU[0] disabled! It doesn't work for ARC.\n");
770
771 /*
772 * If we want to launch linux on all CPUs we don't need to patch
773 * linux DTB as it is default configuration
774 */
775 if (env_common.core_mask.val == ALL_CPU_MASK)
776 return 0;
777
778 if (!IMAGE_ENABLE_OF_LIBFDT || !images->ft_len) {
779 pr_err("WARN: core_mask setup will work properly only with external DTB!\n");
780 return 0;
781 }
782
783 /* patch '/possible-cpus' property according to cpu mask */
784 ofst = fdt_path_offset(images->ft_addr, "/");
785 sprintf(mask, "%s%s%s%s",
786 is_cpu_used(0) ? "0," : "",
787 is_cpu_used(1) ? "1," : "",
788 is_cpu_used(2) ? "2," : "",
789 is_cpu_used(3) ? "3," : "");
790 ret = fdt_setprop_string(images->ft_addr, ofst, "possible-cpus", mask);
791 /*
792 * If we failed to patch '/possible-cpus' property we don't need break
793 * linux loading process: kernel will handle it but linux will print
794 * warning like "Timeout: CPU1 FAILED to comeup !!!".
795 * So warn here about error, but return 0 like no error had occurred.
796 */
797 if (ret)
798 pr_err("WARN: failed to patch '/possible-cpus' property, ret=%d\n",
799 ret);
800
801 return 0;
802}
803
804void board_jump_and_run(ulong entry, int zero, int arch, uint params)
805{
806 void (*kernel_entry)(int zero, int arch, uint params);
807 u32 cpu_start_reg;
808
809 kernel_entry = (void (*)(int, int, uint))entry;
810
811 /* Prepare CREG_CPU_START for kicking chosen CPUs */
812 cpu_start_reg = prepare_cpu_ctart_reg();
813
814 /* In case of run without hsdk_init */
815 slave_cpu_set_boot_addr(entry);
816
817 /* In case of run with hsdk_init */
818 for (u32 i = 0; i < NR_CPUS; i++) {
819 env_core.entry[i].val = entry;
820 env_core.entry[i].set = true;
821 }
822 /* sync cross_cpu struct as we updated core-entry variables */
823 sync_cross_cpu_data();
824
825 /* Kick chosen slave CPUs */
826 writel(cpu_start_reg, (void __iomem *)CREG_CPU_START);
827
828 if (is_cpu_used(0))
829 kernel_entry(zero, arch, params);
830}
831
832static int hsdk_go_prepare_and_run(void)
833{
834 /* Prepare CREG_CPU_START for kicking chosen CPUs */
835 u32 reg = prepare_cpu_ctart_reg();
836
837 if (env_common.halt_on_boot)
838 printf("CPU will halt before application start, start application with debugger.\n");
839
840 return hsdk_go_run(reg);
841}
842
843static int do_hsdk_go(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
844{
845 int ret;
846
Eugeniy Paltsevf0f84ef2020-04-22 00:33:40 +0300847 if (board_mismatch()) {
848 printf("ERR: U-boot is not configured for this board!\n");
849 return CMD_RET_FAILURE;
850 }
851
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300852 /*
853 * Check for 'halt' parameter. 'halt' = enter halt-mode just before
854 * starting the application; can be used for debug.
855 */
856 if (argc > 1) {
857 env_common.halt_on_boot = !strcmp(argv[1], "halt");
858 if (!env_common.halt_on_boot) {
859 pr_err("Unrecognised parameter: \'%s\'\n", argv[1]);
860 return CMD_RET_FAILURE;
861 }
862 }
863
864 ret = check_master_cpu_id();
865 if (ret)
866 return ret;
867
868 ret = envs_process_and_validate(env_map_mask, env_map_go, is_cpu_used);
869 if (ret)
870 return ret;
871
872 /* sync cross_cpu struct as we updated core-entry variables */
873 sync_cross_cpu_data();
874
875 ret = hsdk_go_prepare_and_run();
876
877 return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
878}
879
880U_BOOT_CMD(
881 hsdk_go, 3, 0, do_hsdk_go,
882 "Synopsys HSDK specific command",
883 " - Boot stand-alone application on HSDK\n"
884 "hsdk_go halt - Boot stand-alone application on HSDK, halt CPU just before application run\n"
885);
886
887static int do_hsdk_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
888{
889 static bool done = false;
890 int ret;
891
Eugeniy Paltsevf0f84ef2020-04-22 00:33:40 +0300892 if (board_mismatch()) {
893 printf("ERR: U-boot is not configured for this board!\n");
894 return CMD_RET_FAILURE;
895 }
896
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +0300897 /* hsdk_init can be run only once */
898 if (done) {
899 printf("HSDK HW is already initialized! Please reset the board if you want to change the configuration.\n");
900 return CMD_RET_FAILURE;
901 }
902
903 ret = prepare_cpus();
904 if (!ret)
905 done = true;
906
907 return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
908}
909
910U_BOOT_CMD(
911 hsdk_init, 1, 0, do_hsdk_init,
912 "Synopsys HSDK specific command",
913 "- Init HSDK HW\n"
914);
915
916static int do_hsdk_clock_set(cmd_tbl_t *cmdtp, int flag, int argc,
917 char *const argv[])
918{
919 int ret = 0;
920
921 /* Strip off leading subcommand argument */
922 argc--;
923 argv++;
924
925 envs_cleanup_common(env_map_clock);
926
927 if (!argc) {
928 printf("Set clocks to values specified in environment\n");
929 ret = envs_read_common(env_map_clock);
930 } else {
931 printf("Set clocks to values specified in args\n");
932 ret = args_envs_enumerate(env_map_clock, 2, argc, argv);
933 }
934
935 if (ret)
936 return CMD_RET_FAILURE;
937
938 ret = envs_validate_common(env_map_clock);
939 if (ret)
940 return CMD_RET_FAILURE;
941
942 /* Setup clock tree HW */
943 setup_clocks();
944
945 return CMD_RET_SUCCESS;
946}
947
948static int do_hsdk_clock_get(cmd_tbl_t *cmdtp, int flag, int argc,
949 char *const argv[])
950{
951 ulong rate;
952
953 if (soc_clk_ctl("cpu-clk", &rate, CLK_GET | CLK_MHZ))
954 return CMD_RET_FAILURE;
955
956 if (env_set_ulong("cpu_freq", rate))
957 return CMD_RET_FAILURE;
958
959 if (soc_clk_ctl("tun-clk", &rate, CLK_GET | CLK_MHZ))
960 return CMD_RET_FAILURE;
961
962 if (env_set_ulong("tun_freq", rate))
963 return CMD_RET_FAILURE;
964
965 if (soc_clk_ctl("axi-clk", &rate, CLK_GET | CLK_MHZ))
966 return CMD_RET_FAILURE;
967
968 if (env_set_ulong("axi_freq", rate))
969 return CMD_RET_FAILURE;
970
971 printf("Clock values are saved to environment\n");
972
973 return CMD_RET_SUCCESS;
974}
975
976static int do_hsdk_clock_print(cmd_tbl_t *cmdtp, int flag, int argc,
977 char *const argv[])
978{
979 /* Main clocks */
980 soc_clk_ctl("cpu-clk", NULL, CLK_PRINT | CLK_MHZ);
981 soc_clk_ctl("tun-clk", NULL, CLK_PRINT | CLK_MHZ);
982 soc_clk_ctl("axi-clk", NULL, CLK_PRINT | CLK_MHZ);
983 soc_clk_ctl("ddr-clk", NULL, CLK_PRINT | CLK_MHZ);
984
985 return CMD_RET_SUCCESS;
986}
987
988static int do_hsdk_clock_print_all(cmd_tbl_t *cmdtp, int flag, int argc,
989 char *const argv[])
990{
991 /*
992 * NOTE: as of today we don't use some peripherals like HDMI / EBI
993 * so we don't want to print their clocks ("hdmi-sys-clk", "hdmi-pll",
994 * "hdmi-clk", "ebi-clk"). Nevertheless their clock subsystems is fully
995 * functional and we can print their clocks if it is required
996 */
997
998 /* CPU clock domain */
999 soc_clk_ctl("cpu-pll", NULL, CLK_PRINT | CLK_MHZ);
1000 soc_clk_ctl("cpu-clk", NULL, CLK_PRINT | CLK_MHZ);
1001 printf("\n");
1002
1003 /* SYS clock domain */
1004 soc_clk_ctl("sys-pll", NULL, CLK_PRINT | CLK_MHZ);
1005 soc_clk_ctl("apb-clk", NULL, CLK_PRINT | CLK_MHZ);
1006 soc_clk_ctl("axi-clk", NULL, CLK_PRINT | CLK_MHZ);
1007 soc_clk_ctl("eth-clk", NULL, CLK_PRINT | CLK_MHZ);
1008 soc_clk_ctl("usb-clk", NULL, CLK_PRINT | CLK_MHZ);
1009 soc_clk_ctl("sdio-clk", NULL, CLK_PRINT | CLK_MHZ);
Eugeniy Paltsevb84aa4c2020-04-22 02:08:06 +03001010 if (is_board_match_runtime(T_BOARD_HSDK_4XD))
1011 soc_clk_ctl("hdmi-sys-clk", NULL, CLK_PRINT | CLK_MHZ);
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +03001012 soc_clk_ctl("gfx-core-clk", NULL, CLK_PRINT | CLK_MHZ);
Eugeniy Paltsevda34c6b2020-04-22 22:44:24 +03001013 if (is_board_match_runtime(T_BOARD_HSDK)) {
1014 soc_clk_ctl("gfx-dma-clk", NULL, CLK_PRINT | CLK_MHZ);
1015 soc_clk_ctl("gfx-cfg-clk", NULL, CLK_PRINT | CLK_MHZ);
1016 }
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +03001017 soc_clk_ctl("dmac-core-clk", NULL, CLK_PRINT | CLK_MHZ);
1018 soc_clk_ctl("dmac-cfg-clk", NULL, CLK_PRINT | CLK_MHZ);
1019 soc_clk_ctl("sdio-ref-clk", NULL, CLK_PRINT | CLK_MHZ);
1020 soc_clk_ctl("spi-clk", NULL, CLK_PRINT | CLK_MHZ);
1021 soc_clk_ctl("i2c-clk", NULL, CLK_PRINT | CLK_MHZ);
1022/* soc_clk_ctl("ebi-clk", NULL, CLK_PRINT | CLK_MHZ); */
1023 soc_clk_ctl("uart-clk", NULL, CLK_PRINT | CLK_MHZ);
1024 printf("\n");
1025
1026 /* DDR clock domain */
1027 soc_clk_ctl("ddr-clk", NULL, CLK_PRINT | CLK_MHZ);
1028 printf("\n");
1029
1030 /* HDMI clock domain */
Eugeniy Paltsevb84aa4c2020-04-22 02:08:06 +03001031 if (is_board_match_runtime(T_BOARD_HSDK_4XD)) {
1032 soc_clk_ctl("hdmi-pll", NULL, CLK_PRINT | CLK_MHZ);
1033 soc_clk_ctl("hdmi-clk", NULL, CLK_PRINT | CLK_MHZ);
1034 printf("\n");
1035 }
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +03001036
1037 /* TUN clock domain */
1038 soc_clk_ctl("tun-pll", NULL, CLK_PRINT | CLK_MHZ);
1039 soc_clk_ctl("tun-clk", NULL, CLK_PRINT | CLK_MHZ);
1040 soc_clk_ctl("rom-clk", NULL, CLK_PRINT | CLK_MHZ);
1041 soc_clk_ctl("pwm-clk", NULL, CLK_PRINT | CLK_MHZ);
Eugeniy Paltsevd4ee5c32020-04-23 14:52:43 +03001042 if (is_board_match_runtime(T_BOARD_HSDK_4XD))
1043 soc_clk_ctl("timer-clk", NULL, CLK_PRINT | CLK_MHZ);
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +03001044 printf("\n");
1045
1046 return CMD_RET_SUCCESS;
1047}
1048
1049cmd_tbl_t cmd_hsdk_clock[] = {
1050 U_BOOT_CMD_MKENT(set, 3, 0, do_hsdk_clock_set, "", ""),
1051 U_BOOT_CMD_MKENT(get, 3, 0, do_hsdk_clock_get, "", ""),
1052 U_BOOT_CMD_MKENT(print, 4, 0, do_hsdk_clock_print, "", ""),
1053 U_BOOT_CMD_MKENT(print_all, 4, 0, do_hsdk_clock_print_all, "", ""),
1054};
1055
1056static int do_hsdk_clock(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
1057{
1058 cmd_tbl_t *c;
1059
1060 if (argc < 2)
1061 return CMD_RET_USAGE;
1062
1063 /* Strip off leading 'hsdk_clock' command argument */
1064 argc--;
1065 argv++;
1066
1067 c = find_cmd_tbl(argv[0], cmd_hsdk_clock, ARRAY_SIZE(cmd_hsdk_clock));
1068 if (!c)
1069 return CMD_RET_USAGE;
1070
1071 return c->cmd(cmdtp, flag, argc, argv);
1072}
1073
1074U_BOOT_CMD(
1075 hsdk_clock, CONFIG_SYS_MAXARGS, 0, do_hsdk_clock,
1076 "Synopsys HSDK specific clock command",
1077 "set - Set clock to values specified in environment / command line arguments\n"
1078 "hsdk_clock get - Save clock values to environment\n"
1079 "hsdk_clock print - Print main clock values to console\n"
1080 "hsdk_clock print_all - Print all clock values to console\n"
1081);
1082
1083/* init calls */
1084int board_early_init_f(void)
1085{
1086 /*
1087 * Setup AXI apertures unconditionally as we want to have DDR
1088 * in 0x00000000 region when we are kicking slave cpus.
1089 */
1090 init_memory_bridge();
1091
Eugeniy Paltsev54858312019-02-25 18:35:29 +03001092 /*
1093 * Switch SDIO external ciu clock divider from default div-by-8 to
1094 * minimum possible div-by-2.
1095 */
1096 writel(SDIO_UHS_REG_EXT_DIV_2, (void __iomem *)SDIO_UHS_REG_EXT);
1097
Eugeniy Paltsevada8aff2018-03-26 15:57:37 +03001098 return 0;
1099}
1100
1101int board_early_init_r(void)
1102{
1103 /*
1104 * TODO: Init USB here to be able read environment from USB MSD.
1105 * It can be done with usb_init() call. We can't do it right now
1106 * due to brocken USB IP SW reset and lack of USB IP HW reset in
1107 * linux kernel (if we init USB here we will break USB in linux)
1108 */
1109
1110 /*
1111 * Flush all d$ as we want to use uncached area with st.di / ld.di
1112 * instructions and we don't want to have any dirty line in L1d$ or SL$
1113 * in this area. It is enough to flush all d$ once here as we access to
1114 * uncached area with regular st (non .di) instruction only when we copy
1115 * data during u-boot relocation.
1116 */
1117 flush_dcache_all();
1118
1119 printf("Relocation Offset is: %08lx\n", gd->reloc_off);
1120
1121 return 0;
1122}
1123
1124int board_late_init(void)
1125{
1126 /*
1127 * Populate environment with clock frequency values -
1128 * run hsdk_clock get callback without uboot command run.
1129 */
1130 do_hsdk_clock_get(NULL, 0, 0, NULL);
1131
1132 return 0;
1133}
Eugeniy Paltsev4e782b52017-10-21 15:35:12 +03001134
Alexey Brodkin6ef705b2018-11-27 09:47:01 +03001135int checkboard(void)
1136{
Eugeniy Paltsevf0f84ef2020-04-22 00:33:40 +03001137 printf("Board: Synopsys %s\n", board_name(get_board_type_runtime()));
1138
1139 if (board_mismatch())
1140 printf("WARN: U-boot is configured NOT for this board but for %s!\n",
1141 board_name(get_board_type_config()));
1142
Alexey Brodkin6ef705b2018-11-27 09:47:01 +03001143 return 0;
1144};