Commit 2230b76b authored by Bryan Wu's avatar Bryan Wu Committed by David Woodhouse

[MTD] m25p80: add FAST_READ access support to M25Pxx

Signed-off-by: default avatarBryan Wu <cooloney@kernel.org>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent afc4bca6
...@@ -77,6 +77,13 @@ config MTD_M25P80 ...@@ -77,6 +77,13 @@ config MTD_M25P80
if you want to specify device partitioning or to use a device which if you want to specify device partitioning or to use a device which
doesn't support the JEDEC ID instruction. doesn't support the JEDEC ID instruction.
config M25PXX_USE_FAST_READ
bool "Use FAST_READ OPCode allowing SPI CLK <= 50MHz"
depends on MTD_M25P80
default y
help
This option enables FAST_READ access supported by ST M25Pxx.
config MTD_SLRAM config MTD_SLRAM
tristate "Uncached system RAM" tristate "Uncached system RAM"
help help
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
/* Flash opcodes. */ /* Flash opcodes. */
#define OPCODE_WREN 0x06 /* Write enable */ #define OPCODE_WREN 0x06 /* Write enable */
#define OPCODE_RDSR 0x05 /* Read status register */ #define OPCODE_RDSR 0x05 /* Read status register */
#define OPCODE_READ 0x03 /* Read data bytes (low frequency) */ #define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */
#define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ #define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */
#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */
#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ #define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
...@@ -52,7 +52,15 @@ ...@@ -52,7 +52,15 @@
/* Define max times to check status register before we give up. */ /* Define max times to check status register before we give up. */
#define MAX_READY_WAIT_COUNT 100000 #define MAX_READY_WAIT_COUNT 100000
#define CMD_SIZE 4
#ifdef CONFIG_M25PXX_USE_FAST_READ
#define OPCODE_READ OPCODE_FAST_READ
#define FAST_READ_DUMMY_BYTE 1
#else
#define OPCODE_READ OPCODE_NORM_READ
#define FAST_READ_DUMMY_BYTE 0
#endif
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_PARTITIONS
#define mtd_has_partitions() (1) #define mtd_has_partitions() (1)
...@@ -68,7 +76,7 @@ struct m25p { ...@@ -68,7 +76,7 @@ struct m25p {
struct mtd_info mtd; struct mtd_info mtd;
unsigned partitioned:1; unsigned partitioned:1;
u8 erase_opcode; u8 erase_opcode;
u8 command[4]; u8 command[CMD_SIZE + FAST_READ_DUMMY_BYTE];
}; };
static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
...@@ -167,7 +175,7 @@ static int erase_sector(struct m25p *flash, u32 offset) ...@@ -167,7 +175,7 @@ static int erase_sector(struct m25p *flash, u32 offset)
flash->command[2] = offset >> 8; flash->command[2] = offset >> 8;
flash->command[3] = offset; flash->command[3] = offset;
spi_write(flash->spi, flash->command, sizeof(flash->command)); spi_write(flash->spi, flash->command, CMD_SIZE);
return 0; return 0;
} }
...@@ -253,8 +261,12 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, ...@@ -253,8 +261,12 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
spi_message_init(&m); spi_message_init(&m);
memset(t, 0, (sizeof t)); memset(t, 0, (sizeof t));
/* NOTE:
* OPCODE_FAST_READ (if available) is faster.
* Should add 1 byte DUMMY_BYTE.
*/
t[0].tx_buf = flash->command; t[0].tx_buf = flash->command;
t[0].len = sizeof(flash->command); t[0].len = CMD_SIZE + FAST_READ_DUMMY_BYTE;
spi_message_add_tail(&t[0], &m); spi_message_add_tail(&t[0], &m);
t[1].rx_buf = buf; t[1].rx_buf = buf;
...@@ -287,7 +299,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, ...@@ -287,7 +299,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
spi_sync(flash->spi, &m); spi_sync(flash->spi, &m);
*retlen = m.actual_length - sizeof(flash->command); *retlen = m.actual_length - CMD_SIZE - FAST_READ_DUMMY_BYTE;
mutex_unlock(&flash->lock); mutex_unlock(&flash->lock);
...@@ -325,7 +337,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, ...@@ -325,7 +337,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
memset(t, 0, (sizeof t)); memset(t, 0, (sizeof t));
t[0].tx_buf = flash->command; t[0].tx_buf = flash->command;
t[0].len = sizeof(flash->command); t[0].len = CMD_SIZE;
spi_message_add_tail(&t[0], &m); spi_message_add_tail(&t[0], &m);
t[1].tx_buf = buf; t[1].tx_buf = buf;
...@@ -354,7 +366,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, ...@@ -354,7 +366,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
spi_sync(flash->spi, &m); spi_sync(flash->spi, &m);
*retlen = m.actual_length - sizeof(flash->command); *retlen = m.actual_length - CMD_SIZE;
} else { } else {
u32 i; u32 i;
...@@ -364,7 +376,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, ...@@ -364,7 +376,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
t[1].len = page_size; t[1].len = page_size;
spi_sync(flash->spi, &m); spi_sync(flash->spi, &m);
*retlen = m.actual_length - sizeof(flash->command); *retlen = m.actual_length - CMD_SIZE;
/* write everything in PAGESIZE chunks */ /* write everything in PAGESIZE chunks */
for (i = page_size; i < len; i += page_size) { for (i = page_size; i < len; i += page_size) {
...@@ -387,8 +399,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, ...@@ -387,8 +399,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
spi_sync(flash->spi, &m); spi_sync(flash->spi, &m);
if (retlen) if (retlen)
*retlen += m.actual_length *retlen += m.actual_length - CMD_SIZE;
- sizeof(flash->command);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment