xref: /openbmc/u-boot/board/cirrus/edb93xx/edb93xx.c (revision a22bbfda)
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/mach-types.h>
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 
220 int dram_init_banksize(void)
221 {
222 	dram_init_banksize_int(0);
223 
224 	return 0;
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 }
288