From 716ca530e1c4515d8683c9d5be3d56b301758b66 Mon Sep 17 00:00:00 2001 From: James <> Date: Wed, 4 Nov 2015 11:49:21 +0000 Subject: trunk-47381 --- package/boot/uboot-oxnas/files/board/ox820/ox820.c | 374 +++++++++++++++++++++ 1 file changed, 374 insertions(+) create mode 100644 package/boot/uboot-oxnas/files/board/ox820/ox820.c (limited to 'package/boot/uboot-oxnas/files/board/ox820/ox820.c') diff --git a/package/boot/uboot-oxnas/files/board/ox820/ox820.c b/package/boot/uboot-oxnas/files/board/ox820/ox820.c new file mode 100644 index 0000000..f93cc9c --- /dev/null +++ b/package/boot/uboot-oxnas/files/board/ox820/ox820.c @@ -0,0 +1,374 @@ +#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); +} + -- cgit v1.2.3