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