aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2010-01-27 04:17:21 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-02-01 23:02:16 -0500
commit010ab820582d03bcd3648416b5837107e8a9c5f3 (patch)
tree074fb1fba3a498072fce060e04196e0d590b9154 /drivers/mtd
parentb79c7adf82e8b8a6d6ad1dadf7e687a4a030cf8c (diff)
mtd: sh_flctl SHBUSSEL and SEL_16BIT support
This patch extends the sh_flctl driver with support for 16-bit bus configuration using SEL_16BIT and support for multiplexed pins using SHBUSSEL. Signed-off-by: Magnus Damm <damm@opensource.se> Acked-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/sh_flctl.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index ab068a503b29..1842df8bdd93 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -105,6 +105,8 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr)
105 addr = page_addr; /* ERASE1 */ 105 addr = page_addr; /* ERASE1 */
106 } else if (page_addr != -1) { 106 } else if (page_addr != -1) {
107 /* SEQIN, READ0, etc.. */ 107 /* SEQIN, READ0, etc.. */
108 if (flctl->chip.options & NAND_BUSWIDTH_16)
109 column >>= 1;
108 if (flctl->page_size) { 110 if (flctl->page_size) {
109 addr = column & 0x0FFF; 111 addr = column & 0x0FFF;
110 addr |= (page_addr & 0xff) << 16; 112 addr |= (page_addr & 0xff) << 16;
@@ -280,7 +282,7 @@ static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
280static 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)
281{ 283{
282 struct sh_flctl *flctl = mtd_to_flctl(mtd); 284 struct sh_flctl *flctl = mtd_to_flctl(mtd);
283 uint32_t flcmncr_val = readl(FLCMNCR(flctl)); 285 uint32_t flcmncr_val = readl(FLCMNCR(flctl)) & ~SEL_16BIT;
284 uint32_t flcmdcr_val, addr_len_bytes = 0; 286 uint32_t flcmdcr_val, addr_len_bytes = 0;
285 287
286 /* Set SNAND bit if page size is 2048byte */ 288 /* Set SNAND bit if page size is 2048byte */
@@ -302,6 +304,8 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va
302 case NAND_CMD_READOOB: 304 case NAND_CMD_READOOB:
303 addr_len_bytes = flctl->rw_ADRCNT; 305 addr_len_bytes = flctl->rw_ADRCNT;
304 flcmdcr_val |= CDSRC_E; 306 flcmdcr_val |= CDSRC_E;
307 if (flctl->chip.options & NAND_BUSWIDTH_16)
308 flcmncr_val |= SEL_16BIT;
305 break; 309 break;
306 case NAND_CMD_SEQIN: 310 case NAND_CMD_SEQIN:
307 /* This case is that cmd is READ0 or READ1 or READ00 */ 311 /* This case is that cmd is READ0 or READ1 or READ00 */
@@ -310,6 +314,8 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va
310 case NAND_CMD_PAGEPROG: 314 case NAND_CMD_PAGEPROG:
311 addr_len_bytes = flctl->rw_ADRCNT; 315 addr_len_bytes = flctl->rw_ADRCNT;
312 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;
313 break; 319 break;
314 case NAND_CMD_READID: 320 case NAND_CMD_READID:
315 flcmncr_val &= ~SNAND_E; 321 flcmncr_val &= ~SNAND_E;
@@ -528,6 +534,8 @@ static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command,
528 set_addr(mtd, 0, page_addr); 534 set_addr(mtd, 0, page_addr);
529 535
530 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;
531 flctl->index += column; 539 flctl->index += column;
532 goto read_normal_exit; 540 goto read_normal_exit;
533 541
@@ -691,6 +699,18 @@ static uint8_t flctl_read_byte(struct mtd_info *mtd)
691 return data; 699 return data;
692} 700}
693 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
694static 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)
695{ 715{
696 int i; 716 int i;
@@ -829,6 +849,11 @@ static int __devinit flctl_probe(struct platform_device *pdev)
829 nand->select_chip = flctl_select_chip; 849 nand->select_chip = flctl_select_chip;
830 nand->cmdfunc = flctl_cmdfunc; 850 nand->cmdfunc = flctl_cmdfunc;
831 851
852 if (pdata->flcmncr_val & SEL_16BIT) {
853 nand->options |= NAND_BUSWIDTH_16;
854 nand->read_word = flctl_read_word;
855 }
856
832 ret = nand_scan_ident(flctl_mtd, 1); 857 ret = nand_scan_ident(flctl_mtd, 1);
833 if (ret) 858 if (ret)
834 goto err; 859 goto err;