aboutsummaryrefslogtreecommitdiffstats
path: root/uart-monitor/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'uart-monitor/drivers')
m---------uart-monitor0
-rw-r--r--uart-monitor/drivers/Makefile70
-rw-r--r--uart-monitor/drivers/k9f1g08r0a.c512
-rw-r--r--uart-monitor/drivers/k9f5616.c229
-rw-r--r--uart-monitor/drivers/k9k1216.c258
-rw-r--r--uart-monitor/drivers/ns16550.c69
-rw-r--r--uart-monitor/drivers/onenand.c203
-rw-r--r--uart-monitor/drivers/onenand_regs.h167
-rw-r--r--uart-monitor/drivers/serial.c119
9 files changed, 1627 insertions, 0 deletions
diff --git a/uart-monitor b/uart-monitor
deleted file mode 160000
-Subproject eb8b047c29a2027fbdd841cd1289fa27ddb22d7
diff --git a/uart-monitor/drivers/Makefile b/uart-monitor/drivers/Makefile
new file mode 100644
index 0000000..ffc38b3
--- /dev/null
+++ b/uart-monitor/drivers/Makefile
@@ -0,0 +1,70 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@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
+
+# CFLAGS += -DET_DEBUG -DDEBUG
+
+LIB = libdrivers.a
+OBJS = serial.o ns16550.o onenand.o
+
+ifeq ($(BOARD), omap3430sdp)
+OBJS += k9f1g08r0a.o
+endif
+
+ifeq ($(BOARD), omap3430labrador)
+OBJS += k9f1g08r0a.o
+endif
+
+ifeq ($(BOARD), omap2420h4)
+OBJS += k9k1216.o
+endif
+
+ifeq ($(BOARD), omap2430sdp)
+OBJS += k9k1216.o
+endif
+
+ifeq ($(BOARD), omap1710h3)
+OBJS += k9f5616.o
+endif
+
+
+## Disabled for now:
+## cs8900.o ct69000.o dataflash.o dc2114x.o ds1722.o \
+## lan91c96.o mw_eeprom.o natsemi.o \
+## smc91111.o smiLynxEM.o spi_eeprom.o sym53c8xx.o \
+##
+
+all: $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/uart-monitor/drivers/k9f1g08r0a.c b/uart-monitor/drivers/k9f1g08r0a.c
new file mode 100644
index 0000000..f0d6452
--- /dev/null
+++ b/uart-monitor/drivers/k9f1g08r0a.c
@@ -0,0 +1,512 @@
+/*
+ * (C) Copyright 2004 Texas Instruments
+ * Jian Zhang <jzhang@ti.com>
+ *
+ * Samsung K9F1G08R0AQ0C NAND chip driver for an OMAP2420 board
+ *
+ * This file is based on the following u-boot file:
+ * common/cmd_nand.c
+ *
+ * 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/sys_proto.h>
+#include <asm/arch/sys_info.h>
+
+#ifdef CFG_NAND_K9F1G08R0A
+
+#define K9F1G08R0A_MFR 0xec /* Samsung */
+#define K9F1G08R0A_ID 0xa1 /* part # */
+
+/* Since Micron and Samsung parts are similar in geometry and bus width
+ * we can use the same driver. Need to revisit to make this file independent
+ * of part/manufacturer
+ */
+#define MT29F1G_MFR 0x2c /* Micron */
+#define MT29F1G_ID 0xa1 /* x8, 1GiB */
+#define MT29F2G_ID 0xba /* x16, 2GiB */
+#define MT29F4G_ID 0xbc /* x16, 4GiB */
+
+#define ADDR_COLUMN 1
+#define ADDR_PAGE 2
+#define ADDR_COLUMN_PAGE (ADDR_COLUMN | ADDR_PAGE)
+
+#define ADDR_OOB (0x4 | ADDR_COLUMN_PAGE)
+
+#define PAGE_SIZE 2048
+#define OOB_SIZE 64
+#define MAX_NUM_PAGES 64
+
+#ifdef NAND_HW_ROMCODE_ECC_LAYOUT
+#define __raw_ecc_readl(a) (*(volatile unsigned int *)(a))
+#define __raw_ecc_writel(v, a) (*(volatile unsigned int *)(a) = (v))
+/* Register definitions */
+#define GPMC_BASE_ADDR OMAP34XX_GPMC_BASE
+
+#define ECCCLEAR (0x1 << 8)
+#define ECCRESULTREG1 (0x1 << 0)
+#define ECCSIZE512BYTE 0xFF
+#define ECCSIZE1 (ECCSIZE512BYTE << 22)
+#define ECCSIZE0 (ECCSIZE512BYTE << 12)
+#define ECCSIZE0SEL (0x000 << 0)
+
+#define ECC_BLOCK_SIZE 512
+#ifdef NAND_16BIT
+#define DEV_WIDTH 1
+static u_char ecc_pos[] = { 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13
+};
+#else
+#define DEV_WIDTH 0
+static u_char ecc_pos[] = { 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12
+};
+#endif
+
+#else
+#ifdef NAND_16BIT
+#define DEV_WIDTH 1
+#else
+#define DEV_WIDTH 0
+#endif
+
+#ifdef CFG_SW_ECC_512
+#define ECC_BLOCK_SIZE 512
+#else
+#define ECC_BLOCK_SIZE 256
+#endif
+/* JFFS2 large page layout for 3-byte ECC per 256 bytes ECC layout */
+/* This is the only SW ECC supported by u-boot. So to load u-boot
+ * this should be supported */
+static u_char ecc_pos[] = {40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63};
+
+#endif
+
+#define ECC_SIZE (sizeof(ecc_pos))
+#define ECC_STEPS 3
+#define ECC_CHECK_ENABLE
+
+/*******************************************************
+ * Routine: delay
+ * Description: spinning delay to use before udelay works
+ ******************************************************/
+static inline void delay (unsigned long loops)
+{
+ __asm__ volatile ("1:\n"
+ "subs %0, %0, #1\n"
+ "bne 1b" : "=r" (loops) : "0" (loops));
+}
+
+static int nand_read_page(u_char *buf, ulong page_addr);
+static int nand_read_oob(u_char *buf, ulong page_addr);
+
+static unsigned long chipsize = (256 << 20);
+
+/* NanD_Command: Send a flash command to the flash chip */
+static int NanD_Command(unsigned char command)
+{
+ NAND_CTL_SETCLE(NAND_ADDR);
+
+ WRITE_NAND_COMMAND(command, NAND_ADDR);
+ NAND_CTL_CLRCLE(NAND_ADDR);
+
+ if (command == NAND_CMD_RESET) {
+ unsigned char ret_val;
+ NanD_Command(NAND_CMD_STATUS);
+ do {
+ ret_val = READ_NAND(NAND_ADDR); /* wait till ready */
+ } while ((ret_val & 0x40) != 0x40);
+ }
+
+ NAND_WAIT_READY();
+ return 0;
+}
+
+
+/* NanD_Address: Set the current address for the flash chip */
+static int NanD_Address(unsigned int numbytes, unsigned long ofs)
+{
+ uchar u;
+
+ NAND_CTL_SETALE(NAND_ADDR);
+
+ if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE
+ || numbytes == ADDR_OOB)
+ {
+ ushort col = ofs;
+
+ u = col & 0xff;
+ WRITE_NAND_ADDRESS(u, NAND_ADDR);
+
+ u = (col >> 8) & 0x07;
+ if (numbytes == ADDR_OOB)
+ u = u | ((DEV_WIDTH == 1) ? (1 << 2) : (1 << 3));
+ WRITE_NAND_ADDRESS(u, NAND_ADDR);
+ }
+
+ if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE
+ || numbytes == ADDR_OOB)
+ {
+ u = (ofs >> 11) & 0xff;
+ WRITE_NAND_ADDRESS(u, NAND_ADDR);
+ u = (ofs >> 19) & 0xff;
+ WRITE_NAND_ADDRESS(u, NAND_ADDR);
+
+ /* One more address cycle for devices > 128MiB */
+ if (chipsize > (128 << 20)) {
+ u = (ofs >> 27) & 0xff;
+ WRITE_NAND_ADDRESS(u, NAND_ADDR);
+ }
+ }
+
+ NAND_CTL_CLRALE(NAND_ADDR);
+
+ NAND_WAIT_READY();
+ return 0;
+}
+
+/* read chip mfr and id
+ * return 0 if they match board config
+ * return 1 if not
+ */
+int nand_chip()
+{
+ int mfr, id;
+
+ NAND_ENABLE_CE();
+
+ if (NanD_Command(NAND_CMD_RESET)) {
+ printf("Err: RESET\n");
+ NAND_DISABLE_CE();
+ return 1;
+ }
+
+ if (NanD_Command(NAND_CMD_READID)) {
+ printf("Err: READID\n");
+ NAND_DISABLE_CE();
+ return 1;
+ }
+
+ NanD_Address(ADDR_COLUMN, 0);
+
+ mfr = READ_NAND(NAND_ADDR);
+ id = READ_NAND(NAND_ADDR);
+
+ NAND_DISABLE_CE();
+
+ /* Check Micron part or Samsung part */
+ if ((mfr == MT29F1G_MFR && (id == MT29F1G_ID ||
+ id == MT29F2G_ID || id == MT29F4G_ID)) ||
+ (mfr == K9F1G08R0A_MFR && (id == K9F1G08R0A_ID)))
+ return 0;
+
+ return 1;
+}
+
+/* read a block data to buf
+ * return 1 if the block is bad or ECC error can't be corrected for any page
+ * return 0 on sucess
+ */
+int nand_read_block(unsigned char *buf, ulong block_addr)
+{
+ int i, offset = 0;
+
+#ifdef ECC_CHECK_ENABLE
+ u8 oob_buf[OOB_SIZE];
+
+ /* check bad block */
+ /* 0th word in spare area needs be 0xff */
+ if (nand_read_oob(oob_buf, block_addr) || (oob_buf[0] & 0xff) != 0xff) {
+ printf("Skipped bad block at 0x%x\n", block_addr);
+ return 1; /* skip bad block */
+ }
+#endif
+ /* read the block page by page*/
+ for (i = 0; i < MAX_NUM_PAGES; i++) {
+ if (nand_read_page(buf + offset, block_addr + offset))
+ return 1;
+ offset += PAGE_SIZE;
+ }
+
+ return 0;
+}
+
+#ifdef NAND_HW_ROMCODE_ECC_LAYOUT
+/*
+ * omap_hwecc_init - Initialize the Hardware ECC for NAND flash in
+ * GPMC controller
+ *
+ */
+static void omap_hwecc_init(void)
+{
+ /*
+ * Init ECC Control Register
+ * Clear all ECC | Enable Reg1
+ */
+ __raw_ecc_writel(ECCCLEAR | ECCRESULTREG1,
+ GPMC_BASE_ADDR + GPMC_ECC_CONTROL);
+ __raw_ecc_writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL,
+ GPMC_BASE_ADDR + GPMC_ECC_SIZE_CONFIG);
+ __raw_ecc_writel(0x1 | (0 << 1) | (DEV_WIDTH << 7),
+ GPMC_BASE_ADDR + GPMC_ECC_CONFIG);
+}
+
+/*
+ * gen_true_ecc - This function will generate true ECC value, which
+ * can be used when correcting data read from NAND flash memory core
+ *
+ * @ecc_buf: buffer to store ecc code
+ *
+ * @return: re-formatted ECC value
+ */
+static uint32_t gen_true_ecc(uint8_t *ecc_buf)
+{
+ return ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xF0) << 20) |
+ ((ecc_buf[2] & 0x0F) << 8);
+}
+
+/*
+ * omap_calculate_ecc - Generate non-inverted ECC bytes.
+ *
+ * Using noninverted ECC can be considered ugly since writing a blank
+ * page ie. padding will clear the ECC bytes. This is no problem as
+ * long nobody is trying to write data on the seemingly unused page.
+ * Reading an erased page will produce an ECC mismatch between
+ * generated and read ECC bytes that has to be dealt with separately.
+ * E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
+ * is used, the result of read will be 0x0 while the ECC offsets of the
+ * spare area will be 0xFF which will result in an ECC mismatch.
+ * @dat: unused
+ * @ecc_code: ecc_code buffer
+ */
+static int omap_calculate_ecc(const uint8_t *dat, uint8_t *ecc_code)
+{
+ u_int32_t val;
+
+ /* Start Reading from HW ECC1_Result = 0x200 */
+ val = __raw_ecc_readl(GPMC_BASE_ADDR + GPMC_ECC1_RESULT);
+
+ ecc_code[0] = val & 0xFF;
+ ecc_code[1] = (val >> 16) & 0xFF;
+ ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
+
+ /*
+ * Stop reading anymore ECC vals and clear old results
+ * enable will be called if more reads are required
+ */
+ __raw_ecc_writel(0x000, GPMC_BASE_ADDR + GPMC_ECC_CONFIG);
+
+ return 0;
+}
+
+static int hweight32(unsigned int val)
+{
+ u_char count = 0;
+ for ( ; val; count++)
+ val &= (val - 1);
+ return count;
+}
+
+/*
+ * omap_correct_data - Compares the ecc read from nand spare area with ECC
+ * registers values and corrects one bit error if it has occured
+ * Further details can be had from OMAP TRM and the following selected links:
+ * http://en.wikipedia.org/wiki/Hamming_code
+ * http://www.cs.utexas.edu/users/plaxton/c/337/05f/slides/ErrorCorrection-4.pdf
+ *
+ * @dat: page data
+ * @read_ecc: ecc read from nand flash
+ * @calc_ecc: ecc read from ECC registers
+ *
+ * @return 0 if data is OK or corrected, else returns -1
+ */
+static int omap_correct_data(uint8_t *dat,
+ uint8_t *read_ecc, uint8_t *calc_ecc)
+{
+ uint32_t orig_ecc, new_ecc, res, hm;
+ uint16_t parity_bits, byte;
+ uint8_t bit;
+
+ /* Regenerate the orginal ECC */
+ orig_ecc = gen_true_ecc(read_ecc);
+ new_ecc = gen_true_ecc(calc_ecc);
+ /* Get the XOR of real ecc */
+ res = orig_ecc ^ new_ecc;
+ if (res) {
+ /* Get the hamming width */
+ hm = hweight32(res);
+ /* Single bit errors can be corrected! */
+ if (hm == 12) {
+ /* Correctable data! */
+ parity_bits = res >> 16;
+ bit = (parity_bits & 0x7);
+ byte = (parity_bits >> 3) & 0x1FF;
+ /* Flip the bit to correct */
+ dat[byte] ^= (0x1 << bit);
+ } else if (hm == 1) {
+ printf("Error: Ecc is wrong\n");
+ /* ECC itself is corrupted */
+ return 2;
+ } else {
+ /*
+ * hm distance != parity pairs OR one, could mean 2 bit
+ * error OR potentially be on a blank page..
+ * orig_ecc: contains spare area data from nand flash.
+ * new_ecc: generated ecc while reading data area.
+ * Note: if the ecc = 0, all data bits from which it was
+ * generated are 0xFF.
+ * The 3 byte(24 bits) ecc is generated per 512byte
+ * chunk of a page. If orig_ecc(from spare area)
+ * is 0xFF && new_ecc(computed now from data area)=0x0,
+ * this means that data area is 0xFF and spare area is
+ * 0xFF. A sure sign of a erased page!
+ */
+ if ((orig_ecc == 0x0FFF0FFF) && (new_ecc == 0x00000000))
+ return 0;
+ printf("Error: Bad compare! failed\n");
+ /* detected 2 bit error */
+ return -1;
+ }
+ }
+ return 0;
+}
+
+#define NAND_ECC_INIT() omap_hwecc_init()
+#define NAND_ECC_CALC(data_buf, ecc_buf) omap_calculate_ecc(data_buf, ecc_buf)
+#define NAND_ECC_CORRECT(data_buf, ecc_gen, ecc_old)\
+ omap_correct_data(data_buf, ecc_gen, ecc_old)
+#else
+/* Software ECC APIs */
+#define NAND_ECC_INIT()
+#define NAND_ECC_CALC(data_buf, ecc_buf) nand_calculate_ecc(data_buf, ecc_buf)
+#define NAND_ECC_CORRECT(data_buf, ecc_gen, ecc_old)\
+ nand_correct_data(data_buf, ecc_gen, ecc_old)
+#endif /* NAND_HW_ROMCODE_ECC_LAYOUT */
+
+/* read a page with ECC */
+static int nand_read_page(u_char *buf, ulong page_addr)
+{
+#ifdef ECC_CHECK_ENABLE
+ u_char ecc_code[ECC_SIZE];
+ u_char ecc_calc[ECC_SIZE];
+ u_char oob_buf[OOB_SIZE];
+#endif
+ u16 val;
+ int cntr;
+ int len;
+ int count;
+
+#ifdef NAND_16BIT
+ u16 *p = (u16 *) buf;
+#else
+ u_char *p = (u_char *) buf;
+#endif
+
+ NAND_ENABLE_CE();
+ NanD_Command(NAND_CMD_READ0);
+ NanD_Address(ADDR_COLUMN_PAGE, page_addr);
+ NanD_Command(NAND_CMD_READSTART);
+ NAND_WAIT_READY();
+
+ /* A delay seems to be helping here. needs more investigation */
+ delay(10000);
+ len = (DEV_WIDTH == 1) ? ECC_BLOCK_SIZE >> 1 : ECC_BLOCK_SIZE;
+
+ /* Read in chunks of data. */
+ for (count = 0; count < ECC_SIZE; count += ECC_STEPS) {
+ NAND_ECC_INIT();
+ for (cntr = 0; cntr < len; cntr++) {
+ *p++ = READ_NAND(NAND_ADDR);
+ delay(10);
+ }
+ NAND_ECC_CALC((p - ECC_BLOCK_SIZE), &ecc_calc[count]);
+ }
+
+#ifdef ECC_CHECK_ENABLE
+#ifdef NAND_16BIT
+ p = (u16 *) oob_buf;
+#else
+ p = (u_char *) oob_buf;
+#endif
+ len = (DEV_WIDTH == 1) ? OOB_SIZE >> 1 : OOB_SIZE;
+ for (cntr = 0; cntr < len; cntr++) {
+ *p++ = READ_NAND(NAND_ADDR);
+ delay(10);
+ }
+ count = 0;
+ NAND_DISABLE_CE(); /* set pin high */
+
+ /* Pick the ECC bytes out of the oob data */
+ for (cntr = 0; cntr < ECC_SIZE; cntr++)
+ ecc_code[cntr] = oob_buf[ecc_pos[cntr]];
+
+ for (count = 0, cntr = 0; cntr < PAGE_SIZE / ECC_BLOCK_SIZE;
+ cntr++, count += ECC_STEPS) {
+ if (NAND_ECC_CORRECT(buf, &ecc_code[count], &ecc_calc[count])
+ == -1) {
+ printf("ECC Failed, page 0x%08x\n", page_addr);
+ for (val = 0; val < ECC_BLOCK_SIZE; val++)
+ printf("%x ", buf[val]);
+ printf(" Hang!!!\n");
+ for (;;);
+ return 1;
+ }
+ buf += ECC_BLOCK_SIZE;
+ page_addr += ECC_BLOCK_SIZE;
+ }
+#endif
+ return 0;
+}
+
+/* read from the 16 bytes of oob data that correspond to a 512 / 2048 byte page.
+ */
+static int nand_read_oob(u_char *buf, ulong page_addr)
+{
+ int cntr;
+ int len;
+
+#ifdef NAND_16BIT
+ u16 *p = (u16 *) buf;
+#else
+ u_char *p = (u_char *) buf;
+#endif
+ len = (DEV_WIDTH == 1) ? OOB_SIZE >> 1 : OOB_SIZE;
+
+ NAND_ENABLE_CE(); /* set pin low */
+ NanD_Command(NAND_CMD_READ0);
+ NanD_Address(ADDR_OOB, page_addr);
+ NanD_Command(NAND_CMD_READSTART);
+ NAND_WAIT_READY();
+
+ /* A delay seems to be helping here. needs more investigation */
+ delay(10000);
+ for (cntr = 0; cntr < len; cntr++)
+ *p++ = READ_NAND(NAND_ADDR);
+
+ NAND_WAIT_READY();
+ NAND_DISABLE_CE(); /* set pin high */
+
+ return 0;
+}
+
+#endif
diff --git a/uart-monitor/drivers/k9f5616.c b/uart-monitor/drivers/k9f5616.c
new file mode 100644
index 0000000..4081664
--- /dev/null
+++ b/uart-monitor/drivers/k9f5616.c
@@ -0,0 +1,229 @@
+/*
+ * (C) Copyright 2004 Texas Instruments
+ * Jian Zhang <jzhang@ti.com>
+ *
+ * Samsung K9F5616Q0C NAND chip driver for an OMAP16xx board
+ *
+ * This file is based on the following u-boot file:
+ * common/cmd_nand.c
+ *
+ * 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>
+
+#ifdef CFG_NAND_K9F5616
+
+#define K9F5616_MFR 0xec
+#define K9F5616_ID 0x45
+
+#define ADDR_COLUMN 1
+#define ADDR_PAGE 2
+#define ADDR_COLUMN_PAGE 3
+
+#define PAGE_SIZE 512
+
+static int nand_read_page(u_char *buf, ulong page_addr);
+static int nand_read_oob(u_char * buf, ulong page_addr);
+
+/* JFFS2 512-byte-page ECC layout */
+static u_char ecc_pos[] = {0,1,2,3,6,7};
+static u_char eccvalid_pos = 4;
+
+/* NanD_Command: Send a flash command to the flash chip */
+static int NanD_Command(unsigned char command)
+{
+ NAND_CTL_SETCLE(NAND_ADDR);
+ WRITE_NAND_COMMAND(command, NAND_ADDR);
+ NAND_CTL_CLRCLE(NAND_ADDR);
+
+ if(command == NAND_CMD_RESET){
+ unsigned char ret_val;
+ NanD_Command(NAND_CMD_STATUS);
+ do{
+ ret_val = READ_NAND(NAND_ADDR);/* wait till ready */
+ } while((ret_val & 0x40) != 0x40);
+ }
+
+ NAND_WAIT_READY();
+ return 0;
+}
+
+/* NanD_Address: Set the current address for the flash chip */
+static int NanD_Address(int numbytes, unsigned long ofs)
+{
+ int i;
+
+ NAND_CTL_SETALE(NAND_ADDR);
+
+ if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
+ WRITE_NAND_ADDRESS(ofs, NAND_ADDR);
+
+ ofs = ofs >> 8;
+
+ if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE)
+ for (i = 0; i < 2; i++, ofs = ofs >> 8)
+ WRITE_NAND_ADDRESS(ofs, NAND_ADDR);
+
+ NAND_CTL_CLRALE(NAND_ADDR);
+
+ NAND_WAIT_READY();
+ return 0;
+}
+
+/* read chip mfr and id
+ * return 0 if they match board config
+ * return 1 if not
+ */
+int nand_chip()
+{
+ int mfr, id;
+
+ NAND_ENABLE_CE();
+
+ if (NanD_Command(NAND_CMD_RESET)) {
+ printf("Err: RESET\n");
+ NAND_DISABLE_CE();
+ return 1;
+ }
+
+ if (NanD_Command(NAND_CMD_READID)) {
+ printf("Err: READID\n");
+ NAND_DISABLE_CE();
+ return 1;
+ }
+
+ NanD_Address(ADDR_COLUMN, 0);
+
+ mfr = READ_NAND(NAND_ADDR);
+ id = READ_NAND(NAND_ADDR);
+
+ NAND_DISABLE_CE();
+
+ return (mfr != K9F5616_MFR || id != K9F5616_ID);
+}
+
+/* read a block data to buf
+ * return 1 if the block is bad or ECC error can't be corrected for any page
+ * return 0 on sucess
+ */
+int nand_read_block(unsigned char *buf, ulong block_addr)
+{
+ int i, offset = 0;
+ uchar oob_buf[16];
+
+ /* check bad block */
+ /* 0th and 5th words need be 0xffff */
+ if (nand_read_oob(oob_buf, block_addr) ||
+// oob_buf[0] != 0xff || oob_buf[1] != 0xff ||
+// oob_buf[10] != 0xff || oob_buf[11] != 0xff ){
+ oob_buf[5] != 0xff){
+ printf("Skipped bad block at 0x%x\n", block_addr);
+ return 1; /* skip bad block */
+ }
+
+ /* read the block page by page*/
+ for (i=0; i<32; i++){
+ if (nand_read_page(buf+offset, block_addr + offset))
+ return 1;
+ offset += PAGE_SIZE;
+ }
+
+ return 0;
+}
+
+/* read a page with ECC */
+static int nand_read_page(u_char *buf, ulong page_addr)
+{
+ u_char ecc_code[6];
+ u_char ecc_calc[3];
+ u_char oob_buf[16];
+ u_char *p;
+ u16 val;
+ int cntr;
+
+ NAND_ENABLE_CE();
+ NanD_Command(NAND_CMD_READ0);
+ NanD_Address(ADDR_COLUMN_PAGE, page_addr>>1);
+
+ NAND_WAIT_READY();
+ p = buf;
+ for (cntr = 0; cntr < 256; cntr++){
+ val = READ_NAND(NAND_ADDR);
+ *p++ = val & 0xff;
+ *p++ = val >> 8;
+ }
+
+ p = oob_buf;
+ for (cntr = 0; cntr < 8; cntr++){
+ val = READ_NAND(NAND_ADDR);
+ *p++ = val & 0xff;
+ *p++ = val >> 8;
+ }
+ NAND_DISABLE_CE(); /* set pin high */
+
+ /* Pick the ECC bytes out of the oob data */
+ for (cntr = 0; cntr < 6; cntr++)
+ ecc_code[cntr] = oob_buf[ecc_pos[cntr]];
+
+
+ if ((oob_buf[eccvalid_pos] & 0x0f) != 0x0f) {
+ nand_calculate_ecc (buf, &ecc_calc[0]);
+ if (nand_correct_data (buf, &ecc_code[0], &ecc_calc[0]) == -1) {
+ printf ("ECC Failed, page 0x%08x\n", page_addr);
+ return 1;
+ }
+ }
+
+ if ((oob_buf[eccvalid_pos] & 0xf0) != 0xf0) {
+ nand_calculate_ecc (buf + 256, &ecc_calc[0]);
+ if (nand_correct_data (buf + 256, &ecc_code[3], &ecc_calc[0]) == -1) {
+ printf ("ECC Failed, page 0x%08x\n", page_addr+0x100);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* read from the 16 bytes of oob data that correspond to a 512 byte page.
+ */
+static int nand_read_oob(u_char *buf, ulong page_addr)
+{
+ u16 val;
+ int cntr;
+
+ NAND_ENABLE_CE(); /* set pin low */
+ NanD_Command(NAND_CMD_READOOB);
+ NanD_Address(ADDR_COLUMN_PAGE, page_addr>>1);
+ NAND_WAIT_READY();
+
+ for (cntr = 0; cntr < 8; cntr++){
+ val = READ_NAND(NAND_ADDR);
+ *buf++ = val & 0xff;
+ *buf++ = val >> 8;
+ }
+
+ NAND_WAIT_READY();
+ NAND_DISABLE_CE(); /* set pin high */
+
+ return 0;
+}
+
+#endif
diff --git a/uart-monitor/drivers/k9k1216.c b/uart-monitor/drivers/k9k1216.c
new file mode 100644
index 0000000..888fb6b
--- /dev/null
+++ b/uart-monitor/drivers/k9k1216.c
@@ -0,0 +1,258 @@
+/*
+ * (C) Copyright 2004 Texas Instruments
+ * Jian Zhang <jzhang@ti.com>
+ *
+ * Samsung K9K1216Q0C NAND chip driver for an OMAP2420 board
+ *
+ * This file is based on the following u-boot file:
+ * common/cmd_nand.c
+ *
+ * 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>
+
+#ifdef CFG_NAND_K9K1216
+
+#define K9K1216_MFR 0xec
+#define K9K1216_ID 0x46
+
+#define ADDR_COLUMN 1
+#define ADDR_PAGE 2
+#define ADDR_COLUMN_PAGE 3
+
+#define PAGE_SIZE 512
+/*******************************************************
+ * Routine: delay
+ * Description: spinning delay to use before udelay works
+ ******************************************************/
+static inline void delay (unsigned long loops)
+{
+ __asm__ volatile ("1:\n"
+ "subs %0, %1, #1\n"
+ "bne 1b":"=r" (loops):"0" (loops));
+}
+
+static int nand_read_page(u_char *buf, ulong page_addr);
+static int nand_read_oob(u_char * buf, ulong page_addr);
+
+/* JFFS2 512-byte-page ECC layout */
+static u_char ecc_pos[] = {0,1,2,3,6,7};
+static u_char eccvalid_pos = 4;
+
+/* NanD_Command: Send a flash command to the flash chip */
+static int NanD_Command(unsigned char command)
+{
+ NAND_CTL_SETCLE(NAND_ADDR);
+ WRITE_NAND_COMMAND(command, NAND_ADDR);
+ NAND_CTL_CLRCLE(NAND_ADDR);
+
+ if(command == NAND_CMD_RESET){
+ unsigned char ret_val;
+ NanD_Command(NAND_CMD_STATUS);
+ do{
+ ret_val = READ_NAND(NAND_ADDR);/* wait till ready */
+ } while((ret_val & 0x40) != 0x40);
+ }
+
+ NAND_WAIT_READY();
+ return 0;
+}
+
+/* NanD_Address: Set the current address for the flash chip */
+static int NanD_Address(int numbytes, unsigned long ofs)
+{
+ int i;
+
+ NAND_CTL_SETALE(NAND_ADDR);
+
+ if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
+ WRITE_NAND_ADDRESS(ofs, NAND_ADDR);
+
+ ofs = ofs >> 9;
+
+ if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE)
+ for (i = 0; i < 3; i++, ofs = ofs >> 8)
+ WRITE_NAND_ADDRESS(ofs, NAND_ADDR);
+
+ NAND_CTL_CLRALE(NAND_ADDR);
+
+ NAND_WAIT_READY();
+ return 0;
+}
+
+/* read chip mfr and id
+ * return 0 if they match board config
+ * return 1 if not
+ */
+int nand_chip()
+{
+ int mfr, id;
+
+ NAND_ENABLE_CE();
+
+ if (NanD_Command(NAND_CMD_RESET)) {
+ printf("Err: RESET\n");
+ NAND_DISABLE_CE();
+ return 1;
+ }
+
+ if (NanD_Command(NAND_CMD_READID)) {
+ printf("Err: READID\n");
+ NAND_DISABLE_CE();
+ return 1;
+ }
+
+ NanD_Address(ADDR_COLUMN, 0);
+
+ mfr = READ_NAND(NAND_ADDR);
+ id = READ_NAND(NAND_ADDR);
+
+ NAND_DISABLE_CE();
+
+ return (mfr != K9K1216_MFR || id != K9K1216_ID);
+}
+
+/* read a block data to buf
+ * return 1 if the block is bad or ECC error can't be corrected for any page
+ * return 0 on sucess
+ */
+int nand_read_block(unsigned char *buf, ulong block_addr)
+{
+ int i, offset = 0;
+ uchar oob_buf[16];
+
+ /* check bad block */
+ /* 0th and 5th words need be 0xffff */
+ if (nand_read_oob(oob_buf, block_addr) ||
+// oob_buf[0] != 0xff || oob_buf[1] != 0xff ||
+// oob_buf[10] != 0xff || oob_buf[11] != 0xff ){
+ oob_buf[5] != 0xff){
+ printf("Skipped bad block at 0x%x\n", block_addr);
+ return 1; /* skip bad block */
+ }
+
+ /* read the block page by page*/
+ for (i=0; i<32; i++){
+ if (nand_read_page(buf+offset, block_addr + offset))
+ return 1;
+ offset += PAGE_SIZE;
+ }
+
+ return 0;
+}
+static count = 0;
+/* read a page with ECC */
+static int nand_read_page(u_char *buf, ulong page_addr)
+{
+ u_char ecc_code[6];
+ u_char ecc_calc[3];
+ u_char oob_buf[16];
+ u_char *p;
+ u16 val;
+ int cntr;
+
+ NAND_ENABLE_CE();
+ NanD_Command(NAND_CMD_READ0);
+ NanD_Address(ADDR_COLUMN_PAGE, page_addr);
+ NAND_WAIT_READY();
+
+ delay(500); /* we go through NFC need a bigger delay. 200 is not enough */
+
+ p = buf;
+ for (cntr = 0; cntr < 256; cntr++){
+ val = READ_NAND(NAND_ADDR);
+ *p++ = val & 0xff;
+ *p++ = val >> 8;
+ }
+
+ p = oob_buf;
+ for (cntr = 0; cntr < 8; cntr++){
+ val = READ_NAND(NAND_ADDR);
+ *p++ = val & 0xff;
+ *p++ = val >> 8;
+ }
+ count = 1;
+ NAND_DISABLE_CE(); /* set pin high */
+
+ /* Pick the ECC bytes out of the oob data */
+ for (cntr = 0; cntr < 6; cntr++)
+ ecc_code[cntr] = oob_buf[ecc_pos[cntr]];
+
+ if ((oob_buf[eccvalid_pos] & 0x0f) != 0x0f) {
+ nand_calculate_ecc (buf, &ecc_calc[0]);
+ if (nand_correct_data (buf, &ecc_code[0], &ecc_calc[0]) == -1) {
+ printf ("ECC Failed, page 0x%08x\n", page_addr);
+ for (val=0; val <256; val++)
+ printf("%x ", buf[val]);
+ printf("\n");
+ for (;;);
+ return 1;
+ }
+ }
+
+ if ((oob_buf[eccvalid_pos] & 0xf0) != 0xf0) {
+ nand_calculate_ecc (buf + 256, &ecc_calc[0]);
+ if (nand_correct_data (buf + 256, &ecc_code[3], &ecc_calc[0]) == -1) {
+ printf ("ECC Failed, page 0x%08x\n", page_addr+0x100);
+ for (val=0; val <256; val++)
+ printf("%x ", buf[val+256]);
+ printf("\n");
+ for (;;);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* read from the 16 bytes of oob data that correspond to a 512 byte page.
+ */
+static int nand_read_oob(u_char *buf, ulong page_addr)
+{
+ u16 val;
+ int cntr;
+
+ NAND_ENABLE_CE(); /* set pin low */
+ NanD_Command(NAND_CMD_READOOB);
+ NanD_Address(ADDR_COLUMN_PAGE, page_addr);
+ NAND_WAIT_READY();
+
+/* do {
+ *(volatile u32 *)(0x6800A07c) = NAND_CMD_STATUS;
+ val = *(volatile u32 *)(0x6800A084);
+ printf("val = %x\n", val);
+ } while ((val & 0x40) != 0x40);
+*/
+ /* the above code from OSTBoot doesn't work, we use delay */
+ delay(500); /* we go through NFC need a bigger delay. 200 is not enough */
+
+ for (cntr = 0; cntr < 8; cntr++){
+ val = READ_NAND(NAND_ADDR);
+ *buf++ = val & 0xff;
+ *buf++ = val >> 8;
+ }
+
+ NAND_WAIT_READY();
+ NAND_DISABLE_CE(); /* set pin high */
+
+ return 0;
+}
+
+#endif
diff --git a/uart-monitor/drivers/ns16550.c b/uart-monitor/drivers/ns16550.c
new file mode 100644
index 0000000..b5a5c12
--- /dev/null
+++ b/uart-monitor/drivers/ns16550.c
@@ -0,0 +1,69 @@
+/*
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * COM1 NS16550 support
+ * originally from linux source (arch/ppc/boot/ns16550.c)
+ * modified to use CFG_ISA_MEM and new defines
+ */
+
+#include <config.h>
+
+#ifdef CFG_PRINTF
+#ifdef CFG_NS16550
+
+#include <ns16550.h>
+
+#define LCRVAL LCR_8N1 /* 8 data, 1 stop, no parity */
+#define MCRVAL (MCR_DTR | MCR_RTS) /* RTS/DTR */
+#define FCRVAL (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR) /* Clear & enable FIFOs */
+
+void NS16550_init (NS16550_t com_port, int baud_divisor)
+{
+ com_port->ier = 0x00;
+#ifdef CONFIG_OMAP
+ com_port->mdr1 = 0x7; /* mode select reset TL16C750*/
+#endif
+ com_port->lcr = LCR_BKSE | LCRVAL;
+ com_port->dll = baud_divisor & 0xff;
+ com_port->dlm = (baud_divisor >> 8) & 0xff;
+ com_port->lcr = LCRVAL;
+ com_port->mcr = MCRVAL;
+ com_port->fcr = FCRVAL;
+#if defined(CONFIG_OMAP)
+ com_port->mdr1 = 0; /* select uart mode */
+#endif
+}
+
+void NS16550_reinit (NS16550_t com_port, int baud_divisor)
+{
+ com_port->ier = 0x00;
+ com_port->lcr = LCR_BKSE;
+ com_port->dll = baud_divisor & 0xff;
+ com_port->dlm = (baud_divisor >> 8) & 0xff;
+ com_port->lcr = LCRVAL;
+ com_port->mcr = MCRVAL;
+ com_port->fcr = FCRVAL;
+}
+
+void NS16550_putc (NS16550_t com_port, char c)
+{
+ while ((com_port->lsr & LSR_THRE) == 0);
+ com_port->thr = c;
+}
+
+char NS16550_getc (NS16550_t com_port)
+{
+ while ((com_port->lsr & LSR_DR) == 0);
+ return (com_port->rbr);
+}
+
+int NS16550_tstc (NS16550_t com_port)
+{
+ return ((com_port->lsr & LSR_DR) != 0);
+}
+
+#endif
+#endif
diff --git a/uart-monitor/drivers/onenand.c b/uart-monitor/drivers/onenand.c
new file mode 100644
index 0000000..7d4e454
--- /dev/null
+++ b/uart-monitor/drivers/onenand.c
@@ -0,0 +1,203 @@
+/*
+ * (C) Copyright 2005 Samsung Electronis
+ * Kyungmin Park <kyungmin.park@samsung.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 <common.h>
+
+#include <asm/string.h>
+
+#include "onenand_regs.h"
+
+#define onenand_readw(a) (*(volatile unsigned short *)(a))
+#define onenand_writew(v, a) ((*(volatile unsigned short *)(a)) = (u16) (v))
+
+#define SAMSUNG_MFR_ID 0xEC
+#define KFM1G16Q2A_DEV_ID 0x30
+#define KFN2G16Q2A_DEV_ID 0x40
+
+#ifdef CFG_ONENAND
+
+#define THIS_ONENAND(a) (ONENAND_ADDR + (a))
+
+#define READ_INTERRUPT() \
+ onenand_readw(THIS_ONENAND(ONENAND_REG_INTERRUPT))
+
+#define SET_EMIFS_CS_CONFIG(v) \
+ (*(volatile unsigned long *)(OMAP_EMIFS_CS_CONFIG) = (v))
+
+#define onenand_block_address(block) (block)
+#define onenand_sector_address(page) (page << 2)
+#define onenand_buffer_address() ((1 << 3) << 8)
+#define onenand_bufferram_address(block) (0)
+
+#if defined(CFG_SYNC_BURST_READ) && defined(CONFIG_OMAP1610)
+static inline void set_sync_burst_read(void)
+{
+ unsigned int value;
+ value = 0
+ | (0x1 << 15) /* Read Mode: Synchronous */
+ | (0x4 << 12) /* Burst Read Latency: 4 cycles */
+ | (0x4 << 9) /* Burst Length: 8 word */
+ | (0x1 << 7) /* RDY signal plarity */
+ | (0x1 << 6) /* INT signal plarity */
+ | (0x1 << 5) /* I/O buffer enable */
+ ;
+ onenand_writew(value, THIS_ONENAND(ONENAND_REG_SYS_CFG1));
+
+ value = 0
+ | (4 << 16) /* Synchronous Burst Read */
+ | (1 << 12) /* PGWST/WELEN */
+ | (1 << 8) /* WRWST */
+ | (4 << 4) /* RDWST */
+ | (1 << 0) /* FCLKDIV => 48MHz */
+ ;
+ SET_EMIFS_CS_CONFIG(value);
+}
+
+static inline void set_async_read(void)
+{
+ unsigned int value;
+ value = 0
+ | (0x0 << 15) /* Read Mode: Asynchronous */
+ | (0x4 << 12) /* Burst Read Latency: 4 cycles */
+ | (0x0 << 9) /* Burst Length: continuous */
+ | (0x1 << 7) /* RDY signal plarity */
+ | (0x1 << 6) /* INT signal plarity */
+ | (0x0 << 5) /* I/O buffer disable */
+ ;
+ onenand_writew(value, THIS_ONENAND(ONENAND_REG_SYS_CFG1));
+
+ value = 0
+ | (0 << 16) /* Asynchronous Read */
+ | (1 << 12) /* PGWST/WELEN */
+ | (1 << 8) /* WRWST */
+ | (3 << 4) /* RDWST */
+ | (1 << 0) /* FCLKDIV => 48MHz */
+ ;
+ SET_EMIFS_CS_CONFIG(value);
+}
+#else
+#define set_sync_burst_read(...) do { } while (0)
+#define set_async_read(...) do { } while (0)
+#endif
+
+int
+onenand_chip()
+{
+ unsigned short mf_id, dev_id;
+ mf_id = (*(volatile unsigned short *)(THIS_ONENAND(ONENAND_REG_MANUFACTURER_ID)));
+ dev_id = (*(volatile unsigned short *)(THIS_ONENAND(ONENAND_REG_DEVICE_ID)));
+
+ if(mf_id == SAMSUNG_MFR_ID) {
+ if (dev_id == KFM1G16Q2A_DEV_ID) {
+ printf("Detected Samsung MuxOneNAND1G Flash \r\n");
+ return 0;
+ } else if (dev_id == KFN2G16Q2A_DEV_ID) {
+ printf("Detected Samsung MuxOneNAND2G Flash \r\n");
+ return 0;
+ } else {
+ printf(" ONENAND Flash unsupported\r\n");
+ return 1;
+ }
+ } else {
+ printf("ONENAND Flash Unsupported\r\n");
+ return 1;
+ }
+}
+
+/* read a page with ECC */
+static inline int onenand_read_page(ulong block, ulong page, u_char *buf)
+{
+ unsigned long *base;
+
+#ifndef __HAVE_ARCH_MEMCPY32
+ unsigned int offset, value;
+ unsigned long *p;
+#endif
+
+ onenand_writew(onenand_block_address(block),
+ THIS_ONENAND(ONENAND_REG_START_ADDRESS1));
+
+ onenand_writew(onenand_sector_address(page),
+ THIS_ONENAND(ONENAND_REG_START_ADDRESS8));
+
+ onenand_writew(onenand_buffer_address(),
+ THIS_ONENAND(ONENAND_REG_START_BUFFER));
+
+ onenand_writew(onenand_bufferram_address(block),
+ THIS_ONENAND(ONENAND_REG_START_ADDRESS2));
+
+ onenand_writew(ONENAND_INT_CLEAR, THIS_ONENAND(ONENAND_REG_INTERRUPT));
+
+ onenand_writew(ONENAND_CMD_READ, THIS_ONENAND(ONENAND_REG_COMMAND));
+
+#ifndef __HAVE_ARCH_MEMCPY32
+ p = (unsigned long *) buf;
+#endif
+ base = (unsigned long *) (ONENAND_ADDR + ONENAND_DATARAM);
+
+ while (!(READ_INTERRUPT() & ONENAND_INT_MASTER))
+ continue;
+
+#ifdef __HAVE_ARCH_MEMCPY32
+ /* 32 bytes boundary memory copy */
+ memcpy32(buf, base, ONENAND_PAGE_SIZE);
+#else
+ for (offset = 0; offset < (ONENAND_PAGE_SIZE >> 2); offset++) {
+ value = *(base + offset);
+ *p++ = value;
+ }
+#endif
+
+ return 0;
+}
+
+#define ONENAND_START_PAGE 0
+#define ONENAND_PAGES_PER_BLOCK 64
+
+/**
+ * onenand_read_block - Read a block data to buf
+ * @return 0 on sucess
+ */
+
+int onenand_read_block(unsigned char *buf, ulong block)
+{
+ int page, offset = 0;
+
+ set_sync_burst_read();
+
+ /* NOTE: you must read page from page 1 of block 0 */
+ /* read the block page by page*/
+ for (page = ONENAND_START_PAGE;
+ page < ONENAND_PAGES_PER_BLOCK; page++) {
+
+ onenand_read_page(block, page, buf + offset);
+
+ offset += ONENAND_PAGE_SIZE;
+ }
+
+ set_async_read();
+
+ return 0;
+}
+
+#endif /* CFG_ONENAND */
diff --git a/uart-monitor/drivers/onenand_regs.h b/uart-monitor/drivers/onenand_regs.h
new file mode 100644
index 0000000..d8acc8c
--- /dev/null
+++ b/uart-monitor/drivers/onenand_regs.h
@@ -0,0 +1,167 @@
+/*
+ * linux/include/linux/mtd/onenand_regs.h
+ *
+ * OneNAND Register header file
+ *
+ * Copyright (C) 2005 Samsung Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ONENAND_REG_H
+#define __ONENAND_REG_H
+
+/* Memory Address Map Translation (Word order) */
+#define ONENAND_MEMORY_MAP(x) ((x) << 1)
+
+/*
+ * External BufferRAM area
+ */
+#define ONENAND_BOOTRAM ONENAND_MEMORY_MAP(0x0000)
+#define ONENAND_DATARAM ONENAND_MEMORY_MAP(0x0200)
+#define ONENAND_SPARERAM ONENAND_MEMORY_MAP(0x8010)
+
+/*
+ * OneNAND Registers
+ */
+#define ONENAND_REG_MANUFACTURER_ID ONENAND_MEMORY_MAP(0xF000)
+#define ONENAND_REG_DEVICE_ID ONENAND_MEMORY_MAP(0xF001)
+#define ONENAND_REG_VERSION_ID ONENAND_MEMORY_MAP(0xF002)
+#define ONENAND_REG_DATA_BUFFER_SIZE ONENAND_MEMORY_MAP(0xF003)
+#define ONENAND_REG_BOOT_BUFFER_SIZE ONENAND_MEMORY_MAP(0xF004)
+#define ONENAND_REG_NUM_BUFFERS ONENAND_MEMORY_MAP(0xF005)
+#define ONENAND_REG_TECHNOLOGY ONENAND_MEMORY_MAP(0xF006)
+
+#define ONENAND_REG_START_ADDRESS1 ONENAND_MEMORY_MAP(0xF100)
+#define ONENAND_REG_START_ADDRESS2 ONENAND_MEMORY_MAP(0xF101)
+#define ONENAND_REG_START_ADDRESS3 ONENAND_MEMORY_MAP(0xF102)
+#define ONENAND_REG_START_ADDRESS4 ONENAND_MEMORY_MAP(0xF103)
+#define ONENAND_REG_START_ADDRESS5 ONENAND_MEMORY_MAP(0xF104)
+#define ONENAND_REG_START_ADDRESS6 ONENAND_MEMORY_MAP(0xF105)
+#define ONENAND_REG_START_ADDRESS7 ONENAND_MEMORY_MAP(0xF106)
+#define ONENAND_REG_START_ADDRESS8 ONENAND_MEMORY_MAP(0xF107)
+
+#define ONENAND_REG_START_BUFFER ONENAND_MEMORY_MAP(0xF200)
+#define ONENAND_REG_COMMAND ONENAND_MEMORY_MAP(0xF220)
+#define ONENAND_REG_SYS_CFG1 ONENAND_MEMORY_MAP(0xF221)
+#define ONENAND_REG_SYS_CFG2 ONENAND_MEMORY_MAP(0xF222)
+#define ONENAND_REG_CTRL_STATUS ONENAND_MEMORY_MAP(0xF240)
+#define ONENAND_REG_INTERRUPT ONENAND_MEMORY_MAP(0xF241)
+#define ONENAND_REG_START_BLOCK_ADDRESS ONENAND_MEMORY_MAP(0xF24C)
+#define ONENAND_REG_END_BLOCK_ADDRESS ONENAND_MEMORY_MAP(0xF24D)
+#define ONENAND_REG_WP_STATUS ONENAND_MEMORY_MAP(0xF24E)
+
+#define ONENAND_REG_ECC_STATUS ONENAND_MEMORY_MAP(0xFF00)
+#define ONENAND_REG_ECC_M0 ONENAND_MEMORY_MAP(0xFF01)
+#define ONENAND_REG_ECC_S0 ONENAND_MEMORY_MAP(0xFF02)
+#define ONENAND_REG_ECC_M1 ONENAND_MEMORY_MAP(0xFF03)
+#define ONENAND_REG_ECC_S1 ONENAND_MEMORY_MAP(0xFF04)
+#define ONENAND_REG_ECC_M2 ONENAND_MEMORY_MAP(0xFF05)
+#define ONENAND_REG_ECC_S2 ONENAND_MEMORY_MAP(0xFF06)
+#define ONENAND_REG_ECC_M3 ONENAND_MEMORY_MAP(0xFF07)
+#define ONENAND_REG_ECC_S3 ONENAND_MEMORY_MAP(0xFF08)
+
+/*
+ * Device ID Register F001h (R)
+ */
+#define ONENAND_DEVICE_DENSITY_SHIFT (4)
+#define ONENAND_DEVICE_IS_DDP (1 << 3)
+#define ONENAND_DEVICE_IS_DEMUX (1 << 2)
+#define ONENAND_DEVICE_VCC_MASK (0x3)
+
+#define ONENAND_DEVICE_DENSITY_512Mb (0x002)
+
+/*
+ * Version ID Register F002h (R)
+ */
+#define ONENAND_VERSION_PROCESS_SHIFT (8)
+
+/*
+ * Start Address 1 F100h (R/W)
+ */
+#define ONENAND_DDP_SHIFT (15)
+
+/*
+ * Start Address 8 F107h (R/W)
+ */
+#define ONENAND_FPA_MASK (0x3f)
+#define ONENAND_FPA_SHIFT (2)
+#define ONENAND_FSA_MASK (0x03)
+
+/*
+ * Start Buffer Register F200h (R/W)
+ */
+#define ONENAND_BSA_MASK (0x03)
+#define ONENAND_BSA_SHIFT (8)
+#define ONENAND_BSA_BOOTRAM (0 << 2)
+#define ONENAND_BSA_DATARAM0 (2 << 2)
+#define ONENAND_BSA_DATARAM1 (3 << 2)
+#define ONENAND_BSC_MASK (0x03)
+
+/*
+ * Command Register F220h (R/W)
+ */
+#define ONENAND_CMD_READ (0x00)
+#define ONENAND_CMD_READOOB (0x13)
+#define ONENAND_CMD_PROG (0x80)
+#define ONENAND_CMD_PROGOOB (0x1A)
+#define ONENAND_CMD_UNLOCK (0x23)
+#define ONENAND_CMD_LOCK (0x2A)
+#define ONENAND_CMD_LOCK_TIGHT (0x2C)
+#define ONENAND_CMD_ERASE (0x94)
+#define ONENAND_CMD_RESET (0xF0)
+#define ONENAND_CMD_READID (0x90)
+
+/* NOTE: Those are not *REAL* commands */
+#define ONENAND_CMD_BUFFERRAM (0x1978)
+
+/*
+ * System Configuration 1 Register F221h (R, R/W)
+ */
+#define ONENAND_SYS_CFG1_SYNC_READ (1 << 15)
+#define ONENAND_SYS_CFG1_BRL (12)
+#define ONENAND_SYS_CFG1_BL (9)
+#define ONENAND_SYS_CFG1_NO_ECC (1 << 8)
+#define ONENAND_SYS_CFG1_RDY (1 << 7)
+#define ONENAND_SYS_CFG1_INT (1 << 6)
+#define ONENAND_SYS_CFG1_IOBE (1 << 5)
+#define ONENAND_SYS_CFG1_RDY_CONF (1 << 4)
+
+/*
+ * Controller Status Register F240h (R)
+ */
+#define ONENAND_CTRL_ONGO (1 << 15)
+#define ONENAND_CTRL_LOCK (1 << 14)
+#define ONENAND_CTRL_LOAD (1 << 13)
+#define ONENAND_CTRL_PROGRAM (1 << 12)
+#define ONENAND_CTRL_ERASE (1 << 11)
+#define ONENAND_CTRL_ERROR (1 << 10)
+#define ONENAND_CTRL_RSTB (1 << 7)
+
+/*
+ * Interrupt Status Register F241h (R)
+ */
+#define ONENAND_INT_MASTER (1 << 15)
+#define ONENAND_INT_READ (1 << 7)
+#define ONENAND_INT_WRITE (1 << 6)
+#define ONENAND_INT_ERASE (1 << 5)
+#define ONENAND_INT_RESET (1 << 4)
+#define ONENAND_INT_CLEAR (0 << 0)
+
+/*
+ * NAND Flash Write Protection Status Register F24Eh (R)
+ */
+#define ONENAND_WP_US (1 << 2)
+#define ONENAND_WP_LS (1 << 1)
+#define ONENAND_WP_LTS (1 << 0)
+
+/*
+ * ECC Status Reigser FF00h (R)
+ */
+#define ONENAND_ECC_1BIT (1 << 0)
+#define ONENAND_ECC_2BIT (1 << 1)
+#define ONENAND_ECC_2BIT_ALL (0xAAAA)
+
+#endif /* __ONENAND_REG_H */
diff --git a/uart-monitor/drivers/serial.c b/uart-monitor/drivers/serial.c
new file mode 100644
index 0000000..b9ecf2a
--- /dev/null
+++ b/uart-monitor/drivers/serial.c
@@ -0,0 +1,119 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.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 <common.h>
+
+#ifdef CFG_PRINTF
+#ifdef CFG_NS16550_SERIAL
+
+#include <ns16550.h>
+#ifdef CFG_NS87308
+#include <ns87308.h>
+#endif
+
+#if CONFIG_CONS_INDEX == 1
+static NS16550_t console = (NS16550_t) CFG_NS16550_COM1;
+#elif CONFIG_CONS_INDEX == 2
+static NS16550_t console = (NS16550_t) CFG_NS16550_COM2;
+#elif CONFIG_CONS_INDEX == 3
+static NS16550_t console = (NS16550_t) CFG_NS16550_COM3;
+#elif CONFIG_CONS_INDEX == 4
+static NS16550_t console = (NS16550_t) CFG_NS16550_COM4;
+#else
+#error no valid console defined
+#endif
+
+static int calc_divisor (void)
+{
+// DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_OMAP1510
+ /* If can't cleanly clock 115200 set div to 1 */
+ if ((CFG_NS16550_CLK == 12000000) && (CONFIG_BAUDRATE == 115200)) {
+ console->osc_12m_sel = OSC_12M_SEL; /* enable 6.5 * divisor */
+ return (1); /* return 1 for base divisor */
+ }
+ console->osc_12m_sel = 0; /* clear if previsouly set */
+#endif
+#if defined(CONFIG_OMAP1610) || defined(CONFIG_OMAP1710)
+ /* If can't cleanly clock 115200 set div to 1 */
+ if ((CFG_NS16550_CLK == 48000000) && (CONFIG_BAUDRATE == 115200)) {
+ return (26); /* return 26 for base divisor */
+ }
+#endif
+ return (CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE);
+}
+
+int serial_init (void)
+{
+ int clock_divisor = calc_divisor();
+
+#ifdef CFG_NS87308
+ initialise_ns87308();
+#endif
+
+ NS16550_init(console, clock_divisor);
+
+ return (0);
+}
+
+void
+serial_putc(const char c)
+{
+ if (c == '\n')
+ NS16550_putc(console, '\r');
+
+ NS16550_putc(console, c);
+}
+
+void
+serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+
+int
+serial_getc(void)
+{
+ return NS16550_getc(console);
+}
+
+int
+serial_tstc(void)
+{
+ return NS16550_tstc(console);
+}
+
+void
+serial_setbrg (void)
+{
+ int clock_divisor;
+
+ clock_divisor = calc_divisor();
+ NS16550_reinit(console, clock_divisor);
+}
+
+#endif
+#endif