summaryrefslogtreecommitdiffstats
path: root/qemu/roms/u-boot/board/dave
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/u-boot/board/dave')
-rw-r--r--qemu/roms/u-boot/board/dave/PPChameleonEVB/Makefile8
-rw-r--r--qemu/roms/u-boot/board/dave/PPChameleonEVB/PPChameleonEVB.c231
-rw-r--r--qemu/roms/u-boot/board/dave/PPChameleonEVB/flash.c99
-rw-r--r--qemu/roms/u-boot/board/dave/PPChameleonEVB/nand.c99
-rw-r--r--qemu/roms/u-boot/board/dave/PPChameleonEVB/u-boot.lds115
-rw-r--r--qemu/roms/u-boot/board/dave/common/flash.c691
6 files changed, 1243 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/board/dave/PPChameleonEVB/Makefile b/qemu/roms/u-boot/board/dave/PPChameleonEVB/Makefile
new file mode 100644
index 000000000..31edc4a57
--- /dev/null
+++ b/qemu/roms/u-boot/board/dave/PPChameleonEVB/Makefile
@@ -0,0 +1,8 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y = PPChameleonEVB.o flash.o nand.o
diff --git a/qemu/roms/u-boot/board/dave/PPChameleonEVB/PPChameleonEVB.c b/qemu/roms/u-boot/board/dave/PPChameleonEVB/PPChameleonEVB.c
new file mode 100644
index 000000000..c9ab50e12
--- /dev/null
+++ b/qemu/roms/u-boot/board/dave/PPChameleonEVB/PPChameleonEVB.c
@@ -0,0 +1,231 @@
+/*
+ * (C) Copyright 2003
+ * DAVE Srl
+ * http://www.dave-tech.it
+ * http://www.wawnet.biz
+ * mailto:info@wawnet.biz
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <command.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* ------------------------------------------------------------------------- */
+
+int board_early_init_f (void)
+{
+ out32(GPIO0_OR, CONFIG_SYS_NAND0_CE); /* set initial outputs */
+ out32(GPIO0_OR, CONFIG_SYS_NAND1_CE); /* set initial outputs */
+
+ /*
+ * IRQ 0-15 405GP internally generated; active high; level sensitive
+ * IRQ 16 405GP internally generated; active low; level sensitive
+ * IRQ 17-24 RESERVED
+ * IRQ 25 (EXT IRQ 0)
+ * IRQ 26 (EXT IRQ 1)
+ * IRQ 27 (EXT IRQ 2)
+ * IRQ 28 (EXT IRQ 3)
+ * IRQ 29 (EXT IRQ 4)
+ * IRQ 30 (EXT IRQ 5)
+ * IRQ 31 (EXT IRQ 6)
+ */
+ mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
+ mtdcr(UIC0ER, 0x00000000); /* disable all ints */
+ mtdcr(UIC0CR, 0x00000000); /* set all to be non-critical*/
+ mtdcr(UIC0PR, 0xFFFFFF80); /* set int polarities */
+ mtdcr(UIC0TR, 0x10000000); /* set int trigger levels */
+ mtdcr(UIC0VCR, 0x00000001); /* set vect base=0,INT0 highest priority*/
+ mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
+
+ /*
+ * EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 15 us
+ */
+#if 1 /* test-only */
+ mtebc (EBC0_CFG, 0xa8400000); /* ebc always driven */
+#else
+ mtebc (EBC0_CFG, 0x28400000); /* ebc in high-z */
+#endif
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+int misc_init_f (void)
+{
+ return 0; /* dummy implementation */
+}
+
+extern flash_info_t flash_info[]; /* info for FLASH chips */
+
+int misc_init_r (void)
+{
+ /* adjust flash start and size as well as the offset */
+ gd->bd->bi_flashstart = 0 - flash_info[0].size;
+ gd->bd->bi_flashoffset= flash_info[0].size - CONFIG_SYS_MONITOR_LEN;
+#if 0
+ volatile unsigned short *fpga_mode =
+ (unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL);
+ volatile unsigned char *duart0_mcr =
+ (unsigned char *)((ulong)DUART0_BA + 4);
+ volatile unsigned char *duart1_mcr =
+ (unsigned char *)((ulong)DUART1_BA + 4);
+
+ bd_t *bd = gd->bd;
+ char * tmp; /* Temporary char pointer */
+ unsigned char *dst;
+ ulong len = sizeof(fpgadata);
+ int status;
+ int index;
+ int i;
+ unsigned long CPC0_CR0Reg;
+
+ dst = malloc(CONFIG_SYS_FPGA_MAX_SIZE);
+ if (gunzip (dst, CONFIG_SYS_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) {
+ printf ("GUNZIP ERROR - must RESET board to recover\n");
+ do_reset (NULL, 0, 0, NULL);
+ }
+
+ status = fpga_boot(dst, len);
+ if (status != 0) {
+ printf("\nFPGA: Booting failed ");
+ switch (status) {
+ case ERROR_FPGA_PRG_INIT_LOW:
+ printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
+ break;
+ case ERROR_FPGA_PRG_INIT_HIGH:
+ printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
+ break;
+ case ERROR_FPGA_PRG_DONE:
+ printf("(Timeout: DONE not high after programming FPGA)\n ");
+ break;
+ }
+
+ /* display infos on fpgaimage */
+ index = 15;
+ for (i=0; i<4; i++) {
+ len = dst[index];
+ printf("FPGA: %s\n", &(dst[index+1]));
+ index += len+3;
+ }
+ putc ('\n');
+ /* delayed reboot */
+ for (i=20; i>0; i--) {
+ printf("Rebooting in %2d seconds \r",i);
+ for (index=0;index<1000;index++)
+ udelay(1000);
+ }
+ putc ('\n');
+ do_reset(NULL, 0, 0, NULL);
+ }
+
+ puts("FPGA: ");
+
+ /* display infos on fpgaimage */
+ index = 15;
+ for (i=0; i<4; i++) {
+ len = dst[index];
+ printf("%s ", &(dst[index+1]));
+ index += len+3;
+ }
+ putc ('\n');
+
+ free(dst);
+
+ /*
+ * Reset FPGA via FPGA_DATA pin
+ */
+ SET_FPGA(FPGA_PRG | FPGA_CLK);
+ udelay(1000); /* wait 1ms */
+ SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
+ udelay(1000); /* wait 1ms */
+#endif
+
+#if 0
+ /*
+ * Enable power on PS/2 interface
+ */
+ *fpga_mode |= CONFIG_SYS_FPGA_CTRL_PS2_RESET;
+
+ /*
+ * Enable interrupts in exar duart mcr[3]
+ */
+ *duart0_mcr = 0x08;
+ *duart1_mcr = 0x08;
+#endif
+ return (0);
+}
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ char str[64];
+ int i = getenv_f("serial#", str, sizeof(str));
+
+ puts ("Board: ");
+
+ if (i == -1) {
+ puts ("### No HW ID - assuming PPChameleonEVB");
+ } else {
+ puts(str);
+ }
+
+ putc ('\n');
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+ /* TODO: XXX XXX XXX */
+ printf ("test: 16 MB - ok\n");
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_CFB_CONSOLE
+# ifdef CONFIG_CONSOLE_EXTRA_INFO
+# include <video_fb.h>
+extern GraphicDevice smi;
+
+void video_get_info_str (int line_number, char *info)
+{
+ uint pvr = get_pvr ();
+
+ /* init video info strings for graphic console */
+ switch (line_number) {
+ case 1:
+ switch (pvr) {
+ case PVR_405EP_RB:
+ sprintf (info, " AMCC PowerPC 405EP Rev. B");
+ break;
+ default:
+ sprintf (info, " AMCC PowerPC 405EP Rev. <unknown>");
+ break;
+ }
+ return;
+ case 2:
+ sprintf (info, " DAVE Srl PPChameleonEVB - www.dave-tech.it");
+ return;
+ case 3:
+ sprintf (info, " %s", smi.modeIdent);
+ return;
+ }
+
+ /* no more info lines */
+ *info = 0;
+ return;
+}
+# endif /* CONFIG_CONSOLE_EXTRA_INFO */
+#endif /* CONFIG_CFB_CONSOLE */
diff --git a/qemu/roms/u-boot/board/dave/PPChameleonEVB/flash.c b/qemu/roms/u-boot/board/dave/PPChameleonEVB/flash.c
new file mode 100644
index 000000000..771151b80
--- /dev/null
+++ b/qemu/roms/u-boot/board/dave/PPChameleonEVB/flash.c
@@ -0,0 +1,99 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/ppc4xx.h>
+#include <asm/processor.h>
+
+/*
+ * include common flash code (for esd boards)
+ */
+#include "../common/flash.c"
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long * addr, flash_info_t * info);
+static void flash_get_offsets (ulong base, flash_info_t * info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+#ifdef __DEBUG_START_FROM_SRAM__
+ return CONFIG_SYS_DUMMY_FLASH_SIZE;
+#else
+ unsigned long size;
+ int i;
+ uint pbcr;
+ unsigned long base;
+ int size_val = 0;
+
+ debug("[%s, %d] Entering ...\n", __FUNCTION__, __LINE__);
+ debug("[%s, %d] flash_info = 0x%p ...\n", __func__, __LINE__,
+ flash_info);
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /* Static FLASH Bank configuration here - FIXME XXX */
+
+ debug("[%s, %d] Calling flash_get_size ...\n", __FUNCTION__, __LINE__);
+ size = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+ if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+ size, size<<20);
+ }
+
+ debug("[%s, %d] Test point ...\n", __FUNCTION__, __LINE__);
+
+ /* Setup offsets */
+ flash_get_offsets (-size, &flash_info[0]);
+ debug("[%s, %d] Test point ...\n", __FUNCTION__, __LINE__);
+
+ /* Re-do sizing to get full correct info */
+ mtdcr(EBC0_CFGADDR, PB0CR);
+ pbcr = mfdcr(EBC0_CFGDATA);
+ mtdcr(EBC0_CFGADDR, PB0CR);
+ base = -size;
+ switch (size) {
+ case 1 << 20:
+ size_val = 0;
+ break;
+ case 2 << 20:
+ size_val = 1;
+ break;
+ case 4 << 20:
+ size_val = 2;
+ break;
+ case 8 << 20:
+ size_val = 3;
+ break;
+ case 16 << 20:
+ size_val = 4;
+ break;
+ }
+ pbcr = (pbcr & 0x0001ffff) | base | (size_val << 17);
+ mtdcr(EBC0_CFGDATA, pbcr);
+ debug("[%s, %d] Test point ...\n", __FUNCTION__, __LINE__);
+
+ /* Monitor protection ON by default */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ -CONFIG_SYS_MONITOR_LEN,
+ 0xffffffff,
+ &flash_info[0]);
+
+ debug("[%s, %d] Test point ...\n", __FUNCTION__, __LINE__);
+ flash_info[0].size = size;
+
+ return (size);
+#endif
+}
diff --git a/qemu/roms/u-boot/board/dave/PPChameleonEVB/nand.c b/qemu/roms/u-boot/board/dave/PPChameleonEVB/nand.c
new file mode 100644
index 000000000..a191a0c3a
--- /dev/null
+++ b/qemu/roms/u-boot/board/dave/PPChameleonEVB/nand.c
@@ -0,0 +1,99 @@
+/*
+ * (C) Copyright 2006 DENX Software Engineering
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_CMD_NAND)
+
+#include <nand.h>
+
+/*
+ * hardware specific access to control-lines
+ * function borrowed from Linux 2.6 (drivers/mtd/nand/ppchameleonevb.c)
+ */
+static void ppchameleonevb_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ ulong base = (ulong) this->IO_ADDR_W;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if ( ctrl & NAND_CLE )
+ MACRO_NAND_CTL_SETCLE((unsigned long)base);
+ else
+ MACRO_NAND_CTL_CLRCLE((unsigned long)base);
+ if ( ctrl & NAND_ALE )
+ MACRO_NAND_CTL_CLRCLE((unsigned long)base);
+ else
+ MACRO_NAND_CTL_CLRALE((unsigned long)base);
+ if ( ctrl & NAND_NCE )
+ MACRO_NAND_ENABLE_CE((unsigned long)base);
+ else
+ MACRO_NAND_DISABLE_CE((unsigned long)base);
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ writeb(cmd, this->IO_ADDR_W);
+}
+
+
+/*
+ * read device ready pin
+ * function +/- borrowed from Linux 2.6 (drivers/mtd/nand/ppchameleonevb.c)
+ */
+static int ppchameleonevb_device_ready(struct mtd_info *mtdinfo)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong rb_gpio_pin;
+
+ /* use the base addr to find out which chip are we dealing with */
+ switch((ulong) this->IO_ADDR_W) {
+ case CONFIG_SYS_NAND0_BASE:
+ rb_gpio_pin = CONFIG_SYS_NAND0_RDY;
+ break;
+ case CONFIG_SYS_NAND1_BASE:
+ rb_gpio_pin = CONFIG_SYS_NAND1_RDY;
+ break;
+ default: /* this should never happen */
+ return 0;
+ break;
+ }
+
+ if (in32(GPIO0_IR) & rb_gpio_pin)
+ return 1;
+ return 0;
+}
+
+
+/*
+ * Board-specific NAND initialization. The following members of the
+ * argument are board-specific (per include/linux/mtd/nand.h):
+ * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
+ * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
+ * - cmd_ctrl: hardwarespecific function for accesing control-lines
+ * - dev_ready: hardwarespecific function for accesing device ready/busy line
+ * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must
+ * only be provided if a hardware ECC is available
+ * - ecc.mode: mode of ecc, see defines
+ * - chip_delay: chip dependent delay for transfering data from array to
+ * read regs (tR)
+ * - options: various chip options. They can partly be set to inform
+ * nand_scan about special functionality. See the defines for further
+ * explanation
+ * Members with a "?" were not set in the merged testing-NAND branch,
+ * so they are not set here either.
+ */
+int board_nand_init(struct nand_chip *nand)
+{
+
+ nand->cmd_ctrl = ppchameleonevb_hwcontrol;
+ nand->dev_ready = ppchameleonevb_device_ready;
+ nand->ecc.mode = NAND_ECC_SOFT;
+ nand->chip_delay = NAND_BIG_DELAY_US;
+ nand->options = NAND_SAMSUNG_LP_OPTIONS;
+ return 0;
+}
+#endif
diff --git a/qemu/roms/u-boot/board/dave/PPChameleonEVB/u-boot.lds b/qemu/roms/u-boot/board/dave/PPChameleonEVB/u-boot.lds
new file mode 100644
index 000000000..94b707614
--- /dev/null
+++ b/qemu/roms/u-boot/board/dave/PPChameleonEVB/u-boot.lds
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "config.h"
+
+#ifndef RESET_VECTOR_ADDRESS
+#define RESET_VECTOR_ADDRESS 0xfffffffc
+#endif
+
+OUTPUT_ARCH(powerpc)
+
+PHDRS
+{
+ text PT_LOAD;
+ bss PT_LOAD;
+}
+
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .text :
+ {
+ *(.text*)
+ } :text
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ } :text
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ _GOT2_TABLE_ = .;
+ KEEP(*(.got2))
+ KEEP(*(.got))
+ PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
+ _FIXUP_TABLE_ = .;
+ KEEP(*(.fixup))
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data*)
+ *(.sdata*)
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+
+ . = ALIGN(4);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ }
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ ppcenv_assert = ASSERT(. < 0xFFFF8000, ".bss section too big, overlaps .ppcenv section. Please update your confguration: CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN and CONFIG_SYS_TEXT_BASE may need to be modified.");
+ . = 0xFFFF8000;
+ .ppcenv :
+ {
+ common/env_embedded.o(.ppcenv);
+ }
+
+ .resetvec RESET_VECTOR_ADDRESS :
+ {
+ KEEP(*(.resetvec))
+ } :text = 0xffff
+
+ . = RESET_VECTOR_ADDRESS + 0x4;
+
+ /*
+ * Make sure that the bss segment isn't linked at 0x0, otherwise its
+ * address won't be updated during relocation fixups. Note that
+ * this is a temporary fix. Code to dynamically the fixup the bss
+ * location will be added in the future. When the bss relocation
+ * fixup code is present this workaround should be removed.
+ */
+#if (RESET_VECTOR_ADDRESS == 0xfffffffc)
+ . |= 0x10;
+#endif
+
+ __bss_start = .;
+ .bss (NOLOAD) :
+ {
+ *(.bss*)
+ *(.sbss*)
+ *(COMMON)
+ } :bss
+
+ . = ALIGN(4);
+ __bss_end = . ;
+ PROVIDE (end = .);
+}
diff --git a/qemu/roms/u-boot/board/dave/common/flash.c b/qemu/roms/u-boot/board/dave/common/flash.c
new file mode 100644
index 000000000..f05adf9f1
--- /dev/null
+++ b/qemu/roms/u-boot/board/dave/common/flash.c
@@ -0,0 +1,691 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+
+flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+ int i;
+ short n;
+
+ /* set up sector start address table */
+ if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+ } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {
+ /* set sector offsets for bottom boot block type */
+ for (i=0; i<8; ++i) { /* 8 x 8k boot sectors */
+ info->start[i] = base;
+ base += 8 << 10;
+ }
+ while (i < info->sector_count) { /* 64k regular sectors */
+ info->start[i] = base;
+ base += 64 << 10;
+ ++i;
+ }
+ } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {
+ /* set sector offsets for top boot block type */
+ base += info->size;
+ i = info->sector_count;
+ for (n=0; n<8; ++n) { /* 8 x 8k boot sectors */
+ base -= 8 << 10;
+ --i;
+ info->start[i] = base;
+ }
+ while (i > 0) { /* 64k regular sectors */
+ base -= 64 << 10;
+ --i;
+ info->start[i] = base;
+ }
+ } else {
+ if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00010000) - 0x00030000;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00010000;
+ }
+ }
+ }
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t *info)
+{
+ int i;
+ int k;
+ int size;
+ int erased;
+ volatile unsigned long *flash;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("missing or unknown FLASH type\n");
+ return;
+ }
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case FLASH_MAN_AMD: printf ("AMD "); break;
+ case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
+ case FLASH_MAN_SST: printf ("SST "); break;
+ case FLASH_MAN_STM: printf ("ST "); break;
+ default: printf ("Unknown Vendor "); break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM320T: printf ("AM29LV320T (32 M, top sector)\n");
+ break;
+ case FLASH_AM320B: printf ("AM29LV320B (32 M, bottom sector)\n");
+ break;
+ case FLASH_AMDL322T: printf ("AM29DL322T (32 M, top sector)\n");
+ break;
+ case FLASH_AMDL322B: printf ("AM29DL322B (32 M, bottom sector)\n");
+ break;
+ case FLASH_AMDL323T: printf ("AM29DL323T (32 M, top sector)\n");
+ break;
+ case FLASH_AMDL323B: printf ("AM29DL323B (32 M, bottom sector)\n");
+ break;
+ case FLASH_AM640U: printf ("AM29LV640D (64 M, uniform sector)\n");
+ break;
+ case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
+ break;
+ case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
+ break;
+ case FLASH_STMW320DT: printf ("M29W320DT (32 M, top sector)\n");
+ break;
+ default: printf ("Unknown Chip Type\n");
+ break;
+ }
+
+ printf (" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i=0; i<info->sector_count; ++i) {
+#ifdef CONFIG_SYS_FLASH_EMPTY_INFO
+ /*
+ * Check if whole sector is erased
+ */
+ if (i != (info->sector_count-1))
+ size = info->start[i+1] - info->start[i];
+ else
+ size = info->start[0] + info->size - info->start[i];
+ erased = 1;
+ flash = (volatile unsigned long *)info->start[i];
+ size = size >> 2; /* divide by 4 for longword access */
+ for (k=0; k<size; k++)
+ {
+ if (*flash++ != 0xffffffff)
+ {
+ erased = 0;
+ break;
+ }
+ }
+
+ if ((i % 5) == 0)
+ printf ("\n ");
+ /* print empty and read-only info */
+ printf (" %08lX%s%s",
+ info->start[i],
+ erased ? " E" : " ",
+ info->protect[i] ? "RO " : " ");
+#else
+ if ((i % 5) == 0)
+ printf ("\n ");
+ printf (" %08lX%s",
+ info->start[i],
+ info->protect[i] ? " (RO)" : " ");
+#endif
+
+ }
+ printf ("\n");
+ return;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+ short i;
+ short n;
+ CONFIG_SYS_FLASH_WORD_SIZE value;
+ ulong base = (ulong)addr;
+ volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)addr;
+
+ debug("[%s, %d] Entering ...\n", __FUNCTION__, __LINE__);
+
+ /* Write auto select command: read Manufacturer ID */
+ addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
+ addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
+ addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00900090;
+
+ value = addr2[CONFIG_SYS_FLASH_READ0];
+
+ switch (value) {
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ case (CONFIG_SYS_FLASH_WORD_SIZE)FUJ_MANUFACT:
+ info->flash_id = FLASH_MAN_FUJ;
+ break;
+ case (CONFIG_SYS_FLASH_WORD_SIZE)SST_MANUFACT:
+ info->flash_id = FLASH_MAN_SST;
+ break;
+ case (CONFIG_SYS_FLASH_WORD_SIZE)STM_MANUFACT:
+ info->flash_id = FLASH_MAN_STM;
+ break;
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ return (0); /* no or unknown flash */
+ }
+
+ value = addr2[CONFIG_SYS_FLASH_READ1]; /* device ID */
+
+ switch (value) {
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400T:
+ info->flash_id += FLASH_AM400T;
+ info->sector_count = 11;
+ info->size = 0x00080000;
+ break; /* => 0.5 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400B:
+ info->flash_id += FLASH_AM400B;
+ info->sector_count = 11;
+ info->size = 0x00080000;
+ break; /* => 0.5 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800T:
+ info->flash_id += FLASH_AM800T;
+ info->sector_count = 19;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800B:
+ info->flash_id += FLASH_AM800B;
+ info->sector_count = 19;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160T:
+ info->flash_id += FLASH_AM160T;
+ info->sector_count = 35;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160B:
+ info->flash_id += FLASH_AM160B;
+ info->sector_count = 35;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)STM_ID_29W320DT:
+ info->flash_id += FLASH_STMW320DT;
+ info->sector_count = 67;
+ info->size = 0x00400000; break; /* => 4 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320T:
+ info->flash_id += FLASH_AM320T;
+ info->sector_count = 71;
+ info->size = 0x00400000; break; /* => 4 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320B:
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 71;
+ info->size = 0x00400000; break; /* => 4 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322T:
+ info->flash_id += FLASH_AMDL322T;
+ info->sector_count = 71;
+ info->size = 0x00400000; break; /* => 4 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322B:
+ info->flash_id += FLASH_AMDL322B;
+ info->sector_count = 71;
+ info->size = 0x00400000; break; /* => 4 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323T:
+ info->flash_id += FLASH_AMDL323T;
+ info->sector_count = 71;
+ info->size = 0x00400000; break; /* => 4 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323B:
+ info->flash_id += FLASH_AMDL323B;
+ info->sector_count = 71;
+ info->size = 0x00400000; break; /* => 4 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV640U:
+ info->flash_id += FLASH_AM640U;
+ info->sector_count = 128;
+ info->size = 0x00800000; break; /* => 8 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF800A:
+ info->flash_id += FLASH_SST800A;
+ info->sector_count = 16;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF160A:
+ info->flash_id += FLASH_SST160A;
+ info->sector_count = 32;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ return (0); /* => no or unknown flash */
+
+ }
+
+ /* set up sector start address table */
+ if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+ } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {
+ /* set sector offsets for bottom boot block type */
+ for (i=0; i<8; ++i) { /* 8 x 8k boot sectors */
+ info->start[i] = base;
+ base += 8 << 10;
+ }
+ while (i < info->sector_count) { /* 64k regular sectors */
+ info->start[i] = base;
+ base += 64 << 10;
+ ++i;
+ }
+ } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {
+ /* set sector offsets for top boot block type */
+ base += info->size;
+ i = info->sector_count;
+ for (n=0; n<8; ++n) { /* 8 x 8k boot sectors */
+ base -= 8 << 10;
+ --i;
+ info->start[i] = base;
+ }
+ while (i > 0) { /* 64k regular sectors */
+ base -= 64 << 10;
+ --i;
+ info->start[i] = base;
+ }
+ } else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT) {
+ /* set sector offsets for top boot block type */
+ base += info->size;
+ i = info->sector_count;
+ /* 1 x 16k boot sector */
+ base -= 16 << 10;
+ --i;
+ info->start[i] = base;
+ /* 2 x 8k boot sectors */
+ for (n=0; n<2; ++n) {
+ base -= 8 << 10;
+ --i;
+ info->start[i] = base;
+ }
+ /* 1 x 32k boot sector */
+ base -= 32 << 10;
+ --i;
+ info->start[i] = base;
+
+ while (i > 0) { /* 64k regular sectors */
+ base -= 64 << 10;
+ --i;
+ info->start[i] = base;
+ }
+ } else {
+ if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00010000) - 0x00030000;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00010000;
+ }
+ }
+ }
+
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+ addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
+ info->protect[i] = 0;
+ else
+ info->protect[i] = addr2[CONFIG_SYS_FLASH_READ2] & 1;
+ }
+
+ /*
+ * Prevent writes to uninitialized FLASH.
+ */
+ if (info->flash_id != FLASH_UNKNOWN) {
+ addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0];
+ *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
+ }
+
+ return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]);
+ volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
+ int flag, prot, sect, l_sect;
+ ulong start, now, last;
+ int i;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("- missing\n");
+ } else {
+ printf ("- no sectors to erase\n");
+ }
+ return 1;
+ }
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("Can't erase unknown flash type - aborted\n");
+ return 1;
+ }
+
+ prot = 0;
+ for (sect=s_first; sect<=s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+
+ if (prot) {
+ printf ("- Warning: %d protected sectors will not be erased!\n",
+ prot);
+ } else {
+ printf ("\n");
+ }
+
+ l_sect = -1;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect<=s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[sect]);
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
+ addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
+ addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
+ addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080;
+ addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
+ addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
+ addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00500050; /* block erase */
+ for (i=0; i<50; i++)
+ udelay(1000); /* wait 1 ms */
+ } else {
+ if (sect == s_first) {
+ addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
+ addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
+ addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080;
+ addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
+ addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
+ }
+ addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00300030; /* sector erase */
+ }
+ l_sect = sect;
+ }
+ }
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+ /*
+ * We wait for the last triggered sector
+ */
+ if (l_sect < 0)
+ goto DONE;
+
+ start = get_timer (0);
+ last = start;
+ addr = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[l_sect]);
+ while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) != (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) {
+ if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ return 1;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ putc ('.');
+ last = now;
+ }
+ }
+
+DONE:
+ /* reset to read mode */
+ addr = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0];
+ addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
+
+ printf (" done\n");
+ return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ ulong cp, wp, data;
+ int i, l, rc;
+
+ wp = (addr & ~3); /* get lower word aligned address */
+
+ /*
+ * handle unaligned start bytes
+ */
+ if ((l = addr - wp) != 0) {
+ data = 0;
+ for (i=0, cp=wp; i<l; ++i, ++cp) {
+#ifdef CONFIG_B2
+ data = data | ((*(uchar *)cp)<<(8*i));
+#else
+ data = (data << 8) | (*(uchar *)cp);
+#endif
+ }
+ for (; i<4 && cnt>0; ++i) {
+#ifdef CONFIG_B2
+ data = data | ((*src++)<<(8*i));
+#else
+ data = (data << 8) | *src++;
+#endif
+ --cnt;
+ ++cp;
+ }
+ for (; cnt==0 && i<4; ++i, ++cp) {
+#ifdef CONFIG_B2
+ data = data | ((*(uchar *)cp)<<(8*i));
+#else
+ data = (data << 8) | (*(uchar *)cp);
+#endif
+ }
+
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 4) {
+ data = 0;
+#ifdef CONFIG_B2
+ data = (*(ulong*)src);
+ src += 4;
+#else
+ for (i=0; i<4; ++i) {
+ data = (data << 8) | *src++;
+ }
+#endif
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ cnt -= 4;
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+#ifdef CONFIG_B2
+ data = data | ((*src++)<<(8*i));
+#else
+ data = (data << 8) | *src++;
+#endif
+ --cnt;
+ }
+ for (; i<4; ++i, ++cp) {
+#ifdef CONFIG_B2
+ data = data | ((*(uchar *)cp)<<(8*i));
+#else
+ data = (data << 8) | (*(uchar *)cp);
+#endif
+ }
+
+ return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+ ulong *data_ptr = &data;
+ volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]);
+ volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *)dest;
+ volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 = (CONFIG_SYS_FLASH_WORD_SIZE *)data_ptr;
+ ulong start;
+ int flag;
+ int i;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((volatile ulong *)dest) & data) != data) {
+ return (2);
+ }
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ for (i=0; i<4/sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++)
+ {
+ addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
+ addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
+ addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00A000A0;
+
+ dest2[i] = data2[i];
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* data polling for D7 */
+ start = get_timer (0);
+ while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) !=
+ (data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080)) {
+ if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+ }
+
+ return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */