51ff16215ef41fd987fec10817cd226f63ddbf4a
[oweals/u-boot.git] / board / cirrus / edb93xx / edb93xx.c
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
219 void dram_init_banksize(void)
220 {
221         dram_init_banksize_int(0);
222 }
223
224 /* called in board_init_f (before relocation) */
225 int dram_init(void)
226 {
227         struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
228         unsigned sec_id = readl(SECURITY_EXTENSIONID);
229         unsigned chip_id = readl(&syscon->chipid);
230
231         printf("CPU: Cirrus Logic ");
232         switch (sec_id & 0x000001FE) {
233         case 0x00000008:
234                 printf("EP9301");
235                 break;
236         case 0x00000004:
237                 printf("EP9307");
238                 break;
239         case 0x00000002:
240                 printf("EP931x");
241                 break;
242         case 0x00000000:
243                 printf("EP9315");
244                 break;
245         default:
246                 printf("<unknown>");
247                 break;
248         }
249
250         printf(" - Rev. ");
251         switch (chip_id & 0xF0000000) {
252         case 0x00000000:
253                 printf("A");
254                 break;
255         case 0x10000000:
256                 printf("B");
257                 break;
258         case 0x20000000:
259                 printf("C");
260                 break;
261         case 0x30000000:
262                 printf("D0");
263                 break;
264         case 0x40000000:
265                 printf("D1");
266                 break;
267         case 0x50000000:
268                 printf("E0");
269                 break;
270         case 0x60000000:
271                 printf("E1");
272                 break;
273         case 0x70000000:
274                 printf("E2");
275                 break;
276         default:
277                 printf("?");
278                 break;
279         }
280         printf(" (SecExtID=%.8x/ChipID=%.8x)\n", sec_id, chip_id);
281
282         gd->ram_size = dram_init_banksize_int(1);
283         return 0;
284 }