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