aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2014-01-29 17:08:12 -0500
committerBrian Norris <computersforpeace@gmail.com>2014-03-11 01:42:22 -0400
commit3dad2344e92c6e1aeae42df1c4824f307c51bcc7 (patch)
treeca71a7005c582cd98eebf5e16049b125564925f5
parent55e571bd0707fb6516d0e38598c9e51683e03ee9 (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.c11
-rw-r--r--drivers/mtd/nand/au1550nd.c3
-rw-r--r--drivers/mtd/nand/diskonchip.c3
-rw-r--r--drivers/mtd/nand/nand_base.c6
-rw-r--r--drivers/mtd/nand/nuc900_nand.c3
-rw-r--r--include/linux/mtd/nand.h10
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
1662static int nfc_make_addr(struct mtd_info *mtd, int column, int page_addr, 1662static 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 */
840static 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 */