1 // SPDX-License-Identifier: GPL-2.0+
3 * Board initialization for EP93xx
6 * Sergey Kostanbaev <sergey.kostanbaev <at> fairwaves.ru>
9 * Matthias Kaehlcke <matthias <at> kaehlcke.net>
11 * (C) Copyright 2002 2003
12 * Network Audio Technologies, Inc. <www.netaudiotech.com>
13 * Adam Bezanson <bezanson <at> netaudiotech.com>
22 #include <status_led.h>
24 #include <asm/mach-types.h>
25 #include <asm/arch/ep93xx.h>
27 DECLARE_GLOBAL_DATA_PTR;
30 * usb_div: 4, nbyp2: 1, pll2_en: 1
31 * pll2_x1: 368640000.000000, pll2_x2ip: 15360000.000000,
32 * pll2_x2: 384000000.000000, pll2_out: 192000000.000000
34 #define CLKSET2_VAL (23 << SYSCON_CLKSET_PLL_X2IPD_SHIFT | \
35 24 << SYSCON_CLKSET_PLL_X2FBD2_SHIFT | \
36 24 << SYSCON_CLKSET_PLL_X1FBD1_SHIFT | \
37 1 << SYSCON_CLKSET_PLL_PS_SHIFT | \
38 SYSCON_CLKSET2_PLL2_EN | \
39 SYSCON_CLKSET2_NBYP2 | \
40 3 << SYSCON_CLKSET2_USB_DIV_SHIFT)
42 #define SMC_BCR6_VALUE (2 << SMC_BCR_IDCY_SHIFT | 5 << SMC_BCR_WST1_SHIFT | \
43 SMC_BCR_BLE | 2 << SMC_BCR_WST2_SHIFT | \
44 1 << SMC_BCR_MW_SHIFT)
46 /* delay execution before timers are initialized */
47 static inline void early_udelay(uint32_t usecs)
49 /* loop takes 4 cycles at 5.0ns (fastest case, running at 200MHz) */
50 register uint32_t loops = (usecs * 1000) / 20;
52 __asm__ volatile ("1:\n"
54 "bne 1b" : "=r" (loops) : "0" (loops));
57 #ifndef CONFIG_EP93XX_NO_FLASH_CFG
58 static void flash_cfg(void)
60 struct smc_regs *smc = (struct smc_regs *)SMC_BASE;
62 writel(SMC_BCR6_VALUE, &smc->bcr6);
71 * Setup PLL2, PPL1 has been set during lowlevel init
73 struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
74 writel(CLKSET2_VAL, &syscon->clkset2);
77 * the user's guide recommends to wait at least 1 ms for PLL2 to
82 /* Go to Async mode */
83 __asm__ volatile ("mrc p15, 0, r0, c1, c0, 0");
84 __asm__ volatile ("orr r0, r0, #0xc0000000");
85 __asm__ volatile ("mcr p15, 0, r0, c1, c0, 0");
93 /* Machine number, as defined in linux/arch/arm/tools/mach-types */
94 gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
96 /* adress of boot parameters */
97 gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
99 /* We have a console */
100 gd->have_console = 1;
112 int board_early_init_f(void)
115 * set UARTBAUD bit to drive UARTs with 14.7456MHz instead of
118 struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
119 writel(SYSCON_PWRCNT_UART_BAUD, &syscon->pwrcnt);
123 int board_eth_init(bd_t *bd)
125 return ep93xx_eth_initialize(0, MAC_BASE);
128 static void dram_fill_bank_addr(unsigned dram_addr_mask, unsigned dram_bank_cnt,
129 unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS])
131 if (dram_bank_cnt == 1) {
132 dram_bank_base[0] = PHYS_SDRAM_1;
134 /* Table lookup for holes in address space. Maximum memory
135 * for the single SDCS may be up to 256Mb. We start scanning
136 * banks from 1Mb, so it could be up to 128 banks theoretically.
137 * We need at maximum 7 bits for the loockup, 8 slots is
138 * enough for the worst case.
141 unsigned i = dram_bank_cnt / 2;
142 unsigned j = 0x00100000; /* 1 Mb */
143 unsigned *ptbl = tbl;
145 while (!(dram_addr_mask & j)) {
153 for (i = dram_bank_cnt, j = 0;
154 (i != 0) && (j < CONFIG_NR_DRAM_BANKS); --i, ++j) {
155 unsigned addr = PHYS_SDRAM_1;
159 for (k = 0, bit = 1; k < 8; k++, bit <<= 1) {
164 dram_bank_base[j] = addr;
169 /* called in board_init_f (before relocation) */
170 static unsigned dram_init_banksize_int(int print)
173 * Collect information of banks that has been filled during lowlevel
177 unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS];
178 unsigned dram_total = 0;
179 unsigned dram_bank_size = *(unsigned *)
180 (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_SIZE);
181 unsigned dram_addr_mask = *(unsigned *)
182 (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_MASK);
183 unsigned dram_bank_cnt = *(unsigned *)
184 (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_COUNT);
186 dram_fill_bank_addr(dram_addr_mask, dram_bank_cnt, dram_bank_base);
188 for (i = 0; i < dram_bank_cnt; i++) {
189 gd->bd->bi_dram[i].start = dram_bank_base[i];
190 gd->bd->bi_dram[i].size = dram_bank_size;
191 dram_total += dram_bank_size;
193 for (; i < CONFIG_NR_DRAM_BANKS; i++) {
194 gd->bd->bi_dram[i].start = 0;
195 gd->bd->bi_dram[i].size = 0;
199 printf("DRAM mask: %08x\n", dram_addr_mask);
200 printf("DRAM total %u banks:\n", dram_bank_cnt);
201 printf("bank base-address size\n");
203 if (dram_bank_cnt > CONFIG_NR_DRAM_BANKS) {
204 printf("WARNING! UBoot was configured for %u banks,\n"
205 "but %u has been found. "
206 "Supressing extra memory banks\n",
207 CONFIG_NR_DRAM_BANKS, dram_bank_cnt);
208 dram_bank_cnt = CONFIG_NR_DRAM_BANKS;
211 for (i = 0; i < dram_bank_cnt; i++) {
212 printf(" %u %08x %08x\n",
213 i, dram_bank_base[i], dram_bank_size);
215 printf(" ------------------------------------------\n"
223 int dram_init_banksize(void)
225 dram_init_banksize_int(0);
230 /* called in board_init_f (before relocation) */
233 struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
234 unsigned sec_id = readl(SECURITY_EXTENSIONID);
235 unsigned chip_id = readl(&syscon->chipid);
237 printf("CPU: Cirrus Logic ");
238 switch (sec_id & 0x000001FE) {
257 switch (chip_id & 0xF0000000) {
286 printf(" (SecExtID=%.8x/ChipID=%.8x)\n", sec_id, chip_id);
288 gd->ram_size = dram_init_banksize_int(1);