/* * Board initialization for EP93xx * * Copyright (C) 2013 * Sergey Kostanbaev fairwaves.ru> * * Copyright (C) 2009 * Matthias Kaehlcke kaehlcke.net> * * (C) Copyright 2002 2003 * Network Audio Technologies, Inc. * Adam Bezanson netaudiotech.com> * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; /* * usb_div: 4, nbyp2: 1, pll2_en: 1 * pll2_x1: 368640000.000000, pll2_x2ip: 15360000.000000, * pll2_x2: 384000000.000000, pll2_out: 192000000.000000 */ #define CLKSET2_VAL (23 << SYSCON_CLKSET_PLL_X2IPD_SHIFT | \ 24 << SYSCON_CLKSET_PLL_X2FBD2_SHIFT | \ 24 << SYSCON_CLKSET_PLL_X1FBD1_SHIFT | \ 1 << SYSCON_CLKSET_PLL_PS_SHIFT | \ SYSCON_CLKSET2_PLL2_EN | \ SYSCON_CLKSET2_NBYP2 | \ 3 << SYSCON_CLKSET2_USB_DIV_SHIFT) #define SMC_BCR6_VALUE (2 << SMC_BCR_IDCY_SHIFT | 5 << SMC_BCR_WST1_SHIFT | \ SMC_BCR_BLE | 2 << SMC_BCR_WST2_SHIFT | \ 1 << SMC_BCR_MW_SHIFT) /* delay execution before timers are initialized */ static inline void early_udelay(uint32_t usecs) { /* loop takes 4 cycles at 5.0ns (fastest case, running at 200MHz) */ register uint32_t loops = (usecs * 1000) / 20; __asm__ volatile ("1:\n" "subs %0, %1, #1\n" "bne 1b" : "=r" (loops) : "0" (loops)); } #ifndef CONFIG_EP93XX_NO_FLASH_CFG static void flash_cfg(void) { struct smc_regs *smc = (struct smc_regs *)SMC_BASE; writel(SMC_BCR6_VALUE, &smc->bcr6); } #else #define flash_cfg() #endif int board_init(void) { /* * Setup PLL2, PPL1 has been set during lowlevel init */ struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; writel(CLKSET2_VAL, &syscon->clkset2); /* * the user's guide recommends to wait at least 1 ms for PLL2 to * stabilize */ early_udelay(1000); /* Go to Async mode */ __asm__ volatile ("mrc p15, 0, r0, c1, c0, 0"); __asm__ volatile ("orr r0, r0, #0xc0000000"); __asm__ volatile ("mcr p15, 0, r0, c1, c0, 0"); icache_enable(); #ifdef USE_920T_MMU dcache_enable(); #endif /* Machine number, as defined in linux/arch/arm/tools/mach-types */ gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* adress of boot parameters */ gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; /* We have a console */ gd->have_console = 1; enable_interrupts(); flash_cfg(); green_led_on(); red_led_off(); return 0; } int board_early_init_f(void) { /* * set UARTBAUD bit to drive UARTs with 14.7456MHz instead of * 14.7456/2 MHz */ struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; writel(SYSCON_PWRCNT_UART_BAUD, &syscon->pwrcnt); return 0; } int board_eth_init(bd_t *bd) { return ep93xx_eth_initialize(0, MAC_BASE); } static void dram_fill_bank_addr(unsigned dram_addr_mask, unsigned dram_bank_cnt, unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS]) { if (dram_bank_cnt == 1) { dram_bank_base[0] = PHYS_SDRAM_1; } else { /* Table lookup for holes in address space. Maximum memory * for the single SDCS may be up to 256Mb. We start scanning * banks from 1Mb, so it could be up to 128 banks theoretically. * We need at maximum 7 bits for the loockup, 8 slots is * enough for the worst case. */ unsigned tbl[8]; unsigned i = dram_bank_cnt / 2; unsigned j = 0x00100000; /* 1 Mb */ unsigned *ptbl = tbl; do { while (!(dram_addr_mask & j)) { j <<= 1; } *ptbl++ = j; j <<= 1; i >>= 1; } while (i != 0); for (i = dram_bank_cnt, j = 0; (i != 0) && (j < CONFIG_NR_DRAM_BANKS); --i, ++j) { unsigned addr = PHYS_SDRAM_1; unsigned k; unsigned bit; for (k = 0, bit = 1; k < 8; k++, bit <<= 1) { if (bit & j) addr |= tbl[k]; } dram_bank_base[j] = addr; } } } /* called in board_init_f (before relocation) */ static unsigned dram_init_banksize_int(int print) { /* * Collect information of banks that has been filled during lowlevel * initialization */ unsigned i; unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS]; unsigned dram_total = 0; unsigned dram_bank_size = *(unsigned *) (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_SIZE); unsigned dram_addr_mask = *(unsigned *) (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_MASK); unsigned dram_bank_cnt = *(unsigned *) (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_COUNT); dram_fill_bank_addr(dram_addr_mask, dram_bank_cnt, dram_bank_base); for (i = 0; i < dram_bank_cnt; i++) { gd->bd->bi_dram[i].start = dram_bank_base[i]; gd->bd->bi_dram[i].size = dram_bank_size; dram_total += dram_bank_size; } for (; i < CONFIG_NR_DRAM_BANKS; i++) { gd->bd->bi_dram[i].start = 0; gd->bd->bi_dram[i].size = 0; } if (print) { printf("DRAM mask: %08x\n", dram_addr_mask); printf("DRAM total %u banks:\n", dram_bank_cnt); printf("bank base-address size\n"); if (dram_bank_cnt > CONFIG_NR_DRAM_BANKS) { printf("WARNING! UBoot was configured for %u banks,\n" "but %u has been found. " "Supressing extra memory banks\n", CONFIG_NR_DRAM_BANKS, dram_bank_cnt); dram_bank_cnt = CONFIG_NR_DRAM_BANKS; } for (i = 0; i < dram_bank_cnt; i++) { printf(" %u %08x %08x\n", i, dram_bank_base[i], dram_bank_size); } printf(" ------------------------------------------\n" "Total %9d\n\n", dram_total); } return dram_total; } void dram_init_banksize(void) { dram_init_banksize_int(0); } /* called in board_init_f (before relocation) */ int dram_init(void) { struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; unsigned sec_id = readl(SECURITY_EXTENSIONID); unsigned chip_id = readl(&syscon->chipid); printf("CPU: Cirrus Logic "); switch (sec_id & 0x000001FE) { case 0x00000008: printf("EP9301"); break; case 0x00000004: printf("EP9307"); break; case 0x00000002: printf("EP931x"); break; case 0x00000000: printf("EP9315"); break; default: printf(""); break; } printf(" - Rev. "); switch (chip_id & 0xF0000000) { case 0x00000000: printf("A"); break; case 0x10000000: printf("B"); break; case 0x20000000: printf("C"); break; case 0x30000000: printf("D0"); break; case 0x40000000: printf("D1"); break; case 0x50000000: printf("E0"); break; case 0x60000000: printf("E1"); break; case 0x70000000: printf("E2"); break; default: printf("?"); break; } printf(" (SecExtID=%.8x/ChipID=%.8x)\n", sec_id, chip_id); gd->ram_size = dram_init_banksize_int(1); return 0; } #ifdef CONFIG_EP93XX_SPI #include /* * EGIO0-EGIPO7 -> port A * EGIO8-EGIP15 -> port B */ static void ep93xx_set_epgio(unsigned num) { struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE; if (num < 8) writel(readl(®s->padr) | (1<padr); else writel(readl(®s->pbdr) | (1<<(num-8)), ®s->pbdr); } static void ep93xx_clear_epgio(unsigned num) { struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE; if (num < 8) writel(readl(®s->padr) & (~(1<padr); else writel(readl(®s->pbdr) & (~(1<<(num-8))), ®s->pbdr); } static void ep93xx_dir_epgio_out(unsigned num) { struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE; if (num < 8) writel(readl(®s->paddr) | (1<paddr); else writel(readl(®s->pbddr) | (1<<(num-8)), ®s->pbddr); } int spi_cs_is_valid(unsigned int bus, unsigned int cs) { if (bus == 0 && cs < 16) return 1; return 0; } void spi_cs_activate(struct spi_slave *slave) { ep93xx_clear_epgio(slave->cs); } void spi_cs_deactivate(struct spi_slave *slave) { ep93xx_set_epgio(slave->cs); } #ifdef CONFIG_MMC_SPI #include #ifndef CONFIG_MMC_SPI_CS_EPGIO # define CONFIG_MMC_SPI_CS_EPGIO 4 #endif #ifndef CONFIG_MMC_SPI_SPEED # define CONFIG_MMC_SPI_SPEED 25000000 #endif #ifndef CONFIG_MMC_SPI_MODE # define CONFIG_MMC_SPI_MODE SPI_MODE_0 #endif int board_mmc_init(bd_t *bis) { struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE; ep93xx_set_epgio(CONFIG_MMC_SPI_CS_EPGIO); ep93xx_dir_epgio_out(CONFIG_MMC_SPI_CS_EPGIO); #ifdef CONFIG_MMC_SPI_POWER_EGPIO ep93xx_dir_epgio_out(CONFIG_MMC_SPI_POWER_EGPIO); ep93xx_set_epgio(CONFIG_MMC_SPI_POWER_EGPIO); #elif defined(CONFIG_MMC_SPI_NPOWER_EGPIO) ep93xx_dir_epgio_out(CONFIG_MMC_SPI_NPOWER_EGPIO); ep93xx_clear_epgio(CONFIG_MMC_SPI_NPOWER_EGPIO); #endif struct mmc *mmc = mmc_spi_init(0, CONFIG_MMC_SPI_CS_EPGIO, CONFIG_MMC_SPI_SPEED, CONFIG_MMC_SPI_MODE); if (!mmc) { printf("Failed to create MMC Device\n"); return 1; } mmc_init(mmc); return 0; } #endif /* CONFIG_MMC_SPI */ #endif /* CONFIG_EP93XX_SPI */