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