U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
September 2008
- 151 participants
- 458 discussions

10 Feb '09
Hi again
This series of patches adds support for the NAND flash controller in the
i.MX31 device and also introduces the Freescale i.MX31 PDK board.
Changes since v2:
- Added doc/README.mx31 (contains MC13783 SPI config documentation)
- Split the PDK patch into two patches, the first introduces the
board without NAND support, the second adds NAND support.
- Re-ordered the series so the NAND patches are placed last
- mx31_nand.c has been updated w.r.t. coding style.
- There are still issues with the NAND driver (i.e. not all comments from
Scott Wood have been taken care of yet). Therefore I suspect that the
NAND driver is not ready for inclusion yet, the other patches should be
OK.
The patches are based on the current main U-boot git repo (as of
Friday morning).
Changes since v1:
- Moved PDK board to boards/freescale/mx31pdk
- Moved mxc_nd.c to driver/mtd/nand/mx31_nand.c
- Moved contents of mxc_nd.h to mx31-regs.h
- Cleaned up the mx31pdk.h config file after comments from this list
- CONFIG_CMD_IMLS is still #undef'd but a comment is added in the config
file about that.
- A new patch has been inserted into the series, it makes the MC13783 SPI
bus and chip select configurable.
The patches are based on the current main U-boot git repo.
Original intro for this series of patches:
At the moment, the patch series does not add support for booting from
NAND. This means that the PDK board support assumes that some other entity
configures the SDRAM and loads U-boot into RAM (e.g. another bootloader or a
JTAG debugger). Support for NAND boot is in progress and will be submitted
later.
The NAND driver is based on Freescale's Linux driver from their BSP. I've
cleaned it up a bit and made the (minor) modifications necessary for
U-boot. Perhaps the driver should be cleaned up even more, there are some
CONFIG_MTD_MXC_* leftovers in the driver.
I have tested the driver on the Litekit (small page NAND) and on the PDK
(large page NAND) by having the U-boot environment placed in NAND.
Regards, Magnus
5
28

[U-Boot] [PATCH 1/1] qemu_mips: move env storage just after u-boot
by Jean-Christophe PLAGNIOL-VILLARD 17 Dec '08
by Jean-Christophe PLAGNIOL-VILLARD 17 Dec '08
17 Dec '08
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj(a)jcrosoft.com>
---
include/configs/qemu-mips.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/configs/qemu-mips.h b/include/configs/qemu-mips.h
index faaa889..e46976d 100644
--- a/include/configs/qemu-mips.h
+++ b/include/configs/qemu-mips.h
@@ -150,7 +150,7 @@
#define CFG_FLASH_USE_BUFFER_WRITE 1
#define CONFIG_ENV_IS_IN_FLASH 1
-#define CONFIG_ENV_ADDR (CFG_FLASH_BASE + 0x40000)
+#define CONFIG_ENV_ADDR (CFG_FLASH_BASE + 0x30000)
/* Address and size of Primary Environment Sector */
#define CONFIG_ENV_SIZE 0x8000
--
1.5.6.5
3
13

07 Dec '08
See doc/README.iomux for a general description of what this does.
This is the first of two commits. The second commit touches net/eth.c
and has to go through the custodian, so I split it out for simplicity.
Tested with MAKEALL 8xx.
Signed-off-by: Gary Jennejohn <garyj(a)denx.de>
---
common/Makefile | 1 +
common/cmd_nvedit.c | 6 ++
common/console.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++
common/iomux.c | 133 +++++++++++++++++++++++++++++++++++++++
doc/README.iomux | 90 ++++++++++++++++++++++++++
include/common.h | 7 ++
include/iomux.h | 48 ++++++++++++++
7 files changed, 458 insertions(+), 0 deletions(-)
create mode 100644 common/iomux.c
create mode 100644 doc/README.iomux
create mode 100644 include/iomux.h
diff --git a/common/Makefile b/common/Makefile
index 8bddf8e..9138742 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -155,6 +155,7 @@ COBJS-$(CONFIG_LCD) += lcd.o
COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o
+COBJS-$(CONFIG_IO_MUX) += iomux.o
COBJS := $(sort $(COBJS-y))
SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 637d6c9..6fc9313 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -213,6 +213,11 @@ int _do_setenv (int flag, int argc, char *argv[])
return 1;
}
+#ifdef CONFIG_IO_MUX
+ i = iomux_doenv(console, argv[2]);
+ if (i)
+ return i;
+#else
/* Try assigning specified device */
if (console_assign (console, argv[2]) < 0)
return 1;
@@ -221,6 +226,7 @@ int _do_setenv (int flag, int argc, char *argv[])
if (serial_assign (argv[2]) < 0)
return 1;
#endif
+#endif /* CONFIG_IO_MUX */
}
/*
diff --git a/common/console.c b/common/console.c
index 56d9118..6158af9 100644
--- a/common/console.c
+++ b/common/console.c
@@ -93,6 +93,78 @@ static int console_setfile (int file, device_t * dev)
return error;
}
+#if defined(CONFIG_IO_MUX)
+/** Console I/O multiplexing *******************************************/
+
+static device_t *tstcdev;
+device_t *console_devices[MAX_FILES][MAX_CONSARGS];
+
+/*
+ * This depends on tstc() always being called before getc().
+ * No attempt is made to demultiplex multiple input sources.
+ */
+static int iomux_getc(void)
+{
+ unsigned char ret;
+
+ ret = tstcdev->getc();
+ tstcdev = NULL;
+ return ret;
+}
+
+static int iomux_tstc(int file)
+{
+ int i, ret;
+ device_t *dev;
+
+ disable_ctrlc(1);
+ for (i = 0; i < MAX_CONSARGS; i++) {
+ dev = console_devices[file][i];
+ if (dev == NULL)
+ break;
+ if (dev->tstc != NULL) {
+ ret = dev->tstc();
+ if (ret > 0) {
+ tstcdev = dev;
+ disable_ctrlc(0);
+ return ret;
+ }
+ }
+ }
+ disable_ctrlc(0);
+
+ return 0;
+}
+
+static void iomux_putc(int file, const char c)
+{
+ int i;
+ device_t *dev;
+
+ for (i = 0; i < MAX_CONSARGS; i++) {
+ dev = console_devices[file][i];
+ if (dev == NULL)
+ break;
+ if (dev->putc != NULL)
+ dev->putc(c);
+ }
+}
+
+static void iomux_puts(int file, const char *s)
+{
+ int i;
+ device_t *dev;
+
+ for (i = 0; i < MAX_CONSARGS; i++) {
+ dev = console_devices[file][i];
+ if (dev == NULL)
+ break;
+ if (dev->puts != NULL)
+ dev->puts(s);
+ }
+}
+#endif /* defined(CONFIG_IO_MUX) */
+
/** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
void serial_printf (const char *fmt, ...)
@@ -115,7 +187,41 @@ void serial_printf (const char *fmt, ...)
int fgetc (int file)
{
if (file < MAX_FILES)
+#if defined(CONFIG_IO_MUX)
+ {
+ int cntr = 0;
+
+ /*
+ * Effectively poll for input wherever it may be available.
+ */
+ for (;;) {
+ /*
+ * Upper layer may have already called tstc() so
+ * check for that first.
+ */
+ if (tstcdev != NULL)
+ return iomux_getc();
+ iomux_tstc(file);
+ /*
+ * Even this is too slow for serial cut&paste due
+ * to the overhead of calling tstc() then getc().
+ * It gets worse if nc is set as a console because
+ * nc_tstc() is really slow.
+ *
+ * The idea behind this counter is to avoid calling
+ * the watchdog via udelay() too often.
+ * COUNT_TIL_UDELAY is defined in iomux.h and is just
+ * a guesstimate.
+ */
+ if (cntr++ > COUNT_TIL_UDELAY) {
+ udelay(1);
+ cntr = 0;
+ }
+ }
+ }
+#else
return stdio_devices[file]->getc ();
+#endif
return -1;
}
@@ -123,7 +229,11 @@ int fgetc (int file)
int ftstc (int file)
{
if (file < MAX_FILES)
+#if defined(CONFIG_IO_MUX)
+ return iomux_tstc(file);
+#else
return stdio_devices[file]->tstc ();
+#endif
return -1;
}
@@ -131,13 +241,21 @@ int ftstc (int file)
void fputc (int file, const char c)
{
if (file < MAX_FILES)
+#if defined(CONFIG_IO_MUX)
+ iomux_putc(file, c);
+#else
stdio_devices[file]->putc (c);
+#endif
}
void fputs (int file, const char *s)
{
if (file < MAX_FILES)
+#if defined(CONFIG_IO_MUX)
+ iomux_puts(file, s);
+#else
stdio_devices[file]->puts (s);
+#endif
}
void fprintf (int file, const char *fmt, ...)
@@ -407,6 +525,9 @@ int console_init_r (void)
#ifdef CFG_CONSOLE_ENV_OVERWRITE
int i;
#endif /* CFG_CONSOLE_ENV_OVERWRITE */
+#ifdef CONFIG_IO_MUX
+ int iomux_err = 0;
+#endif
/* set default handlers at first */
gd->jt[XF_getc] = serial_getc;
@@ -425,6 +546,14 @@ int console_init_r (void)
inputdev = search_device (DEV_FLAGS_INPUT, stdinname);
outputdev = search_device (DEV_FLAGS_OUTPUT, stdoutname);
errdev = search_device (DEV_FLAGS_OUTPUT, stderrname);
+#ifdef CONFIG_IO_MUX
+ iomux_err = iomux_doenv(stdin, stdinname);
+ iomux_err += iomux_doenv(stdout, stdoutname);
+ iomux_err += iomux_doenv(stderr, stderrname);
+ if (!iomux_err)
+ /* Successful, so skip all the code below. */
+ goto done;
+#endif
}
/* if the devices are overwritten or not found, use default device */
if (inputdev == NULL) {
@@ -439,15 +568,40 @@ int console_init_r (void)
/* Initializes output console first */
if (outputdev != NULL) {
console_setfile (stdout, outputdev);
+#ifdef CONFIG_IO_MUX
+ /* need to set a console if not done above. */
+ console_devices[stdout][0] = outputdev;
+#endif
}
if (errdev != NULL) {
console_setfile (stderr, errdev);
+#ifdef CONFIG_IO_MUX
+ /* need to set a console if not done above. */
+ console_devices[stderr][0] = errdev;
+#endif
}
if (inputdev != NULL) {
console_setfile (stdin, inputdev);
+#ifdef CONFIG_IO_MUX
+ /* need to set a console if not done above. */
+ console_devices[stdin][0] = inputdev;
+#endif
}
+#ifdef CONFIG_IO_MUX
+#ifdef CONFIG_NETCONSOLE
+ /*
+ * Must do this very late in net/eth.c because a network device may
+ * be set as a console at boot.
+ */
+ gd->flags |= 0;
+#else
+ gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
+#endif /* CONFIG_NETCONSOLE */
+done:
+#else
gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
+#endif /* CONFIG_IO_MUX */
#ifndef CFG_CONSOLE_INFO_QUIET
/* Print information */
@@ -455,21 +609,33 @@ int console_init_r (void)
if (stdio_devices[stdin] == NULL) {
puts ("No input devices available!\n");
} else {
+#ifdef CONFIG_IO_MUX
+ iomux_printdevs(stdin);
+#else
printf ("%s\n", stdio_devices[stdin]->name);
+#endif
}
puts ("Out: ");
if (stdio_devices[stdout] == NULL) {
puts ("No output devices available!\n");
} else {
+#ifdef CONFIG_IO_MUX
+ iomux_printdevs(stdout);
+#else
printf ("%s\n", stdio_devices[stdout]->name);
+#endif
}
puts ("Err: ");
if (stdio_devices[stderr] == NULL) {
puts ("No error devices available!\n");
} else {
+#ifdef CONFIG_IO_MUX
+ iomux_printdevs(stderr);
+#else
printf ("%s\n", stdio_devices[stderr]->name);
+#endif
}
#endif /* CFG_CONSOLE_INFO_QUIET */
@@ -524,11 +690,18 @@ int console_init_r (void)
if (outputdev != NULL) {
console_setfile (stdout, outputdev);
console_setfile (stderr, outputdev);
+#ifdef CONFIG_IO_MUX
+ console_devices[stdout][0] = outputdev;
+ console_devices[stderr][0] = outputdev;
+#endif
}
/* Initializes input console */
if (inputdev != NULL) {
console_setfile (stdin, inputdev);
+#ifdef CONFIG_IO_MUX
+ console_devices[stdin][0] = inputdev;
+#endif
}
gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
diff --git a/common/iomux.c b/common/iomux.c
new file mode 100644
index 0000000..d62f7e4
--- /dev/null
+++ b/common/iomux.c
@@ -0,0 +1,133 @@
+/*
+ * (C) Copyright 2008
+ * Gary Jennejohn, DENX Software Engineering GmbH, garyj(a)denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <serial.h>
+#include <malloc.h>
+
+#ifdef CONFIG_IO_MUX
+void iomux_printdevs(const int console)
+{
+ int i;
+ device_t *dev;
+
+ for (i = 0; i < MAX_CONSARGS; i++) {
+ dev = console_devices[console][i];
+ if (dev == NULL)
+ break;
+ serial_printf("%s ", dev->name);
+ }
+ serial_printf("\n");
+}
+
+int iomux_doenv(const int console, const char *arg)
+{
+ char *console_args, *temp, *start[MAX_CONSARGS];
+ int i, j, io_flag, cs_idx;
+ device_t *dev;
+ device_t *cons_set[MAX_CONSARGS];
+
+#ifdef CFG_CONSOLE_IS_IN_ENV
+ if (arg == NULL)
+ return 1;
+#endif
+
+ i = 0;
+ console_args = strdup(arg);
+ if (console_args == NULL)
+ return 1;
+ start[0] = console_args;
+ /*
+ * Check whether a comma separated list of devices was
+ * entered and count how many devices were entered.
+ * The array start[] has pointers to the beginning of
+ * each device name (up to MAX_CONSARGS devices).
+ */
+ for (;;) {
+ temp = strchr(start[i], ',');
+ if (temp != NULL) {
+ i++;
+ *temp = '\0';
+ if (i == MAX_CONSARGS)
+ break;
+ start[i] = temp + 1;
+ continue;
+ }
+ break;
+ }
+ if (i != MAX_CONSARGS)
+ i++;
+ cs_idx = 0;
+ memset((void *)cons_set, 0, CONSDEVS_LINE_SIZE);
+
+ switch (console) {
+ case stdin:
+ io_flag = DEV_FLAGS_INPUT;
+ break;
+ case stdout:
+ case stderr:
+ io_flag = DEV_FLAGS_OUTPUT;
+ break;
+ default:
+ return 1;
+ }
+
+ for (j = 0; j < i; j++) {
+ /*
+ * Check whether the device exists and is valid.
+ * console_assign() also calls search_device(),
+ * but I need the pointer to the device.
+ */
+ dev = search_device(io_flag, start[j]);
+ if (dev == NULL)
+ continue;
+ /*
+ * Try assigning the specified device.
+ * This could screw up the console settings for apps.
+ */
+ if (console_assign(console, start[j]) < 0)
+ continue;
+#ifdef CONFIG_SERIAL_MULTI
+ /*
+ * This was taken from common/cmd_nvedit.c.
+ * This will never work because serial_assign() returns
+ * 1 upon error, not -1.
+ * This would almost always return an error anyway because
+ * serial_assign() expects the name of a serial device, like
+ * serial_smc, but the user generally only wants to set serial.
+ */
+ if (serial_assign(start[j]) < 0)
+ continue;
+#endif
+ cons_set[cs_idx++] = dev;
+ }
+ free(console_args);
+ /* failed to set any console */
+ if (cs_idx == 0)
+ return 1;
+ else
+ memcpy(console_devices[console], cons_set,
+ CONSDEVS_LINE_SIZE);;
+ return 0;
+}
+#endif /* CONFIG_IO_MUX */
diff --git a/doc/README.iomux b/doc/README.iomux
new file mode 100644
index 0000000..222843c
--- /dev/null
+++ b/doc/README.iomux
@@ -0,0 +1,90 @@
+/*
+ * (C) Copyright 2008
+ * Gary Jennejohn, DENX Software Engineering GmbH <garyj(a)denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+U-Boot console multiplexing
+===========================
+
+HOW CONSOLE MULTIPLEXING WORKS
+------------------------------
+
+This functionality is controlled with CONFIG_IO_MUX in the board
+configuration file.
+
+Two new files, common/iomux.c and include/iomux.h, contain the heart
+of the environment setting implementation.
+
+The execution is then in common/cmd_nvedit.c and common/console.c.
+
+A user can use a comma-separated list of devices to set stdin, stdout
+and stderr. For example: setenv stdin serial,nc. NOTE: No spaces
+are allowed around the comma(s)!
+
+The length of the list is limited to MAX_CONSARGS entries, which is
+defined in include/iomux.h and presently set to 6.
+
+It should be possible to specify any device which console_assign()
+finds acceptable, but the code has only been tested with serial and
+nc.
+
+The major change in common/console.c was to modify fgetc() to call
+the iomux_tstc() routine in a for-loop. iomux_tstc() in turn calls
+the tstc() routine for every registered device, but exits immediately
+when one of them returns true. fgetc() then calls iomux_getc(),
+which calls the correpsonding getc() routine. fgetc() hangs in
+the for-loop until iomux_tstc() returns true and the input can be
+retrieved.
+
+Thus, a user can type into any device registered for stdin. No effort
+has been made to demulitplex simultaneous input from multiple stdin
+devices.
+
+fputc() and fputs() have been modified to call iomux_putc() and
+iomux_puts() respectively, which call the corresponding output
+routines for every registered device.
+
+Thus, a user can see the ouput for any device registered for stdout
+or stderr on all devices registered for stdout or stderr. As an
+example, if stdin=serial,nc and stdout=serial,nc then all output
+for serial, e.g. echos of input on serial, will appear on serial and nc.
+
+Just as with the old console code, this statement is still true:
+If not defined in the environment, the first input device is assigned
+to the 'stdin' file, the first output one to 'stdout' and 'stderr'.
+
+If CONFIG_CONSOLE_IS_IN_ENV is defined then multiple input/output
+devices will be set at boot time.
+
+CAVEATS
+-------
+
+Note that common/iomux.c calls console_assign() for every registered
+device as it is discovered. This means that the environment settings
+for application consoles will be set to the last device in the list.
+
+The overhead associated with calling tstc() and then getc() means that
+cut&paste will not work, even if serial is set as the only device for
+stdin, stdout and stderr.
+
+Using nc as a stdin device results in even more overhead because nc_tstc()
+is extremely slow. The slowdown is so extreme that it negatively impacts
+timers such as the autoboot countdown.
diff --git a/include/common.h b/include/common.h
index 33c6e10..8cc7e3a 100644
--- a/include/common.h
+++ b/include/common.h
@@ -675,6 +675,13 @@ void fputc(int file, const char c);
int ftstc(int file);
int fgetc(int file);
+/*
+ * CONSOLE multiplexing.
+ */
+#ifdef CONFIG_IO_MUX
+#include <iomux.h>
+#endif
+
int pcmcia_init (void);
#ifdef CONFIG_STATUS_LED
diff --git a/include/iomux.h b/include/iomux.h
new file mode 100644
index 0000000..1310a75
--- /dev/null
+++ b/include/iomux.h
@@ -0,0 +1,48 @@
+/*
+ * (C) Copyright 2008
+ * Gary Jennejohn, DENX Software Engineering GmbH, garyj(a)denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version.
+ * * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _IO_MUX_H
+#define _IO_MUX_H
+
+#include <devices.h>
+
+/*
+ * Stuff required to support console multiplexing.
+ */
+/* Only allow this many devices in the comma separated list of consoles */
+#define MAX_CONSARGS 6
+
+/*
+ * Avoid invoking WATCHDOG via udelayy() on every pass through the loop
+ * in fgetc(). Note this is all based on guesswork.
+ */
+#define COUNT_TIL_UDELAY 10000
+
+/*
+ * Pointers to devices used for each file type. Defined in console.c.
+ */
+extern device_t *console_devices[MAX_FILES][MAX_CONSARGS];
+#define CONSDEVS_LINE_SIZE (sizeof(device_t *) * MAX_CONSARGS)
+
+int iomux_doenv(const int, const char *);
+void iomux_printdevs(const int);
+device_t *search_device(int, char *);
+
+#endif /* _IO_MUX_H */
--
1.5.4.3
---
Gary Jennejohn
*********************************************************************
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office(a)denx.de
*********************************************************************
3
14
Hi to all,
I'd like to use u-boot lo load small applications program on a board based
on IXP425. My customer has used redboot to load linux over this board and
now He asked to me to write some applications to test the hardware.
I tought to use u-boot because I have no knowledge on redboot and because I
have already used u-boot over ixp425 few years ago.
Moreover I knew that quite recently, some improvements have been made on
u-boot to avoid the use of Intel APIs.
Now I don't know if this activity has been completely carried out and allows
the use of both eth interfaces which are provided by the uP.
Can anybody suggest me where can I find some further info on the status of
u-boot on ixp425?
Many thanks in advance
Gianfranco
6
6
*CHANGELOG Added Support for Embedded Planet Boards EP852 EP866 and
EP85xxm. See respective board config file for original author
information. Merged from internal company port and QUICCstart kit into
the most recent u-boot git by J. Mann, Embedded Planet, 2006-JUL-27.
(this is part 2 of 2 split in half for size reasons.)
(the first attempt to send this e-mail resulted in a message too big
error. Sorry if you get two on acident)
2
1

