aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/pxa3xx_nand.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/pxa3xx_nand.c')
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c83
1 files changed, 69 insertions, 14 deletions
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 6ea520ae2410..5d55152162cf 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -9,6 +9,7 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/kernel.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/interrupt.h> 14#include <linux/interrupt.h>
14#include <linux/platform_device.h> 15#include <linux/platform_device.h>
@@ -20,9 +21,10 @@
20#include <linux/mtd/partitions.h> 21#include <linux/mtd/partitions.h>
21#include <linux/io.h> 22#include <linux/io.h>
22#include <linux/irq.h> 23#include <linux/irq.h>
24#include <linux/slab.h>
23 25
24#include <mach/dma.h> 26#include <mach/dma.h>
25#include <mach/pxa3xx_nand.h> 27#include <plat/pxa3xx_nand.h>
26 28
27#define CHIP_DELAY_TIMEOUT (2 * HZ/10) 29#define CHIP_DELAY_TIMEOUT (2 * HZ/10)
28 30
@@ -84,10 +86,6 @@
84#define NDCB0_CMD1_MASK (0xff) 86#define NDCB0_CMD1_MASK (0xff)
85#define NDCB0_ADDR_CYC_SHIFT (16) 87#define NDCB0_ADDR_CYC_SHIFT (16)
86 88
87/* dma-able I/O address for the NAND data and commands */
88#define NDCB0_DMA_ADDR (0x43100048)
89#define NDDB_DMA_ADDR (0x43100040)
90
91/* macros for registers read/write */ 89/* macros for registers read/write */
92#define nand_writel(info, off, val) \ 90#define nand_writel(info, off, val) \
93 __raw_writel((val), (info)->mmio_base + (off)) 91 __raw_writel((val), (info)->mmio_base + (off))
@@ -123,6 +121,7 @@ struct pxa3xx_nand_info {
123 121
124 struct clk *clk; 122 struct clk *clk;
125 void __iomem *mmio_base; 123 void __iomem *mmio_base;
124 unsigned long mmio_phys;
126 125
127 unsigned int buf_start; 126 unsigned int buf_start;
128 unsigned int buf_count; 127 unsigned int buf_count;
@@ -228,13 +227,35 @@ static struct pxa3xx_nand_flash samsung512MbX16 = {
228 .chip_id = 0x46ec, 227 .chip_id = 0x46ec,
229}; 228};
230 229
230static struct pxa3xx_nand_flash samsung2GbX8 = {
231 .timing = &samsung512MbX16_timing,
232 .cmdset = &smallpage_cmdset,
233 .page_per_block = 64,
234 .page_size = 2048,
235 .flash_width = 8,
236 .dfc_width = 8,
237 .num_blocks = 2048,
238 .chip_id = 0xdaec,
239};
240
241static struct pxa3xx_nand_flash samsung32GbX8 = {
242 .timing = &samsung512MbX16_timing,
243 .cmdset = &smallpage_cmdset,
244 .page_per_block = 128,
245 .page_size = 4096,
246 .flash_width = 8,
247 .dfc_width = 8,
248 .num_blocks = 8192,
249 .chip_id = 0xd7ec,
250};
251
231static struct pxa3xx_nand_timing micron_timing = { 252static struct pxa3xx_nand_timing micron_timing = {
232 .tCH = 10, 253 .tCH = 10,
233 .tCS = 25, 254 .tCS = 25,
234 .tWH = 15, 255 .tWH = 15,
235 .tWP = 25, 256 .tWP = 25,
236 .tRH = 15, 257 .tRH = 15,
237 .tRP = 25, 258 .tRP = 30,
238 .tR = 25000, 259 .tR = 25000,
239 .tWHR = 60, 260 .tWHR = 60,
240 .tAR = 10, 261 .tAR = 10,
@@ -262,6 +283,28 @@ static struct pxa3xx_nand_flash micron1GbX16 = {
262 .chip_id = 0xb12c, 283 .chip_id = 0xb12c,
263}; 284};
264 285
286static struct pxa3xx_nand_flash micron4GbX8 = {
287 .timing = &micron_timing,
288 .cmdset = &largepage_cmdset,
289 .page_per_block = 64,
290 .page_size = 2048,
291 .flash_width = 8,
292 .dfc_width = 8,
293 .num_blocks = 4096,
294 .chip_id = 0xdc2c,
295};
296
297static struct pxa3xx_nand_flash micron4GbX16 = {
298 .timing = &micron_timing,
299 .cmdset = &largepage_cmdset,
300 .page_per_block = 64,
301 .page_size = 2048,
302 .flash_width = 16,
303 .dfc_width = 16,
304 .num_blocks = 4096,
305 .chip_id = 0xcc2c,
306};
307
265static struct pxa3xx_nand_timing stm2GbX16_timing = { 308static struct pxa3xx_nand_timing stm2GbX16_timing = {
266 .tCH = 10, 309 .tCH = 10,
267 .tCS = 35, 310 .tCS = 35,
@@ -287,8 +330,12 @@ static struct pxa3xx_nand_flash stm2GbX16 = {
287 330
288static struct pxa3xx_nand_flash *builtin_flash_types[] = { 331static struct pxa3xx_nand_flash *builtin_flash_types[] = {
289 &samsung512MbX16, 332 &samsung512MbX16,
333 &samsung2GbX8,
334 &samsung32GbX8,
290 &micron1GbX8, 335 &micron1GbX8,
291 &micron1GbX16, 336 &micron1GbX16,
337 &micron4GbX8,
338 &micron4GbX16,
292 &stm2GbX16, 339 &stm2GbX16,
293}; 340};
294#endif /* CONFIG_MTD_NAND_PXA3xx_BUILTIN */ 341#endif /* CONFIG_MTD_NAND_PXA3xx_BUILTIN */
@@ -489,7 +536,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info)
489 switch (info->state) { 536 switch (info->state) {
490 case STATE_PIO_WRITING: 537 case STATE_PIO_WRITING:
491 __raw_writesl(info->mmio_base + NDDB, info->data_buff, 538 __raw_writesl(info->mmio_base + NDDB, info->data_buff,
492 info->data_size << 2); 539 DIV_ROUND_UP(info->data_size, 4));
493 540
494 enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); 541 enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD);
495 542
@@ -501,7 +548,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info)
501 break; 548 break;
502 case STATE_PIO_READING: 549 case STATE_PIO_READING:
503 __raw_readsl(info->mmio_base + NDDB, info->data_buff, 550 __raw_readsl(info->mmio_base + NDDB, info->data_buff,
504 info->data_size << 2); 551 DIV_ROUND_UP(info->data_size, 4));
505 break; 552 break;
506 default: 553 default:
507 printk(KERN_ERR "%s: invalid state %d\n", __func__, 554 printk(KERN_ERR "%s: invalid state %d\n", __func__,
@@ -523,11 +570,11 @@ static void start_data_dma(struct pxa3xx_nand_info *info, int dir_out)
523 570
524 if (dir_out) { 571 if (dir_out) {
525 desc->dsadr = info->data_buff_phys; 572 desc->dsadr = info->data_buff_phys;
526 desc->dtadr = NDDB_DMA_ADDR; 573 desc->dtadr = info->mmio_phys + NDDB;
527 desc->dcmd |= DCMD_INCSRCADDR | DCMD_FLOWTRG; 574 desc->dcmd |= DCMD_INCSRCADDR | DCMD_FLOWTRG;
528 } else { 575 } else {
529 desc->dtadr = info->data_buff_phys; 576 desc->dtadr = info->data_buff_phys;
530 desc->dsadr = NDDB_DMA_ADDR; 577 desc->dsadr = info->mmio_phys + NDDB;
531 desc->dcmd |= DCMD_INCTRGADDR | DCMD_FLOWSRC; 578 desc->dcmd |= DCMD_INCTRGADDR | DCMD_FLOWSRC;
532 } 579 }
533 580
@@ -669,6 +716,7 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
669 /* disable HW ECC to get all the OOB data */ 716 /* disable HW ECC to get all the OOB data */
670 info->buf_count = mtd->writesize + mtd->oobsize; 717 info->buf_count = mtd->writesize + mtd->oobsize;
671 info->buf_start = mtd->writesize + column; 718 info->buf_start = mtd->writesize + column;
719 memset(info->data_buff, 0xFF, info->buf_count);
672 720
673 if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr)) 721 if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr))
674 break; 722 break;
@@ -1239,13 +1287,17 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
1239 ret = -ENODEV; 1287 ret = -ENODEV;
1240 goto fail_free_res; 1288 goto fail_free_res;
1241 } 1289 }
1290 info->mmio_phys = r->start;
1242 1291
1243 ret = pxa3xx_nand_init_buff(info); 1292 ret = pxa3xx_nand_init_buff(info);
1244 if (ret) 1293 if (ret)
1245 goto fail_free_io; 1294 goto fail_free_io;
1246 1295
1247 ret = request_irq(IRQ_NAND, pxa3xx_nand_irq, IRQF_DISABLED, 1296 /* initialize all interrupts to be disabled */
1248 pdev->name, info); 1297 disable_int(info, NDSR_MASK);
1298
1299 ret = request_irq(irq, pxa3xx_nand_irq, IRQF_DISABLED,
1300 pdev->name, info);
1249 if (ret < 0) { 1301 if (ret < 0) {
1250 dev_err(&pdev->dev, "failed to request IRQ\n"); 1302 dev_err(&pdev->dev, "failed to request IRQ\n");
1251 goto fail_free_buf; 1303 goto fail_free_buf;
@@ -1271,7 +1323,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
1271 return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); 1323 return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
1272 1324
1273fail_free_irq: 1325fail_free_irq:
1274 free_irq(IRQ_NAND, info); 1326 free_irq(irq, info);
1275fail_free_buf: 1327fail_free_buf:
1276 if (use_dma) { 1328 if (use_dma) {
1277 pxa_free_dma(info->data_dma_ch); 1329 pxa_free_dma(info->data_dma_ch);
@@ -1296,12 +1348,15 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
1296 struct mtd_info *mtd = platform_get_drvdata(pdev); 1348 struct mtd_info *mtd = platform_get_drvdata(pdev);
1297 struct pxa3xx_nand_info *info = mtd->priv; 1349 struct pxa3xx_nand_info *info = mtd->priv;
1298 struct resource *r; 1350 struct resource *r;
1351 int irq;
1299 1352
1300 platform_set_drvdata(pdev, NULL); 1353 platform_set_drvdata(pdev, NULL);
1301 1354
1302 del_mtd_device(mtd); 1355 del_mtd_device(mtd);
1303 del_mtd_partitions(mtd); 1356 del_mtd_partitions(mtd);
1304 free_irq(IRQ_NAND, info); 1357 irq = platform_get_irq(pdev, 0);
1358 if (irq >= 0)
1359 free_irq(irq, info);
1305 if (use_dma) { 1360 if (use_dma) {
1306 pxa_free_dma(info->data_dma_ch); 1361 pxa_free_dma(info->data_dma_ch);
1307 dma_free_writecombine(&pdev->dev, info->data_buff_size, 1362 dma_free_writecombine(&pdev->dev, info->data_buff_size,