diff options
Diffstat (limited to 'packages/linux/compulab-pxa270-2.6.20/0004-nand-driver.patch')
-rw-r--r-- | packages/linux/compulab-pxa270-2.6.20/0004-nand-driver.patch | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/packages/linux/compulab-pxa270-2.6.20/0004-nand-driver.patch b/packages/linux/compulab-pxa270-2.6.20/0004-nand-driver.patch new file mode 100644 index 0000000000..f8e05c3c22 --- /dev/null +++ b/packages/linux/compulab-pxa270-2.6.20/0004-nand-driver.patch @@ -0,0 +1,324 @@ +From nobody Mon Sep 17 00:00:00 2001 +From: Cliff Brake <cbrake@happy.dev.bec-systems.com> +Date: Tue Apr 3 11:38:59 2007 -0400 +Subject: [PATCH] nand driver + +2.6.20 NAND flash driver for cm-x270 + +--- + + drivers/mtd/nand/Kconfig | 4 + + drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/cmx270-nand.c | 271 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 276 insertions(+), 0 deletions(-) + create mode 100644 drivers/mtd/nand/cmx270-nand.c + +base a34beb5936e5819d8b2d51b153434825700463ef +last deaa2960bd8fb1f706a935cd7a87321977e6f568 +diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig +index 358f55a82dbe4ebb73b1b0ee460063a6145e3f0e..c80272bcc69b6e13ab0c4403e4635a8a4076dc6c 100644 +--- a/drivers/mtd/nand/Kconfig ++++ b/drivers/mtd/nand/Kconfig +@@ -247,6 +247,10 @@ config MTD_NAND_AT91 + help + Enables support for NAND Flash / Smart Media Card interface + on Atmel AT91 processors. ++ ++config MTD_NAND_CM_X270 ++ tristate "Support for NAND Flash on CompuLab CM-X270" ++ depends on MTD_NAND && ARCH_PXA + + config MTD_NAND_NANDSIM + tristate "Support for NAND Flash Simulator" +diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile +index f7a53f0b70177451680402a2c2cce4c98991cd6e..d5abbca6d5ae18e287af0b02075f99838d35dc85 100644 +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -24,6 +24,7 @@ obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o + obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o + obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o + obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o ++obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270-nand.o + + nand-objs := nand_base.o nand_bbt.o + cafe_nand-objs := cafe.o cafe_ecc.o +diff --git a/drivers/mtd/nand/cmx270-nand.c b/drivers/mtd/nand/cmx270-nand.c +new file mode 100644 +index 0000000000000000000000000000000000000000..1cd531e610dee846e246b4b1d56bb4119939682b +--- /dev/null ++++ b/drivers/mtd/nand/cmx270-nand.c +@@ -0,0 +1,271 @@ ++/* ++ * drivers/mtd/nand/cmx270-nand.c ++ * ++ * Copyright (C) 2005 Compulab, Ltd. (mike@compulab.co.il) ++ * 2007 BEC Systems, LLC (cbrake@bec-systems.com) ++ * - updated to 2.6.20 NAND API ++ * ++ * Derived from drivers/mtd/nand/h1910.c ++ * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) ++ * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) ++ * ++ * ++ * 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. ++ * ++ * Overview: ++ * This is a device driver for the NAND flash device found on the ++ * CM-X270 board. ++ */ ++ ++#include <linux/slab.h> ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/nand.h> ++#include <linux/mtd/partitions.h> ++ ++#include <asm/io.h> ++#include <asm/irq.h> ++#include <asm/arch/hardware.h> ++#include <asm/arch/pxa-regs.h> ++ ++#define GPIO_NAND_CS (11) ++#define GPIO_NAND_RB (89) ++ ++#define DRAIN_WB() \ ++ do { \ ++ unsigned char dummy; \ ++ asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0"); \ ++ dummy=*((volatile unsigned char*)UNCACHED_ADDR); \ ++ } while(0); ++ ++/* ++ * MTD structure for CM-X270 board ++ */ ++static struct mtd_info *cmx270_nand_mtd = NULL; ++ ++/* ++ * Module stuff ++ */ ++ ++#ifdef CONFIG_MTD_PARTITIONS ++/* ++ * Define static partitions for flash device ++ */ ++static struct mtd_partition partition_info[] = { ++ { ++ .name = "app", ++ .offset = 0, ++ .size = 64*1024*1024 ++ }, ++ { ++ .name = "data", ++ .offset = MTDPART_OFS_APPEND, ++ .size = MTDPART_SIZ_FULL ++ } ++}; ++ ++#define NUM_PARTITIONS ARRAY_SIZE(partition_info) ++ ++#endif ++ ++ ++static u_char cmx270_read_byte(struct mtd_info *mtd) ++{ ++ struct nand_chip *this = mtd->priv; ++ return (readl(this->IO_ADDR_R) >> 16); ++} ++ ++static void cmx270_write_byte(struct mtd_info *mtd, u_char byte) ++{ ++ struct nand_chip *this = mtd->priv; ++ writel((byte << 16), this->IO_ADDR_W); ++} ++ ++static void cmx270_write_buf(struct mtd_info *mtd, const u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; i<len; i++) { ++ writel((*buf++ << 16), this->IO_ADDR_W); ++ } ++} ++ ++static void cmx270_read_buf(struct mtd_info *mtd, u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; i<len; i++) { ++ *buf++ = readl(this->IO_ADDR_R) >> 16; ++ } ++} ++ ++static int cmx270_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; i<len; i++) { ++ if ( buf[i] != (u_char)(readl(this->IO_ADDR_R) >> 16) ) ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++static inline void nand_cs_on(void) ++{ ++ GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); ++} ++ ++static void nand_cs_off(void) ++{ ++ DRAIN_WB(); ++ ++ GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); ++} ++ ++/* ++ * hardware specific access to control-lines ++ * ++ * NAND_NCE: bit 0 - GPIO_NAND_CS ++ * NAND_CLE: bit 1 - address bit 2 ++ * NAND_ALE: bit 2 - address bit 3 ++ */ ++static void cmx270_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) ++{ ++ struct nand_chip* chip = mtd->priv; ++ ++ DRAIN_WB(); ++ ++ if (ctrl & NAND_CTRL_CHANGE) { ++ if (ctrl & NAND_NCE) nand_cs_on(); ++ else nand_cs_off(); ++ } ++ ++ ++ if (cmd != NAND_CMD_NONE) { ++ writel(cmd << 16, (unsigned int)(chip->IO_ADDR_W) | ((ctrl & 0x6) << 1 )); ++ } ++ ++ DRAIN_WB(); ++} ++ ++/* ++ * read device ready pin ++ */ ++static int cmx270_device_ready(struct mtd_info *mtd) ++{ ++ DRAIN_WB(); ++ return ( GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB) ); ++} ++ ++/* ++ * Main initialization routine ++ */ ++static int __init cmx270_init (void) ++{ ++ struct nand_chip *this; ++ const char *part_type = 0; ++ int mtd_parts_nb = 0; ++ struct mtd_partition *mtd_parts = 0; ++ static unsigned int nandaddr = 0; ++ ++ ++ /* Allocate memory for MTD device structure and private data */ ++ cmx270_nand_mtd = kmalloc(sizeof(struct mtd_info) + ++ sizeof(struct nand_chip), ++ GFP_KERNEL); ++ if (!cmx270_nand_mtd) { ++ printk("Unable to allocate CM-X270 NAND MTD device structure.\n"); ++ return -ENOMEM; ++ } ++ ++ nandaddr = (volatile unsigned int)ioremap(PXA_CS1_PHYS, 100); ++ ++ /* Get pointer to private data */ ++ this = (struct nand_chip *) (&cmx270_nand_mtd[1]); ++ ++ /* Initialize structures */ ++ memset((char *) cmx270_nand_mtd, 0, sizeof(struct mtd_info)); ++ memset((char *) this, 0, sizeof(struct nand_chip)); ++ ++ /* Link the private data with the MTD structure */ ++ cmx270_nand_mtd->priv = this; ++ cmx270_nand_mtd->owner = THIS_MODULE; ++ ++ /* insert callbacks */ ++ this->IO_ADDR_R = (void __iomem *)nandaddr; ++ this->IO_ADDR_W = (void __iomem *)nandaddr; ++ this->cmd_ctrl = cmx270_hwcontrol; ++/* this->dev_ready = cmx270_device_ready; /\* unknown whether that was correct or not so we will just do it like this *\/ */ ++ ++ /* 15 us command delay time */ ++ this->chip_delay = 50; ++ this->ecc.mode = NAND_ECC_SOFT; ++ ++ /* read/write functions */ ++ this->read_byte = cmx270_read_byte; ++ //this->write_byte = cmx270_write_byte; ++ this->read_buf = cmx270_read_buf; ++ this->write_buf = cmx270_write_buf; ++ this->verify_buf = cmx270_verify_buf; ++ ++ /* Scan to find existence of the device */ ++ if (nand_scan (cmx270_nand_mtd, 1)) { ++ printk(KERN_NOTICE "No NAND device - returning -ENXIO\n"); ++ iounmap((void*)nandaddr); ++ kfree (cmx270_nand_mtd); ++ return -ENXIO; ++ } ++ ++//#ifdef CONFIG_MTD_CMDLINE_PARTS ++#if 0 ++ mtd_parts_nb = parse_cmdline_partitions(cmx270_nand_mtd, &mtd_parts, ++ "cmx270"); ++ if (mtd_parts_nb > 0) ++ part_type = "command line"; ++ else ++ mtd_parts_nb = 0; ++#endif ++ if (mtd_parts_nb == 0) ++ { ++ mtd_parts = partition_info; ++ mtd_parts_nb = NUM_PARTITIONS; ++ part_type = "static"; ++ } ++ ++ /* Register the partitions */ ++ printk(KERN_NOTICE "Using %s partition definition\n", part_type); ++ add_mtd_partitions(cmx270_nand_mtd, mtd_parts, mtd_parts_nb); ++ ++ /* Return happy */ ++ return 0; ++} ++module_init(cmx270_init); ++ ++/* ++ * Clean up routine ++ */ ++static void __exit cmx270_cleanup (void) ++{ ++ struct nand_chip *this; ++ ++ this = (struct nand_chip *) (&cmx270_nand_mtd[1]); ++ iounmap(this->IO_ADDR_R); ++ ++ /* Release resources, unregister device */ ++ nand_release (cmx270_nand_mtd); ++ ++ /* Free the MTD device structure */ ++ kfree (cmx270_nand_mtd); ++} ++module_exit(cmx270_cleanup); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Mike Rapoport <mike at compulab dot co dot il>"); ++MODULE_DESCRIPTION("NAND flash driver for Compulab CM-X270 Core"); +-- +1.4.4.4 + |