aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r--drivers/mtd/nand/Kconfig4
-rw-r--r--drivers/mtd/nand/au1550nd.c4
-rw-r--r--drivers/mtd/nand/sh_flctl.c69
3 files changed, 54 insertions, 23 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 677cd53f18c3..bb6465604235 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -457,10 +457,10 @@ config MTD_NAND_NOMADIK
457 457
458config MTD_NAND_SH_FLCTL 458config MTD_NAND_SH_FLCTL
459 tristate "Support for NAND on Renesas SuperH FLCTL" 459 tristate "Support for NAND on Renesas SuperH FLCTL"
460 depends on MTD_NAND && SUPERH && CPU_SUBTYPE_SH7723 460 depends on MTD_NAND && SUPERH
461 help 461 help
462 Several Renesas SuperH CPU has FLCTL. This option enables support 462 Several Renesas SuperH CPU has FLCTL. This option enables support
463 for NAND Flash using FLCTL. This driver support SH7723. 463 for NAND Flash using FLCTL.
464 464
465config MTD_NAND_DAVINCI 465config MTD_NAND_DAVINCI
466 tristate "Support NAND on DaVinci SoC" 466 tristate "Support NAND on DaVinci SoC"
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 92c334ff4508..43d46e424040 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -19,6 +19,7 @@
19#include <asm/io.h> 19#include <asm/io.h>
20 20
21#include <asm/mach-au1x00/au1xxx.h> 21#include <asm/mach-au1x00/au1xxx.h>
22#include <asm/mach-db1x00/bcsr.h>
22 23
23/* 24/*
24 * MTD structure for NAND controller 25 * MTD structure for NAND controller
@@ -475,7 +476,8 @@ static int __init au1xxx_nand_init(void)
475 /* set gpio206 high */ 476 /* set gpio206 high */
476 au_writel(au_readl(GPIO2_DIR) & ~(1 << 6), GPIO2_DIR); 477 au_writel(au_readl(GPIO2_DIR) & ~(1 << 6), GPIO2_DIR);
477 478
478 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr->status >> 6) & 0x1); 479 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
480
479 switch (boot_swapboot) { 481 switch (boot_swapboot) {
480 case 0: 482 case 0:
481 case 2: 483 case 2:
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 02bef21f2e4b..1842df8bdd93 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * SuperH FLCTL nand controller 2 * SuperH FLCTL nand controller
3 * 3 *
4 * Copyright © 2008 Renesas Solutions Corp. 4 * Copyright (c) 2008 Renesas Solutions Corp.
5 * Copyright © 2008 Atom Create Engineering Co., Ltd. 5 * Copyright (c) 2008 Atom Create Engineering Co., Ltd.
6 * 6 *
7 * Based on fsl_elbc_nand.c, Copyright © 2006-2007 Freescale Semiconductor 7 * Based on fsl_elbc_nand.c, Copyright (c) 2006-2007 Freescale Semiconductor
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -75,6 +75,11 @@ static void start_translation(struct sh_flctl *flctl)
75 writeb(TRSTRT, FLTRCR(flctl)); 75 writeb(TRSTRT, FLTRCR(flctl));
76} 76}
77 77
78static void timeout_error(struct sh_flctl *flctl, const char *str)
79{
80 dev_err(&flctl->pdev->dev, "Timeout occured in %s\n", str);
81}
82
78static void wait_completion(struct sh_flctl *flctl) 83static void wait_completion(struct sh_flctl *flctl)
79{ 84{
80 uint32_t timeout = LOOP_TIMEOUT_MAX; 85 uint32_t timeout = LOOP_TIMEOUT_MAX;
@@ -87,7 +92,7 @@ static void wait_completion(struct sh_flctl *flctl)
87 udelay(1); 92 udelay(1);
88 } 93 }
89 94
90 printk(KERN_ERR "wait_completion(): Timeout occured \n"); 95 timeout_error(flctl, __func__);
91 writeb(0x0, FLTRCR(flctl)); 96 writeb(0x0, FLTRCR(flctl));
92} 97}
93 98
@@ -100,6 +105,8 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr)
100 addr = page_addr; /* ERASE1 */ 105 addr = page_addr; /* ERASE1 */
101 } else if (page_addr != -1) { 106 } else if (page_addr != -1) {
102 /* SEQIN, READ0, etc.. */ 107 /* SEQIN, READ0, etc.. */
108 if (flctl->chip.options & NAND_BUSWIDTH_16)
109 column >>= 1;
103 if (flctl->page_size) { 110 if (flctl->page_size) {
104 addr = column & 0x0FFF; 111 addr = column & 0x0FFF;
105 addr |= (page_addr & 0xff) << 16; 112 addr |= (page_addr & 0xff) << 16;
@@ -132,7 +139,7 @@ static void wait_rfifo_ready(struct sh_flctl *flctl)
132 return; 139 return;
133 udelay(1); 140 udelay(1);
134 } 141 }
135 printk(KERN_ERR "wait_rfifo_ready(): Timeout occured \n"); 142 timeout_error(flctl, __func__);
136} 143}
137 144
138static void wait_wfifo_ready(struct sh_flctl *flctl) 145static void wait_wfifo_ready(struct sh_flctl *flctl)
@@ -146,7 +153,7 @@ static void wait_wfifo_ready(struct sh_flctl *flctl)
146 return; 153 return;
147 udelay(1); 154 udelay(1);
148 } 155 }
149 printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n"); 156 timeout_error(flctl, __func__);
150} 157}
151 158
152static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number) 159static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
@@ -198,7 +205,7 @@ static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
198 writel(0, FL4ECCCR(flctl)); 205 writel(0, FL4ECCCR(flctl));
199 } 206 }
200 207
201 printk(KERN_ERR "wait_recfifo_ready(): Timeout occured \n"); 208 timeout_error(flctl, __func__);
202 return 1; /* timeout */ 209 return 1; /* timeout */
203} 210}
204 211
@@ -214,7 +221,7 @@ static void wait_wecfifo_ready(struct sh_flctl *flctl)
214 return; 221 return;
215 udelay(1); 222 udelay(1);
216 } 223 }
217 printk(KERN_ERR "wait_wecfifo_ready(): Timeout occured \n"); 224 timeout_error(flctl, __func__);
218} 225}
219 226
220static void read_datareg(struct sh_flctl *flctl, int offset) 227static void read_datareg(struct sh_flctl *flctl, int offset)
@@ -275,7 +282,7 @@ static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
275static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val) 282static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
276{ 283{
277 struct sh_flctl *flctl = mtd_to_flctl(mtd); 284 struct sh_flctl *flctl = mtd_to_flctl(mtd);
278 uint32_t flcmncr_val = readl(FLCMNCR(flctl)); 285 uint32_t flcmncr_val = readl(FLCMNCR(flctl)) & ~SEL_16BIT;
279 uint32_t flcmdcr_val, addr_len_bytes = 0; 286 uint32_t flcmdcr_val, addr_len_bytes = 0;
280 287
281 /* Set SNAND bit if page size is 2048byte */ 288 /* Set SNAND bit if page size is 2048byte */
@@ -297,6 +304,8 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va
297 case NAND_CMD_READOOB: 304 case NAND_CMD_READOOB:
298 addr_len_bytes = flctl->rw_ADRCNT; 305 addr_len_bytes = flctl->rw_ADRCNT;
299 flcmdcr_val |= CDSRC_E; 306 flcmdcr_val |= CDSRC_E;
307 if (flctl->chip.options & NAND_BUSWIDTH_16)
308 flcmncr_val |= SEL_16BIT;
300 break; 309 break;
301 case NAND_CMD_SEQIN: 310 case NAND_CMD_SEQIN:
302 /* This case is that cmd is READ0 or READ1 or READ00 */ 311 /* This case is that cmd is READ0 or READ1 or READ00 */
@@ -305,6 +314,8 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va
305 case NAND_CMD_PAGEPROG: 314 case NAND_CMD_PAGEPROG:
306 addr_len_bytes = flctl->rw_ADRCNT; 315 addr_len_bytes = flctl->rw_ADRCNT;
307 flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW; 316 flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW;
317 if (flctl->chip.options & NAND_BUSWIDTH_16)
318 flcmncr_val |= SEL_16BIT;
308 break; 319 break;
309 case NAND_CMD_READID: 320 case NAND_CMD_READID:
310 flcmncr_val &= ~SNAND_E; 321 flcmncr_val &= ~SNAND_E;
@@ -523,6 +534,8 @@ static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command,
523 set_addr(mtd, 0, page_addr); 534 set_addr(mtd, 0, page_addr);
524 535
525 flctl->read_bytes = mtd->writesize + mtd->oobsize; 536 flctl->read_bytes = mtd->writesize + mtd->oobsize;
537 if (flctl->chip.options & NAND_BUSWIDTH_16)
538 column >>= 1;
526 flctl->index += column; 539 flctl->index += column;
527 goto read_normal_exit; 540 goto read_normal_exit;
528 541
@@ -686,6 +699,18 @@ static uint8_t flctl_read_byte(struct mtd_info *mtd)
686 return data; 699 return data;
687} 700}
688 701
702static uint16_t flctl_read_word(struct mtd_info *mtd)
703{
704 struct sh_flctl *flctl = mtd_to_flctl(mtd);
705 int index = flctl->index;
706 uint16_t data;
707 uint16_t *buf = (uint16_t *)&flctl->done_buff[index];
708
709 data = *buf;
710 flctl->index += 2;
711 return data;
712}
713
689static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) 714static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
690{ 715{
691 int i; 716 int i;
@@ -769,38 +794,36 @@ static int flctl_chip_init_tail(struct mtd_info *mtd)
769 return 0; 794 return 0;
770} 795}
771 796
772static int __init flctl_probe(struct platform_device *pdev) 797static int __devinit flctl_probe(struct platform_device *pdev)
773{ 798{
774 struct resource *res; 799 struct resource *res;
775 struct sh_flctl *flctl; 800 struct sh_flctl *flctl;
776 struct mtd_info *flctl_mtd; 801 struct mtd_info *flctl_mtd;
777 struct nand_chip *nand; 802 struct nand_chip *nand;
778 struct sh_flctl_platform_data *pdata; 803 struct sh_flctl_platform_data *pdata;
779 int ret; 804 int ret = -ENXIO;
780 805
781 pdata = pdev->dev.platform_data; 806 pdata = pdev->dev.platform_data;
782 if (pdata == NULL) { 807 if (pdata == NULL) {
783 printk(KERN_ERR "sh_flctl platform_data not found.\n"); 808 dev_err(&pdev->dev, "no platform data defined\n");
784 return -ENODEV; 809 return -EINVAL;
785 } 810 }
786 811
787 flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL); 812 flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
788 if (!flctl) { 813 if (!flctl) {
789 printk(KERN_ERR "Unable to allocate NAND MTD dev structure.\n"); 814 dev_err(&pdev->dev, "failed to allocate driver data\n");
790 return -ENOMEM; 815 return -ENOMEM;
791 } 816 }
792 817
793 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 818 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
794 if (!res) { 819 if (!res) {
795 printk(KERN_ERR "%s: resource not found.\n", __func__); 820 dev_err(&pdev->dev, "failed to get I/O memory\n");
796 ret = -ENODEV;
797 goto err; 821 goto err;
798 } 822 }
799 823
800 flctl->reg = ioremap(res->start, res->end - res->start + 1); 824 flctl->reg = ioremap(res->start, resource_size(res));
801 if (flctl->reg == NULL) { 825 if (flctl->reg == NULL) {
802 printk(KERN_ERR "%s: ioremap error.\n", __func__); 826 dev_err(&pdev->dev, "failed to remap I/O memory\n");
803 ret = -ENOMEM;
804 goto err; 827 goto err;
805 } 828 }
806 829
@@ -808,6 +831,7 @@ static int __init flctl_probe(struct platform_device *pdev)
808 flctl_mtd = &flctl->mtd; 831 flctl_mtd = &flctl->mtd;
809 nand = &flctl->chip; 832 nand = &flctl->chip;
810 flctl_mtd->priv = nand; 833 flctl_mtd->priv = nand;
834 flctl->pdev = pdev;
811 flctl->hwecc = pdata->has_hwecc; 835 flctl->hwecc = pdata->has_hwecc;
812 836
813 flctl_register_init(flctl, pdata->flcmncr_val); 837 flctl_register_init(flctl, pdata->flcmncr_val);
@@ -825,6 +849,11 @@ static int __init flctl_probe(struct platform_device *pdev)
825 nand->select_chip = flctl_select_chip; 849 nand->select_chip = flctl_select_chip;
826 nand->cmdfunc = flctl_cmdfunc; 850 nand->cmdfunc = flctl_cmdfunc;
827 851
852 if (pdata->flcmncr_val & SEL_16BIT) {
853 nand->options |= NAND_BUSWIDTH_16;
854 nand->read_word = flctl_read_word;
855 }
856
828 ret = nand_scan_ident(flctl_mtd, 1); 857 ret = nand_scan_ident(flctl_mtd, 1);
829 if (ret) 858 if (ret)
830 goto err; 859 goto err;
@@ -846,7 +875,7 @@ err:
846 return ret; 875 return ret;
847} 876}
848 877
849static int __exit flctl_remove(struct platform_device *pdev) 878static int __devexit flctl_remove(struct platform_device *pdev)
850{ 879{
851 struct sh_flctl *flctl = platform_get_drvdata(pdev); 880 struct sh_flctl *flctl = platform_get_drvdata(pdev);
852 881