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