diff options
author | Brian Norris <computersforpeace@gmail.com> | 2014-01-29 17:08:12 -0500 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2014-03-11 01:42:22 -0400 |
commit | 3dad2344e92c6e1aeae42df1c4824f307c51bcc7 (patch) | |
tree | ca71a7005c582cd98eebf5e16049b125564925f5 | |
parent | 55e571bd0707fb6516d0e38598c9e51683e03ee9 (diff) |
mtd: nand: force NAND_CMD_READID onto 8-bit bus
The NAND command helpers tend to automatically shift the column address
for x16 bus devices, since most commands expect a word address, not a
byte address. The Read ID command, however, expects an 8-bit address
(i.e., 0x00, 0x20, or 0x40 should not be translated to 0x00, 0x10, or
0x20).
This fixes the column address for a few drivers which imitate the
nand_base defaults. Note that I don't touch sh_flctl.c, since it already
handles this problem slightly differently (note its comment "READID is
always performed using an 8-bit bus").
I have not tested this patch, as I only have x8 parts up for testing at
this point. Hopefully that can change soon...
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-By: Pekon Gupta <pekon@ti.com>
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 11 | ||||
-rw-r--r-- | drivers/mtd/nand/au1550nd.c | 3 | ||||
-rw-r--r-- | drivers/mtd/nand/diskonchip.c | 3 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 6 | ||||
-rw-r--r-- | drivers/mtd/nand/nuc900_nand.c | 3 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 10 |
6 files changed, 26 insertions, 10 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index c36e9b84487c..1955389c8fa6 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -1659,8 +1659,8 @@ static void nfc_select_chip(struct mtd_info *mtd, int chip) | |||
1659 | nfc_writel(host->nfc->hsmc_regs, CTRL, NFC_CTRL_ENABLE); | 1659 | nfc_writel(host->nfc->hsmc_regs, CTRL, NFC_CTRL_ENABLE); |
1660 | } | 1660 | } |
1661 | 1661 | ||
1662 | static int nfc_make_addr(struct mtd_info *mtd, int column, int page_addr, | 1662 | static int nfc_make_addr(struct mtd_info *mtd, int command, int column, |
1663 | unsigned int *addr1234, unsigned int *cycle0) | 1663 | int page_addr, unsigned int *addr1234, unsigned int *cycle0) |
1664 | { | 1664 | { |
1665 | struct nand_chip *chip = mtd->priv; | 1665 | struct nand_chip *chip = mtd->priv; |
1666 | 1666 | ||
@@ -1674,7 +1674,8 @@ static int nfc_make_addr(struct mtd_info *mtd, int column, int page_addr, | |||
1674 | *addr1234 = 0; | 1674 | *addr1234 = 0; |
1675 | 1675 | ||
1676 | if (column != -1) { | 1676 | if (column != -1) { |
1677 | if (chip->options & NAND_BUSWIDTH_16) | 1677 | if (chip->options & NAND_BUSWIDTH_16 && |
1678 | !nand_opcode_8bits(command)) | ||
1678 | column >>= 1; | 1679 | column >>= 1; |
1679 | addr_bytes[acycle++] = column & 0xff; | 1680 | addr_bytes[acycle++] = column & 0xff; |
1680 | if (mtd->writesize > 512) | 1681 | if (mtd->writesize > 512) |
@@ -1787,8 +1788,8 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, | |||
1787 | } | 1788 | } |
1788 | 1789 | ||
1789 | if (do_addr) | 1790 | if (do_addr) |
1790 | acycle = nfc_make_addr(mtd, column, page_addr, &addr1234, | 1791 | acycle = nfc_make_addr(mtd, command, column, page_addr, |
1791 | &cycle0); | 1792 | &addr1234, &cycle0); |
1792 | 1793 | ||
1793 | nfc_addr_cmd = cmd1 | cmd2 | vcmd2 | acycle | csid | dataen | nfcwr; | 1794 | nfc_addr_cmd = cmd1 | cmd2 | vcmd2 | acycle | csid | dataen | nfcwr; |
1794 | nfc_send_command(host, nfc_addr_cmd, addr1234, cycle0); | 1795 | nfc_send_command(host, nfc_addr_cmd, addr1234, cycle0); |
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 7d84c4e4bf43..bc5c518828d2 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
@@ -307,7 +307,8 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
307 | /* Serially input address */ | 307 | /* Serially input address */ |
308 | if (column != -1) { | 308 | if (column != -1) { |
309 | /* Adjust columns for 16 bit buswidth */ | 309 | /* Adjust columns for 16 bit buswidth */ |
310 | if (this->options & NAND_BUSWIDTH_16) | 310 | if (this->options & NAND_BUSWIDTH_16 && |
311 | !nand_opcode_8bits(command)) | ||
311 | column >>= 1; | 312 | column >>= 1; |
312 | ctx->write_byte(mtd, column); | 313 | ctx->write_byte(mtd, column); |
313 | } | 314 | } |
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index fec31d71b84e..b9b4db607850 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
@@ -698,7 +698,8 @@ static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int colu | |||
698 | /* Serially input address */ | 698 | /* Serially input address */ |
699 | if (column != -1) { | 699 | if (column != -1) { |
700 | /* Adjust columns for 16 bit buswidth */ | 700 | /* Adjust columns for 16 bit buswidth */ |
701 | if (this->options & NAND_BUSWIDTH_16) | 701 | if (this->options & NAND_BUSWIDTH_16 && |
702 | !nand_opcode_8bits(command)) | ||
702 | column >>= 1; | 703 | column >>= 1; |
703 | WriteDOC(column, docptr, Mplus_FlashAddress); | 704 | WriteDOC(column, docptr, Mplus_FlashAddress); |
704 | } | 705 | } |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index deeaa1cc4a85..6281151e4cb7 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -589,7 +589,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, | |||
589 | /* Serially input address */ | 589 | /* Serially input address */ |
590 | if (column != -1) { | 590 | if (column != -1) { |
591 | /* Adjust columns for 16 bit buswidth */ | 591 | /* Adjust columns for 16 bit buswidth */ |
592 | if (chip->options & NAND_BUSWIDTH_16) | 592 | if (chip->options & NAND_BUSWIDTH_16 && |
593 | !nand_opcode_8bits(command)) | ||
593 | column >>= 1; | 594 | column >>= 1; |
594 | chip->cmd_ctrl(mtd, column, ctrl); | 595 | chip->cmd_ctrl(mtd, column, ctrl); |
595 | ctrl &= ~NAND_CTRL_CHANGE; | 596 | ctrl &= ~NAND_CTRL_CHANGE; |
@@ -680,7 +681,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, | |||
680 | /* Serially input address */ | 681 | /* Serially input address */ |
681 | if (column != -1) { | 682 | if (column != -1) { |
682 | /* Adjust columns for 16 bit buswidth */ | 683 | /* Adjust columns for 16 bit buswidth */ |
683 | if (chip->options & NAND_BUSWIDTH_16) | 684 | if (chip->options & NAND_BUSWIDTH_16 && |
685 | !nand_opcode_8bits(command)) | ||
684 | column >>= 1; | 686 | column >>= 1; |
685 | chip->cmd_ctrl(mtd, column, ctrl); | 687 | chip->cmd_ctrl(mtd, column, ctrl); |
686 | ctrl &= ~NAND_CTRL_CHANGE; | 688 | ctrl &= ~NAND_CTRL_CHANGE; |
diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index 90c99ea5184a..331fccbdde61 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c | |||
@@ -151,7 +151,8 @@ static void nuc900_nand_command_lp(struct mtd_info *mtd, unsigned int command, | |||
151 | if (column != -1 || page_addr != -1) { | 151 | if (column != -1 || page_addr != -1) { |
152 | 152 | ||
153 | if (column != -1) { | 153 | if (column != -1) { |
154 | if (chip->options & NAND_BUSWIDTH_16) | 154 | if (chip->options & NAND_BUSWIDTH_16 && |
155 | !nand_opcode_8bits(command)) | ||
155 | column >>= 1; | 156 | column >>= 1; |
156 | write_addr_reg(nand, column); | 157 | write_addr_reg(nand, column); |
157 | write_addr_reg(nand, column >> 8 | ENDADDR); | 158 | write_addr_reg(nand, column >> 8 | ENDADDR); |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index a719686c9cce..c034dc4224cb 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -832,4 +832,14 @@ static inline bool nand_is_slc(struct nand_chip *chip) | |||
832 | { | 832 | { |
833 | return chip->bits_per_cell == 1; | 833 | return chip->bits_per_cell == 1; |
834 | } | 834 | } |
835 | |||
836 | /** | ||
837 | * Check if the opcode's address should be sent only on the lower 8 bits | ||
838 | * @command: opcode to check | ||
839 | */ | ||
840 | static inline int nand_opcode_8bits(unsigned int command) | ||
841 | { | ||
842 | return command == NAND_CMD_READID; | ||
843 | } | ||
844 | |||
835 | #endif /* __LINUX_MTD_NAND_H */ | 845 | #endif /* __LINUX_MTD_NAND_H */ |