From a88bdbb54a9352b916877bfc5e316c44ec1b2d8f Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Fri, 11 Sep 2009 19:33:58 +0800 Subject: pxa3xx_nand: fix memory out of bound When fetch nand data with non-DMA mode, we should align info->data_size to 32bit, not 8bit. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- drivers/mtd/nand/pxa3xx_nand.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 6ea520ae241..f463ad272d3 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -9,6 +9,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -489,7 +490,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info) switch (info->state) { case STATE_PIO_WRITING: __raw_writesl(info->mmio_base + NDDB, info->data_buff, - info->data_size << 2); + DIV_ROUND_UP(info->data_size, 4)); enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); @@ -501,7 +502,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info) break; case STATE_PIO_READING: __raw_readsl(info->mmio_base + NDDB, info->data_buff, - info->data_size << 2); + DIV_ROUND_UP(info->data_size, 4)); break; default: printk(KERN_ERR "%s: invalid state %d\n", __func__, -- cgit v1.2.3-70-g09d2 From 7ce33aff68f653769ba16108834ed212788bcbb6 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 14 Sep 2009 20:21:01 +0800 Subject: pxa3xx_nand: reset read buffer before reading Initialize the read buffer content to 0xFF. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- drivers/mtd/nand/pxa3xx_nand.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index f463ad272d3..9140fdc42bc 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -670,6 +670,7 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, /* disable HW ECC to get all the OOB data */ info->buf_count = mtd->writesize + mtd->oobsize; info->buf_start = mtd->writesize + column; + memset(info->data_buff, 0xFF, info->buf_count); if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr)) break; -- cgit v1.2.3-70-g09d2 From 726de6e16d88986db3102ebe6ae277f73df63eaf Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 14 Oct 2009 15:47:01 +0800 Subject: pxa3xx_nand: adjust timing of Micron NAND flash Slow down the tRp of Micron NAND flash timing. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- drivers/mtd/nand/pxa3xx_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 9140fdc42bc..a085cd0a6e5 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -235,7 +235,7 @@ static struct pxa3xx_nand_timing micron_timing = { .tWH = 15, .tWP = 25, .tRH = 15, - .tRP = 25, + .tRP = 30, .tR = 25000, .tWHR = 60, .tAR = 10, -- cgit v1.2.3-70-g09d2 From 8638fac849c181176324f26b4b82e3b96f378dde Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 10 Sep 2009 14:11:44 +0800 Subject: pxa3xx_nand: remove hardcode register address Although nand controller is same between PXA3xx and MMP, the register space is different. Remove the hardcode register address setting in pxa3xx_nand.h. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- drivers/mtd/nand/pxa3xx_nand.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index a085cd0a6e5..3b4bc54df69 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -85,10 +85,6 @@ #define NDCB0_CMD1_MASK (0xff) #define NDCB0_ADDR_CYC_SHIFT (16) -/* dma-able I/O address for the NAND data and commands */ -#define NDCB0_DMA_ADDR (0x43100048) -#define NDDB_DMA_ADDR (0x43100040) - /* macros for registers read/write */ #define nand_writel(info, off, val) \ __raw_writel((val), (info)->mmio_base + (off)) @@ -124,6 +120,7 @@ struct pxa3xx_nand_info { struct clk *clk; void __iomem *mmio_base; + unsigned long mmio_phys; unsigned int buf_start; unsigned int buf_count; @@ -524,11 +521,11 @@ static void start_data_dma(struct pxa3xx_nand_info *info, int dir_out) if (dir_out) { desc->dsadr = info->data_buff_phys; - desc->dtadr = NDDB_DMA_ADDR; + desc->dtadr = info->mmio_phys + NDDB; desc->dcmd |= DCMD_INCSRCADDR | DCMD_FLOWTRG; } else { desc->dtadr = info->data_buff_phys; - desc->dsadr = NDDB_DMA_ADDR; + desc->dsadr = info->mmio_phys + NDDB; desc->dcmd |= DCMD_INCTRGADDR | DCMD_FLOWSRC; } @@ -1241,6 +1238,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) ret = -ENODEV; goto fail_free_res; } + info->mmio_phys = r->start; ret = pxa3xx_nand_init_buff(info); if (ret) -- cgit v1.2.3-70-g09d2 From dbf5986aed62620d3dde54e1b63889821c857675 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 10 Sep 2009 14:22:55 +0800 Subject: pxa3xx_nand: remove hardcode irq number Nand driver uses IRQ_NAND as hardcode irq number. In ARCH_MMP, the irq number is different. So get irq resource from platform device structure and use it in initialization and deinitialization code. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- drivers/mtd/nand/pxa3xx_nand.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 3b4bc54df69..e75b1bf6df1 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1244,8 +1244,8 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) if (ret) goto fail_free_io; - ret = request_irq(IRQ_NAND, pxa3xx_nand_irq, IRQF_DISABLED, - pdev->name, info); + ret = request_irq(irq, pxa3xx_nand_irq, IRQF_DISABLED, + pdev->name, info); if (ret < 0) { dev_err(&pdev->dev, "failed to request IRQ\n"); goto fail_free_buf; @@ -1271,7 +1271,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); fail_free_irq: - free_irq(IRQ_NAND, info); + free_irq(irq, info); fail_free_buf: if (use_dma) { pxa_free_dma(info->data_dma_ch); @@ -1296,12 +1296,15 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) struct mtd_info *mtd = platform_get_drvdata(pdev); struct pxa3xx_nand_info *info = mtd->priv; struct resource *r; + int irq; platform_set_drvdata(pdev, NULL); del_mtd_device(mtd); del_mtd_partitions(mtd); - free_irq(IRQ_NAND, info); + irq = platform_get_irq(pdev, 0); + if (irq >= 0) + free_irq(irq, info); if (use_dma) { pxa_free_dma(info->data_dma_ch); dma_free_writecombine(&pdev->dev, info->data_buff_size, -- cgit v1.2.3-70-g09d2 From 346e125967c39fc25263f3071dfc88224ae843f4 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 10 Sep 2009 14:27:23 +0800 Subject: pxa3xx_nand: disable nand irq in initialization In some bootloader, IRQ is enabled. Writing nand triggers unexpected interrupts. So disable nand irq in initialization. After nand initialized and in working state, irq is controlled by nand driver. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- drivers/mtd/nand/pxa3xx_nand.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index e75b1bf6df1..11f32454fc7 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1244,6 +1244,9 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) if (ret) goto fail_free_io; + /* initialize all interrupts to be disabled */ + disable_int(info, NDSR_MASK); + ret = request_irq(irq, pxa3xx_nand_irq, IRQF_DISABLED, pdev->name, info); if (ret < 0) { -- cgit v1.2.3-70-g09d2 From d3490dfdbc453a16bc7f3cff731c9f7851735ab3 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 10 Sep 2009 14:33:30 +0800 Subject: pxa3xx_nand: add new nand chip support Support samsung 2GbX8 and 32GbX8 nand flash. Support micron 4GbX8 and 4GbX16 nand flash. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- drivers/mtd/nand/pxa3xx_nand.c | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 11f32454fc7..7f97d57e8a5 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -226,6 +226,28 @@ static struct pxa3xx_nand_flash samsung512MbX16 = { .chip_id = 0x46ec, }; +static struct pxa3xx_nand_flash samsung2GbX8 = { + .timing = &samsung512MbX16_timing, + .cmdset = &smallpage_cmdset, + .page_per_block = 64, + .page_size = 2048, + .flash_width = 8, + .dfc_width = 8, + .num_blocks = 2048, + .chip_id = 0xdaec, +}; + +static struct pxa3xx_nand_flash samsung32GbX8 = { + .timing = &samsung512MbX16_timing, + .cmdset = &smallpage_cmdset, + .page_per_block = 128, + .page_size = 4096, + .flash_width = 8, + .dfc_width = 8, + .num_blocks = 8192, + .chip_id = 0xd7ec, +}; + static struct pxa3xx_nand_timing micron_timing = { .tCH = 10, .tCS = 25, @@ -260,6 +282,28 @@ static struct pxa3xx_nand_flash micron1GbX16 = { .chip_id = 0xb12c, }; +static struct pxa3xx_nand_flash micron4GbX8 = { + .timing = µn_timing, + .cmdset = &largepage_cmdset, + .page_per_block = 64, + .page_size = 2048, + .flash_width = 8, + .dfc_width = 8, + .num_blocks = 4096, + .chip_id = 0xdc2c, +}; + +static struct pxa3xx_nand_flash micron4GbX16 = { + .timing = µn_timing, + .cmdset = &largepage_cmdset, + .page_per_block = 64, + .page_size = 2048, + .flash_width = 16, + .dfc_width = 16, + .num_blocks = 4096, + .chip_id = 0xcc2c, +}; + static struct pxa3xx_nand_timing stm2GbX16_timing = { .tCH = 10, .tCS = 35, @@ -285,8 +329,12 @@ static struct pxa3xx_nand_flash stm2GbX16 = { static struct pxa3xx_nand_flash *builtin_flash_types[] = { &samsung512MbX16, + &samsung2GbX8, + &samsung32GbX8, µn1GbX8, µn1GbX16, + µn4GbX8, + µn4GbX16, &stm2GbX16, }; #endif /* CONFIG_MTD_NAND_PXA3xx_BUILTIN */ -- cgit v1.2.3-70-g09d2 From 171d0fbee2b80cd21ff590449a05a48c1dc917b8 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 10 Sep 2009 13:49:45 +0800 Subject: pxa3xx_nand: update dependancy to support ARCH_MMP MTD_NAND_PXA3xx module is shared between ARCH_PXA and ARCH_MMP. Update this configuration according to it. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- drivers/mtd/nand/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 2fda0b61524..8f8e87b7ed6 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -358,7 +358,7 @@ endchoice config MTD_NAND_PXA3xx tristate "Support for NAND flash devices on PXA3xx" - depends on MTD_NAND && PXA3xx + depends on MTD_NAND && (PXA3xx || ARCH_MMP) help This enables the driver for the NAND flash device found on PXA3xx processors -- cgit v1.2.3-70-g09d2 From 82b95ecb96122896fd5b7b75001fdda3e047ef38 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 10 Sep 2009 13:55:23 +0800 Subject: pxa3xx_nand: move pxa3xx_nand.h common into plat directory Since the same nand controller is shared between ARCH_PXA and ARCH_MMP. Move the pxa3xx_nand.h from mach directory to plat directoy. Signed-off-by: Haojian Zhuang Cc: David Woodhouse Signed-off-by: Eric Miao --- arch/arm/mach-pxa/cm-x300.c | 2 +- arch/arm/mach-pxa/colibri-pxa3xx.c | 2 +- arch/arm/mach-pxa/devices.c | 4 +- arch/arm/mach-pxa/include/mach/pxa3xx_nand.h | 63 ---------------------------- arch/arm/mach-pxa/littleton.c | 4 +- arch/arm/mach-pxa/zylonite.c | 2 +- arch/arm/plat-pxa/include/plat/pxa3xx_nand.h | 63 ++++++++++++++++++++++++++++ drivers/mtd/nand/pxa3xx_nand.c | 2 +- 8 files changed, 71 insertions(+), 71 deletions(-) delete mode 100644 arch/arm/mach-pxa/include/mach/pxa3xx_nand.h create mode 100644 arch/arm/plat-pxa/include/plat/pxa3xx_nand.h (limited to 'drivers/mtd') diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 102916f1e46..06552ca9181 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c index efebaf4d734..e6c0a2287eb 100644 --- a/arch/arm/mach-pxa/colibri-pxa3xx.c +++ b/arch/arm/mach-pxa/colibri-pxa3xx.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include "generic.h" #include "devices.h" diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 46fabe1cca1..e2b427fa55e 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -8,13 +8,13 @@ #include #include #include -#include #include #include #include #include #include -#include +#include +#include #include "devices.h" #include "generic.h" diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h deleted file mode 100644 index 3478eae32d8..00000000000 --- a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef __ASM_ARCH_PXA3XX_NAND_H -#define __ASM_ARCH_PXA3XX_NAND_H - -#include -#include - -struct pxa3xx_nand_timing { - unsigned int tCH; /* Enable signal hold time */ - unsigned int tCS; /* Enable signal setup time */ - unsigned int tWH; /* ND_nWE high duration */ - unsigned int tWP; /* ND_nWE pulse time */ - unsigned int tRH; /* ND_nRE high duration */ - unsigned int tRP; /* ND_nRE pulse width */ - unsigned int tR; /* ND_nWE high to ND_nRE low for read */ - unsigned int tWHR; /* ND_nWE high to ND_nRE low for status read */ - unsigned int tAR; /* ND_ALE low to ND_nRE low delay */ -}; - -struct pxa3xx_nand_cmdset { - uint16_t read1; - uint16_t read2; - uint16_t program; - uint16_t read_status; - uint16_t read_id; - uint16_t erase; - uint16_t reset; - uint16_t lock; - uint16_t unlock; - uint16_t lock_status; -}; - -struct pxa3xx_nand_flash { - const struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ - const struct pxa3xx_nand_cmdset *cmdset; - - uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */ - uint32_t page_size; /* Page size in bytes (PAGE_SZ) */ - uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */ - uint32_t dfc_width; /* Width of flash controller(DWIDTH_C) */ - uint32_t num_blocks; /* Number of physical blocks in Flash */ - uint32_t chip_id; -}; - -struct pxa3xx_nand_platform_data { - - /* the data flash bus is shared between the Static Memory - * Controller and the Data Flash Controller, the arbiter - * controls the ownership of the bus - */ - int enable_arbiter; - - /* allow platform code to keep OBM/bootloader defined NFC config */ - int keep_config; - - const struct mtd_partition *parts; - unsigned int nr_parts; - - const struct pxa3xx_nand_flash * flash; - size_t num_flash; -}; - -extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info); -#endif /* __ASM_ARCH_PXA3XX_NAND_H */ diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 13848955d13..ce5e6175a05 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -44,10 +44,10 @@ #include #include #include -#include #include -#include #include +#include +#include #include "generic.h" diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 09784d3954e..8fcb69411cf 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "devices.h" #include "generic.h" diff --git a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h new file mode 100644 index 00000000000..3478eae32d8 --- /dev/null +++ b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h @@ -0,0 +1,63 @@ +#ifndef __ASM_ARCH_PXA3XX_NAND_H +#define __ASM_ARCH_PXA3XX_NAND_H + +#include +#include + +struct pxa3xx_nand_timing { + unsigned int tCH; /* Enable signal hold time */ + unsigned int tCS; /* Enable signal setup time */ + unsigned int tWH; /* ND_nWE high duration */ + unsigned int tWP; /* ND_nWE pulse time */ + unsigned int tRH; /* ND_nRE high duration */ + unsigned int tRP; /* ND_nRE pulse width */ + unsigned int tR; /* ND_nWE high to ND_nRE low for read */ + unsigned int tWHR; /* ND_nWE high to ND_nRE low for status read */ + unsigned int tAR; /* ND_ALE low to ND_nRE low delay */ +}; + +struct pxa3xx_nand_cmdset { + uint16_t read1; + uint16_t read2; + uint16_t program; + uint16_t read_status; + uint16_t read_id; + uint16_t erase; + uint16_t reset; + uint16_t lock; + uint16_t unlock; + uint16_t lock_status; +}; + +struct pxa3xx_nand_flash { + const struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ + const struct pxa3xx_nand_cmdset *cmdset; + + uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */ + uint32_t page_size; /* Page size in bytes (PAGE_SZ) */ + uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */ + uint32_t dfc_width; /* Width of flash controller(DWIDTH_C) */ + uint32_t num_blocks; /* Number of physical blocks in Flash */ + uint32_t chip_id; +}; + +struct pxa3xx_nand_platform_data { + + /* the data flash bus is shared between the Static Memory + * Controller and the Data Flash Controller, the arbiter + * controls the ownership of the bus + */ + int enable_arbiter; + + /* allow platform code to keep OBM/bootloader defined NFC config */ + int keep_config; + + const struct mtd_partition *parts; + unsigned int nr_parts; + + const struct pxa3xx_nand_flash * flash; + size_t num_flash; +}; + +extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info); +#endif /* __ASM_ARCH_PXA3XX_NAND_H */ diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 7f97d57e8a5..1a5a0365c98 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -23,7 +23,7 @@ #include #include -#include +#include #define CHIP_DELAY_TIMEOUT (2 * HZ/10) -- cgit v1.2.3-70-g09d2