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