diff options
author | Magnus Damm <damm@opensource.se> | 2010-01-27 04:17:21 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-02-01 23:02:16 -0500 |
commit | 010ab820582d03bcd3648416b5837107e8a9c5f3 (patch) | |
tree | 074fb1fba3a498072fce060e04196e0d590b9154 /drivers/mtd | |
parent | b79c7adf82e8b8a6d6ad1dadf7e687a4a030cf8c (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.c | 27 |
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) | |||
280 | static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val) | 282 | static 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 | ||
702 | static 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 | |||
694 | static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 714 | static 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; |