aboutsummaryrefslogtreecommitdiffstats
path: root/packages/linux/linux-davinci/davinci-nand.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/linux/linux-davinci/davinci-nand.patch')
-rw-r--r--packages/linux/linux-davinci/davinci-nand.patch905
1 files changed, 0 insertions, 905 deletions
diff --git a/packages/linux/linux-davinci/davinci-nand.patch b/packages/linux/linux-davinci/davinci-nand.patch
deleted file mode 100644
index 33e53cf095..0000000000
--- a/packages/linux/linux-davinci/davinci-nand.patch
+++ /dev/null
@@ -1,905 +0,0 @@
-Index: linux-davinci/drivers/mtd/nand/davinci_nand.c
-===================================================================
---- /dev/null
-+++ linux-davinci/drivers/mtd/nand/davinci_nand.c
-@@ -0,0 +1,638 @@
-+/*
-+ * linux/drivers/mtd/nand/davinci_nand.c
-+ *
-+ * NAND Flash Driver
-+ *
-+ * Copyright (C) 2006 Texas Instruments.
-+ *
-+ * ported to 2.6.23 (C) 2008 by
-+ * Sander Huijsen <Shuijsen@optelecom-nkf.com>
-+ * Troy Kisky <troy.kisky@boundarydevices.com>
-+ * Dirk Behme <Dirk.Behme@gmail.com>
-+ *
-+ * --------------------------------------------------------------------------
-+ *
-+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ * --------------------------------------------------------------------------
-+ *
-+ * Overview:
-+ * This is a device driver for the NAND flash device found on the
-+ * DaVinci board which utilizes the Samsung k9k2g08 part.
-+ *
-+ * Modifications:
-+ * ver. 1.0: Feb 2005, Vinod/Sudhakar
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/err.h>
-+#include <linux/clk.h>
-+#include <linux/io.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/nand.h>
-+#include <asm/arch/mux.h>
-+
-+#include <asm/mach/flash.h>
-+
-+#ifdef CONFIG_NAND_FLASH_HW_ECC
-+#define DAVINCI_NAND_ECC_MODE NAND_ECC_HW3_512
-+#else
-+#define DAVINCI_NAND_ECC_MODE NAND_ECC_SOFT
-+#endif
-+
-+#define DRIVER_NAME "davinci_nand"
-+
-+static struct clk *nand_clock;
-+static void __iomem *nand_vaddr;
-+
-+/*
-+ * MTD structure for DaVinici board
-+ */
-+static struct mtd_info *nand_davinci_mtd;
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+const char *part_probes[] = { "cmdlinepart", NULL };
-+#endif
-+
-+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
-+
-+/* BB marker is byte 5 in OOB of page 0 */
-+static struct nand_bbt_descr davinci_memorybased_small = {
-+ .options = NAND_BBT_SCAN2NDPAGE,
-+ .offs = 5,
-+ .len = 1,
-+ .pattern = scan_ff_pattern
-+};
-+
-+/* BB marker is bytes 0-1 in OOB of page 0 */
-+static struct nand_bbt_descr davinci_memorybased_large = {
-+ .options = 0,
-+ .offs = 0,
-+ .len = 2,
-+ .pattern = scan_ff_pattern
-+};
-+
-+inline unsigned int davinci_nand_readl(int offset)
-+{
-+ return davinci_readl(DAVINCI_ASYNC_EMIF_CNTRL_BASE + offset);
-+}
-+
-+inline void davinci_nand_writel(unsigned long value, int offset)
-+{
-+ davinci_writel(value, DAVINCI_ASYNC_EMIF_CNTRL_BASE + offset);
-+}
-+
-+/*
-+ * Hardware specific access to control-lines
-+ */
-+static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
-+ unsigned int ctrl)
-+{
-+ struct nand_chip *chip = mtd->priv;
-+ u32 IO_ADDR_W = (u32)chip->IO_ADDR_W;
-+
-+ /* Did the control lines change? */
-+ if (ctrl & NAND_CTRL_CHANGE) {
-+ IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
-+
-+ if ((ctrl & NAND_CTRL_CLE) == NAND_CTRL_CLE)
-+ IO_ADDR_W |= MASK_CLE;
-+ else if ((ctrl & NAND_CTRL_ALE) == NAND_CTRL_ALE)
-+ IO_ADDR_W |= MASK_ALE;
-+
-+ chip->IO_ADDR_W = (void __iomem *)IO_ADDR_W;
-+ }
-+
-+ if (cmd != NAND_CMD_NONE)
-+ writeb(cmd, chip->IO_ADDR_W);
-+}
-+
-+static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
-+{
-+ /* do nothing */
-+}
-+
-+#ifdef CONFIG_NAND_FLASH_HW_ECC
-+static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
-+{
-+ u32 retval;
-+
-+ /* Reset ECC hardware */
-+ retval = davinci_nand_readl(NANDF1ECC_OFFSET);
-+
-+ /* Restart ECC hardware */
-+ retval = davinci_nand_readl(NANDFCR_OFFSET);
-+ retval |= (1 << 8);
-+ davinci_nand_writel(retval, NANDFCR_OFFSET);
-+}
-+
-+/*
-+ * Read DaVinci ECC register
-+ */
-+static u32 nand_davinci_readecc(struct mtd_info *mtd)
-+{
-+ /* Read register ECC and clear it */
-+ return davinci_nand_readl(NANDF1ECC_OFFSET);
-+}
-+
-+/*
-+ * Read DaVinci ECC registers and rework into MTD format
-+ */
-+static int nand_davinci_calculate_ecc(struct mtd_info *mtd,
-+ const u_char *dat, u_char *ecc_code)
-+{
-+ unsigned int ecc_val = nand_davinci_readecc(mtd);
-+ /* squeeze 0 middle bits out so that it fits in 3 bytes */
-+ unsigned int tmp = (ecc_val&0x0fff)|((ecc_val&0x0fff0000)>>4);
-+ /* invert so that erased block ecc is correct */
-+ tmp = ~tmp;
-+ ecc_code[0] = (u_char)(tmp);
-+ ecc_code[1] = (u_char)(tmp >> 8);
-+ ecc_code[2] = (u_char)(tmp >> 16);
-+
-+ return 0;
-+}
-+
-+static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat,
-+ u_char *read_ecc, u_char *calc_ecc)
-+{
-+ struct nand_chip *chip = mtd->priv;
-+ u_int32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) |
-+ (read_ecc[2] << 16);
-+ u_int32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) |
-+ (calc_ecc[2] << 16);
-+ u_int32_t diff = eccCalc ^ eccNand;
-+
-+ if (diff) {
-+ if ((((diff>>12)^diff) & 0xfff) == 0xfff) {
-+ /* Correctable error */
-+ if ((diff>>(12+3)) < chip->ecc.size) {
-+ dat[diff>>(12+3)] ^= (1 << ((diff>>12)&7));
-+ return 1;
-+ } else {
-+ return -1;
-+ }
-+ } else if (!(diff & (diff-1))) {
-+ /* Single bit ECC error in the ECC itself,
-+ nothing to fix */
-+ return 1;
-+ } else {
-+ /* Uncorrectable error */
-+ return -1;
-+ }
-+
-+ }
-+ return 0;
-+}
-+#endif
-+
-+/*
-+ * Read OOB data from flash.
-+ */
-+static int read_oob_and_check(struct mtd_info *mtd, loff_t offs, uint8_t *buf,
-+ struct nand_bbt_descr *bd)
-+{
-+ int i, ret;
-+ int page;
-+ struct nand_chip *chip = mtd->priv;
-+
-+ /* Calculate page address from offset */
-+ page = (int)(offs >> chip->page_shift);
-+ page &= chip->pagemask;
-+
-+ /* Read OOB data from flash */
-+ ret = chip->ecc.read_oob(mtd, chip, page, 1);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Copy read OOB data to the buffer*/
-+ memcpy(buf, chip->oob_poi, mtd->oobsize);
-+
-+ /* Check pattern against BBM in OOB area */
-+ for (i = 0; i < bd->len; i++) {
-+ if (buf[bd->offs + i] != bd->pattern[i])
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Fill in the memory based Bad Block Table (BBT).
-+ */
-+static int nand_davinci_memory_bbt(struct mtd_info *mtd,
-+ struct nand_bbt_descr *bd)
-+{
-+ int i, numblocks;
-+ int startblock = 0;
-+ loff_t from = 0;
-+ struct nand_chip *chip = mtd->priv;
-+ int blocksize = 1 << chip->bbt_erase_shift;
-+ uint8_t *buf = chip->buffers->databuf;
-+ int len = bd->options & NAND_BBT_SCAN2NDPAGE ? 2 : 1;
-+
-+ /* -numblocks- is 2 times the actual number of eraseblocks */
-+ numblocks = mtd->size >> (chip->bbt_erase_shift - 1);
-+
-+ /* Now loop through all eraseblocks in the flash */
-+ for (i = startblock; i < numblocks; i += 2) {
-+ int j, ret;
-+ int offs = from;
-+
-+ /* If NAND_BBT_SCAN2NDPAGE flag is set in bd->options,
-+ * also each 2nd page of an eraseblock is checked
-+ * for a Bad Block Marker. In that case, len equals 2.
-+ */
-+ for (j = 0; j < len; j++) {
-+ /* Read OOB data and check pattern */
-+ ret = read_oob_and_check(mtd, from, buf, bd);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Check pattern for bad block markers */
-+ if (ret) {
-+ /* Mark bad block by writing 0b11 in the
-+ table */
-+ chip->bbt[i >> 3] |= 0x03 << (i & 0x6);
-+
-+ printk(KERN_WARNING "Bad eraseblock %d at " \
-+ "0x%08x\n", i >> 1,
-+ (unsigned int)from);
-+
-+ mtd->ecc_stats.badblocks++;
-+ break;
-+ }
-+ offs += mtd->writesize;
-+ }
-+
-+ /* Make -from- point to next eraseblock */
-+ from += blocksize;
-+ }
-+
-+ printk(KERN_NOTICE "Bad block scan: %d out of %d blocks are bad.\n",
-+ mtd->ecc_stats.badblocks, numblocks>>1);
-+
-+ return 0;
-+}
-+
-+/*
-+ * This function creates a memory based bad block table (BBT).
-+ * It is largely based on the standard BBT function, but all
-+ * unnecessary junk is thrown out to speed up.
-+ */
-+static int nand_davinci_scan_bbt(struct mtd_info *mtd)
-+{
-+ struct nand_chip *chip = mtd->priv;
-+ struct nand_bbt_descr *bd;
-+ int len, ret = 0;
-+
-+ chip->bbt_td = NULL;
-+ chip->bbt_md = NULL;
-+
-+ /* pagesize determines location of BBM */
-+ if (mtd->writesize > 512)
-+ bd = &davinci_memorybased_large;
-+ else
-+ bd = &davinci_memorybased_small;
-+
-+ chip->badblock_pattern = bd;
-+
-+ /* Use 2 bits per page meaning 4 page markers per byte */
-+ len = mtd->size >> (chip->bbt_erase_shift + 2);
-+
-+ /* Allocate memory (2bit per block) and clear the memory bad block
-+ table */
-+ chip->bbt = kzalloc(len, GFP_KERNEL);
-+ if (!chip->bbt) {
-+ printk(KERN_ERR "nand_davinci_scan_bbt: Out of memory\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* Now try to fill in the BBT */
-+ ret = nand_davinci_memory_bbt(mtd, bd);
-+ if (ret) {
-+ printk(KERN_ERR "nand_davinci_scan_bbt: "
-+ "Can't scan flash and build the RAM-based BBT\n");
-+
-+ kfree(chip->bbt);
-+ chip->bbt = NULL;
-+ }
-+
-+ return ret;
-+}
-+
-+/*
-+ * Read from memory register: we can read 4 bytes at a time.
-+ * The hardware takes care of actually reading the NAND flash.
-+ */
-+static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-+{
-+ int i;
-+ int num_words = len >> 2;
-+ u32 *p = (u32 *)buf;
-+ struct nand_chip *chip = mtd->priv;
-+
-+ for (i = 0; i < num_words; i++)
-+ p[i] = readl(chip->IO_ADDR_R);
-+}
-+
-+/*
-+ * Check hardware register for wait status. Returns 1 if device is ready,
-+ * 0 if it is still busy.
-+ */
-+static int nand_davinci_dev_ready(struct mtd_info *mtd)
-+{
-+ return (davinci_nand_readl(NANDFSR_OFFSET) & NAND_BUSY_FLAG);
-+}
-+
-+static void nand_davinci_set_eccsize(struct nand_chip *chip)
-+{
-+ chip->ecc.size = 256;
-+
-+#ifdef CONFIG_NAND_FLASH_HW_ECC
-+ switch (chip->ecc.mode) {
-+ case NAND_ECC_HW12_2048:
-+ chip->ecc.size = 2048;
-+ break;
-+
-+ case NAND_ECC_HW3_512:
-+ case NAND_ECC_HW6_512:
-+ case NAND_ECC_HW8_512:
-+ chip->ecc.size = 512;
-+ break;
-+
-+ case NAND_ECC_HW3_256:
-+ default:
-+ /* do nothing */
-+ break;
-+ }
-+#endif
-+}
-+
-+static void nand_davinci_set_eccbytes(struct nand_chip *chip)
-+{
-+ chip->ecc.bytes = 3;
-+
-+#ifdef CONFIG_NAND_FLASH_HW_ECC
-+ switch (chip->ecc.mode) {
-+ case NAND_ECC_HW12_2048:
-+ chip->ecc.bytes += 4;
-+ case NAND_ECC_HW8_512:
-+ chip->ecc.bytes += 2;
-+ case NAND_ECC_HW6_512:
-+ chip->ecc.bytes += 3;
-+ case NAND_ECC_HW3_512:
-+ case NAND_ECC_HW3_256:
-+ default:
-+ /* do nothing */
-+ break;
-+ }
-+#endif
-+}
-+
-+static void __devinit nand_davinci_flash_init(void)
-+{
-+ u32 regval, tmp;
-+
-+ /* Check for correct pin mux, reconfigure if necessary */
-+ tmp = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + PINMUX0);
-+
-+ if ((tmp & 0x20020C1F) != 0x00000C1F) {
-+ /* Disable HPI and ATA mux */
-+ davinci_mux_peripheral(DAVINCI_MUX_HPIEN, 0);
-+ davinci_mux_peripheral(DAVINCI_MUX_ATAEN, 0);
-+
-+ /* Enable VLYNQ and AEAW */
-+ davinci_mux_peripheral(DAVINCI_MUX_AEAW0, 1);
-+ davinci_mux_peripheral(DAVINCI_MUX_AEAW1, 1);
-+ davinci_mux_peripheral(DAVINCI_MUX_AEAW2, 1);
-+ davinci_mux_peripheral(DAVINCI_MUX_AEAW3, 1);
-+ davinci_mux_peripheral(DAVINCI_MUX_AEAW4, 1);
-+ davinci_mux_peripheral(DAVINCI_MUX_VLSCREN, 1);
-+ davinci_mux_peripheral(DAVINCI_MUX_VLYNQEN, 1);
-+
-+ regval = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + PINMUX0);
-+
-+ printk(KERN_WARNING "Warning: MUX config for NAND: Set " \
-+ "PINMUX0 reg to 0x%08x, was 0x%08x, should be done " \
-+ "by bootloader.\n", regval, tmp);
-+ }
-+
-+ regval = davinci_nand_readl(AWCCR_OFFSET);
-+ regval |= 0x10000000;
-+ davinci_nand_writel(regval, AWCCR_OFFSET);
-+
-+ /*------------------------------------------------------------------*
-+ * NAND FLASH CHIP TIMEOUT @ 459 MHz *
-+ * *
-+ * AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz *
-+ * AEMIF.CLK period = 1/76.5 MHz = 13.1 ns *
-+ * *
-+ *------------------------------------------------------------------*/
-+ regval = 0
-+ | (0 << 31) /* selectStrobe */
-+ | (0 << 30) /* extWait */
-+ | (1 << 26) /* writeSetup 10 ns */
-+ | (3 << 20) /* writeStrobe 40 ns */
-+ | (1 << 17) /* writeHold 10 ns */
-+ | (0 << 13) /* readSetup 10 ns */
-+ | (3 << 7) /* readStrobe 60 ns */
-+ | (0 << 4) /* readHold 10 ns */
-+ | (3 << 2) /* turnAround ?? ns */
-+ | (0 << 0) /* asyncSize 8-bit bus */
-+ ;
-+ tmp = davinci_nand_readl(A1CR_OFFSET);
-+ if (tmp != regval) {
-+ printk(KERN_WARNING "Warning: NAND config: Set A1CR " \
-+ "reg to 0x%08x, was 0x%08x, should be done by " \
-+ "bootloader.\n", regval, tmp);
-+ davinci_nand_writel(regval, A1CR_OFFSET); /* 0x0434018C */
-+ }
-+
-+ davinci_nand_writel(0x00000101, NANDFCR_OFFSET);
-+}
-+
-+/*
-+ * Main initialization routine
-+ */
-+int __devinit nand_davinci_probe(struct platform_device *pdev)
-+{
-+ struct nand_platform_data *pdata = pdev->dev.platform_data;
-+ struct resource *res = pdev->resource;
-+ struct nand_chip *chip;
-+ struct device *dev = NULL;
-+ u32 nand_rev_code;
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+ char *master_name;
-+ int mtd_parts_nb = 0;
-+ struct mtd_partition *mtd_parts = 0;
-+#endif
-+
-+ nand_clock = clk_get(dev, "AEMIFCLK");
-+ if (IS_ERR(nand_clock)) {
-+ printk(KERN_ERR "Error %ld getting AEMIFCLK clock?\n",
-+ PTR_ERR(nand_clock));
-+ return -1;
-+ }
-+
-+ clk_enable(nand_clock);
-+
-+ /* Allocate memory for MTD device structure and private data */
-+ nand_davinci_mtd = kmalloc(sizeof(struct mtd_info) +
-+ sizeof(struct nand_chip), GFP_KERNEL);
-+
-+ if (!nand_davinci_mtd) {
-+ printk(KERN_ERR "Unable to allocate davinci NAND MTD device " \
-+ "structure.\n");
-+ clk_disable(nand_clock);
-+ return -ENOMEM;
-+ }
-+
-+ /* Get pointer to private data */
-+ chip = (struct nand_chip *) (&nand_davinci_mtd[1]);
-+
-+ /* Initialize structures */
-+ memset((char *)nand_davinci_mtd, 0, sizeof(struct mtd_info));
-+ memset((char *)chip, 0, sizeof(struct nand_chip));
-+
-+ /* Link the private data with the MTD structure */
-+ nand_davinci_mtd->priv = chip;
-+
-+ nand_rev_code = davinci_nand_readl(NRCSR_OFFSET);
-+
-+ printk("DaVinci NAND Controller rev. %d.%d\n",
-+ (nand_rev_code >> 8) & 0xff, nand_rev_code & 0xff);
-+
-+ nand_vaddr = ioremap(res->start, res->end - res->start);
-+ if (nand_vaddr == NULL) {
-+ printk(KERN_ERR "DaVinci NAND: ioremap failed.\n");
-+ clk_disable(nand_clock);
-+ kfree(nand_davinci_mtd);
-+ return -ENOMEM;
-+ }
-+
-+ chip->IO_ADDR_R = (void __iomem *)nand_vaddr;
-+ chip->IO_ADDR_W = (void __iomem *)nand_vaddr;
-+ chip->chip_delay = 0;
-+ chip->select_chip = nand_davinci_select_chip;
-+ chip->options = 0;
-+ chip->ecc.mode = DAVINCI_NAND_ECC_MODE;
-+
-+ /* Set ECC size and bytes */
-+ nand_davinci_set_eccsize(chip);
-+ nand_davinci_set_eccbytes(chip);
-+
-+ /* Set address of hardware control function */
-+ chip->cmd_ctrl = nand_davinci_hwcontrol;
-+ chip->dev_ready = nand_davinci_dev_ready;
-+
-+#ifdef CONFIG_NAND_FLASH_HW_ECC
-+ chip->ecc.calculate = nand_davinci_calculate_ecc;
-+ chip->ecc.correct = nand_davinci_correct_data;
-+ chip->ecc.hwctl = nand_davinci_enable_hwecc;
-+#endif
-+
-+ /* Speed up the read buffer */
-+ chip->read_buf = nand_davinci_read_buf;
-+
-+ /* Speed up the creation of the bad block table */
-+ chip->scan_bbt = nand_davinci_scan_bbt;
-+
-+ nand_davinci_flash_init();
-+
-+ nand_davinci_mtd->owner = THIS_MODULE;
-+
-+ /* Scan to find existence of the device */
-+ if (nand_scan(nand_davinci_mtd, 1)) {
-+ printk(KERN_ERR "Chip Select is not set for NAND\n");
-+ clk_disable(nand_clock);
-+ kfree(nand_davinci_mtd);
-+ return -ENXIO;
-+ }
-+
-+ /* Register the partitions */
-+ add_mtd_partitions(nand_davinci_mtd, pdata->parts, pdata->nr_parts);
-+
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+ /* Set nand_davinci_mtd->name = 0 temporarily */
-+ master_name = nand_davinci_mtd->name;
-+ nand_davinci_mtd->name = (char *)0;
-+
-+ /* nand_davinci_mtd->name == 0, means: don't bother checking
-+ <mtd-id> */
-+ mtd_parts_nb = parse_mtd_partitions(nand_davinci_mtd, part_probes,
-+ &mtd_parts, 0);
-+
-+ /* Restore nand_davinci_mtd->name */
-+ nand_davinci_mtd->name = master_name;
-+
-+ add_mtd_partitions(nand_davinci_mtd, mtd_parts, mtd_parts_nb);
-+#endif
-+
-+ return 0;
-+}
-+
-+/*
-+ * Clean up routine
-+ */
-+static int nand_davinci_remove(struct platform_device *pdev)
-+{
-+ clk_disable(nand_clock);
-+
-+ if (nand_vaddr)
-+ iounmap(nand_vaddr);
-+
-+ /* Release resources, unregister device */
-+ nand_release(nand_davinci_mtd);
-+
-+ /* Free the MTD device structure */
-+ kfree(nand_davinci_mtd);
-+
-+ return 0;
-+}
-+
-+
-+static struct platform_driver nand_davinci_driver = {
-+ .probe = nand_davinci_probe,
-+ .remove = nand_davinci_remove,
-+ .driver = {
-+ .name = DRIVER_NAME,
-+ },
-+};
-+
-+static int __init nand_davinci_init(void)
-+{
-+ return platform_driver_register(&nand_davinci_driver);
-+}
-+module_init(nand_davinci_init);
-+
-+#ifdef MODULE
-+static void __exit nand_davinci_exit(void)
-+{
-+ platform_driver_unregister(&nand_davinci_driver);
-+}
-+module_exit(nand_davinci_exit);
-+#endif
-+
-+MODULE_ALIAS(DRIVER_NAME);
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Texas Instruments");
-+MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on davinci" \
-+ "board");
-Index: linux-davinci/drivers/mtd/nand/Makefile
-===================================================================
---- linux-davinci.orig/drivers/mtd/nand/Makefile
-+++ linux-davinci/drivers/mtd/nand/Makefile
-@@ -29,5 +29,6 @@ obj-$(CONFIG_MTD_NAND_AT91) += at91_nan
- obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o
- obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
- obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
-+obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o
-
- nand-objs := nand_base.o nand_bbt.o
-Index: linux-davinci/drivers/mtd/nand/Kconfig
-===================================================================
---- linux-davinci.orig/drivers/mtd/nand/Kconfig
-+++ linux-davinci/drivers/mtd/nand/Kconfig
-@@ -293,5 +293,17 @@ config MTD_NAND_PLATFORM
- devices. You will need to provide platform-specific functions
- via platform_data.
-
-+config MTD_NAND_DAVINCI
-+ tristate "NAND Flash device on DaVinci SoC"
-+ depends on MTD_NAND
-+ select MTD_PARTITIONS
-+ help
-+ Support for NAND flash on Texas Instruments DaVinci SoC.
-+
-+config NAND_FLASH_HW_ECC
-+ bool "Hardware ECC Support on NAND Device for DaVinci"
-+ depends on MTD_NAND_DAVINCI
-+ help
-+ Support for Hardware ECC on NAND device for DaVinci.
-
- endif # MTD_NAND
-Index: linux-davinci/include/asm-arm/arch-davinci/nand.h
-===================================================================
---- /dev/null
-+++ linux-davinci/include/asm-arm/arch-davinci/nand.h
-@@ -0,0 +1,45 @@
-+/*
-+ * include/asm-arm/arch-davinci/nand.h
-+ *
-+ * Copyright (C) 2006 Texas Instruments.
-+ *
-+ * ported to 2.6.23 (C) 2008 by
-+ * Sander Huijsen <Shuijsen@optelecom-nkf.com>
-+ * Troy Kisky <troy.kisky@boundarydevices.com>
-+ * Dirk Behme <Dirk.Behme@gmail.com>
-+ *
-+ * --------------------------------------------------------------------------
-+ *
-+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ * --------------------------------------------------------------------------
-+ *
-+ */
-+
-+#ifndef __ARCH_ARM_DAVINCI_NAND_H
-+#define __ARCH_ARM_DAVINCI_NAND_H
-+
-+#define NRCSR_OFFSET 0x00
-+#define AWCCR_OFFSET 0x04
-+#define A1CR_OFFSET 0x10
-+#define NANDFCR_OFFSET 0x60
-+#define NANDFSR_OFFSET 0x64
-+#define NANDF1ECC_OFFSET 0x70
-+
-+#define MASK_ALE 0x0A
-+#define MASK_CLE 0x10
-+
-+#define NAND_BUSY_FLAG 0x01
-+
-+#endif /* __ARCH_ARM_DAVINCI_NAND_H */
-Index: linux-davinci/arch/arm/mach-davinci/mux.c
-===================================================================
---- linux-davinci.orig/arch/arm/mach-davinci/mux.c
-+++ linux-davinci/arch/arm/mach-davinci/mux.c
-@@ -15,10 +15,6 @@
-
- #include <asm/arch/mux.h>
-
--/* System control register offsets */
--#define PINMUX0 0x00
--#define PINMUX1 0x04
--
- static DEFINE_SPINLOCK(mux_lock);
-
- void davinci_mux_peripheral(unsigned int mux, unsigned int enable)
-Index: linux-davinci/include/asm-arm/arch-davinci/mux.h
-===================================================================
---- linux-davinci.orig/include/asm-arm/arch-davinci/mux.h
-+++ linux-davinci/include/asm-arm/arch-davinci/mux.h
-@@ -11,6 +11,11 @@
- #ifndef __ASM_ARCH_MUX_H
- #define __ASM_ARCH_MUX_H
-
-+/* System control register offsets */
-+#define PINMUX0 0x00
-+#define PINMUX1 0x04
-+
-+/* System control register bits */
- #define DAVINCI_MUX_AEAW0 0
- #define DAVINCI_MUX_AEAW1 1
- #define DAVINCI_MUX_AEAW2 2
-Index: linux-davinci/include/linux/mtd/nand.h
-===================================================================
---- linux-davinci.orig/include/linux/mtd/nand.h
-+++ linux-davinci/include/linux/mtd/nand.h
-@@ -123,6 +123,13 @@ typedef enum {
- NAND_ECC_SOFT,
- NAND_ECC_HW,
- NAND_ECC_HW_SYNDROME,
-+#ifdef CONFIG_NAND_FLASH_HW_ECC
-+ NAND_ECC_HW3_256,
-+ NAND_ECC_HW3_512,
-+ NAND_ECC_HW6_512,
-+ NAND_ECC_HW8_512,
-+ NAND_ECC_HW12_2048,
-+#endif
- } nand_ecc_modes_t;
-
- /*
-Index: linux-davinci/drivers/mtd/nand/nand_base.c
-===================================================================
---- linux-davinci.orig/drivers/mtd/nand/nand_base.c
-+++ linux-davinci/drivers/mtd/nand/nand_base.c
-@@ -2456,6 +2456,13 @@ int nand_scan_tail(struct mtd_info *mtd)
- chip->ecc.write_page_raw = nand_write_page_raw;
-
- switch (chip->ecc.mode) {
-+#ifdef CONFIG_NAND_FLASH_HW_ECC
-+ case NAND_ECC_HW12_2048:
-+ case NAND_ECC_HW8_512:
-+ case NAND_ECC_HW6_512:
-+ case NAND_ECC_HW3_512:
-+ case NAND_ECC_HW3_256:
-+#endif
- case NAND_ECC_HW:
- /* Use standard hwecc read page function ? */
- if (!chip->ecc.read_page)
-Index: linux-davinci/arch/arm/mach-davinci/board-evm.c
-===================================================================
---- linux-davinci.orig/arch/arm/mach-davinci/board-evm.c
-+++ linux-davinci/arch/arm/mach-davinci/board-evm.c
-@@ -14,6 +14,7 @@
- #include <linux/dma-mapping.h>
- #include <linux/platform_device.h>
- #include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
- #include <linux/mtd/partitions.h>
- #include <linux/mtd/physmap.h>
-
-@@ -27,6 +28,7 @@
- #include <asm/mach/flash.h>
-
- #include <asm/arch/common.h>
-+#include <asm/arch/hardware.h>
- #include <asm/arch/psc.h>
-
- /* other misc. init functions */
-@@ -38,7 +40,7 @@ void __init davinci_init_common_hw(void)
- /* NOR Flash base address set to CS0 by default */
- #define NOR_FLASH_PHYS 0x02000000
-
--static struct mtd_partition davinci_evm_partitions[] = {
-+static struct mtd_partition davinci_evm_norflash_partitions[] = {
- /* bootloader (U-Boot, etc) in first 4 sectors */
- {
- .name = "bootloader",
-@@ -69,30 +71,63 @@ static struct mtd_partition davinci_evm_
- }
- };
-
--static struct physmap_flash_data davinci_evm_flash_data = {
-+static struct physmap_flash_data davinci_evm_norflash_data = {
- .width = 2,
-- .parts = davinci_evm_partitions,
-- .nr_parts = ARRAY_SIZE(davinci_evm_partitions),
-+ .parts = davinci_evm_norflash_partitions,
-+ .nr_parts = ARRAY_SIZE(davinci_evm_norflash_partitions),
- };
-
- /* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF
- * limits addresses to 16M, so using addresses past 16M will wrap */
--static struct resource davinci_evm_flash_resource = {
-+static struct resource davinci_evm_norflash_resource = {
- .start = NOR_FLASH_PHYS,
- .end = NOR_FLASH_PHYS + SZ_16M - 1,
- .flags = IORESOURCE_MEM,
- };
-
--static struct platform_device davinci_evm_flash_device = {
-+static struct platform_device davinci_evm_norflash_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
-- .platform_data = &davinci_evm_flash_data,
-+ .platform_data = &davinci_evm_norflash_data,
- },
- .num_resources = 1,
-- .resource = &davinci_evm_flash_resource,
-+ .resource = &davinci_evm_norflash_resource,
- };
-
-+#if defined(CONFIG_MTD_NAND_DAVINCI) || defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
-+struct mtd_partition davinci_evm_nandflash_partition[] = {
-+ /* 5 MB space at the beginning for bootloader and kernel */
-+ {
-+ .name = "NAND filesystem",
-+ .offset = 5 * SZ_1M,
-+ .size = MTDPART_SIZ_FULL,
-+ .mask_flags = 0,
-+ }
-+};
-+
-+static struct nand_platform_data davinci_evm_nandflash_data = {
-+ .parts = davinci_evm_nandflash_partition,
-+ .nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition),
-+};
-+
-+static struct resource davinci_evm_nandflash_resource = {
-+ .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
-+ .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16K - 1,
-+ .flags = IORESOURCE_MEM,
-+};
-+
-+static struct platform_device davinci_evm_nandflash_device = {
-+ .name = "davinci_nand",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &davinci_evm_nandflash_data,
-+ },
-+ .num_resources = 1,
-+ .resource = &davinci_evm_nandflash_resource,
-+};
-+#endif
-+
- #if defined(CONFIG_FB_DAVINCI) || defined(CONFIG_FB_DAVINCI_MODULE)
-
- static u64 davinci_fb_dma_mask = DMA_32BIT_MASK;
-@@ -168,7 +203,10 @@ static struct platform_device rtc_dev =
- };
-
- static struct platform_device *davinci_evm_devices[] __initdata = {
-- &davinci_evm_flash_device,
-+ &davinci_evm_norflash_device,
-+#if defined(CONFIG_MTD_NAND_DAVINCI) || defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
-+ &davinci_evm_nandflash_device,
-+#endif
- #if defined(CONFIG_FB_DAVINCI) || defined(CONFIG_FB_DAVINCI_MODULE)
- &davinci_fb_device,
- #endif