]> git.sur5r.net Git - u-boot/blob - arch/arm/cpu/armv7/ls102xa/cpu.c
arm/ls102xa: create TLB to map PCIe region
[u-boot] / arch / arm / cpu / armv7 / ls102xa / 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/arch/clock.h>
9 #include <asm/io.h>
10 #include <asm/arch/immap_ls102xa.h>
11 #include <asm/cache.h>
12 #include <asm/system.h>
13 #include <tsec.h>
14 #include <netdev.h>
15 #include <fsl_esdhc.h>
16
17 #include "fsl_epu.h"
18
19 DECLARE_GLOBAL_DATA_PTR;
20
21 #ifndef CONFIG_SYS_DCACHE_OFF
22
23 /*
24  * Bit[1] of the descriptor indicates the descriptor type,
25  * and bit[0] indicates whether the descriptor is valid.
26  */
27 #define PMD_TYPE_TABLE          0x3
28 #define PMD_TYPE_SECT           0x1
29
30 /* AttrIndx[2:0] */
31 #define PMD_ATTRINDX(t)         ((t) << 2)
32
33 /* Section */
34 #define PMD_SECT_AF             (1 << 10)
35
36 #define BLOCK_SIZE_L1           (1UL << 30)
37 #define BLOCK_SIZE_L2           (1UL << 21)
38
39 /* TTBCR flags */
40 #define TTBCR_EAE               (1 << 31)
41 #define TTBCR_T0SZ(x)           ((x) << 0)
42 #define TTBCR_T1SZ(x)           ((x) << 16)
43 #define TTBCR_USING_TTBR0       (TTBCR_T0SZ(0) | TTBCR_T1SZ(0))
44 #define TTBCR_IRGN0_NC          (0 << 8)
45 #define TTBCR_IRGN0_WBWA        (1 << 8)
46 #define TTBCR_IRGN0_WT          (2 << 8)
47 #define TTBCR_IRGN0_WBNWA       (3 << 8)
48 #define TTBCR_IRGN0_MASK        (3 << 8)
49 #define TTBCR_ORGN0_NC          (0 << 10)
50 #define TTBCR_ORGN0_WBWA        (1 << 10)
51 #define TTBCR_ORGN0_WT          (2 << 10)
52 #define TTBCR_ORGN0_WBNWA       (3 << 10)
53 #define TTBCR_ORGN0_MASK        (3 << 10)
54 #define TTBCR_SHARED_NON        (0 << 12)
55 #define TTBCR_SHARED_OUTER      (2 << 12)
56 #define TTBCR_SHARED_INNER      (3 << 12)
57 #define TTBCR_EPD0              (0 << 7)
58 #define TTBCR                   (TTBCR_SHARED_NON | \
59                                  TTBCR_ORGN0_NC | \
60                                  TTBCR_IRGN0_NC | \
61                                  TTBCR_USING_TTBR0 | \
62                                  TTBCR_EAE)
63
64 /*
65  * Memory region attributes for LPAE (defined in pgtable):
66  *
67  * n = AttrIndx[2:0]
68  *
69  *                            n       MAIR
70  *      UNCACHED              000     00000000
71  *      BUFFERABLE            001     01000100
72  *      DEV_WC                001     01000100
73  *      WRITETHROUGH          010     10101010
74  *      WRITEBACK             011     11101110
75  *      DEV_CACHED            011     11101110
76  *      DEV_SHARED            100     00000100
77  *      DEV_NONSHARED         100     00000100
78  *      unused                101
79  *      unused                110
80  *      WRITEALLOC            111     11111111
81  */
82 #define MT_MAIR0                0xeeaa4400
83 #define MT_MAIR1                0xff000004
84 #define MT_STRONLY_ORDER        0
85 #define MT_NORMAL_NC            1
86 #define MT_DEVICE_MEM           4
87 #define MT_NORMAL               7
88
89 /* The phy_addr must be aligned to 4KB */
90 static inline void set_pgtable(u32 *page_table, u32 index, u32 phy_addr)
91 {
92         u32 value = phy_addr | PMD_TYPE_TABLE;
93
94         page_table[2 * index] = value;
95         page_table[2 * index + 1] = 0;
96 }
97
98 /* The phy_addr must be aligned to 4KB */
99 static inline void set_pgsection(u32 *page_table, u32 index, u64 phy_addr,
100                                  u32 memory_type)
101 {
102         u64 value;
103
104         value = phy_addr | PMD_TYPE_SECT | PMD_SECT_AF;
105         value |= PMD_ATTRINDX(memory_type);
106         page_table[2 * index] = value & 0xFFFFFFFF;
107         page_table[2 * index + 1] = (value >> 32) & 0xFFFFFFFF;
108 }
109
110 /*
111  * Start MMU after DDR is available, we create MMU table in DRAM.
112  * The base address of TTLB is gd->arch.tlb_addr. We use two
113  * levels of translation tables here to cover 40-bit address space.
114  *
115  * The TTLBs are located at PHY 2G~4G.
116  *
117  * VA mapping:
118  *
119  *  -------  <---- 0GB
120  * |       |
121  * |       |
122  * |-------| <---- 0x24000000
123  * |///////|  ===> 192MB VA map for PCIe1 with offset 0x40_0000_0000
124  * |-------| <---- 0x300000000
125  * |       |
126  * |-------| <---- 0x34000000
127  * |///////|  ===> 192MB VA map for PCIe2 with offset 0x48_0000_0000
128  * |-------| <---- 0x40000000
129  * |       |
130  * |-------| <---- 0x80000000 DDR0 space start
131  * |\\\\\\\|
132  *.|\\\\\\\|  ===> 2GB VA map for 2GB DDR0 Memory space
133  * |\\\\\\\|
134  *  -------  <---- 4GB DDR0 space end
135  */
136 static void mmu_setup(void)
137 {
138         u32 *level0_table = (u32 *)gd->arch.tlb_addr;
139         u32 *level1_table = (u32 *)(gd->arch.tlb_addr + 0x1000);
140         u64 va_start = 0;
141         u32 reg;
142         int i;
143
144         /* Level 0 Table 2-3 are used to map DDR */
145         set_pgsection(level0_table, 3, 3 * BLOCK_SIZE_L1, MT_NORMAL);
146         set_pgsection(level0_table, 2, 2 * BLOCK_SIZE_L1, MT_NORMAL);
147         /* Level 0 Table 1 is used to map device */
148         set_pgsection(level0_table, 1, 1 * BLOCK_SIZE_L1, MT_DEVICE_MEM);
149         /* Level 0 Table 0 is used to map device including PCIe MEM */
150         set_pgtable(level0_table, 0, (u32)level1_table);
151
152         /* Level 1 has 512 entries */
153         for (i = 0; i < 512; i++) {
154                 /* Mapping for PCIe 1 */
155                 if (va_start >= CONFIG_SYS_PCIE1_VIRT_ADDR &&
156                     va_start < (CONFIG_SYS_PCIE1_VIRT_ADDR +
157                                  CONFIG_SYS_PCIE_MMAP_SIZE))
158                         set_pgsection(level1_table, i,
159                                       CONFIG_SYS_PCIE1_PHYS_BASE + va_start,
160                                       MT_DEVICE_MEM);
161                 /* Mapping for PCIe 2 */
162                 else if (va_start >= CONFIG_SYS_PCIE2_VIRT_ADDR &&
163                          va_start < (CONFIG_SYS_PCIE2_VIRT_ADDR +
164                                      CONFIG_SYS_PCIE_MMAP_SIZE))
165                         set_pgsection(level1_table, i,
166                                       CONFIG_SYS_PCIE2_PHYS_BASE + va_start,
167                                       MT_DEVICE_MEM);
168                 else
169                         set_pgsection(level1_table, i,
170                                       va_start,
171                                       MT_DEVICE_MEM);
172                 va_start += BLOCK_SIZE_L2;
173         }
174
175         asm volatile("dsb sy;isb");
176         asm volatile("mcr p15, 0, %0, c2, c0, 2" /* Write RT to TTBCR */
177                         : : "r" (TTBCR) : "memory");
178         asm volatile("mcrr p15, 0, %0, %1, c2" /* TTBR 0 */
179                         : : "r" ((u32)level0_table), "r" (0) : "memory");
180         asm volatile("mcr p15, 0, %0, c10, c2, 0" /* write MAIR 0 */
181                         : : "r" (MT_MAIR0) : "memory");
182         asm volatile("mcr p15, 0, %0, c10, c2, 1" /* write MAIR 1 */
183                         : : "r" (MT_MAIR1) : "memory");
184
185         /* Set the access control to all-supervisor */
186         asm volatile("mcr p15, 0, %0, c3, c0, 0"
187                      : : "r" (~0));
188
189         /* Enable the mmu */
190         reg = get_cr();
191         set_cr(reg | CR_M);
192 }
193
194 /*
195  * This function is called from lib/board.c. It recreates MMU
196  * table in main memory. MMU and i/d-cache are enabled here.
197  */
198 void enable_caches(void)
199 {
200         /* Invalidate all TLB */
201         mmu_page_table_flush(gd->arch.tlb_addr,
202                              gd->arch.tlb_addr +  gd->arch.tlb_size);
203         /* Set up and enable mmu */
204         mmu_setup();
205
206         /* Invalidate & Enable d-cache */
207         invalidate_dcache_all();
208         set_cr(get_cr() | CR_C);
209 }
210 #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
211
212 #if defined(CONFIG_DISPLAY_CPUINFO)
213 int print_cpuinfo(void)
214 {
215         char buf1[32], buf2[32];
216         struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
217         unsigned int svr, major, minor, ver, i;
218
219         svr = in_be32(&gur->svr);
220         major = SVR_MAJ(svr);
221         minor = SVR_MIN(svr);
222
223         puts("CPU:   Freescale LayerScape ");
224
225         ver = SVR_SOC_VER(svr);
226         switch (ver) {
227         case SOC_VER_SLS1020:
228                 puts("SLS1020");
229                 break;
230         case SOC_VER_LS1020:
231                 puts("LS1020");
232                 break;
233         case SOC_VER_LS1021:
234                 puts("LS1021");
235                 break;
236         case SOC_VER_LS1022:
237                 puts("LS1022");
238                 break;
239         default:
240                 puts("Unknown");
241                 break;
242         }
243
244         if (IS_E_PROCESSOR(svr) && (ver != SOC_VER_SLS1020))
245                 puts("E");
246
247         printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
248
249         puts("Clock Configuration:");
250
251         printf("\n       CPU0(ARMV7):%-4s MHz, ", strmhz(buf1, gd->cpu_clk));
252         printf("\n       Bus:%-4s MHz, ", strmhz(buf1, gd->bus_clk));
253         printf("DDR:%-4s MHz (%s MT/s data rate), ",
254                strmhz(buf1, gd->mem_clk/2), strmhz(buf2, gd->mem_clk));
255         puts("\n");
256
257         /* Display the RCW, so that no one gets confused as to what RCW
258          * we're actually using for this boot.
259          */
260         puts("Reset Configuration Word (RCW):");
261         for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) {
262                 u32 rcw = in_be32(&gur->rcwsr[i]);
263
264                 if ((i % 4) == 0)
265                         printf("\n       %08x:", i * 4);
266                 printf(" %08x", rcw);
267         }
268         puts("\n");
269
270         return 0;
271 }
272 #endif
273
274 #ifdef CONFIG_FSL_ESDHC
275 int cpu_mmc_init(bd_t *bis)
276 {
277         return fsl_esdhc_mmc_init(bis);
278 }
279 #endif
280
281 int cpu_eth_init(bd_t *bis)
282 {
283 #ifdef CONFIG_TSEC_ENET
284         tsec_standard_init(bis);
285 #endif
286
287         return 0;
288 }
289
290 int arch_cpu_init(void)
291 {
292         void *epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET);
293
294         /*
295          * After wakeup from deep sleep, Clear EPU registers
296          * as early as possible to prevent from possible issue.
297          * It's also safe to clear at normal boot.
298          */
299         fsl_epu_clean(epu_base);
300
301         return 0;
302 }
303
304 #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
305 /* Set the address at which the secondary core starts from.*/
306 void smp_set_core_boot_addr(unsigned long addr, int corenr)
307 {
308         struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
309
310         out_be32(&gur->scratchrw[0], addr);
311 }
312
313 /* Release the secondary core from holdoff state and kick it */
314 void smp_kick_all_cpus(void)
315 {
316         struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
317
318         out_be32(&gur->brrl, 0x2);
319 }
320 #endif