29 Nov '08
3
2

21 Nov '08
Hello,
i took the already submitted patches from Daniel Mack, fixed some minor
problems and patched it against the 1.3.4 tree.
The patch compiles clean and all my boards boots well.
If there are any objections leave me a note
peter
diff -purN u-boot-1.3.4/board/colibri/colibri.c
u-boot-1.3.4-col/board/colibri/colibri.c
--- u-boot-1.3.4/board/colibri/colibri.c 1970-01-01
01:00:00.000000000 +0100
+++ u-boot-1.3.4-col/board/colibri/colibri.c 2008-09-23
15:13:35.000000000 +0200
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2007
+ * Daniel Mack, caiaq <daniel(a)caiaq.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
------------------------------------------------------------------------- */
+
+/*
+ * Miscelaneous platform dependent initialisations
+ */
+
+int board_init (void)
+{
+ /* memory and cpu-speed are setup before relocation */
+ /* so we do _nothing_ here */
+
+ /* arch number of COLIRBI-Board */
+ gd->bd->bi_arch_number = MACH_TYPE_COLIBRI;
+
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = 0xa0000100;
+
+ return 0;
+}
+
+int board_late_init(void)
+{
+ setenv("stdout", "serial");
+ setenv("stderr", "serial");
+ return 0;
+}
+
+
+int dram_init (void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+ return 0;
+}
diff -purN u-boot-1.3.4/board/colibri/config.mk
u-boot-1.3.4-col/board/colibri/config.mk
--- u-boot-1.3.4/board/colibri/config.mk 1970-01-01
01:00:00.000000000 +0100
+++ u-boot-1.3.4-col/board/colibri/config.mk 2008-09-23
15:13:35.000000000 +0200
@@ -0,0 +1 @@
+TEXT_BASE = 0xa1700000
diff -purN u-boot-1.3.4/board/colibri/lowlevel_init.S
u-boot-1.3.4-col/board/colibri/lowlevel_init.S
--- u-boot-1.3.4/board/colibri/lowlevel_init.S 1970-01-01
01:00:00.000000000 +0100
+++ u-boot-1.3.4-col/board/colibri/lowlevel_init.S 2008-09-23
15:13:35.000000000 +0200
@@ -0,0 +1,465 @@
+/*
+* This was originally from the Lubbock u-boot port.
+*
+* Most of this taken from Redboot hal_platform_setup.h with cleanup
+*
+* NOTE: I haven't clean this up considerably, just enough to get it
+* running. See hal_platform_setup.h for the source. See
+* board/cradle/lowlevel_init.S for another PXA250 setup that is
+* much cleaner.
+*
+* See file CREDITS for list of people who contributed to this
+* project.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+* MA 02111-1307 USA
+*/
+
+#include <config.h>
+#include <version.h>
+#include <asm/arch/pxa-regs.h>
+
+/* wait for coprocessor write complete */
+.macro CPWAIT reg
+mrc p15,0,\reg,c2,c0,0
+mov \reg,\reg
+sub pc,pc,#4
+.endm
+
+
+/*
+* Memory setup
+*/
+
+.globl lowlevel_init
+lowlevel_init:
+
+ /* Set up GPIO pins first ----------------------------------------- */
+
+ ldr r0, =GPSR0
+ ldr r1, =CFG_GPSR0_VAL
+ str r1, [r0]
+
+ ldr r0, =GPSR1
+ ldr r1, =CFG_GPSR1_VAL
+ str r1, [r0]
+
+ ldr r0, =GPSR2
+ ldr r1, =CFG_GPSR2_VAL
+ str r1, [r0]
+
+ ldr r0, =GPSR3
+ ldr r1, =CFG_GPSR3_VAL
+ str r1, [r0]
+
+ ldr r0, =GPCR0
+ ldr r1, =CFG_GPCR0_VAL
+ str r1, [r0]
+
+ ldr r0, =GPCR1
+ ldr r1, =CFG_GPCR1_VAL
+ str r1, [r0]
+
+ ldr r0, =GPCR2
+ ldr r1, =CFG_GPCR2_VAL
+ str r1, [r0]
+
+ ldr r0, =GPCR3
+ ldr r1, =CFG_GPCR3_VAL
+ str r1, [r0]
+
+ ldr r0, =GPDR0
+ ldr r1, =CFG_GPDR0_VAL
+ str r1, [r0]
+
+ ldr r0, =GPDR1
+ ldr r1, =CFG_GPDR1_VAL
+ str r1, [r0]
+
+ ldr r0, =GPDR2
+ ldr r1, =CFG_GPDR2_VAL
+ str r1, [r0]
+
+ ldr r0, =GPDR3
+ ldr r1, =CFG_GPDR3_VAL
+ str r1, [r0]
+
+ ldr r0, =GAFR0_L
+ ldr r1, =CFG_GAFR0_L_VAL
+ str r1, [r0]
+
+ ldr r0, =GAFR0_U
+ ldr r1, =CFG_GAFR0_U_VAL
+ str r1, [r0]
+
+ ldr r0, =GAFR1_L
+ ldr r1, =CFG_GAFR1_L_VAL
+ str r1, [r0]
+
+ ldr r0, =GAFR1_U
+ ldr r1, =CFG_GAFR1_U_VAL
+ str r1, [r0]
+
+ ldr r0, =GAFR2_L
+ ldr r1, =CFG_GAFR2_L_VAL
+ str r1, [r0]
+
+ ldr r0, =GAFR2_U
+ ldr r1, =CFG_GAFR2_U_VAL
+ str r1, [r0]
+
+ ldr r0, =GAFR3_L
+ ldr r1, =CFG_GAFR3_L_VAL
+ str r1, [r0]
+
+ ldr r0, =GAFR3_U
+ ldr r1, =CFG_GAFR3_U_VAL
+ str r1, [r0]
+
+ ldr r0, =PSSR /* enable GPIO pins */
+ ldr r1, =CFG_PSSR_VAL
+ str r1, [r0]
+
+ /* ---------------------------------------------------------------- */
+ /* Enable memory interface */
+ /* */
+ /* The sequence below is based on the recommended init steps */
+ /* detailed in the Intel PXA250 Operating Systems Developers Guide, */
+ /* Chapter 10. */
+ /* ---------------------------------------------------------------- */
+
+ /* ---------------------------------------------------------------- */
+ /* Step 1: Wait for at least 200 microsedonds to allow internal
*/
+ /* clocks to settle. Only necessary after hard reset... */
+ /* FIXME: can be optimized later */
+ /* ---------------------------------------------------------------- */
+
+ ldr r3, =OSCR /* reset the OS Timer Count to zero */
+ mov r2, #0
+ str r2, [r3]
+ ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
+ /* so 0x300 should be plenty */
+1:
+ ldr r2, [r3]
+ cmp r4, r2
+ bgt 1b
+
+mem_init:
+
+ ldr r1, =MEMC_BASE /* get memory controller base addr. */
+
+ /* ---------------------------------------------------------------- */
+ /* Step 2a: Initialize Asynchronous static memory controller */
+ /* ---------------------------------------------------------------- */
+
+ /* MSC registers: timing, bus width, mem type */
+
+ /* MSC0: nCS(0,1) */
+ ldr r2, =CFG_MSC0_VAL
+ str r2, [r1, #MSC0_OFFSET]
+ ldr r2, [r1, #MSC0_OFFSET] /* read back to ensure */
+ /* that data latches */
+ /* MSC1: nCS(2,3) */
+ ldr r2, =CFG_MSC1_VAL
+ str r2, [r1, #MSC1_OFFSET]
+ ldr r2, [r1, #MSC1_OFFSET]
+
+ /* MSC2: nCS(4,5) */
+ ldr r2, =CFG_MSC2_VAL
+ str r2, [r1, #MSC2_OFFSET]
+ ldr r2, [r1, #MSC2_OFFSET]
+
+ /* ---------------------------------------------------------------- */
+ /* Step 2b: Initialize Card Interface */
+ /* ---------------------------------------------------------------- */
+
+ /* MECR: Memory Expansion Card Register */
+ ldr r2, =CFG_MECR_VAL
+ str r2, [r1, #MECR_OFFSET]
+ ldr r2, [r1, #MECR_OFFSET]
+
+ /* MCMEM0: Card Interface slot 0 timing */
+ ldr r2, =CFG_MCMEM0_VAL
+ str r2, [r1, #MCMEM0_OFFSET]
+ ldr r2, [r1, #MCMEM0_OFFSET]
+
+ /* MCMEM1: Card Interface slot 1 timing */
+ ldr r2, =CFG_MCMEM1_VAL
+ str r2, [r1, #MCMEM1_OFFSET]
+ ldr r2, [r1, #MCMEM1_OFFSET]
+
+ /* MCATT0: Card Interface Attribute Space Timing, slot 0 */
+ ldr r2, =CFG_MCATT0_VAL
+ str r2, [r1, #MCATT0_OFFSET]
+ ldr r2, [r1, #MCATT0_OFFSET]
+
+ /* MCATT1: Card Interface Attribute Space Timing, slot 1 */
+ ldr r2, =CFG_MCATT1_VAL
+ str r2, [r1, #MCATT1_OFFSET]
+ ldr r2, [r1, #MCATT1_OFFSET]
+
+ /* MCIO0: Card Interface I/O Space Timing, slot 0 */
+ ldr r2, =CFG_MCIO0_VAL
+ str r2, [r1, #MCIO0_OFFSET]
+ ldr r2, [r1, #MCIO0_OFFSET]
+
+ /* MCIO1: Card Interface I/O Space Timing, slot 1 */
+ ldr r2, =CFG_MCIO1_VAL
+ str r2, [r1, #MCIO1_OFFSET]
+ ldr r2, [r1, #MCIO1_OFFSET]
+
+ /* ---------------------------------------------------------------- */
+ /* Step 2c: Write FLYCNFG FIXME: what's that??? */
+ /* ---------------------------------------------------------------- */
+ /*ldr r2, =CFG_FLYCNFG_VAL
+ str r2, [r1, #FLYCNFG_OFFSET]
+ str r2, [r1, #FLYCNFG_OFFSET]*/
+
+ /* ---------------------------------------------------------------- */
+ /* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */
+ /* ---------------------------------------------------------------- */
+
+ /* Before accessing MDREFR we need a valid DRI field, so we set
*/
+ /* this to power on defaults + DRI field. */
+
+ ldr r4, [r1, #MDREFR_OFFSET]
+ ldr r2, =0xFFF
+ bic r4, r4, r2
+
+ ldr r3, =CFG_MDREFR_VAL
+ and r3, r3, r2
+
+ orr r4, r4, r3
+ str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
+
+ orr r4, r4, #MDREFR_K0RUN
+ orr r4, r4, #MDREFR_K0DB4
+ orr r4, r4, #MDREFR_K0FREE
+ orr r4, r4, #MDREFR_K0DB2
+ orr r4, r4, #MDREFR_K1DB2
+ bic r4, r4, #MDREFR_K1FREE
+ bic r4, r4, #MDREFR_K2FREE
+
+ str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
+ ldr r4, [r1, #MDREFR_OFFSET]
+
+ /* Note: preserve the mdrefr value in r4 */
+
+
+ /* ---------------------------------------------------------------- */
+ /* Step 3: Initialize Synchronous Static Memory (Flash/Peripherals) */
+ /* ---------------------------------------------------------------- */
+
+ /* Initialize SXCNFG register. Assert the enable bits */
+
+ /* Write SXMRS to cause an MRS command to all enabled banks of
*/
+ /* synchronous static memory. Note that SXLCR need not be written */
+ /* at this time. */
+
+/* ldr r2, =CFG_SXCNFG_VAL
+ str r2, [r1, #SXCNFG_OFFSET] */
+
+ /* ---------------------------------------------------------------- */
+ /* Step 4: Initialize SDRAM */
+ /* ---------------------------------------------------------------- */
+
+ bic r4, r4, #(MDREFR_K2FREE |MDREFR_K1FREE | MDREFR_K0FREE)
+
+ orr r4, r4, #MDREFR_K1RUN
+ bic r4, r4, #MDREFR_K2DB2
+ str r4, [r1, #MDREFR_OFFSET]
+ ldr r4, [r1, #MDREFR_OFFSET]
+
+ bic r4, r4, #MDREFR_SLFRSH
+ str r4, [r1, #MDREFR_OFFSET]
+ ldr r4, [r1, #MDREFR_OFFSET]
+
+ orr r4, r4, #MDREFR_E1PIN
+ str r4, [r1, #MDREFR_OFFSET]
+ ldr r4, [r1, #MDREFR_OFFSET]
+
+ nop
+ nop
+
+ /* Step 4d: write MDCNFG with MDCNFG:DEx deasserted (set to 0), to */
+ /* configure but not enable each SDRAM partition pair. */
+
+ ldr r4, =CFG_MDCNFG_VAL
+ bic r4, r4, #(MDCNFG_DE0|MDCNFG_DE1)
+ bic r4, r4, #(MDCNFG_DE2|MDCNFG_DE3)
+
+ str r4, [r1, #MDCNFG_OFFSET] /* write back MDCNFG */
+ ldr r4, [r1, #MDCNFG_OFFSET]
+
+
+ /* Step 4e: Wait for the clock to the SDRAMs to stabilize, */
+ /* 100..200 µsec. */
+
+ ldr r3, =OSCR /* reset the OS Timer Count to zero */
+ mov r2, #0
+ str r2, [r3]
+ ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
+ /* so 0x300 should be plenty */
+1:
+ ldr r2, [r3]
+ cmp r4, r2
+ bgt 1b
+
+
+ /* Step 4f: Trigger a number (usually 8) refresh cycles by */
+ /* attempting non-burst read or write accesses to disabled */
+ /* SDRAM, as commonly specified in the power up sequence */
+ /* documented in SDRAM data sheets. The address(es) used */
+ /* for this purpose must not be cacheable. */
+
+ ldr r3, =CFG_DRAM_BASE
+ str r2, [r3]
+ str r2, [r3]
+ str r2, [r3]
+ str r2, [r3]
+ str r2, [r3]
+ str r2, [r3]
+ str r2, [r3]
+ str r2, [r3]
+
+
+ /* Step 4g: Write MDCNFG with enable bits asserted */
+ /* (MDCNFG:DEx set to 1). */
+
+ ldr r3, [r1, #MDCNFG_OFFSET]
+ mov r4, r3
+ orr r3, r3, #MDCNFG_DE0
+ str r3, [r1, #MDCNFG_OFFSET]
+ mov r0, r3
+
+ /* Step 4h: Write MDMRS. */
+
+ ldr r2, =CFG_MDMRS_VAL
+ str r2, [r1, #MDMRS_OFFSET]
+
+ /* enable APD */
+ ldr r3, [r1, #MDREFR_OFFSET]
+ orr r3, r3, #MDREFR_APD
+ str r3, [r1, #MDREFR_OFFSET]
+
+ /* We are finished with Intel's memory controller initialisation */
+
+@setvoltage:
+@
+@ mov r10, lr
+@ bl initPXAvoltage /* In case the board is rebooting with a */
+@ mov lr, r10 /* low voltage raise it up to a good one. */
+
+wakeup:
+ /* Are we waking from sleep? */
+ ldr r0, =RCSR
+ ldr r1, [r0]
+ and r1, r1, #(RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR)
+ str r1, [r0]
+ teq r1, #RCSR_SMR
+
+ bne initirqs
+
+ ldr r0, =PSSR
+ mov r1, #PSSR_PH
+ str r1, [r0]
+
+ /* if so, resume at PSPR */
+ ldr r0, =PSPR
+ ldr r1, [r0]
+ mov pc, r1
+
+ /* ---------------------------------------------------------------- */
+ /* Disable (mask) all interrupts at interrupt controller */
+ /* ---------------------------------------------------------------- */
+
+initirqs:
+
+ mov r1, #0 /* clear int. level register (IRQ, not FIQ) */
+ ldr r2, =ICLR
+ str r1, [r2]
+
+ ldr r2, =ICMR /* mask all interrupts at the controller */
+ str r1, [r2]
+
+ /* ---------------------------------------------------------------- */
+ /* Clock initialisation */
+ /* ---------------------------------------------------------------- */
+
+initclks:
+
+ /* Disable the peripheral clocks, and set the core clock frequency */
+
+ /* Turn Off on-chip peripheral clocks (except for memory) */
+ /* for re-configuration. */
+ ldr r1, =CKEN
+ ldr r2, =CFG_CKEN
+ str r2, [r1]
+
+ /* ... and write the core clock config register */
+ ldr r2, =CFG_CCCR
+ ldr r1, =CCCR
+ str r2, [r1]
+
+ /* Turn on turbo mode */
+ mrc p14, 0, r2, c6, c0, 0
+ orr r2, r2, #0xB /* Turbo, Fast-Bus, Freq change**/
+ mcr p14, 0, r2, c6, c0, 0
+
+ /* Re-write MDREFR */
+ ldr r1, =MEMC_BASE
+ ldr r2, [r1, #MDREFR_OFFSET]
+ str r2, [r1, #MDREFR_OFFSET]
+#ifdef RTC
+ /* enable the 32Khz oscillator for RTC and PowerManager */
+ ldr r1, =OSCC
+ mov r2, #OSCC_OON
+ str r2, [r1]
+
+ /* NOTE: spin here until OSCC.OOK get set, meaning the PLL */
+ /* has settled. */
+60:
+ /*ldr r2, [r1]
+ ands r2, r2, #1
+ beq 60b*/
+#else
+#error "RTC not defined"
+#endif
+
+ /* Interrupt init: Mask all interrupts */
+ldr r0, =ICMR /* enable no sources */
+ mov r1, #0
+str r1, [r0]
+ /* FIXME */
+
+#ifdef NODEBUG
+ /*Disable software and data breakpoints */
+ mov r0,#0
+ mcr p15,0,r0,c14,c8,0 /* ibcr0 */
+ mcr p15,0,r0,c14,c9,0 /* ibcr1 */
+ mcr p15,0,r0,c14,c4,0 /* dbcon */
+
+ /*Enable all debug functionality */
+ mov r0,#0x80000000
+ mcr p14,0,r0,c10,c0,0 /* dcsr */
+#endif
+
+ /* ---------------------------------------------------------------- */
+ /* End lowlevel_init */
+ /* ---------------------------------------------------------------- */
+
+endlowlevel_init:
+
+ mov pc, lr
diff -purN u-boot-1.3.4/board/colibri/Makefile
u-boot-1.3.4-col/board/colibri/Makefile
--- u-boot-1.3.4/board/colibri/Makefile 1970-01-01 01:00:00.000000000
+0100
+++ u-boot-1.3.4-col/board/colibri/Makefile 2008-09-23
15:13:35.000000000 +0200
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := colibri.o
+SOBJS := lowlevel_init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff -purN u-boot-1.3.4/board/colibri/u-boot.lds
u-boot-1.3.4-col/board/colibri/u-boot.lds
--- u-boot-1.3.4/board/colibri/u-boot.lds 1970-01-01
01:00:00.000000000 +0100
+++ u-boot-1.3.4-col/board/colibri/u-boot.lds 2008-09-23
15:13:35.000000000 +0200
@@ -0,0 +1,56 @@
+/*
+* (C) Copyright 2000
+* Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
+*
+* See file CREDITS for list of people who contributed to this
+* project.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+* MA 02111-1307 USA
+*/
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/pxa/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss) }
+ _end = .;
+}
diff -purN u-boot-1.3.4/include/asm-arm/mach-types.h
u-boot-1.3.4-col/include/asm-arm/mach-types.h
--- u-boot-1.3.4/include/asm-arm/mach-types.h 2008-08-12
16:08:38.000000000 +0200
+++ u-boot-1.3.4-col/include/asm-arm/mach-types.h 2008-09-23
15:13:35.000000000 +0200
@@ -11689,6 +11689,18 @@ extern unsigned int __machine_arch_type;
# define machine_is_ax8004() (0)
#endif
+#ifdef CONFIG_MACH_COLIBRI
+# ifdef machine_arch_type
+# undef machine_arch_type
+# define machine_arch_type __machine_arch_type
+# else
+# define machine_arch_type MACH_TYPE_COLIBRI
+# endif
+# define machine_is_colibri() (machine_arch_type == MACH_TYPE_COLIBRI)
+#else
+# define machine_is_colibri() (0)
+#endif
+
#ifdef CONFIG_MACH_AT91SAM9261EK
# ifdef machine_arch_type
# undef machine_arch_type
diff -purN u-boot-1.3.4/include/configs/colibri.h
u-boot-1.3.4-col/include/configs/colibri.h
--- u-boot-1.3.4/include/configs/colibri.h 1970-01-01
01:00:00.000000000 +0100
+++ u-boot-1.3.4-col/include/configs/colibri.h 2008-09-23
15:13:35.000000000 +0200
@@ -0,0 +1,276 @@
+/*
+ * (c) Copyright 2007
+ * Daniel Mack, caiaq <daniel(a)caiaq.de>
+ *
+ * Configuation settings for the Colibri board.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+/* #define DEBUG 15 */
+#define CONFIG_PXA27X 1 /* This is an PXA27x CPU */
+#define CONFIG_COLIBRI 1 /* on a Colibri Board */
+/* #define CONFIG_MMC 1 */
+#define BOARD_LATE_INIT 1
+
+#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
+
+#define RTC
+
+/*
+ * Size of malloc() pool
+ */
+#define CFG_MALLOC_LEN (CFG_ENV_SECT_SIZE + 128*1024)
+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for
initial data */
+
+/*
+ * Hardware drivers
+ */
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_FFUART 1 /* we use FFUART */
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE 9600
+
+/* #define CONFIG_DOS_PARTITION 1 */
+
+#undef CONFIG_SHOW_BOOT_PROGRESS
+
+#define CONFIG_BOOTDELAY -1
+#define CONFIG_ETHADDR 00:00:00:00:00:00
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_IPADDR 192.168.1.99
+#define CONFIG_SERVERIP 192.168.1.1
+#define CONFIG_BOOTCOMMAND "bootm 80000 || dhcp && bootm"
+#define CONFIG_BOOTARGS "console=ttyS0,9600n8 "\
+ " rw root=/dev/nfs ip=:::::eth0:"
+
+#define CONFIG_EXTRA_ENV_SETTINGS ""
+
+/*
+ * Command line configuration.
+ */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_DFL
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_SDRAM
+/* #define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_DIAG
| CFG_CMD_DHCP | CFG_CMD_SDRAM | CFG_CMD_KGDB) */
+/*#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_DIAG
| CFG_CMD_SDRAM)*/
+
+
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
+/* #define CONFIG_INITRD_TAG 1 */
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb
serial port */
+#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_HUSH_PARSER 1
+#define CFG_PROMPT_HUSH_PS2 "> "
+
+#define CFG_LONGHELP /* undef to save memory */
+#ifdef CFG_HUSH_PARSER
+#define CFG_PROMPT "$ " /* Monitor Command Prompt */
+#else
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#endif
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer
Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size
*/
+#define CFG_DEVICE_NULLDEV 1
+
+#define CFG_MEMTEST_START 0xa0400000 /* memtest works on */
+#define CFG_MEMTEST_END 0xa0800000 /* 4 ... 8 MB in DRAM */
+
+#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
+
+#define CFG_LOAD_ADDR 0xa1000000 /* default load address */
+
+#define CFG_HZ 3686400 /* incrementer freq: 3.6864 MHz */
+#define CFG_CPUSPEED 0x190
+
+ /* valid baudrates */
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define CFG_MMC_BASE 0xF0000000
+
+/*
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE (128*1024) /* regular stack */
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
+#endif
+
+/*
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
+#define PHYS_SDRAM_1 0xa0000000 /* SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */
+#define PHYS_SDRAM_2 0xa4000000 /* SDRAM Bank #2 */
+#define PHYS_SDRAM_2_SIZE 0x00000000 /* 0 MB */
+#define PHYS_SDRAM_3 0xa8000000 /* SDRAM Bank #3 */
+#define PHYS_SDRAM_3_SIZE 0x00000000 /* 0 MB */
+#define PHYS_SDRAM_4 0xac000000 /* SDRAM Bank #4 */
+#define PHYS_SDRAM_4_SIZE 0x00000000 /* 0 MB */
+
+#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
+#define PHYS_FLASH_SIZE 0x02000000 /* 32 MB */
+#define PHYS_FLASH_BANK_SIZE 0x02000000 /* 32 MB Bank */
+#define PHYS_FLASH_SECT_SIZE 0x00040000 /* 256 KB sectors (x2) */
+
+#define CFG_DRAM_BASE 0xa0000000
+#define CFG_DRAM_SIZE 0x04000000
+
+#define CFG_FLASH_BASE PHYS_FLASH_1
+
+/*
+ * DM9000 ethernet chip
+ */
+
+#define CONFIG_DRIVER_DM9000 1
+#define CONFIG_DM9000_BASE 0x08000000 /* CS2 */
+#define DM9000_IO (CONFIG_DM9000_BASE)
+#define DM9000_DATA (CONFIG_DM9000_BASE+4)
+/* #define CONFIG_DM9000_USE_8BIT */
+/* #define CONFIG_DM9000_USE_16BIT */
+#define CONFIG_DM9000_USE_32BIT 1
+
+#define CFG_GPSR3_VAL 0x00000000
+#define CFG_GPSR2_VAL 0x0000c000 /*GPIO78, GPIO79 set -->
78-nCS<2>, 79-nEXT_CS[1]*/
+#define CFG_GPSR1_VAL 0x00020000 /*GPIO49 set --> 49-nPWE-Ethernet*/
+#define CFG_GPSR0_VAL 0x00000000
+
+#define CFG_GPCR3_VAL 0x0
+#define CFG_GPCR2_VAL 0x0
+#define CFG_GPCR1_VAL 0x0
+#define CFG_GPCR0_VAL 0x0
+
+#define CFG_GPDR3_VAL 0x00000000
+#define CFG_GPDR2_VAL 0x0000c000 /*GPIO78, GPIO79 output*/
+#define CFG_GPDR1_VAL 0x00020180 /*GPIO39, GPIO40, GPIO49 output
-->39-FF_TXD, 40-FF_DTR*/
+#define CFG_GPDR0_VAL 0x08000000 /*GPIO27 output --> 27-FF_RTS*/
+
+#define CFG_GAFR3_U_VAL 0x00000000
+#define CFG_GAFR3_L_VAL 0x00000200
+#define CFG_GAFR2_U_VAL 0x00000000
+#define CFG_GAFR2_L_VAL 0xa0000000 /*GPIO78_AF2, GPIO79_AF2 -->
78-nCS<2>, 79-nCS<3>*/
+#define CFG_GAFR1_U_VAL 0x00000008 /*GPIO49_AF2 --> 49- nPWE*/
+#define CFG_GAFR1_L_VAL 0x00029018 /*GPIO33_AF2,
GPIO34_AF1,GPIO38_AF1, GPIO39_AF2, GPIO40_AF2 --> 33-FF_DSR, 34-FF_RXD,
38-FF_RI, 39-FF_TXD, 40-FF_DTR*/
+#define CFG_GAFR0_U_VAL 0x00c00010 /*GPIO18_AF1, GPIO27_AF3 -->
18-RDY, 27-FF_RTS*/
+#define CFG_GAFR0_L_VAL 0x00100000 /*GPIO10_AF1 --> FFDCD*/
+
+#define CFG_PSSR_VAL 0x30
+
+/*
+ * Clock settings
+ */
+#define CFG_CKEN 0x00400240
+/* #define CFG_CCCR 0x02000290 */ /* 520Mhz */
+/* #define CFG_CCCR 0x02000210 */ /* 416 Mhz */
+#define CFG_CCCR 0x00000190 /* 312 MHz */
+
+/*
+ * Memory settings
+ */
+
+#define CFG_MSC0_VAL 0x9ee1c5f2
+#define CFG_MSC1_VAL 0x9ee1f974
+#define CFG_MSC2_VAL 0x9ee19ee1
+#define CFG_MDCNFG_VAL 0x090009c9
+#define CFG_MDREFR_VAL 0x00000031
+#define CFG_MDMRS_VAL 0x00000000
+
+#define CFG_FLYCNFG_VAL 0x00010001
+#define CFG_SXCNFG_VAL 0x40044004
+
+/*
+ * PCMCIA and CF Interfaces
+ */
+#define CFG_MECR_VAL 0x00000002
+#define CFG_MCMEM0_VAL 0x00004204
+#define CFG_MCMEM1_VAL 0x00000000
+#define CFG_MCATT0_VAL 0x00010504
+#define CFG_MCATT1_VAL 0x00000000
+#define CFG_MCIO0_VAL 0x00008407
+#define CFG_MCIO1_VAL 0x00000000
+
+/*
+#undef CONFIG_PXA_PCMCIA
+#undef CONFIG_PXA_IDE
+*/
+
+/*#define CONFIG_PCMCIA_SLOT_A 1 */
+/* just to keep build system happy */
+
+/*
+ * FLASH and environment organization
+ */
+
+#define CFG_FLASH_CFI 1
+#define CFG_FLASH_CFI_DRIVER 1
+#define CFG_FLASH_CFI_WIDTH FLASH_CFI_32BIT
+#define CFG_FLASH_USE_BUFFER_WRITE 1
+#define CFG_FLASH_PROTECTION 1
+
+
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+/*#define CFG_MONITOR_LEN 0x20000
+*/
+#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip
*/
+
+/* timeout values are in ticks */
+#define CFG_FLASH_ERASE_TOUT (25*CFG_HZ) /* Timeout for Flash Erase */
+#define CFG_FLASH_WRITE_TOUT (25*CFG_HZ) /* Timeout for Flash Write */
+
+
+/* Flash environment locations */
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_FIX_PARAM_SIZE 256
+#define CFG_ENV_ADDR (PHYS_FLASH_1 + PHYS_FLASH_SECT_SIZE)/*
Addr of Environment Sector */
+#define CFG_ENV_SIZE (PHYS_FLASH_SECT_SIZE - CFG_FIX_PARAM_SIZE)
/* Total Size of Environment */
+#define CFG_ENV_SECT_SIZE PHYS_FLASH_SECT_SIZE /* Total Size of
Environment Sector */
+
+#endif /* __CONFIG_H */
diff -purN u-boot-1.3.4/MAKEALL u-boot-1.3.4-col/MAKEALL
--- u-boot-1.3.4/MAKEALL 2008-08-12 16:08:38.000000000 +0200
+++ u-boot-1.3.4-col/MAKEALL 2008-09-23 15:13:35.000000000 +0200
@@ -541,6 +541,7 @@ LIST_at91=" \
LIST_pxa=" \
cerf250 \
+ colibri \
cradle \
csb226 \
delta \
diff -purN u-boot-1.3.4/Makefile u-boot-1.3.4-col/Makefile
--- u-boot-1.3.4/Makefile 2008-08-12 16:08:38.000000000 +0200
+++ u-boot-1.3.4-col/Makefile 2008-09-23 15:13:35.000000000 +0200
@@ -2597,6 +2597,9 @@ actux4_config : unconfig
cerf250_config : unconfig
@$(MKCONFIG) $(@:_config=) arm pxa cerf250
+colibri_config : unconfig
+ @$(MKCONFIG) $(@:_config=) arm pxa colibri
+
cradle_config : unconfig
@$(MKCONFIG) $(@:_config=) arm pxa cradle
2
1
Hi All,
This patch adds support for Samsung Flex-OneNAND devices.
Flex-OneNAND combines SLC and MLC technologies into a single
device. SLC area provides increased reliability and speed, suitable
for storing code and data, such as bootloader, kernel
and root file system. MLC area provides high density and is best used
for storing user data. Users can configure the size of SLC and MLC
regions through 'onenand setboundary' command.
Signed-off-by: Rohit Hagargundgi <h.rohit(a)samsung.com>
---
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
index 8d87b78..7260017 100644
--- a/common/cmd_onenand.c
+++ b/common/cmd_onenand.c
@@ -20,9 +20,64 @@
extern struct mtd_info onenand_mtd;
extern struct onenand_chip onenand_chip;
+loff_t flexonenand_get_addr(int block)
+{
+ struct mtd_info *mtd = &onenand_mtd;
+ struct onenand_chip *this = mtd->priv;
+ loff_t ofs;
+ int die = 0, boundary;
+
+ ofs = 0;
+ if (this->dies == 2 && block >= this->density_mask) {
+ block -= this->density_mask;
+ die = 1;
+ ofs = this->diesize[0];
+ }
+ boundary = this->boundary[die];
+ ofs += block << (this->erase_shift - 1);
+ if (block > (boundary + 1))
+ ofs += (block - boundary - 1) << (this->erase_shift - 1);
+ return ofs;
+}
+
+static int do_erase(ulong start, ulong end)
+{
+ struct mtd_info *mtd = &onenand_mtd;
+ struct onenand_chip *this = mtd->priv;
+ struct erase_info instr = {
+ .callback = NULL,
+ };
+ int i, ret;
+ ulong block;
+
+ printf("Erase block from %lu to %lu\n", start, end);
+
+ for (block = start; block <= end; block++) {
+ if (FLEXONENAND(this))
+ instr.addr = flexonenand_get_addr(block);
+ else
+ instr.addr = block << onenand_chip.erase_shift;
+
+ if (FLEXONENAND(this) && (mtd->numeraseregions > 1)) {
+ for (i = 0; i < mtd->numeraseregions &&
+ mtd->eraseregions[i].offset <= instr.addr;
i++)
+ ;
+ i--;
+ instr.len =
+ mtd->eraseregions[i].erasesize;
+ } else
+ instr.len = mtd->erasesize;
+ ret = onenand_erase(&onenand_mtd, &instr);
+ if (ret)
+ printf("erase failed %lu\n", block);
+ }
+ return 0;
+}
int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
+ struct mtd_info *mtd = &onenand_mtd;
+ struct onenand_chip *this = mtd->priv;
int ret = 0;
switch (argc) {
@@ -42,11 +97,7 @@
default:
/* At least 4 args */
if (strncmp(argv[1], "erase", 5) == 0) {
- struct erase_info instr = {
- .callback = NULL,
- };
ulong start, end;
- ulong block;
char *endtail;
if (strncmp(argv[2], "block", 5) == 0) {
@@ -57,28 +108,18 @@
start = simple_strtoul(argv[2], NULL, 10);
end = simple_strtoul(argv[3], NULL, 10);
- start >>= onenand_chip.erase_shift;
- end >>= onenand_chip.erase_shift;
+ start = onenand_get_block(&onenand_mtd,
+ start, NULL);
+ end = onenand_get_block(&onenand_mtd,
+ end, NULL);
/* Don't include the end block */
- end--;
+ if (end > 0)
+ end--;
}
if (!end || end < 0)
end = start;
-
- printf("Erase block from %lu to %lu\n", start, end);
-
- for (block = start; block <= end; block++) {
- instr.addr = block <<
onenand_chip.erase_shift;
- instr.len = 1 << onenand_chip.erase_shift;
- ret = onenand_erase(&onenand_mtd, &instr);
- if (ret) {
- printf("erase failed %lu\n", block);
- break;
- }
- }
-
- return 0;
+ return do_erase(start, end);
}
if (strncmp(argv[1], "read", 4) == 0) {
@@ -134,15 +175,18 @@
ops.mode = MTD_OOB_PLACE;
- ofs = block << onenand_chip.erase_shift;
+ if (FLEXONENAND(this))
+ ofs = flexonenand_get_addr(block);
+ else
+ ofs = block << onenand_chip.erase_shift;
if (page)
ofs += page << onenand_chip.page_shift;
if (!len) {
if (oob)
- ops.ooblen = 64;
+ ops.ooblen = FLEXONENAND(this) ? 128
: 64;
else
- ops.len = 512;
+ ops.len = FLEXONENAND(this) ? 4096 :
512;
}
if (oob) {
@@ -158,6 +202,39 @@
return 0;
}
+ if (strncmp(argv[1], "setboundary", 11) == 0) {
+ unsigned die = simple_strtoul(argv[2], NULL, 0);
+ unsigned bdry = simple_strtoul(argv[3], NULL, 0);
+ int lock = 0, old;
+
+ if (!FLEXONENAND(this)) {
+ printf("Flex-OneNAND not found.\n");
+ return -1;
+ }
+
+ if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0)
+ lock = 1;
+
+ if (die >= this->dies) {
+ printf("Invalid die index\n");
+ return -1;
+ }
+
+ if (!(bdry % 2)) {
+ printf("Attempt to set even boundary
value.\n");
+ bdry += 1;
+ printf("Setting boundary to %d\n", bdry);
+ }
+
+ old = this->boundary[die] + (die *
this->density_mask);
+ ret = flexonenand_set_boundary(mtd, die, bdry,
lock);
+ if (!ret) {
+ int new = this->boundary[die] +
+ (die * this->density_mask);
+ do_erase(min(old, new) + 1, max(old, new));
+ }
+ return 0;
+ }
break;
}
@@ -172,5 +249,7 @@
"onenand write addr ofs len - write data at ofs with len from
addr\n"
"onenand erase saddr eaddr - erase block start addr to end addr\n"
"onenand block[.oob] addr block [page] [len] - "
- "read data with (block [, page]) to addr"
+ "read data with (block [, page]) to addr\n"
+ "onenand setboundary DIE BOUNDARY [LOCK] - "
+ "Change SLC boundary of Flex-OneNAND"
);
diff --git a/common/env_onenand.c b/common/env_onenand.c
--- a/common/env_onenand.c
+++ b/common/env_onenand.c
@@ -58,11 +58,14 @@
void env_relocate_spec(void)
{
+ struct onenand_chip *this = &onenand_chip;
unsigned long env_addr;
int use_default = 0;
size_t retlen;
env_addr = CONFIG_ENV_ADDR;
+ if (FLEXONENAND(this))
+ env_addr = CONFIG_ENV_ADDR_FLEX;
/* Check OneNAND exist */
if (onenand_mtd.writesize)
@@ -89,6 +92,7 @@
int saveenv(void)
{
+ struct onenand_chip *this = &onenand_chip;
unsigned long env_addr = CONFIG_ENV_ADDR;
struct erase_info instr = {
.callback = NULL,
@@ -96,6 +100,12 @@
size_t retlen;
instr.len = CONFIG_ENV_SIZE;
+ if (FLEXONENAND(this)) {
+ env_addr = CONFIG_ENV_ADDR_FLEX;
+ instr.len = CONFIG_ENV_SIZE_FLEX;
+ instr.len <<= onenand_mtd.eraseregions[0].numblocks == 1 ?
+ 1 : 0;
+ }
instr.addr = env_addr;
if (onenand_erase(&onenand_mtd, &instr)) {
printf("OneNAND: erase failed at 0x%08lx\n", env_addr);
diff --git a/drivers/mtd/onenand/onenand_base.c
b/drivers/mtd/onenand/onenand_base.c
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -45,6 +45,14 @@
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 80 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 96 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 112 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 128 */
};
/**
@@ -83,9 +91,11 @@
if (device & ONENAND_DEVICE_IS_DDP) {
/* Device Flash Core select, NAND Flash Block Address */
int dfs = 0, density, mask;
+ int flex = device & DEVICE_IS_FLEXONENAND;
density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
- mask = (1 << (density + 6));
+ density &= ONENAND_DEVICE_DENSITY_MASK;
+ mask = (1 << (density + (flex ? 4 : 6)));
if (block & mask)
dfs = 1;
@@ -109,9 +119,11 @@
if (device & ONENAND_DEVICE_IS_DDP) {
/* Device BufferRAM Select */
int dbs = 0, density, mask;
+ int flex = device & DEVICE_IS_FLEXONENAND;
density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
- mask = (1 << (density + 6));
+ density &= ONENAND_DEVICE_DENSITY_MASK;
+ mask = (1 << (density + (flex ? 4 : 6)));
if (block & mask)
dbs = 1;
@@ -168,6 +180,41 @@
return ((bsa << ONENAND_BSA_SHIFT) | bsc);
}
+unsigned onenand_get_block(struct mtd_info *mtd, loff_t addr,
+ unsigned *isblkslc)
+{
+ struct onenand_chip *this = mtd->priv;
+ unsigned boundary, blk, die = 0;
+
+ if (!FLEXONENAND(this))
+ return addr >> this->erase_shift;
+
+ if (this->chipsize == 0) {
+ /* We have been called by read_boundary
+ * addr contains die index in this case
+ */
+ blk = addr * this->density_mask;
+ return blk;
+ }
+
+ if (addr >= this->diesize[0]) {
+ die = 1;
+ addr -= this->diesize[0];
+ }
+
+ boundary = this->boundary[die];
+
+ blk = addr >> (this->erase_shift - 1);
+ if (blk > boundary)
+ blk = (blk + boundary + 1) >> 1;
+
+ if (isblkslc)
+ *isblkslc = (blk <= boundary) ? 1 : 0;
+
+ blk += die ? this->density_mask : 0;
+ return blk;
+}
+
/**
* onenand_command - [DEFAULT] Send command to OneNAND device
* @param mtd MTD device structure
@@ -182,30 +229,36 @@
size_t len)
{
struct onenand_chip *this = mtd->priv;
- int value, readcmd = 0;
+ int value;
int block, page;
+ unsigned slc = 0;
+
/* Now we use page size operation */
- int sectors = 4, count = 4;
+ int sectors = 0, count = 0;
/* Address translation */
switch (cmd) {
case ONENAND_CMD_UNLOCK:
+ case ONENAND_CMD_UNLOCK_ALL:
case ONENAND_CMD_LOCK:
case ONENAND_CMD_LOCK_TIGHT:
block = -1;
page = -1;
break;
+ case FLEXONENAND_CMD_PI_ACCESS:
case ONENAND_CMD_ERASE:
case ONENAND_CMD_BUFFERRAM:
- block = (int)(addr >> this->erase_shift);
+ block = onenand_get_block(mtd, addr, NULL);
page = -1;
break;
default:
- block = (int)(addr >> this->erase_shift);
+ block = onenand_get_block(mtd, addr, &slc);
page = (int)(addr >> this->page_shift);
page &= this->page_mask;
+ if (FLEXONENAND(this) && slc)
+ page &= (this->page_mask >> 1);
break;
}
@@ -216,8 +269,11 @@
this->write_word(value,
this->base + ONENAND_REG_START_ADDRESS2);
- /* Switch to the next data buffer */
- ONENAND_SET_NEXT_BUFFERRAM(this);
+ if (ONENAND_IS_MLC(this))
+ ONENAND_SET_BUFFERRAM0(this);
+ else
+ /* Switch to the next data buffer */
+ ONENAND_SET_NEXT_BUFFERRAM(this);
return 0;
}
@@ -227,6 +283,10 @@
value = onenand_block_address(this->device_id, block);
this->write_word(value,
this->base + ONENAND_REG_START_ADDRESS1);
+ /* Select DataRAM for DDP */
+ value = onenand_bufferram_address(this->device_id, block);
+ this->write_word(value,
+ this->base + ONENAND_REG_START_ADDRESS2);
}
if (page != -1) {
@@ -235,8 +295,11 @@
switch (cmd) {
case ONENAND_CMD_READ:
case ONENAND_CMD_READOOB:
- dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
- readcmd = 1;
+ if (ONENAND_IS_MLC(this))
+ dataram = ONENAND_SET_BUFFERRAM0(this);
+ else
+ /* Switch to the next data buffer */
+ dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
break;
default:
@@ -253,14 +316,6 @@
value = onenand_buffer_address(dataram, sectors, count);
this->write_word(value, this->base +
ONENAND_REG_START_BUFFER);
- if (readcmd) {
- /* Select DataRAM for DDP */
- value =
- onenand_bufferram_address(this->device_id,
block);
- this->write_word(value,
- this->base +
- ONENAND_REG_START_ADDRESS2);
- }
}
/* Interrupt clear */
@@ -272,6 +327,29 @@
}
/**
+ * onenand_get_ecc - return ecc status
+ * @param mtd MTD device structure
+ */
+int onenand_get_ecc(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ int ecc[4];
+ int i, result = 0;
+
+ for (i = 0; i < 4; i++) {
+ ecc[i] = this->read_word(this->base + ((0xFF00 + i) << 1));
+ if (!FLEXONENAND(this))
+ return ecc[i];
+ if (ecc[i] & FLEXONENAND_UNCORRECTABLE_ERROR) {
+ result = ONENAND_ECC_2BIT_ALL;
+ break;
+ }
+ }
+
+ return result;
+}
+
+/**
* onenand_wait - [DEFAULT] wait until the command is done
* @param mtd MTD device structure
* @param state state to select the max. timeout value
@@ -295,6 +373,15 @@
ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
+ if (interrupt & ONENAND_INT_READ) {
+ ecc = onenand_get_ecc(mtd);
+ if (ecc & ONENAND_ECC_2BIT_ALL) {
+ MTDDEBUG(MTD_DEBUG_LEVEL0,
+ "onenand_wait: ECC error = 0x%04x\n",
ecc);
+ return -EBADMSG;
+ }
+ }
+
if (ctrl & ONENAND_CTRL_ERROR) {
MTDDEBUG (MTD_DEBUG_LEVEL0,
"onenand_wait: controller error = 0x%04x\n",
ctrl);
@@ -307,15 +394,6 @@
return -EIO;
}
- if (interrupt & ONENAND_INT_READ) {
- ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
- if (ecc & ONENAND_ECC_2BIT_ALL) {
- MTDDEBUG (MTD_DEBUG_LEVEL0,
- "onenand_wait: ECC error = 0x%04x\n",
ecc);
- return -EBADMSG;
- }
- }
-
return 0;
}
@@ -433,10 +511,13 @@
struct onenand_chip *this = mtd->priv;
int block, page;
int i;
+ unsigned slc = 0;
- block = (int)(addr >> this->erase_shift);
+ block = onenand_get_block(mtd, addr, &slc);
page = (int)(addr >> this->page_shift);
page &= this->page_mask;
+ if (FLEXONENAND(this) && slc)
+ page &= (this->page_mask >> 1);
i = ONENAND_CURRENT_BUFFERRAM(this);
@@ -462,10 +543,13 @@
struct onenand_chip *this = mtd->priv;
int block, page;
int i;
+ unsigned slc = 0;
- block = (int)(addr >> this->erase_shift);
+ block = onenand_get_block(mtd, addr, &slc);
page = (int)(addr >> this->page_shift);
page &= this->page_mask;
+ if (FLEXONENAND(this) && slc)
+ page &= (this->page_mask >> 1);
/* Invalidate BufferRAM */
for (i = 0; i < MAX_BUFFERRAM; i++) {
@@ -573,6 +657,39 @@
}
/**
+ * onenand_recover_lsb - [Flex-OneNAND] Recover LSB page data
+ * @param mtd MTD device structure
+ * @param addr address to recover
+ * @param status return value from onenand_wait
+ *
+ * Issue recovery command when read fails on MLC area.
+ */
+static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int
status)
+{
+ struct onenand_chip *this = mtd->priv;
+ unsigned slc = 0;
+
+ /* check if we failed due to uncorrectable error */
+ if (status != (-EBADMSG) && status != (ONENAND_BBT_READ_ECC_ERROR))
+ return status;
+
+ /* check if address lies in MLC region */
+ onenand_get_block(mtd, addr, &slc);
+ if (slc)
+ return status;
+
+ /* We are attempting to reread, so decrement stats.failed
+ * which was incremented by onenand_wait due to read failure
+ */
+ printk(KERN_DEBUG "Attempting to recover from uncorrectable
read\n");
+ mtd->ecc_stats.failed--;
+
+ /* Issue the LSB page recovery command */
+ this->command(mtd, FLEXONENAND_CMD_RECOVER_LSB, addr,
this->writesize);
+ return this->wait(mtd, FL_READING);
+}
+
+/**
* onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or
out-of-band
* @param mtd MTD device structure
* @param from offset to read from
@@ -616,12 +733,15 @@
stats = mtd->ecc_stats;
/* Read-while-load method */
+ /* Note: We can't use this feature in MLC */
/* Do first load to bufferRAM */
if (read < len) {
if (!onenand_check_bufferram(mtd, from)) {
this->command(mtd, ONENAND_CMD_READ, from,
writesize);
ret = this->wait(mtd, FL_READING);
+ ret = (FLEXONENAND(this) && ret) ?
+ onenand_recover_lsb(mtd, from, ret) : ret;
onenand_update_bufferram(mtd, from, !ret);
if (ret == -EBADMSG)
ret = 0;
@@ -636,7 +756,7 @@
while (!ret) {
/* If there is more to load then start next load */
from += thislen;
- if (read + thislen < len) {
+ if (!ONENAND_IS_MLC(this) && read + thislen < len) {
this->command(mtd, ONENAND_CMD_READ, from,
writesize);
/*
* Chip boundary handling in DDP
@@ -669,6 +789,16 @@
oobcolumn = 0;
}
+ if (ONENAND_IS_MLC(this) && (read + thislen < len)) {
+ this->command(mtd, ONENAND_CMD_READ, from,
writesize);
+ ret = this->wait(mtd, FL_READING);
+ ret = (FLEXONENAND(this) && ret) ?
+ onenand_recover_lsb(mtd, from, ret) : ret;
+ onenand_update_bufferram(mtd, from, !ret);
+ if (ret == -EBADMSG)
+ ret = 0;
+ }
+
/* See if we are done */
read += thislen;
if (read == len)
@@ -676,16 +806,19 @@
/* Set up for next read from bufferRAM */
if (unlikely(boundary))
this->write_word(ONENAND_DDP_CHIP1, this->base +
ONENAND_REG_START_ADDRESS2);
- ONENAND_SET_NEXT_BUFFERRAM(this);
+ if (!ONENAND_IS_MLC(this))
+ ONENAND_SET_NEXT_BUFFERRAM(this);
buf += thislen;
thislen = min_t(int, writesize, len - read);
column = 0;
- /* Now wait for load */
- ret = this->wait(mtd, FL_READING);
- onenand_update_bufferram(mtd, from, !ret);
- if (ret == -EBADMSG)
- ret = 0;
+ if (!ONENAND_IS_MLC(this)) {
+ /* Now wait for load */
+ ret = this->wait(mtd, FL_READING);
+ onenand_update_bufferram(mtd, from, !ret);
+ if (ret == -EBADMSG)
+ ret = 0;
+ }
}
/*
@@ -722,7 +855,7 @@
size_t len = ops->ooblen;
mtd_oob_mode_t mode = ops->mode;
u_char *buf = ops->oobbuf;
- int ret = 0;
+ int ret = 0, readcmd;
from += ops->ooboffs;
@@ -755,15 +888,19 @@
stats = mtd->ecc_stats;
+ readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ :
ONENAND_CMD_READOOB;
+
while (read < len) {
thislen = oobsize - column;
thislen = min_t(int, thislen, len);
- this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
+ this->command(mtd, readcmd, from, mtd->oobsize);
onenand_update_bufferram(mtd, from, 0);
ret = this->wait(mtd, FL_READING);
+ ret = (FLEXONENAND(this) && ret) ?
+ onenand_recover_lsb(mtd, from, ret) : ret;
if (ret && ret != -EBADMSG) {
printk(KERN_ERR "onenand_read_oob_nolock: read
failed = 0x%x\n", ret);
break;
@@ -886,22 +1023,26 @@
interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
- /* Initial bad block case: 0x2400 or 0x0400 */
- if (ctrl & ONENAND_CTRL_ERROR) {
- printk(KERN_DEBUG "onenand_bbt_wait: controller error =
0x%04x\n", ctrl);
- return ONENAND_BBT_READ_ERROR;
- }
-
if (interrupt & ONENAND_INT_READ) {
- int ecc = this->read_word(this->base +
ONENAND_REG_ECC_STATUS);
- if (ecc & ONENAND_ECC_2BIT_ALL)
+ int ecc = onenand_get_ecc(mtd);
+ if (ecc & ONENAND_ECC_2BIT_ALL) {
+ printk(KERN_INFO "onenand_bbt_wait: ecc error =
0x%04x"
+ ", controller = 0x%04x\n", ecc, ctrl);
return ONENAND_BBT_READ_ERROR;
+ }
} else {
printk(KERN_ERR "onenand_bbt_wait: read timeout!"
"ctrl=0x%04x intr=0x%04x\n", ctrl,
interrupt);
return ONENAND_BBT_READ_FATAL_ERROR;
}
+ /* Initial bad block case: 0x2400 or 0x0400 */
+ if (ctrl & ONENAND_CTRL_ERROR) {
+ printk(KERN_DEBUG "onenand_bbt_wait: controller error"
+ " = 0x%04x\n", ctrl);
+ return ONENAND_BBT_READ_ERROR;
+ }
+
return 0;
}
@@ -918,7 +1059,7 @@
{
struct onenand_chip *this = mtd->priv;
int read = 0, thislen, column;
- int ret = 0;
+ int ret = 0, readcmd;
size_t len = ops->ooblen;
u_char *buf = ops->oobbuf;
@@ -926,6 +1067,8 @@
"onenand_bbt_read_oob: from = 0x%08x, len = %zi\n",
(unsigned int) from, len);
+ readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ :
ONENAND_CMD_READOOB;
+
/* Initialize return value */
ops->oobretlen = 0;
@@ -945,7 +1088,7 @@
thislen = mtd->oobsize - column;
thislen = min_t(int, thislen, len);
- this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
+ this->command(mtd, readcmd, from, mtd->oobsize);
onenand_update_bufferram(mtd, from, 0);
@@ -987,9 +1130,11 @@
{
struct onenand_chip *this = mtd->priv;
u_char *oob_buf = this->oob_buf;
- int status, i;
+ int status, i, readcmd;
+
+ readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ :
ONENAND_CMD_READOOB;
- this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize);
+ this->command(mtd, readcmd, to, mtd->oobsize);
onenand_update_bufferram(mtd, to, 0);
status = this->wait(mtd, FL_READING);
if (status)
@@ -1236,7 +1381,7 @@
{
struct onenand_chip *this = mtd->priv;
int column, ret = 0, oobsize;
- int written = 0;
+ int written = 0, oobcmd;
u_char *oobbuf;
size_t len = ops->ooblen;
const u_char *buf = ops->oobbuf;
@@ -1280,6 +1425,8 @@
oobbuf = this->oob_buf;
+ oobcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_PROG :
ONENAND_CMD_PROGOOB;
+
/* Loop until all data write */
while (written < len) {
int thislen = min_t(int, oobsize, len - written);
@@ -1295,7 +1442,14 @@
memcpy(oobbuf + column, buf, thislen);
this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0,
mtd->oobsize);
- this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
+ if (ONENAND_IS_MLC(this)) {
+ /* Set main area of DataRAM to 0xff*/
+ memset(this->page_buf, 0xff, mtd->writesize);
+ this->write_bufferram(mtd, ONENAND_DATARAM,
+ this->page_buf, 0, mtd->writesize);
+ }
+
+ this->command(mtd, oobcmd, to, mtd->oobsize);
onenand_update_bufferram(mtd, to, 0);
if (ONENAND_IS_2PLANE(this)) {
@@ -1424,19 +1578,30 @@
unsigned int block_size;
loff_t addr;
int len;
- int ret = 0;
+ int ret = 0, i = 0;
MTDDEBUG (MTD_DEBUG_LEVEL3,
"onenand_erase: start = 0x%08x, len = %i\n",
(unsigned int)instr->addr, (unsigned int)ins tr->len);
- block_size = (1 << this->erase_shift);
+ if (FLEXONENAND(this) && (mtd->numeraseregions > 1)) {
+ for (; i < mtd->numeraseregions &&
+ instr->addr >= mtd->eraseregions[i].offset; i++)
+ ;
+ i--;
+ block_size = mtd->eraseregions[i].erasesize;
+ } else
+ block_size = mtd->erasesize;
/* Start address must align on block boundary */
if (unlikely(instr->addr & (block_size - 1))) {
- MTDDEBUG (MTD_DEBUG_LEVEL0,
- "onenand_erase: Unaligned address\n");
- return -EINVAL;
+ /* We come here if boundary is even value. Just skip for
now.*/
+ if (!FLEXONENAND(this) ||
+ (instr->addr & ((block_size >> 1) - 1))) {
+ MTDDEBUG(MTD_DEBUG_LEVEL0, "onenand_erase:"
+ " Unaligned address\n");
+ return -EINVAL;
+ }
}
/* Length must align on block boundary */
@@ -1466,7 +1631,13 @@
while (len) {
- /* TODO Check badblock */
+ /* Check if we have a bad block, we do not erase bad blocks
*/
+ if (onenand_block_isbad_nolock(mtd, addr, 0)) {
+ printk(KERN_WARNING "onenand_erase: attempt to
erase"
+ "bad block at addr 0x%08x\n", (unsigned int)
addr);
+ instr->state = MTD_ERASE_FAILED;
+ goto erase_exit;
+ }
this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
@@ -1481,7 +1652,7 @@
else
MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_erase:
"
"Failed erase, block %d\n",
- (unsigned)(addr >>
this->erase_shift));
+ onenand_get_block(mtd, addr, NULL));
instr->state = MTD_ERASE_FAILED;
instr->fail_addr = addr;
goto erase_exit;
@@ -1489,6 +1660,12 @@
len -= block_size;
addr += block_size;
+ if (FLEXONENAND(this) && (mtd->numeraseregions > 1)) {
+ if ((i < (mtd->numeraseregions - 1)) &&
+ (addr == mtd->eraseregions[i + 1].offset))
+ i++;
+ block_size = mtd->eraseregions[i].erasesize;
+ }
}
instr->state = MTD_ERASE_DONE;
@@ -1539,7 +1716,7 @@
return -EINVAL;
onenand_get_device(mtd, FL_READING);
- ret = onenand_block_isbad_nolock(mtd,ofs, 0);
+ ret = onenand_block_isbad_nolock(mtd, ofs, 0);
onenand_release_device(mtd);
return ret;
}
@@ -1581,8 +1758,8 @@
struct onenand_chip *this = mtd->priv;
int start, end, block, value, status;
- start = ofs >> this->erase_shift;
- end = len >> this->erase_shift;
+ start = onenand_get_block(mtd, ofs, NULL);
+ end = onenand_get_block(mtd, ofs + len, NULL) - 1;
/* Continuous lock scheme */
if (this->options & ONENAND_CONT_LOCK) {
@@ -1590,7 +1767,7 @@
this->write_word(start,
this->base +
ONENAND_REG_START_BLOCK_ADDRESS);
/* Set end block address */
- this->write_word(end - 1,
+ this->write_word(end,
this->base +
ONENAND_REG_END_BLOCK_ADDRESS);
/* Write unlock command */
this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
@@ -1612,12 +1789,23 @@
}
/* Block lock scheme */
- for (block = start; block < end; block++) {
+ for (block = start; block < end + 1; block++) {
+ /* Set block address */
+ value = onenand_block_address(this->device_id, block);
+ this->write_word(value,
+ this->base + ONENAND_REG_START_ADDRESS1);
+ /* Select DataRAM for DDP */
+ value = onenand_bufferram_address(this->device_id, block);
+ this->write_word(value,
+ this->base + ONENAND_REG_START_ADDRESS2);
/* Set start block address */
this->write_word(block,
this->base +
ONENAND_REG_START_BLOCK_ADDRESS);
/* Write unlock command */
- this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
+ if (FLEXONENAND(this))
+ this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
+ else
+ this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
/* There's no return value */
this->wait(mtd, FL_UNLOCKING);
@@ -1643,6 +1831,25 @@
}
/**
+ * flexonenand_unlock_all - [FlexOneNAND Interface] unlock all blocks
+ * @param mtd MTD device structure
+ *
+ * Unlock all blocks
+ */
+static int flexonenand_unlock_all(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ size_t len = mtd->erasesize;
+
+ if (mtd->numeraseregions > 1)
+ len >>= 1;
+ onenand_unlock(mtd, 0, len);
+ if (this->device_id & ONENAND_DEVICE_IS_DDP)
+ onenand_unlock(mtd, this->diesize[0], len);
+ return 0;
+}
+
+/**
* onenand_print_device_info - Print device ID
* @param device device ID
*
@@ -1650,15 +1857,18 @@
*/
char * onenand_print_device_info(int device)
{
- int vcc, demuxed, ddp, density;
+ int vcc, demuxed, ddp, density, flexonenand;
char *dev_info = malloc(80);
vcc = device & ONENAND_DEVICE_VCC_MASK;
demuxed = device & ONENAND_DEVICE_IS_DEMUX;
ddp = device & ONENAND_DEVICE_IS_DDP;
density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
- sprintf(dev_info, "%sOneNAND%s %dMB %sV 16-bit (0x%02x)",
- demuxed ? "" : "Muxed ",
+ density &= ONENAND_DEVICE_DENSITY_MASK;
+ flexonenand = device & DEVICE_IS_FLEXONENAND;
+ sprintf(dev_info, "%s%sOneNAND%s %dMB %sV 16-bit (0x%02x)",
+ flexonenand ? "Flex-" : "",
+ demuxed ? "" : "Mux",
ddp ? "(DDP)" : "",
(16 << density), vcc ? "2.65/3.3" : "1.8", device);
@@ -1694,6 +1904,174 @@
}
/**
+* flexonenand_get_boundary - Reads the SLC boundary
+* @param onenand_info onenand info structure
+**/
+static int flexonenand_get_boundary(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ unsigned die, bdry;
+ int ret, syscfg, unlocked;
+
+ /* Disable ECC */
+ syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
+ this->write_word((syscfg | 0x0100), this->base +
ONENAND_REG_SYS_CFG1);
+
+ for (die = 0; die < this->dies; die++) {
+ this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
+ this->wait(mtd, FL_SYNCING);
+
+ this->command(mtd, ONENAND_CMD_READ, die, 0);
+ ret = this->wait(mtd, FL_READING);
+
+ bdry = this->read_word(this->base + ONENAND_DATARAM);
+ unlocked = bdry >> FLEXONENAND_PI_UNLOCK_SHIFT;
+ unlocked = (unlocked == 0x3) ? 1 : 0;
+ this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
+
+ this->command(mtd, ONENAND_CMD_RESET, 0, 0);
+ ret = this->wait(mtd, FL_RESETING);
+
+ printk(KERN_INFO "Die %d boundary: %d%s\n", die,
+ this->boundary[die],
+ unlocked ? "(Unlocked)" : "(Locked)");
+ }
+
+ /* Enable ECC */
+ this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
+ return 0;
+}
+
+/**
+ * get_flexonenand_size - Fill up fields in onenand_chip
+ * boundary[], diesize[], chipsize
+ * @param mtd - MTD device structure
+ */
+void get_flexonenand_size(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ int die, ofs, i, eraseshift;
+ unsigned blksperdie = 1024;
+ unsigned maxbdry = blksperdie - 1;
+
+ eraseshift = this->erase_shift - 1;
+
+ this->chipsize = 0;
+ mtd->numeraseregions = this->dies << 1;
+
+ /* This fills up the device boundary */
+ flexonenand_get_boundary(mtd);
+ die = ofs = 0;
+ i = -1;
+ for (; die < this->dies; die++) {
+ if (!die || this->boundary[die-1] != maxbdry) {
+ i++;
+ mtd->eraseregions[i].offset = ofs;
+ mtd->eraseregions[i].erasesize = 1 << eraseshift;
+ mtd->eraseregions[i].numblocks = this->boundary[die]
+ 1;
+ ofs += mtd->eraseregions[i].numblocks << eraseshift;
+ eraseshift++;
+ } else {
+ mtd->numeraseregions -= 1;
+ mtd->eraseregions[i].numblocks +=
this->boundary[die] + 1;
+ ofs += (this->boundary[die] + 1) << (eraseshift -
1);
+ }
+ if (this->boundary[die] != maxbdry) {
+ i++;
+ mtd->eraseregions[i].offset = ofs;
+ mtd->eraseregions[i].erasesize = 1 << eraseshift;
+ mtd->eraseregions[i].numblocks =
+ maxbdry ^ this->boundary[die];
+ ofs += mtd->eraseregions[i].numblocks << eraseshift;
+ eraseshift--;
+ } else
+ mtd->numeraseregions -= 1;
+ }
+
+ mtd->erasesize = 1 << (this->erase_shift);
+ if (mtd->numeraseregions == 1)
+ mtd->erasesize >>= 1;
+
+ printk(KERN_INFO "Device has %d eraseregions\n",
mtd->numeraseregions);
+ for (i = 0; i < mtd->numeraseregions; i++)
+ printk(KERN_INFO "[offset: 0x%08x, erasesize: 0x%05x,"
+ " numblocks: %04u]\n", mtd->eraseregions[i].offset,
+ mtd->eraseregions[i].erasesize,
+ mtd->eraseregions[i].numblocks);
+
+ eraseshift = this->erase_shift;
+ for (die = 0, mtd->size = 0; die < this->dies; die++) {
+ this->diesize[die] = (blksperdie << eraseshift);
+ this->diesize[die] -= (this->boundary[die] + 1)
+ << (eraseshift - 1);
+ mtd->size += this->diesize[die];
+ }
+ /* this->chipsize represents maximum possible chip size */
+ this->chipsize = (blksperdie << eraseshift) << (this->dies - 1);
+}
+
+/**
+* flexonenand_set_boundary - Writes the SLC boundary
+* @param onenand_info onenand info structure
+**/
+int flexonenand_set_boundary(struct mtd_info *mtd, unsigned die,
+ int boundary, int lock)
+{
+ struct onenand_chip *this = mtd->priv;
+ int ret, density, blksperdie;
+ unsigned addr;
+
+ density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
+ density &= ONENAND_DEVICE_DENSITY_MASK;
+
+ blksperdie = ((16 << density) << 20) >> this->erase_shift;
+ blksperdie >>= (this->device_id & ONENAND_DEVICE_IS_DDP) ? 1 : 0;
+
+ addr = die ? this->diesize[0] : 0;
+
+ if (this->boundary[die] == boundary)
+ return -1;
+
+ printk(KERN_INFO "Changing boundary: %d%s\n", boundary, lock ?
+ "(Locked)" : "(Unlocked)");
+ if (boundary >= blksperdie) {
+ printk(KERN_ERR "Invalid boundary value.\n");
+ return -1;
+ }
+
+ boundary &= FLEXONENAND_PI_MASK;
+ boundary |= lock ? 0 : (3 << FLEXONENAND_PI_UNLOCK_SHIFT);
+
+ this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, addr, 0);
+ this->wait(mtd, FL_SYNCING);
+
+ this->command(mtd, ONENAND_CMD_ERASE, addr, 0);
+ this->wait(mtd, FL_ERASING);
+
+ this->write_word(boundary, this->base + ONENAND_DATARAM);
+ this->command(mtd, ONENAND_CMD_PROG, addr, 0);
+ ret = this->wait(mtd, FL_WRITING);
+ if (ret) {
+ printk(KERN_ERR "Failed PI write for Die %d\n", die);
+ goto out;
+ }
+
+ this->command(mtd, FLEXONENAND_CMD_PI_UPDATE, addr, 0);
+ ret = this->wait(mtd, FL_WRITING);
+ if (ret)
+ printk(KERN_ERR "Failed PI update for Die %d\n", die);
+ else
+ printk(KERN_INFO "Done\n");
+out:
+ this->write_word(ONENAND_CMD_RESET, this->base +
ONENAND_REG_COMMAND);
+ this->wait(mtd, FL_RESETING);
+ if (!ret)
+ /* Recalculate device size on boundary change*/
+ get_flexonenand_size(mtd);
+ return ret;
+}
+
+/**
* onenand_probe - [OneNAND Interface] Probe the OneNAND device
* @param mtd MTD device structure
*
@@ -1727,31 +2105,47 @@
/* Read manufacturer and device IDs from Register */
maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
+ this->technology = this->read_word(this->base +
ONENAND_REG_TECHNOLOGY);
/* Check OneNAND device */
if (maf_id != bram_maf_id || dev_id != bram_dev_id)
return -ENXIO;
- /* FIXME : Current OneNAND MTD doesn't support Flex-OneNAND */
- if (dev_id & (1 << 9)) {
- printk("Not yet support Flex-OneNAND\n");
- return -ENXIO;
- }
-
/* Flash device information */
mtd->name = onenand_print_device_info(dev_id);
this->device_id = dev_id;
density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
- this->chipsize = (16 << density) << 20;
+ density &= ONENAND_DEVICE_DENSITY_MASK;
+ if (FLEXONENAND(this)) {
+ this->dies = (dev_id & ONENAND_DEVICE_IS_DDP) ? 2 : 1;
+ /* Maximum possible erase regions */
+ mtd->numeraseregions = this->dies << 1;
+ mtd->eraseregions = malloc(sizeof(struct
mtd_erase_region_info)
+ * (this->dies << 1));
+ if (!mtd->eraseregions)
+ return -ENOMEM;
+ }
+ this->chipsize = FLEXONENAND(this) ? 0 : (16 << density) << 20;
+ /* Set density mask. it is used for DDP */
+ if (dev_id & ONENAND_DEVICE_IS_DDP)
+ this->density_mask = (1 << (density + (FLEXONENAND(this) ?
+ 4 : 6)));
+ else
+ this->density_mask = 0;
/* OneNAND page size & block size */
/* The data buffer size is equal to page size */
mtd->writesize =
this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
+ /* We use the full BufferRAM */
+ if (ONENAND_IS_MLC(this))
+ mtd->writesize <<= 1;
+
mtd->oobsize = mtd->writesize >> 5;
/* Pagers per block is always 64 in OneNAND */
mtd->erasesize = mtd->writesize << 6;
+ mtd->erasesize <<= FLEXONENAND(this) ? 1 : 0;
this->erase_shift = ffs(mtd->erasesize) - 1;
this->page_shift = ffs(mtd->writesize) - 1;
@@ -1762,7 +2156,10 @@
/* REVIST: Multichip handling */
- mtd->size = this->chipsize;
+ if (FLEXONENAND(this))
+ get_flexonenand_size(mtd);
+ else
+ mtd->size = this->chipsize;
/* Version ID */
version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
@@ -1787,6 +2184,11 @@
mtd->block_isbad = onenand_block_isbad;
mtd->block_markbad = onenand_block_markbad;
+ if (FLEXONENAND(this)) {
+ this->options &= ~ONENAND_CONT_LOCK;
+ this->options |= ONENAND_UNLOCK_ALL;
+ }
+
return 0;
}
@@ -1850,7 +2252,8 @@
this->options |= ONENAND_OOBBUF_ALLOC;
}
- onenand_unlock(mtd, 0, mtd->size);
+ FLEXONENAND(this) ? flexonenand_unlock_all(mtd) :
+ onenand_unlock(mtd, 0, mtd->size);
return onenand_default_bbt(mtd);
}
diff --git a/drivers/mtd/onenand/onenand_bbt.c
b/drivers/mtd/onenand/onenand_bbt.c
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -66,6 +66,7 @@
struct bbm_info *bbm = this->bbm;
int i, j, numblocks, len, scanlen;
int startblock;
+ unsigned slc;
loff_t from;
size_t readlen, ooblen;
struct mtd_oob_ops ops;
@@ -82,7 +83,7 @@
/* Note that numblocks is 2 * (real numblocks) here;
* see i += 2 below as it makses shifting and masking less painful
*/
- numblocks = mtd->size >> (bbm->bbt_erase_shift - 1);
+ numblocks = this->chipsize >> (bbm->bbt_erase_shift - 1);
startblock = 0;
from = 0;
@@ -115,7 +116,13 @@
}
}
i += 2;
- from += (1 << bbm->bbt_erase_shift);
+ if (FLEXONENAND(this)) {
+ onenand_get_block(mtd, from, &slc);
+ from += (1 << bbm->bbt_erase_shift) >> 1;
+ if (!slc)
+ from += (1 << bbm->bbt_erase_shift) >> 1;
+ } else
+ from += (1 << bbm->bbt_erase_shift);
}
return 0;
@@ -152,7 +159,7 @@
uint8_t res;
/* Get block number * 2 */
- block = (int)(offs >> (bbm->bbt_erase_shift - 1));
+ block = (int) (onenand_get_block(mtd, offs, NULL) << 1);
res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
MTDDEBUG (MTD_DEBUG_LEVEL2,
@@ -191,7 +198,7 @@
struct bbm_info *bbm = this->bbm;
int len, ret = 0;
- len = mtd->size >> (this->erase_shift + 2);
+ len = this->chipsize >> (this->erase_shift + 2);
/* Allocate memory (2bit per block) */
bbm->bbt = malloc(len);
if (!bbm->bbt) {
diff --git a/drivers/mtd/onenand/onenand_uboot.c
b/drivers/mtd/onenand/onenand_uboot.c
--- a/drivers/mtd/onenand/onenand_uboot.c
+++ b/drivers/mtd/onenand/onenand_uboot.c
@@ -31,6 +31,8 @@
onenand_scan(&onenand_mtd, 1);
+ if (onenand_chip.device_id & DEVICE_IS_FLEXONENAND)
+ puts("Flex-");
puts("OneNAND: ");
- print_size(onenand_mtd.size, "\n");
+ print_size(onenand_chip.chipsize, "\n");
}
diff --git a/include/configs/apollon.h b/include/configs/apollon.h
--- a/include/configs/apollon.h
+++ b/include/configs/apollon.h
@@ -73,6 +73,7 @@
* Size of malloc() pool
*/
#define CONFIG_ENV_SIZE SZ_128K /* Total Size of Environment Sector
*/
+#define CONFIG_ENV_SIZE_FLEX SZ_256K /* Can change to 512K */
#define CFG_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_128K)
#define CFG_GBL_DATA_SIZE 128 /* bytes reserved for
initial data */
@@ -227,5 +228,5 @@
#define CFG_ONENAND_BASE 0x00000000
#define CONFIG_ENV_IS_IN_ONENAND 1
#define CONFIG_ENV_ADDR 0x00020000
-
+#define CONFIG_ENV_ADDR_FLEX 0x00040000
#endif /* __CONFIG_H */
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -20,6 +20,7 @@
#include <linux/mtd/compat.h>
#include <linux/mtd/bbm.h>
+#define MAX_DIES 2
#define MAX_BUFFERRAM 2
#define MAX_ONENAND_PAGESIZE (2048 + 64)
@@ -43,6 +44,9 @@
/**
* struct onenand_chip - OneNAND Private Flash Chip Data
* @param base [BOARDSPECIFIC] address to access OneNAND
+ * @dies: [INTERN][FLEXONENAND] number of dies on chip
+ * @boundary: [INTERN][FLEXONENAND] Boundary of the dies
+ * @diesize: [INTERN][FLEXONENAND] Size of the dies
* @param chipsize [INTERN] the size of one chip for multichip arrays
* @param device_id [INTERN] device ID
* @param verstion_id [INTERN] version ID
@@ -67,8 +71,13 @@
*/
struct onenand_chip {
void __iomem *base;
+ unsigned int dies;
+ unsigned int boundary[MAX_DIES];
+ unsigned int diesize[MAX_DIES];
unsigned int chipsize;
unsigned int device_id;
+ unsigned int technology;
+ unsigned int density_mask;
unsigned int options;
unsigned int erase_shift;
@@ -116,6 +125,8 @@
#define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0)
#define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1)
+#define FLEXONENAND(this) (this->device_id & DEVICE_IS_FLEXONENAND)
+#define ONENAND_IS_MLC(this) (this->technology &
ONENAND_TECHNOLOGY_IS_MLC)
#define ONENAND_IS_DDP(this) \
(this->device_id & ONENAND_DEVICE_IS_DDP)
@@ -127,6 +138,7 @@
#define ONENAND_CONT_LOCK (0x0001)
#define ONENAND_PAGEBUF_ALLOC (0x1000)
#define ONENAND_OOBBUF_ALLOC (0x2000)
+#define ONENAND_UNLOCK_ALL (0x0002)
/*
* OneNAND Flash Manufacturer ID Codes
@@ -147,4 +159,8 @@
int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops);
+unsigned onenand_get_block(struct mtd_info *mtd, loff_t addr,
+ unsigned *isblkslc);
+int flexonenand_set_boundary(struct mtd_info *mtd, unsigned die,
+ int bdry, int lock);
#endif /* __LINUX_MTD_ONENAND_H */
diff --git a/include/linux/mtd/onenand_regs.h
b/include/linux/mtd/onenand_regs.h
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -67,6 +67,10 @@
/*
* Device ID Register F001h (R)
*/
+#define DEVICE_IS_FLEXONENAND (1 << 9)
+#define FLEXONENAND_PI_MASK (0x3ff)
+#define FLEXONENAND_PI_UNLOCK_SHIFT (14)
+#define ONENAND_DEVICE_DENSITY_MASK (0xf)
#define ONENAND_DEVICE_DENSITY_SHIFT (4)
#define ONENAND_DEVICE_IS_DDP (1 << 3)
#define ONENAND_DEVICE_IS_DEMUX (1 << 2)
@@ -80,6 +84,11 @@
#define ONENAND_VERSION_PROCESS_SHIFT (8)
/*
+ * Technology Register F006h (R)
+ */
+#define ONENAND_TECHNOLOGY_IS_MLC (1 << 0)
+
+/*
* Start Address 1 F100h (R/W)
*/
#define ONENAND_DDP_SHIFT (15)
@@ -89,7 +98,7 @@
/*
* Start Address 8 F107h (R/W)
*/
-#define ONENAND_FPA_MASK (0x3f)
+#define ONENAND_FPA_MASK (0x7f)
#define ONENAND_FPA_SHIFT (2)
#define ONENAND_FSA_MASK (0x03)
@@ -101,7 +110,7 @@
#define ONENAND_BSA_BOOTRAM (0 << 2)
#define ONENAND_BSA_DATARAM0 (2 << 2)
#define ONENAND_BSA_DATARAM1 (3 << 2)
-#define ONENAND_BSC_MASK (0x03)
+#define ONENAND_BSC_MASK (0x07)
/*
* Command Register F220h (R/W)
@@ -113,9 +122,14 @@
#define ONENAND_CMD_UNLOCK (0x23)
#define ONENAND_CMD_LOCK (0x2A)
#define ONENAND_CMD_LOCK_TIGHT (0x2C)
+#define ONENAND_CMD_UNLOCK_ALL (0x27)
#define ONENAND_CMD_ERASE (0x94)
#define ONENAND_CMD_RESET (0xF0)
#define ONENAND_CMD_READID (0x90)
+#define FLEXONENAND_CMD_RESET (0xF3)
+#define FLEXONENAND_CMD_PI_UPDATE (0x05)
+#define FLEXONENAND_CMD_PI_ACCESS (0x66)
+#define FLEXONENAND_CMD_RECOVER_LSB (0x05)
/* NOTE: Those are not *REAL* commands */
#define ONENAND_CMD_BUFFERRAM (0x1978)
@@ -179,5 +193,6 @@
#define ONENAND_ECC_1BIT (1 << 0)
#define ONENAND_ECC_2BIT (1 << 1)
#define ONENAND_ECC_2BIT_ALL (0xAAAA)
+#define FLEXONENAND_UNCORRECTABLE_ERROR (0x1010)
#endif /* __ONENAND_REG_H */
7
10
The patch is to add support functions which load and boot WinCE image.
It introduces one new CMD macro named 'CONFIG_CMD_WINCE'.
The source codes have tested on STLS board.
Signed-off-by: Ryan Chen <ryan.chen(a)st.com>
---
common/Makefile | 1 +
common/cmd_bootm.c | 32 ++++++++
common/cmd_wince.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++
include/config_cmd_all.h | 1 +
include/image.h | 1 +
5 files changed, 228 insertions(+), 0 deletions(-)
create mode 100644 common/cmd_wince.c
diff --git a/common/Makefile b/common/Makefile
index 4287108..e427828 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -144,6 +144,7 @@ COBJS-y += cmd_mac.o
COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
COBJS-$(CONFIG_MP) += cmd_mp.o
COBJS-$(CONFIG_CMD_SF) += cmd_sf.o
+COBJS-$(CONFIG_CMD_WINCE) += cmd_wince.o
COBJS := $(COBJS-y)
SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 1c0a416..e6397d7 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -106,6 +106,10 @@ int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
#if defined(CONFIG_ARTOS) && defined(CONFIG_PPC)
static boot_os_fn do_bootm_artos;
#endif
+#if defined(CONFIG_CMD_WINCE)
+static boot_os_fn do_bootm_wince;
+int do_bootwince (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+#endif
ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */
static bootm_headers_t images; /* pointers to os/initrd/fdt images */
@@ -358,6 +362,12 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
do_bootm_artos (cmdtp, flag, argc, argv, &images);
break;
#endif
+
+#ifdef CONFIG_CMD_WINCE
+ case IH_OS_WINCE:
+ do_bootm_wince (cmdtp, flag, argc, argv, &images);
+ break;
+#endif
}
show_boot_progress (-9);
@@ -1142,3 +1152,25 @@ static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag,
(*entry) (kbd, cmdline, fwenv, top);
}
#endif
+
+#if defined(CONFIG_CMD_WINCE)
+static void do_bootm_wince (cmd_tbl_t *cmdtp, int flag,
+ int argc, char *argv[],
+ bootm_headers_t *images)
+{
+ char str[80];
+ image_header_t *hdr = &images->legacy_hdr_os_copy;
+
+#if defined(CONFIG_FIT)
+ if (!images->legacy_hdr_valid) {
+ fit_unsupported_reset ("WinCE");
+ do_reset (cmdtp, flag, argc, argv);
+ }
+#endif
+
+ sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */
+ setenv("loadaddr", str);
+ do_bootwince(cmdtp, 0, 0, NULL);
+}
+#endif/* CONFIG_CMD_WINCE */
+
diff --git a/common/cmd_wince.c b/common/cmd_wince.c
new file mode 100644
index 0000000..fdc2e6b
--- /dev/null
+++ b/common/cmd_wince.c
@@ -0,0 +1,193 @@
+/*
+ * 2008 (c) STMicroelectronics, Inc.
+ * Author: Ryan Chen <Ryan.Chen(a)st.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Opsycon AB, Sweden.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <linux/ctype.h>
+#include <net.h>
+
+/*
+ * Windows CE Binary Image Data Format
+ * The binary image (.bin) file format organizes data by sections. Each section contains
+ * a section header that specifies the starting address, length, and checksum for that
+ * section.
+ *
+ * Refer to <http://msdn.microsoft.com/en-us/library/ms924510.aspx>
+ *
+ * The following table shows the .bin file format.
+ * Field Length (bytes) Description
+ * Sync bytes (optional) 7 Byte 0 is B, indicating a .bin file format.
+ * Bytes 1-6 are reserved and set to 0, 0, 0, F, F, \n.
+ * Run-time image address 4 Physical starting address of the run-time image.
+ * Run-time image length 4 Physical length, in bytes, of the run-time image.
+ * Record Address 4 Physical starting address of data record.
+ * If this value is zero, the Record Address is the end of
+ * the file, and record length contains the starting address
+ * of the run-time image.
+ * Record length 4 Length of record data, in bytes.
+ * Record checksum 4 Signed 32-bit sum of record data bytes.
+ * Record data Record length Record data.
+ */
+#define WINCE_IMAGE_SYNC_SIZE 7
+#define WINCE_IMAGE_SYNC "B000FF\n"
+
+typedef struct {
+ unsigned char sync_bytes[WINCE_IMAGE_SYNC_SIZE];
+ unsigned int img_addr;
+ unsigned int img_length;
+} type_wince_image_header;
+
+int check_sum(unsigned char * buf, int len, unsigned int checksum)
+{
+ unsigned int count,i;
+
+ for (i = 0,count = 0 ; i < len ; i++)
+ count += buf[i];
+
+ if (count == checksum)
+ return 0;
+
+ return 1;
+}
+
+/* ======================================================================
+ * Determine if a valid WinCE image exists at the given memory location.
+ * First looks at the image header field, the makes sure that it is
+ * WinCE image.
+ * ====================================================================== */
+int valid_wince_image (unsigned long addr)
+{
+ type_wince_image_header *p = (type_wince_image_header *)addr;
+
+ if(strcmp((char *)p->sync_bytes, (char *)WINCE_IMAGE_SYNC) != 0)
+ return 0;
+
+ return 1;
+}
+
+/* ======================================================================
+ * A very simple WinCE image loader, assumes the image is valid, returns the
+ * entry point address.
+ * ====================================================================== */
+unsigned long load_wince_image (unsigned long addr)
+{
+ unsigned char *p = (unsigned char *)addr;
+ u32 start_addr, total_length;
+ u32 record_addr, record_length, record_checksum;
+ u32 i = 0;
+
+ if(valid_wince_image(addr) == 0)
+ return ~0;
+
+ printf("WINCE image is found: ");
+ p += WINCE_IMAGE_SYNC_SIZE;
+ start_addr = (u32)(p[3]<<24) + (u32)(p[2]<<16) + (u32)(p[1]<<8) + (u32)p[0];
+ p += 4;
+ total_length = (u32)(p[3]<<24) + (u32)(p[2]<<16) + (u32)(p[1]<<8) + (u32)p[0];
+ printf(" Start Address = 0x%x @ Total Length = 0x%x\n", start_addr, total_length);
+ p += 4;
+
+ /* read each records */
+ while(1) {
+ record_length = (u32)(p[7]<<24) + (u32)(p[6]<<16) + (u32)(p[5]<<8) + (u32)p[4];
+ record_checksum = (u32)(p[11]<<24) + (u32)(p[10]<<16) + (u32)(p[9]<<8) + (u32)p[8];
+ record_addr = (u32)(p[3]<<24) + (u32)(p[2]<<16) + (u32)(p[1]<<8) + (u32)p[0];
+ if(record_addr == 0)
+ break;
+
+ if(check_sum((unsigned char *)&p[12], record_length, record_checksum) != 0) {
+ printf("Checksum Error!\n");
+ return (unsigned long)~0;
+ }
+ memcpy ((void *)record_addr, (const void *)&p[12], (unsigned long)record_length);
+ printf("Region %d: Loading from 0x%x to 0x%x @ Length 0x%x\n", i, (unsigned int)&p[12], \
+ (unsigned int)record_addr, record_length);
+ p = p + 12 + record_length;
+ i++;
+ }
+
+ /* the lastest checksun should be zero */
+ if(record_checksum != 0) {
+ printf("Checksum Error!\n");
+ return (unsigned long)~0;
+ }
+
+ /* the lastest length is entry address */
+ return (unsigned long)record_length;
+}
+
+/* ======================================================================
+ * Interpreter command to boot WinCE from a memory image. The image can
+ * be an WinCE image. WinCE image do not need the
+ * bootline and other parameters.
+ * ====================================================================== */
+int do_bootwince (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unsigned long addr; /* Address of image */
+
+ /*
+ * Check the loadaddr variable.
+ * If we don't know where the image is then we're done.
+ */
+ if (argc < 2)
+ addr = load_addr;
+ else
+ addr = simple_strtoul (argv[1], NULL, 16);
+
+#if defined(CONFIG_CMD_NET)
+ /* Check to see if we need to tftp the image ourselves before starting */
+ if ((argc == 2) && (strcmp (argv[1], "tftp") == 0)) {
+ if (NetLoop (TFTP) <= 0)
+ return 1;
+ printf ("Automatic boot of WinCE image at address 0x%08lx ... \n", addr);
+ }
+#endif
+
+ /*
+ * If the data at the load address is an WinCE image, then
+ * treat it like an WinCE image. Otherwise, return 1
+ */
+ if (valid_wince_image (addr)) {
+ addr = load_wince_image (addr);
+ } else {
+ puts ("## Not an WinCE image, exit!\n");
+ return 1;
+ /* leave addr as load_addr */
+ }
+
+ printf ("## Starting Wince at 0x%08lx ...\n", addr);
+
+ ((void (*)(void)) addr) ();
+
+ puts ("## WinCE terminated\n");
+ return 1;
+}
+
diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
index c2bb094..5f6fab5 100644
--- a/include/config_cmd_all.h
+++ b/include/config_cmd_all.h
@@ -81,5 +81,6 @@
#define CONFIG_CMD_VFD /* VFD support (TRAB) */
#define CONFIG_CMD_XIMG /* Load part of Multi Image */
#define CONFIG_CMD_AT91_SPIMUX /* AT91 MMC/SPI Mux Support */
+#define CONFIG_CMD_WINCE /* WinCE load/boot cmd */
#endif /* _CONFIG_CMD_ALL_H */
diff --git a/include/image.h b/include/image.h
index 46138fa..7253278 100644
--- a/include/image.h
+++ b/include/image.h
@@ -85,6 +85,7 @@
#define IH_OS_RTEMS 18 /* RTEMS */
#define IH_OS_ARTOS 19 /* ARTOS */
#define IH_OS_UNITY 20 /* Unity OS */
+#define IH_OS_WINCE 21 /* WinCE OS */
/*
* CPU Architecture Codes (supported by Linux)
--
1.6.0.rc1
3
3
This patch provides support for AFEB9260 board, a product of
OpenSource hardware and software. Some commertial projects
are made with this design. A board is basically AT91SAM9260-EK
with some modifications and different peripherals and different
parts used. Main purpose of this project is to gain experience in
hardware design.
More info: http://groups.google.com/group/arm9fpga-evolution-board
(In Russian only, sorry).
Subversion repository: svn://194.85.238.22/home/users/george/svn/arm9eb
Signed-off-by: Sergey Lapin <slapin(a)ossfans.org>
---
Makefile | 3 +
board/afeb9260/Makefile | 56 +++++++++++
board/afeb9260/afeb9260.c | 230 ++++++++++++++++++++++++++++++++++++++++++++
board/afeb9260/config.mk | 1 +
board/afeb9260/nand.c | 79 +++++++++++++++
board/afeb9260/partition.c | 36 +++++++
include/configs/afeb9260.h | 169 ++++++++++++++++++++++++++++++++
7 files changed, 574 insertions(+), 0 deletions(-)
create mode 100644 board/afeb9260/Makefile
create mode 100644 board/afeb9260/afeb9260.c
create mode 100644 board/afeb9260/config.mk
create mode 100644 board/afeb9260/nand.c
create mode 100644 board/afeb9260/partition.c
create mode 100644 include/configs/afeb9260.h
diff --git a/Makefile b/Makefile
index 3179c67..edef217 100644
--- a/Makefile
+++ b/Makefile
@@ -2387,6 +2387,9 @@ at91cap9adk_config : unconfig
at91sam9260ek_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm926ejs at91sam9260ek atmel at91sam9
+afeb9260_config : unconfig
+ @$(MKCONFIG) $(@:_config=) arm arm926ejs afeb9260 NULL at91sam9
+
########################################################################
## ARM Integrator boards - see doc/README-integrator for more info.
integratorap_config \
diff --git a/board/afeb9260/Makefile b/board/afeb9260/Makefile
new file mode 100644
index 0000000..60c4304
--- /dev/null
+++ b/board/afeb9260/Makefile
@@ -0,0 +1,56 @@
+#
+# (C) Copyright 2003-2008
+# Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
+#
+# (C) Copyright 2008
+# Stelian Pop <stelian.pop(a)leadtechdesign.com>
+# Lead Tech Design <www.leadtechdesign.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS-y += afeb9260.o
+COBJS-y += partition.o
+COBJS-$(CONFIG_CMD_NAND) += nand.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/afeb9260/afeb9260.c b/board/afeb9260/afeb9260.c
new file mode 100644
index 0000000..252a1ea
--- /dev/null
+++ b/board/afeb9260/afeb9260.c
@@ -0,0 +1,230 @@
+/*
+ * (C) Copyright 2008 Sergey Lapin <slapin(a)ossfans.org>
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/at91sam9260.h>
+#include <asm/arch/at91sam9260_matrix.h>
+#include <asm/arch/at91sam9_smc.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91_rstc.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/io.h>
+#if defined(CONFIG_RESET_PHY_R) && defined(CONFIG_MACB)
+#include <net.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* ------------------------------------------------------------------------- */
+/*
+ * Miscelaneous platform dependent initialisations
+ */
+
+static void afeb9260_serial_hw_init(void)
+{
+#ifdef CONFIG_USART0
+ at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */
+ at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_US0);
+#endif
+
+#ifdef CONFIG_USART1
+ at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */
+ at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_US1);
+#endif
+
+#ifdef CONFIG_USART2
+ at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */
+ at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_US2);
+#endif
+
+#ifdef CONFIG_USART3 /* DBGU */
+ at91_set_A_periph(AT91_PIN_PB14, 0); /* DRXD */
+ at91_set_A_periph(AT91_PIN_PB15, 1); /* DTXD */
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_SYS);
+#endif
+}
+
+static void afeb9260_nand_hw_init(void)
+{
+ unsigned long csa;
+
+ /* Enable CS3 */
+ csa = at91_sys_read(AT91_MATRIX_EBICSA);
+ at91_sys_write(AT91_MATRIX_EBICSA,
+ csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
+
+ /* Configure SMC CS3 for NAND/SmartMedia */
+ at91_sys_write(AT91_SMC_SETUP(3),
+ AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) |
+ AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0));
+ at91_sys_write(AT91_SMC_PULSE(3),
+ AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) |
+ AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
+ at91_sys_write(AT91_SMC_CYCLE(3),
+ AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));
+ at91_sys_write(AT91_SMC_MODE(3),
+ AT91_SMC_READMODE | AT91_SMC_WRITEMODE |
+ AT91_SMC_EXNWMODE_DISABLE |
+ AT91_SMC_DBW_8 |
+ AT91_SMC_TDF_(2));
+
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_PIOC);
+
+ /* Configure RDY/BSY */
+ at91_set_gpio_input(AT91_PIN_PC13, 1);
+
+ /* Enable NandFlash */
+ at91_set_gpio_output(AT91_PIN_PC14, 1);
+}
+
+static void afeb9260_spi_hw_init(void)
+{
+ at91_set_A_periph(AT91_PIN_PA3, 0); /* SPI0_NPCS0 */
+ at91_set_B_periph(AT91_PIN_PC11, 0); /* SPI0_NPCS1 */
+
+ at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */
+ at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */
+ at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */
+
+ /* Enable clock */
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_SPI0);
+}
+
+#ifdef CONFIG_MACB
+static void afeb9260_macb_hw_init(void)
+{
+ /* Enable clock */
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_EMAC);
+
+ /*
+ * Disable pull-up on:
+ * RXDV (PA17) => PHY normal mode (not Test mode)
+ * ERX0 (PA14) => PHY ADDR0
+ * ERX1 (PA15) => PHY ADDR1
+ * ERX2 (PA25) => PHY ADDR2
+ * ERX3 (PA26) => PHY ADDR3
+ * ECRS (PA28) => PHY ADDR4 => PHYADDR = 0x0
+ *
+ * PHY has internal pull-down
+ */
+ writel(pin_to_mask(AT91_PIN_PA14) |
+ pin_to_mask(AT91_PIN_PA15) |
+ pin_to_mask(AT91_PIN_PA17) |
+ pin_to_mask(AT91_PIN_PA25) |
+ pin_to_mask(AT91_PIN_PA26) |
+ pin_to_mask(AT91_PIN_PA28),
+ pin_to_controller(AT91_PIN_PA0) + PIO_PUDR);
+
+ /* Need to reset PHY -> 500ms reset */
+ at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
+ AT91_RSTC_ERSTL | (0x0D << 8) |
+ AT91_RSTC_URSTEN);
+
+ at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_EXTRST);
+
+ /* Wait for end hardware reset */
+ while (!(at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_NRSTL));
+
+ /* Restore NRST value */
+ at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
+ AT91_RSTC_ERSTL | (0x0 << 8) |
+ AT91_RSTC_URSTEN);
+
+ /* Re-enable pull-up */
+ writel(pin_to_mask(AT91_PIN_PA14) |
+ pin_to_mask(AT91_PIN_PA15) |
+ pin_to_mask(AT91_PIN_PA17) |
+ pin_to_mask(AT91_PIN_PA25) |
+ pin_to_mask(AT91_PIN_PA26) |
+ pin_to_mask(AT91_PIN_PA28),
+ pin_to_controller(AT91_PIN_PA0) + PIO_PUER);
+
+ at91_set_A_periph(AT91_PIN_PA19, 0); /* ETXCK_EREFCK */
+ at91_set_A_periph(AT91_PIN_PA17, 0); /* ERXDV */
+ at91_set_A_periph(AT91_PIN_PA14, 0); /* ERX0 */
+ at91_set_A_periph(AT91_PIN_PA15, 0); /* ERX1 */
+ at91_set_A_periph(AT91_PIN_PA18, 0); /* ERXER */
+ at91_set_A_periph(AT91_PIN_PA16, 0); /* ETXEN */
+ at91_set_A_periph(AT91_PIN_PA12, 0); /* ETX0 */
+ at91_set_A_periph(AT91_PIN_PA13, 0); /* ETX1 */
+ at91_set_A_periph(AT91_PIN_PA21, 0); /* EMDIO */
+ at91_set_A_periph(AT91_PIN_PA20, 0); /* EMDC */
+
+#ifndef CONFIG_RMII
+ at91_set_B_periph(AT91_PIN_PA28, 0); /* ECRS */
+ at91_set_B_periph(AT91_PIN_PA29, 0); /* ECOL */
+ at91_set_B_periph(AT91_PIN_PA25, 0); /* ERX2 */
+ at91_set_B_periph(AT91_PIN_PA26, 0); /* ERX3 */
+ at91_set_B_periph(AT91_PIN_PA27, 0); /* ERXCK */
+ at91_set_B_periph(AT91_PIN_PA10, 0); /* ETX2 */
+ at91_set_B_periph(AT91_PIN_PA11, 0); /* ETX3 */
+ at91_set_B_periph(AT91_PIN_PA22, 0); /* ETXER */
+#endif
+
+}
+#endif
+
+int board_init(void)
+{
+ /* Enable Ctrlc */
+ console_init_f();
+
+ /* arch number of AT91SAM9260EK-Board */
+ // gd->bd->bi_arch_number = CONFIG_MACH_AFEB9260
+ gd->bd->bi_arch_number = 1859;
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+ afeb9260_serial_hw_init();
+#ifdef CONFIG_CMD_NAND
+ afeb9260_nand_hw_init();
+#endif
+ afeb9260_spi_hw_init();
+#ifdef CONFIG_MACB
+ afeb9260_macb_hw_init();
+#endif
+
+ return 0;
+}
+
+int dram_init(void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
+ return 0;
+}
+
+#ifdef CONFIG_RESET_PHY_R
+void reset_phy(void)
+{
+#ifdef CONFIG_MACB
+ /*
+ * Initialize ethernet HW addr prior to starting Linux,
+ * needed for nfsroot
+ */
+ eth_init(gd->bd);
+#endif
+}
+#endif
+
diff --git a/board/afeb9260/config.mk b/board/afeb9260/config.mk
new file mode 100644
index 0000000..9ce161e
--- /dev/null
+++ b/board/afeb9260/config.mk
@@ -0,0 +1 @@
+TEXT_BASE = 0x21f00000
diff --git a/board/afeb9260/nand.c b/board/afeb9260/nand.c
new file mode 100644
index 0000000..9738f0f
--- /dev/null
+++ b/board/afeb9260/nand.c
@@ -0,0 +1,79 @@
+/*
+ * (C) Copyright 2007-2008
+ * Stelian Pop <stelian.pop(a)leadtechdesign.com>
+ * Lead Tech Design <www.leadtechdesign.com>
+ *
+ * (C) Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/at91sam9260.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/at91_pio.h>
+
+#include <nand.h>
+
+/*
+ * hardware specific access to control-lines
+ */
+#define MASK_ALE (1 << 21) /* our ALE is AD21 */
+#define MASK_CLE (1 << 22) /* our CLE is AD22 */
+
+static void at91sam9260ek_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+ struct nand_chip *this = mtd->priv;
+ ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
+
+ IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
+ switch (cmd) {
+ case NAND_CTL_SETCLE:
+ IO_ADDR_W |= MASK_CLE;
+ break;
+ case NAND_CTL_SETALE:
+ IO_ADDR_W |= MASK_ALE;
+ break;
+ case NAND_CTL_CLRNCE:
+ at91_set_gpio_value(AT91_PIN_PC14, 1);
+ break;
+ case NAND_CTL_SETNCE:
+ at91_set_gpio_value(AT91_PIN_PC14, 0);
+ break;
+ }
+ this->IO_ADDR_W = (void *) IO_ADDR_W;
+}
+
+static int at91sam9260ek_nand_ready(struct mtd_info *mtd)
+{
+ return at91_get_gpio_value(AT91_PIN_PC13);
+}
+
+int board_nand_init(struct nand_chip *nand)
+{
+ nand->eccmode = NAND_ECC_SOFT;
+#ifdef CFG_NAND_DBW_16
+ nand->options = NAND_BUSWIDTH_16;
+#endif
+ nand->hwcontrol = at91sam9260ek_nand_hwcontrol;
+ nand->dev_ready = at91sam9260ek_nand_ready;
+ nand->chip_delay = 20;
+
+ return 0;
+}
diff --git a/board/afeb9260/partition.c b/board/afeb9260/partition.c
new file mode 100644
index 0000000..2b99c9b
--- /dev/null
+++ b/board/afeb9260/partition.c
@@ -0,0 +1,36 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+#include <common.h>
+#include <config.h>
+#include <asm/hardware.h>
+#include <dataflash.h>
+
+AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS];
+
+struct dataflash_addr cs[CFG_MAX_DATAFLASH_BANKS] = {
+ {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}, /* Logical adress, CS */
+ {CFG_DATAFLASH_LOGIC_ADDR_CS1, 1}
+};
+
+/*define the area offsets*/
+dataflash_protect_t area_list[NB_DATAFLASH_AREA] = {
+ {0x00000000, 0x000041FF, FLAG_PROTECT_CLEAR, 0, "Bootstrap"},
+ {0x00004200, 0x000083FF, FLAG_PROTECT_CLEAR, 0, "Environment"},
+ {0x00008400, 0x00041FFF, FLAG_PROTECT_CLEAR, 0, "U-Boot"},
+};
diff --git a/include/configs/afeb9260.h b/include/configs/afeb9260.h
new file mode 100644
index 0000000..6241687
--- /dev/null
+++ b/include/configs/afeb9260.h
@@ -0,0 +1,169 @@
+/*
+ * (C) Copyright 2008 Sergey Lapin
+ *
+ * Configuation settings for the AFEB9260 board.
+ * Based on configuration for AT91SAM9260-EK
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* ARM asynchronous clock */
+#define AT91_MAIN_CLOCK 18429952 /* from 18.432 MHz crystal */
+#define AT91_MASTER_CLOCK 89999598 /* peripheral = main / 2 */
+#define CFG_HZ 1000000 /* 1us resolution */
+
+#define AT91_SLOW_CLOCK 32768 /* slow clock */
+
+#define CONFIG_AT91SAM9260 1 /* It's an Atmel AT91SAM9260 SoC*/
+#define CONFIG_AFEB9260 1 /* on an AFEB9260 Board */
+#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
+
+#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_INITRD_TAG 1
+
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SKIP_RELOCATE_UBOOT
+
+/*
+ * Hardware drivers
+ */
+#define CONFIG_ATMEL_USART 1
+#undef CONFIG_USART0
+#undef CONFIG_USART1
+#undef CONFIG_USART2
+#define CONFIG_USART3 1 /* USART 3 is DBGU */
+
+#define CONFIG_BOOTDELAY 3
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_BOOTFILESIZE 1
+#define CONFIG_BOOTP_BOOTPATH 1
+#define CONFIG_BOOTP_GATEWAY 1
+#define CONFIG_BOOTP_HOSTNAME 1
+
+/*
+ * Command line configuration.
+ */
+#include <config_cmd_default.h>
+#undef CONFIG_CMD_BDI
+#undef CONFIG_CMD_IMI
+#undef CONFIG_CMD_AUTOSCRIPT
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_LOADS
+#undef CONFIG_CMD_IMLS
+
+#define CONFIG_CMD_PING 1
+#define CONFIG_CMD_DHCP 1
+
+#define CONFIG_CMD_NAND 1
+#define CONFIG_CMD_USB 1
+
+/* SDRAM */
+#define CONFIG_NR_DRAM_BANKS 1
+#define PHYS_SDRAM 0x20000000
+#define PHYS_SDRAM_SIZE 0x04000000 /* 64 megs */
+
+/* DataFlash */
+#define CONFIG_HAS_DATAFLASH 1
+#define CFG_SPI_WRITE_TOUT (5*CFG_HZ)
+#define CFG_MAX_DATAFLASH_BANKS 2
+#define CFG_DATAFLASH_LOGIC_ADDR_CS0 0xC0000000 /* CS0 */
+#define CFG_DATAFLASH_LOGIC_ADDR_CS1 0xD0000000 /* CS1 */
+#define AT91_SPI_CLK 15000000
+#define DATAFLASH_TCSS (0x1a << 16)
+#define DATAFLASH_TCHS (0x1 << 24)
+
+/* NAND flash */
+#define NAND_MAX_CHIPS 1
+#define CFG_MAX_NAND_DEVICE 1
+#define CFG_NAND_BASE 0x40000000
+#define CFG_NAND_DBW_8 1
+
+/* NOR flash - no real flash on this board */
+#define CFG_NO_FLASH 1
+
+/* Ethernet */
+#define CONFIG_MACB 1
+#undef CONFIG_RMII /* We have full MII there */
+#define CONFIG_RESET_PHY_R 1
+
+#define CONFIG_NET_MULTI 1
+#define CONFIG_NET_RETRY_COUNT 20
+
+/* USB */
+#define CONFIG_USB_OHCI_NEW 1
+#define LITTLEENDIAN 1
+#define CONFIG_DOS_PARTITION 1
+#define CFG_USB_OHCI_CPU_INIT 1
+#define CFG_USB_OHCI_REGS_BASE 0x00500000 /* AT91SAM9260_UHP_BASE */
+#define CFG_USB_OHCI_SLOT_NAME "at91sam9260"
+#define CFG_USB_OHCI_MAX_ROOT_PORTS 1
+#define CONFIG_USB_STORAGE 1
+
+#define CFG_LOAD_ADDR 0x21000000 /* load address */
+
+#define CFG_MEMTEST_START PHYS_SDRAM
+#define CFG_MEMTEST_END 0x21e00000
+
+#undef CFG_USE_DATAFLASH_CS0
+#define CFG_USE_DATAFLASH_CS1 1
+#undef CFG_USE_NANDFLASH
+
+/* bootstrap + u-boot + env + linux in dataflash on CS1 */
+#define CFG_ENV_IS_IN_DATAFLASH 1
+#define CFG_MONITOR_BASE (CFG_DATAFLASH_LOGIC_ADDR_CS1 + 0x8400)
+#define CFG_ENV_OFFSET 0x4200
+#define CFG_ENV_ADDR (CFG_DATAFLASH_LOGIC_ADDR_CS1 + CFG_ENV_OFFSET)
+#define CFG_ENV_SIZE 0x4200
+#define CONFIG_BOOTCOMMAND "nand read 0x21000000 0xa0000 0x200000; bootm"
+#define CONFIG_BOOTARGS "console=ttyS0,115200 " \
+ "root=/dev/mtdblock2 " \
+ "rw rootfstype=jffs2 panic=20"
+
+#define CONFIG_BAUDRATE 115200
+#define CFG_BAUDRATE_TABLE {115200 , 19200, 38400, 57600, 9600 }
+
+#define CFG_PROMPT "U-Boot> "
+#define CFG_CBSIZE 256
+#define CFG_MAXARGS 16
+#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
+#define CFG_LONGHELP 1
+#define CONFIG_CMDLINE_EDITING 1
+
+#define ROUND(A, B) (((A) + (B)) & ~((B) - 1))
+/*
+ * Size of malloc() pool
+ */
+#define CFG_MALLOC_LEN ROUND(3 * CFG_ENV_SIZE + 128*1024, 0x1000)
+#define CFG_GBL_DATA_SIZE 128 /* 128 bytes for initial data */
+
+#define CONFIG_STACKSIZE (32*1024) /* regular stack */
+
+#ifdef CONFIG_USE_IRQ
+#error CONFIG_USE_IRQ not supported
+#endif
+
+#endif
+
--
1.5.4.1
3
15