]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv8/fsl-lsch3/cpu.c
0e5aa5ca9506f0a6b7bb762701ec7f12bef435e0
[karo-tx-uboot.git] / arch / arm / cpu / armv8 / fsl-lsch3 / cpu.c
1 /*
2  * Copyright 2014 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <asm/io.h>
9 #include <asm/system.h>
10 #include <asm/armv8/mmu.h>
11 #include <asm/io.h>
12 #include <asm/arch-fsl-lsch3/immap_lsch3.h>
13 #include <fsl_debug_server.h>
14 #include <fsl-mc/fsl_mc.h>
15 #include "cpu.h"
16 #include "mp.h"
17 #include "speed.h"
18
19 DECLARE_GLOBAL_DATA_PTR;
20
21 #ifndef CONFIG_SYS_DCACHE_OFF
22 /*
23  * To start MMU before DDR is available, we create MMU table in SRAM.
24  * The base address of SRAM is CONFIG_SYS_FSL_OCRAM_BASE. We use three
25  * levels of translation tables here to cover 40-bit address space.
26  * We use 4KB granule size, with 40 bits physical address, T0SZ=24
27  * Level 0 IA[39], table address @0
28  * Level 1 IA[31:30], table address @01000, 0x2000
29  * Level 2 IA[29:21], table address @0x3000
30  */
31
32 #define SECTION_SHIFT_L0        39UL
33 #define SECTION_SHIFT_L1        30UL
34 #define SECTION_SHIFT_L2        21UL
35 #define BLOCK_SIZE_L0           0x8000000000UL
36 #define BLOCK_SIZE_L1           (1 << SECTION_SHIFT_L1)
37 #define BLOCK_SIZE_L2           (1 << SECTION_SHIFT_L2)
38 #define CONFIG_SYS_IFC_BASE     0x30000000
39 #define CONFIG_SYS_IFC_SIZE     0x10000000
40 #define CONFIG_SYS_IFC_BASE2    0x500000000
41 #define CONFIG_SYS_IFC_SIZE2    0x100000000
42 #define TCR_EL2_PS_40BIT        (2 << 16)
43 #define LSCH3_VA_BITS           (40)
44 #define LSCH3_TCR       (TCR_TG0_4K             | \
45                         TCR_EL2_PS_40BIT        | \
46                         TCR_SHARED_NON          | \
47                         TCR_ORGN_NC             | \
48                         TCR_IRGN_NC             | \
49                         TCR_T0SZ(LSCH3_VA_BITS))
50
51 /*
52  * Final MMU
53  * Let's start from the same layout as early MMU and modify as needed.
54  * IFC regions will be cache-inhibit.
55  */
56 #define FINAL_QBMAN_CACHED_MEM  0x818000000UL
57 #define FINAL_QBMAN_CACHED_SIZE 0x4000000
58
59
60 static inline void early_mmu_setup(void)
61 {
62         int el;
63         u64 i;
64         u64 section_l1t0, section_l1t1, section_l2;
65         u64 *level0_table = (u64 *)CONFIG_SYS_FSL_OCRAM_BASE;
66         u64 *level1_table_0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x1000);
67         u64 *level1_table_1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x2000);
68         u64 *level2_table = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000);
69
70
71         level0_table[0] =
72                 (u64)level1_table_0 | PMD_TYPE_TABLE;
73         level0_table[1] =
74                 (u64)level1_table_1 | PMD_TYPE_TABLE;
75
76         /*
77          * set level 1 table 0 to cache_inhibit, covering 0 to 512GB
78          * set level 1 table 1 to cache enabled, covering 512GB to 1TB
79          * set level 2 table to cache-inhibit, covering 0 to 1GB
80          */
81         section_l1t0 = 0;
82         section_l1t1 = BLOCK_SIZE_L0;
83         section_l2 = 0;
84         for (i = 0; i < 512; i++) {
85                 set_pgtable_section(level1_table_0, i, section_l1t0,
86                                     MT_DEVICE_NGNRNE);
87                 set_pgtable_section(level1_table_1, i, section_l1t1,
88                                     MT_NORMAL);
89                 set_pgtable_section(level2_table, i, section_l2,
90                                     MT_DEVICE_NGNRNE);
91                 section_l1t0 += BLOCK_SIZE_L1;
92                 section_l1t1 += BLOCK_SIZE_L1;
93                 section_l2 += BLOCK_SIZE_L2;
94         }
95
96         level1_table_0[0] =
97                 (u64)level2_table | PMD_TYPE_TABLE;
98         level1_table_0[1] =
99                 0x40000000 | PMD_SECT_AF | PMD_TYPE_SECT |
100                 PMD_ATTRINDX(MT_DEVICE_NGNRNE);
101         level1_table_0[2] =
102                 0x80000000 | PMD_SECT_AF | PMD_TYPE_SECT |
103                 PMD_ATTRINDX(MT_NORMAL);
104         level1_table_0[3] =
105                 0xc0000000 | PMD_SECT_AF | PMD_TYPE_SECT |
106                 PMD_ATTRINDX(MT_NORMAL);
107
108         /* Rewrite table to enable cache */
109         set_pgtable_section(level2_table,
110                             CONFIG_SYS_FSL_OCRAM_BASE >> SECTION_SHIFT_L2,
111                             CONFIG_SYS_FSL_OCRAM_BASE,
112                             MT_NORMAL);
113         for (i = CONFIG_SYS_IFC_BASE >> SECTION_SHIFT_L2;
114              i < (CONFIG_SYS_IFC_BASE + CONFIG_SYS_IFC_SIZE)
115              >> SECTION_SHIFT_L2; i++) {
116                 section_l2 = i << SECTION_SHIFT_L2;
117                 set_pgtable_section(level2_table, i,
118                                     section_l2, MT_NORMAL);
119         }
120
121         el = current_el();
122         set_ttbr_tcr_mair(el, (u64)level0_table, LSCH3_TCR, MEMORY_ATTRIBUTES);
123         set_sctlr(get_sctlr() | CR_M);
124 }
125
126 /*
127  * This final tale looks similar to early table, but different in detail.
128  * These tables are in regular memory. Cache on IFC is disabled. One sub table
129  * is added to enable cache for QBMan.
130  */
131 static inline void final_mmu_setup(void)
132 {
133         int el;
134         u64 i, tbl_base, tbl_limit, section_base;
135         u64 section_l1t0, section_l1t1, section_l2;
136         u64 *level0_table = (u64 *)gd->arch.tlb_addr;
137         u64 *level1_table_0 = (u64 *)(gd->arch.tlb_addr + 0x1000);
138         u64 *level1_table_1 = (u64 *)(gd->arch.tlb_addr + 0x2000);
139         u64 *level2_table_0 = (u64 *)(gd->arch.tlb_addr + 0x3000);
140         u64 *level2_table_1 = (u64 *)(gd->arch.tlb_addr + 0x4000);
141
142
143         level0_table[0] =
144                 (u64)level1_table_0 | PMD_TYPE_TABLE;
145         level0_table[1] =
146                 (u64)level1_table_1 | PMD_TYPE_TABLE;
147
148         /*
149          * set level 1 table 0 to cache_inhibit, covering 0 to 512GB
150          * set level 1 table 1 to cache enabled, covering 512GB to 1TB
151          * set level 2 table 0 to cache-inhibit, covering 0 to 1GB
152          */
153         section_l1t0 = 0;
154         section_l1t1 = BLOCK_SIZE_L0 | PMD_SECT_OUTER_SHARE;
155         section_l2 = 0;
156         for (i = 0; i < 512; i++) {
157                 set_pgtable_section(level1_table_0, i, section_l1t0,
158                                     MT_DEVICE_NGNRNE);
159                 set_pgtable_section(level1_table_1, i, section_l1t1,
160                                     MT_NORMAL);
161                 set_pgtable_section(level2_table_0, i, section_l2,
162                                     MT_DEVICE_NGNRNE);
163                 section_l1t0 += BLOCK_SIZE_L1;
164                 section_l1t1 += BLOCK_SIZE_L1;
165                 section_l2 += BLOCK_SIZE_L2;
166         }
167
168         level1_table_0[0] =
169                 (u64)level2_table_0 | PMD_TYPE_TABLE;
170         level1_table_0[2] =
171                 0x80000000 | PMD_SECT_AF | PMD_TYPE_SECT |
172                 PMD_SECT_OUTER_SHARE | PMD_ATTRINDX(MT_NORMAL);
173         level1_table_0[3] =
174                 0xc0000000 | PMD_SECT_AF | PMD_TYPE_SECT |
175                 PMD_SECT_OUTER_SHARE | PMD_ATTRINDX(MT_NORMAL);
176
177         /* Rewrite table to enable cache */
178         set_pgtable_section(level2_table_0,
179                             CONFIG_SYS_FSL_OCRAM_BASE >> SECTION_SHIFT_L2,
180                             CONFIG_SYS_FSL_OCRAM_BASE,
181                             MT_NORMAL);
182
183         /*
184          * Fill in other part of tables if cache is needed
185          * If finer granularity than 1GB is needed, sub table
186          * should be created.
187          */
188         section_base = FINAL_QBMAN_CACHED_MEM & ~(BLOCK_SIZE_L1 - 1);
189         i = section_base >> SECTION_SHIFT_L1;
190         level1_table_0[i] = (u64)level2_table_1 | PMD_TYPE_TABLE;
191         section_l2 = section_base;
192         for (i = 0; i < 512; i++) {
193                 set_pgtable_section(level2_table_1, i, section_l2,
194                                     MT_DEVICE_NGNRNE);
195                 section_l2 += BLOCK_SIZE_L2;
196         }
197         tbl_base = FINAL_QBMAN_CACHED_MEM & (BLOCK_SIZE_L1 - 1);
198         tbl_limit = (FINAL_QBMAN_CACHED_MEM + FINAL_QBMAN_CACHED_SIZE) &
199                     (BLOCK_SIZE_L1 - 1);
200         for (i = tbl_base >> SECTION_SHIFT_L2;
201              i < tbl_limit >> SECTION_SHIFT_L2; i++) {
202                 section_l2 = section_base + (i << SECTION_SHIFT_L2);
203                 set_pgtable_section(level2_table_1, i,
204                                     section_l2, MT_NORMAL);
205         }
206
207         /* flush new MMU table */
208         flush_dcache_range(gd->arch.tlb_addr,
209                            gd->arch.tlb_addr +  gd->arch.tlb_size);
210
211         /* point TTBR to the new table */
212         el = current_el();
213         asm volatile("dsb sy");
214         if (el == 1) {
215                 asm volatile("msr ttbr0_el1, %0"
216                              : : "r" ((u64)level0_table) : "memory");
217         } else if (el == 2) {
218                 asm volatile("msr ttbr0_el2, %0"
219                              : : "r" ((u64)level0_table) : "memory");
220         } else if (el == 3) {
221                 asm volatile("msr ttbr0_el3, %0"
222                              : : "r" ((u64)level0_table) : "memory");
223         } else {
224                 hang();
225         }
226         asm volatile("isb");
227
228         /*
229          * MMU is already enabled, just need to invalidate TLB to load the
230          * new table. The new table is compatible with the current table, if
231          * MMU somehow walks through the new table before invalidation TLB,
232          * it still works. So we don't need to turn off MMU here.
233          */
234 }
235
236 int arch_cpu_init(void)
237 {
238         icache_enable();
239         __asm_invalidate_dcache_all();
240         __asm_invalidate_tlb_all();
241         early_mmu_setup();
242         set_sctlr(get_sctlr() | CR_C);
243         return 0;
244 }
245
246 /*
247  * This function is called from lib/board.c.
248  * It recreates MMU table in main memory. MMU and d-cache are enabled earlier.
249  * There is no need to disable d-cache for this operation.
250  */
251 void enable_caches(void)
252 {
253         final_mmu_setup();
254         __asm_invalidate_tlb_all();
255 }
256 #endif
257
258 static inline u32 initiator_type(u32 cluster, int init_id)
259 {
260         struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
261         u32 idx = (cluster >> (init_id * 8)) & TP_CLUSTER_INIT_MASK;
262         u32 type = in_le32(&gur->tp_ityp[idx]);
263
264         if (type & TP_ITYP_AV)
265                 return type;
266
267         return 0;
268 }
269
270 u32 cpu_mask(void)
271 {
272         struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
273         int i = 0, count = 0;
274         u32 cluster, type, mask = 0;
275
276         do {
277                 int j;
278                 cluster = in_le32(&gur->tp_cluster[i].lower);
279                 for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
280                         type = initiator_type(cluster, j);
281                         if (type) {
282                                 if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_ARM)
283                                         mask |= 1 << count;
284                                 count++;
285                         }
286                 }
287                 i++;
288         } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
289
290         return mask;
291 }
292
293 /*
294  * Return the number of cores on this SOC.
295  */
296 int cpu_numcores(void)
297 {
298         return hweight32(cpu_mask());
299 }
300
301 int fsl_qoriq_core_to_cluster(unsigned int core)
302 {
303         struct ccsr_gur __iomem *gur =
304                 (void __iomem *)(CONFIG_SYS_FSL_GUTS_ADDR);
305         int i = 0, count = 0;
306         u32 cluster;
307
308         do {
309                 int j;
310                 cluster = in_le32(&gur->tp_cluster[i].lower);
311                 for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
312                         if (initiator_type(cluster, j)) {
313                                 if (count == core)
314                                         return i;
315                                 count++;
316                         }
317                 }
318                 i++;
319         } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
320
321         return -1;      /* cannot identify the cluster */
322 }
323
324 u32 fsl_qoriq_core_to_type(unsigned int core)
325 {
326         struct ccsr_gur __iomem *gur =
327                 (void __iomem *)(CONFIG_SYS_FSL_GUTS_ADDR);
328         int i = 0, count = 0;
329         u32 cluster, type;
330
331         do {
332                 int j;
333                 cluster = in_le32(&gur->tp_cluster[i].lower);
334                 for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
335                         type = initiator_type(cluster, j);
336                         if (type) {
337                                 if (count == core)
338                                         return type;
339                                 count++;
340                         }
341                 }
342                 i++;
343         } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
344
345         return -1;      /* cannot identify the cluster */
346 }
347
348 #ifdef CONFIG_DISPLAY_CPUINFO
349 int print_cpuinfo(void)
350 {
351         struct sys_info sysinfo;
352         char buf[32];
353         unsigned int i, core;
354         u32 type;
355
356         get_sys_info(&sysinfo);
357         puts("Clock Configuration:");
358         for_each_cpu(i, core, cpu_numcores(), cpu_mask()) {
359                 if (!(i % 3))
360                         puts("\n       ");
361                 type = TP_ITYP_VER(fsl_qoriq_core_to_type(core));
362                 printf("CPU%d(%s):%-4s MHz  ", core,
363                        type == TY_ITYP_VER_A7 ? "A7 " :
364                        (type == TY_ITYP_VER_A53 ? "A53" :
365                         (type == TY_ITYP_VER_A57 ? "A57" : "   ")),
366                        strmhz(buf, sysinfo.freq_processor[core]));
367         }
368         printf("\n       Bus:      %-4s MHz  ",
369                strmhz(buf, sysinfo.freq_systembus));
370         printf("DDR:      %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus));
371         printf("     DP-DDR:   %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus2));
372         puts("\n");
373
374         return 0;
375 }
376 #endif
377
378 int cpu_eth_init(bd_t *bis)
379 {
380         int error = 0;
381
382 #ifdef CONFIG_FSL_MC_ENET
383         error = fsl_mc_ldpaa_init(bis);
384 #endif
385         return error;
386 }
387
388 int arch_early_init_r(void)
389 {
390         int rv;
391         rv = fsl_lsch3_wake_seconday_cores();
392
393         if (rv)
394                 printf("Did not wake secondary cores\n");
395
396         return 0;
397 }
398
399 int timer_init(void)
400 {
401         u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
402         u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
403 #ifdef COUNTER_FREQUENCY_REAL
404         unsigned long cntfrq = COUNTER_FREQUENCY_REAL;
405
406         /* Update with accurate clock frequency */
407         asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
408 #endif
409
410         /* Enable timebase for all clusters.
411          * It is safe to do so even some clusters are not enabled.
412          */
413         out_le32(cltbenr, 0xf);
414
415         /* Enable clock for timer
416          * This is a global setting.
417          */
418         out_le32(cntcr, 0x1);
419
420         return 0;
421 }
422
423 void reset_cpu(ulong addr)
424 {
425         u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR;
426         u32 val;
427
428         /* Raise RESET_REQ_B */
429         val = in_le32(rstcr);
430         val |= 0x02;
431         out_le32(rstcr, val);
432 }