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