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