]>
Commit | Line | Data |
---|---|---|
7237d22b SK |
1 | /* |
2 | * Board initialization for EP93xx | |
3 | * | |
4 | * Copyright (C) 2013 | |
5 | * Sergey Kostanbaev <sergey.kostanbaev <at> fairwaves.ru> | |
6 | * | |
7 | * Copyright (C) 2009 | |
8 | * Matthias Kaehlcke <matthias <at> kaehlcke.net> | |
9 | * | |
10 | * (C) Copyright 2002 2003 | |
11 | * Network Audio Technologies, Inc. <www.netaudiotech.com> | |
12 | * Adam Bezanson <bezanson <at> netaudiotech.com> | |
13 | * | |
14 | * SPDX-License-Identifier: GPL-2.0+ | |
15 | */ | |
16 | ||
17 | #include <config.h> | |
18 | #include <common.h> | |
19 | #include <netdev.h> | |
20 | #include <asm/io.h> | |
c62db35d | 21 | #include <asm/mach-types.h> |
7237d22b SK |
22 | #include <asm/arch/ep93xx.h> |
23 | ||
24 | DECLARE_GLOBAL_DATA_PTR; | |
25 | ||
26 | /* | |
27 | * usb_div: 4, nbyp2: 1, pll2_en: 1 | |
28 | * pll2_x1: 368640000.000000, pll2_x2ip: 15360000.000000, | |
29 | * pll2_x2: 384000000.000000, pll2_out: 192000000.000000 | |
30 | */ | |
31 | #define CLKSET2_VAL (23 << SYSCON_CLKSET_PLL_X2IPD_SHIFT | \ | |
32 | 24 << SYSCON_CLKSET_PLL_X2FBD2_SHIFT | \ | |
33 | 24 << SYSCON_CLKSET_PLL_X1FBD1_SHIFT | \ | |
34 | 1 << SYSCON_CLKSET_PLL_PS_SHIFT | \ | |
35 | SYSCON_CLKSET2_PLL2_EN | \ | |
36 | SYSCON_CLKSET2_NBYP2 | \ | |
37 | 3 << SYSCON_CLKSET2_USB_DIV_SHIFT) | |
38 | ||
39 | #define SMC_BCR6_VALUE (2 << SMC_BCR_IDCY_SHIFT | 5 << SMC_BCR_WST1_SHIFT | \ | |
40 | SMC_BCR_BLE | 2 << SMC_BCR_WST2_SHIFT | \ | |
41 | 1 << SMC_BCR_MW_SHIFT) | |
42 | ||
43 | /* delay execution before timers are initialized */ | |
44 | static inline void early_udelay(uint32_t usecs) | |
45 | { | |
46 | /* loop takes 4 cycles at 5.0ns (fastest case, running at 200MHz) */ | |
47 | register uint32_t loops = (usecs * 1000) / 20; | |
48 | ||
49 | __asm__ volatile ("1:\n" | |
50 | "subs %0, %1, #1\n" | |
51 | "bne 1b" : "=r" (loops) : "0" (loops)); | |
52 | } | |
53 | ||
54 | #ifndef CONFIG_EP93XX_NO_FLASH_CFG | |
55 | static void flash_cfg(void) | |
56 | { | |
57 | struct smc_regs *smc = (struct smc_regs *)SMC_BASE; | |
58 | ||
59 | writel(SMC_BCR6_VALUE, &smc->bcr6); | |
60 | } | |
61 | #else | |
62 | #define flash_cfg() | |
63 | #endif | |
64 | ||
65 | int board_init(void) | |
66 | { | |
67 | /* | |
68 | * Setup PLL2, PPL1 has been set during lowlevel init | |
69 | */ | |
70 | struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; | |
71 | writel(CLKSET2_VAL, &syscon->clkset2); | |
72 | ||
73 | /* | |
74 | * the user's guide recommends to wait at least 1 ms for PLL2 to | |
75 | * stabilize | |
76 | */ | |
77 | early_udelay(1000); | |
78 | ||
79 | /* Go to Async mode */ | |
80 | __asm__ volatile ("mrc p15, 0, r0, c1, c0, 0"); | |
81 | __asm__ volatile ("orr r0, r0, #0xc0000000"); | |
82 | __asm__ volatile ("mcr p15, 0, r0, c1, c0, 0"); | |
83 | ||
84 | icache_enable(); | |
85 | ||
86 | #ifdef USE_920T_MMU | |
87 | dcache_enable(); | |
88 | #endif | |
89 | ||
90 | /* Machine number, as defined in linux/arch/arm/tools/mach-types */ | |
91 | gd->bd->bi_arch_number = CONFIG_MACH_TYPE; | |
92 | ||
93 | /* adress of boot parameters */ | |
94 | gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; | |
95 | ||
96 | /* We have a console */ | |
97 | gd->have_console = 1; | |
98 | ||
99 | enable_interrupts(); | |
100 | ||
101 | flash_cfg(); | |
102 | ||
103 | green_led_on(); | |
104 | red_led_off(); | |
105 | ||
106 | return 0; | |
107 | } | |
108 | ||
109 | int board_early_init_f(void) | |
110 | { | |
111 | /* | |
112 | * set UARTBAUD bit to drive UARTs with 14.7456MHz instead of | |
113 | * 14.7456/2 MHz | |
114 | */ | |
115 | struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; | |
116 | writel(SYSCON_PWRCNT_UART_BAUD, &syscon->pwrcnt); | |
117 | return 0; | |
118 | } | |
119 | ||
120 | int board_eth_init(bd_t *bd) | |
121 | { | |
122 | return ep93xx_eth_initialize(0, MAC_BASE); | |
123 | } | |
124 | ||
125 | static void dram_fill_bank_addr(unsigned dram_addr_mask, unsigned dram_bank_cnt, | |
126 | unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS]) | |
127 | { | |
128 | if (dram_bank_cnt == 1) { | |
129 | dram_bank_base[0] = PHYS_SDRAM_1; | |
130 | } else { | |
131 | /* Table lookup for holes in address space. Maximum memory | |
132 | * for the single SDCS may be up to 256Mb. We start scanning | |
133 | * banks from 1Mb, so it could be up to 128 banks theoretically. | |
134 | * We need at maximum 7 bits for the loockup, 8 slots is | |
135 | * enough for the worst case. | |
136 | */ | |
137 | unsigned tbl[8]; | |
138 | unsigned i = dram_bank_cnt / 2; | |
139 | unsigned j = 0x00100000; /* 1 Mb */ | |
140 | unsigned *ptbl = tbl; | |
141 | do { | |
142 | while (!(dram_addr_mask & j)) { | |
143 | j <<= 1; | |
144 | } | |
145 | *ptbl++ = j; | |
146 | j <<= 1; | |
147 | i >>= 1; | |
148 | } while (i != 0); | |
149 | ||
150 | for (i = dram_bank_cnt, j = 0; | |
151 | (i != 0) && (j < CONFIG_NR_DRAM_BANKS); --i, ++j) { | |
152 | unsigned addr = PHYS_SDRAM_1; | |
153 | unsigned k; | |
154 | unsigned bit; | |
155 | ||
156 | for (k = 0, bit = 1; k < 8; k++, bit <<= 1) { | |
157 | if (bit & j) | |
158 | addr |= tbl[k]; | |
159 | } | |
160 | ||
161 | dram_bank_base[j] = addr; | |
162 | } | |
163 | } | |
164 | } | |
165 | ||
166 | /* called in board_init_f (before relocation) */ | |
167 | static unsigned dram_init_banksize_int(int print) | |
168 | { | |
169 | /* | |
170 | * Collect information of banks that has been filled during lowlevel | |
171 | * initialization | |
172 | */ | |
173 | unsigned i; | |
174 | unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS]; | |
175 | unsigned dram_total = 0; | |
176 | unsigned dram_bank_size = *(unsigned *) | |
177 | (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_SIZE); | |
178 | unsigned dram_addr_mask = *(unsigned *) | |
179 | (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_MASK); | |
180 | unsigned dram_bank_cnt = *(unsigned *) | |
181 | (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_COUNT); | |
182 | ||
183 | dram_fill_bank_addr(dram_addr_mask, dram_bank_cnt, dram_bank_base); | |
184 | ||
185 | for (i = 0; i < dram_bank_cnt; i++) { | |
186 | gd->bd->bi_dram[i].start = dram_bank_base[i]; | |
187 | gd->bd->bi_dram[i].size = dram_bank_size; | |
188 | dram_total += dram_bank_size; | |
189 | } | |
190 | for (; i < CONFIG_NR_DRAM_BANKS; i++) { | |
191 | gd->bd->bi_dram[i].start = 0; | |
192 | gd->bd->bi_dram[i].size = 0; | |
193 | } | |
194 | ||
195 | if (print) { | |
196 | printf("DRAM mask: %08x\n", dram_addr_mask); | |
197 | printf("DRAM total %u banks:\n", dram_bank_cnt); | |
198 | printf("bank base-address size\n"); | |
199 | ||
200 | if (dram_bank_cnt > CONFIG_NR_DRAM_BANKS) { | |
201 | printf("WARNING! UBoot was configured for %u banks,\n" | |
202 | "but %u has been found. " | |
203 | "Supressing extra memory banks\n", | |
204 | CONFIG_NR_DRAM_BANKS, dram_bank_cnt); | |
205 | dram_bank_cnt = CONFIG_NR_DRAM_BANKS; | |
206 | } | |
207 | ||
208 | for (i = 0; i < dram_bank_cnt; i++) { | |
209 | printf(" %u %08x %08x\n", | |
210 | i, dram_bank_base[i], dram_bank_size); | |
211 | } | |
212 | printf(" ------------------------------------------\n" | |
213 | "Total %9d\n\n", | |
214 | dram_total); | |
215 | } | |
216 | ||
217 | return dram_total; | |
218 | } | |
219 | ||
76b00aca | 220 | int dram_init_banksize(void) |
7237d22b SK |
221 | { |
222 | dram_init_banksize_int(0); | |
76b00aca SG |
223 | |
224 | return 0; | |
7237d22b SK |
225 | } |
226 | ||
227 | /* called in board_init_f (before relocation) */ | |
228 | int dram_init(void) | |
229 | { | |
230 | struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; | |
231 | unsigned sec_id = readl(SECURITY_EXTENSIONID); | |
232 | unsigned chip_id = readl(&syscon->chipid); | |
233 | ||
234 | printf("CPU: Cirrus Logic "); | |
235 | switch (sec_id & 0x000001FE) { | |
236 | case 0x00000008: | |
237 | printf("EP9301"); | |
238 | break; | |
239 | case 0x00000004: | |
240 | printf("EP9307"); | |
241 | break; | |
242 | case 0x00000002: | |
243 | printf("EP931x"); | |
244 | break; | |
245 | case 0x00000000: | |
246 | printf("EP9315"); | |
247 | break; | |
248 | default: | |
249 | printf("<unknown>"); | |
250 | break; | |
251 | } | |
252 | ||
253 | printf(" - Rev. "); | |
254 | switch (chip_id & 0xF0000000) { | |
255 | case 0x00000000: | |
256 | printf("A"); | |
257 | break; | |
258 | case 0x10000000: | |
259 | printf("B"); | |
260 | break; | |
261 | case 0x20000000: | |
262 | printf("C"); | |
263 | break; | |
264 | case 0x30000000: | |
265 | printf("D0"); | |
266 | break; | |
267 | case 0x40000000: | |
268 | printf("D1"); | |
269 | break; | |
270 | case 0x50000000: | |
271 | printf("E0"); | |
272 | break; | |
273 | case 0x60000000: | |
274 | printf("E1"); | |
275 | break; | |
276 | case 0x70000000: | |
277 | printf("E2"); | |
278 | break; | |
279 | default: | |
280 | printf("?"); | |
281 | break; | |
282 | } | |
283 | printf(" (SecExtID=%.8x/ChipID=%.8x)\n", sec_id, chip_id); | |
284 | ||
285 | gd->ram_size = dram_init_banksize_int(1); | |
286 | return 0; | |
287 | } |