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