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