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