#include #include #include #include #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_SPL_BUILD #ifdef DEBUG #define DILIGENCE (1048576/4) static int test_memory(u32 memory) { volatile u32 *read; volatile u32 *write; const u32 INIT_PATTERN = 0xAA55AA55; const u32 INC_PATTERN = 0x01030507; u32 pattern; int check; int i; check = 0; read = write = (volatile u32 *) memory; pattern = INIT_PATTERN; for (i = 0; i < DILIGENCE; i++) { *write++ = pattern; pattern += INC_PATTERN; } puts("testing\n"); pattern = INIT_PATTERN; for (i = 0; i < DILIGENCE; i++) { check += (pattern == *read++) ? 1 : 0; pattern += INC_PATTERN; } return (check == DILIGENCE) ? 0 : -1; } #endif void uart_init(void) { /* Reset UART1 */ reset_block(SYS_CTRL_RST_UART1, 1); udelay(100); reset_block(SYS_CTRL_RST_UART1, 0); udelay(100); /* Setup pin mux'ing for UART1 */ pinmux_set(PINMUX_BANK_MFA, 30, PINMUX_UARTA_SIN); pinmux_set(PINMUX_BANK_MFA, 31, PINMUX_UARTA_SOUT); } extern void init_ddr(int mhz); void board_inithw(void) { int plla_freq; #ifdef DEBUG int i; #endif /* DEBUG */ timer_init(); uart_init(); preloader_console_init(); plla_freq = plla_set_config(CONFIG_PLLA_FREQ_MHZ); init_ddr(plla_freq); #ifdef DEBUG if(test_memory(CONFIG_SYS_SDRAM_BASE)) { puts("memory test failed\n"); } else { puts("memory test done\n"); } #endif /* DEBUG */ #ifdef CONFIG_SPL_BSS_DRAM_START extern char __bss_dram_start[]; extern char __bss_dram_end[]; memset(&__bss_dram_start, 0, __bss_dram_end - __bss_dram_start); #endif } void board_init_f(ulong dummy) { /* Set the stack pointer. */ asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); /* Set global data pointer. */ gd = &gdata; board_inithw(); board_init_r(NULL, 0); } u32 spl_boot_device(void) { return CONFIG_SPL_BOOT_DEVICE; } #ifdef CONFIG_SPL_BLOCK_SUPPORT void spl_block_device_init(void) { ide_init(); } #endif #ifdef CONFIG_SPL_OS_BOOT int spl_start_uboot(void) { /* break into full u-boot on 'c' */ return (serial_tstc() && serial_getc() == 'c'); } #endif void spl_display_print(void) { /* print a hint, so that we will not use the wrong SPL by mistake */ puts(" Boot device: " BOOT_DEVICE_TYPE "\n" ); } void lowlevel_init(void) { } #ifdef USE_DL_PREFIX /* quick and dirty memory allocation */ static ulong next_mem = CONFIG_SPL_MALLOC_START; void *memalign(size_t alignment, size_t bytes) { ulong mem = ALIGN(next_mem, alignment); next_mem = mem + bytes; if (next_mem > CONFIG_SYS_SDRAM_BASE + CONFIG_MIN_SDRAM_SIZE) { printf("spl: out of memory\n"); hang(); } return (void *)mem; } void free(void* mem) { } #endif #endif /* CONFIG_SPL_BUILD */ int board_early_init_f(void) { return 0; } #define STATIC_CTL_BANK0 (STATIC_CONTROL_BASE + 4) #define STATIC_READ_CYCLE_SHIFT 0 #define STATIC_DELAYED_OE (1 << 7) #define STATIC_WRITE_CYCLE_SHIFT 8 #define STATIC_WRITE_PULSE_SHIFT 16 #define STATIC_WRITE_BURST_EN (1 << 23) #define STATIC_TURN_AROUND_SHIFT 24 #define STATIC_BUFFER_PRESENT (1 << 28) #define STATIC_READ_BURST_EN (1 << 29) #define STATIC_BUS_WIDTH8 (0 << 30) #define STATIC_BUS_WIDTH16 (1 << 30) #define STATIC_BUS_WIDTH32 (2 << 30) void nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd->priv; unsigned long nandaddr = (unsigned long) this->IO_ADDR_W; if (ctrl & NAND_CTRL_CHANGE) { nandaddr &= ~(BIT(NAND_ALE_ADDR_PIN) | BIT(NAND_CLE_ADDR_PIN)); if (ctrl & NAND_CLE) nandaddr |= BIT(NAND_CLE_ADDR_PIN); else if (ctrl & NAND_ALE) nandaddr |= BIT(NAND_ALE_ADDR_PIN); this->IO_ADDR_W = (void __iomem *) nandaddr; } if (cmd != NAND_CMD_NONE) writeb(cmd, (void __iomem *) nandaddr); } #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_BOOT_FROM_NAND) int nand_dev_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; udelay(chip->chip_delay); return 1; } void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { int i; struct nand_chip *chip = mtd->priv; for (i = 0; i < len; i++) buf[i] = readb(chip->IO_ADDR_R); } void nand_dev_reset(struct nand_chip *chip) { writeb(NAND_CMD_RESET, chip->IO_ADDR_W + BIT(NAND_CLE_ADDR_PIN)); udelay(chip->chip_delay); writeb(NAND_CMD_STATUS, chip->IO_ADDR_W + BIT(NAND_CLE_ADDR_PIN)); while (!(readb(chip->IO_ADDR_R) & NAND_STATUS_READY)) { ; } } #else #define nand_dev_reset(chip) /* framework will reset the chip anyway */ #define nand_read_buf NULL /* framework will provide a default one */ #define nand_dev_ready NULL /* dev_ready is optional */ #endif int board_nand_init(struct nand_chip *chip) { /* Block reset Static core */ reset_block(SYS_CTRL_RST_STATIC, 1); reset_block(SYS_CTRL_RST_STATIC, 0); /* Enable clock to Static core */ enable_clock(SYS_CTRL_CLK_STATIC); /* enable flash support on static bus. * Enable static bus onto GPIOs, only CS0 */ pinmux_set(PINMUX_BANK_MFA, 12, PINMUX_STATIC_DATA0); pinmux_set(PINMUX_BANK_MFA, 13, PINMUX_STATIC_DATA1); pinmux_set(PINMUX_BANK_MFA, 14, PINMUX_STATIC_DATA2); pinmux_set(PINMUX_BANK_MFA, 15, PINMUX_STATIC_DATA3); pinmux_set(PINMUX_BANK_MFA, 16, PINMUX_STATIC_DATA4); pinmux_set(PINMUX_BANK_MFA, 17, PINMUX_STATIC_DATA5); pinmux_set(PINMUX_BANK_MFA, 18, PINMUX_STATIC_DATA6); pinmux_set(PINMUX_BANK_MFA, 19, PINMUX_STATIC_DATA7); pinmux_set(PINMUX_BANK_MFA, 20, PINMUX_STATIC_NWE); pinmux_set(PINMUX_BANK_MFA, 21, PINMUX_STATIC_NOE); pinmux_set(PINMUX_BANK_MFA, 22, PINMUX_STATIC_NCS); pinmux_set(PINMUX_BANK_MFA, 23, PINMUX_STATIC_ADDR18); pinmux_set(PINMUX_BANK_MFA, 24, PINMUX_STATIC_ADDR19); /* Setup the static bus CS0 to access FLASH */ writel((0x3f << STATIC_READ_CYCLE_SHIFT) | (0x3f << STATIC_WRITE_CYCLE_SHIFT) | (0x1f << STATIC_WRITE_PULSE_SHIFT) | (0x03 << STATIC_TURN_AROUND_SHIFT) | STATIC_BUS_WIDTH16, STATIC_CTL_BANK0); chip->cmd_ctrl = nand_hwcontrol; chip->ecc.mode = NAND_ECC_SOFT; chip->chip_delay = 30; chip->dev_ready = nand_dev_ready; chip->read_buf = nand_read_buf; nand_dev_reset(chip); return 0; } int board_init(void) { gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; gd->bd->bi_arch_number = MACH_TYPE_OXNAS; /* assume uart is already initialized by SPL */ #if defined(CONFIG_START_IDE) puts("IDE: "); ide_init(); #endif return 0; } /* copied from board/evb64260/sdram_init.c */ /* * Check memory range for valid RAM. A simple memory test determines * the actually available RAM size between addresses `base' and * `base + maxsize'. Some (not all) hardware errors are detected: * - short between address lines * - short between data lines */ static long int dram_size (long int *base, long int maxsize) { volatile long int *addr, *b = base; long int cnt, val, save1, save2; #define STARTVAL (CONFIG_MIN_SDRAM_SIZE / 2) /* start test at half size */ for (cnt = STARTVAL / sizeof (long); cnt < maxsize / sizeof (long); cnt <<= 1) { addr = base + cnt; /* pointer arith! */ save1 = *addr; /* save contents of addr */ save2 = *b; /* save contents of base */ *addr = cnt; /* write cnt to addr */ *b = 0; /* put null at base */ /* check at base address */ if ((*b) != 0) { *addr = save1; /* restore *addr */ *b = save2; /* restore *b */ return (0); } val = *addr; /* read *addr */ *addr = save1; *b = save2; if (val != cnt) { /* fix boundary condition.. STARTVAL means zero */ if (cnt == STARTVAL / sizeof (long)) cnt = 0; return (cnt * sizeof (long)); } } return maxsize; } int dram_init(void) { gd->ram_size = dram_size((long int *)CONFIG_SYS_SDRAM_BASE, CONFIG_MAX_SDRAM_SIZE); return 0; } int board_eth_init(bd_t *bis) { u32 value; /* set the pin multiplexers to enable talking to Ethernent Phys */ pinmux_set(PINMUX_BANK_MFA, 3, PINMUX_MACA_MDC); pinmux_set(PINMUX_BANK_MFA, 4, PINMUX_MACA_MDIO); // Ensure the MAC block is properly reset reset_block(SYS_CTRL_RST_MAC, 1); udelay(10); reset_block(SYS_CTRL_RST_MAC, 0); // Enable the clock to the MAC block enable_clock(SYS_CTRL_CLK_MAC); value = readl(SYS_CTRL_GMAC_CTRL); /* Use simple mux for 25/125 Mhz clock switching */ value |= BIT(SYS_CTRL_GMAC_SIMPLE_MUX); /* Enable GMII_GTXCLK to follow GMII_REFCLK - required for gigabit PHY */ value |= BIT(SYS_CTRL_GMAC_CKEN_GTX); /* set auto tx speed */ value |= BIT(SYS_CTRL_GMAC_AUTOSPEED); writel(value, SYS_CTRL_GMAC_CTRL); return designware_initialize(MAC_BASE, PHY_INTERFACE_MODE_RGMII); }