From dec46a36a6dd8bfebeab8b777f4941ecedeea943 Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki Date: Tue, 20 Aug 2013 12:08:31 +0530 Subject: [PATCH] sf: Add quad read/write commands support Current sf uses PAGE_PROGRAM command for write and FAST_READ, SLOW_READ, DUAL_READ and DUAL_IO_READ commands for read this patch adds support to use the quad read/write commands This implementation will determine the fastest command which is added in below commit "sf: Add extended read commands support" (sha: 4cba440b739f87206faa889f71e9ed369e9832c5) Added wr_cmd and updated rd_cmd support to S25FL256S_64K SPI flash. Signed-off-by: Jagannadha Sutradharudu Teki --- drivers/mtd/spi/spansion.c | 9 +++++++++ drivers/mtd/spi/spi_flash.c | 3 ++- drivers/spi/zynq_qspi.c | 1 + include/spi.h | 2 ++ include/spi_flash.h | 21 ++++++++++++++++++++- 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c index b2452064ebc..0df9c83d183 100644 --- a/drivers/mtd/spi/spansion.c +++ b/drivers/mtd/spi/spansion.c @@ -37,6 +37,7 @@ struct spansion_spi_flash_params { u16 pages_per_sector; u16 nr_sectors; u8 rd_cmd; + u8 wr_cmd; const char *name; }; @@ -110,6 +111,7 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = { .pages_per_sector = 256, .nr_sectors = 512, .rd_cmd = READ_CMD_FULL, + .wr_cmd = PAGE_PROGRAM | QUAD_PAGE_PROGRAM, .name = "S25FL256S_64K", }, { @@ -165,6 +167,13 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode) flash->read_cmd = cmd; } + /* Look for the fastest write cmd */ + cmd = fls(params->wr_cmd & flash->spi->wr_cmd); + if (cmd) { + cmd = spi_write_cmds_array[cmd - 1]; + flash->write_cmd = cmd; + } + flash->page_size = 256; flash->sector_size = 256 * params->pages_per_sector; diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 832372ec5cd..93a9479bc76 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -228,7 +228,7 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset, page_size = flash->page_size; - cmd[0] = CMD_PAGE_PROGRAM; + cmd[0] = flash->write_cmd; for (actual = 0; actual < len; actual += chunk_len) { write_addr = offset; if (is_dual == MODE_DUAL_PARALLEL) @@ -661,6 +661,7 @@ void *spi_flash_do_alloc(int offset, int size, struct spi_slave *spi, /* Go for default command - if caller don't have any addons */ flash->read_cmd = CMD_READ_ARRAY_FAST; + flash->write_cmd = CMD_PAGE_PROGRAM; return flash; } diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index 2000cbc1fb8..82d22783b42 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -994,6 +994,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, qspi->slave.is_dual = is_dual; qspi->slave.rd_cmd = READ_CMD_FULL; + qspi->slave.wr_cmd = PAGE_PROGRAM | QUAD_PAGE_PROGRAM; qspi->qspi.master.speed_hz = qspi->qspi.master.input_clk_hz / 2; qspi->qspi.max_speed_hz = qspi->qspi.master.speed_hz; qspi->qspi.master.is_dual = is_dual; diff --git a/include/spi.h b/include/spi.h index e0ac5794e3f..d65d3924d23 100644 --- a/include/spi.h +++ b/include/spi.h @@ -60,6 +60,7 @@ * max_write_size: If non-zero, the maximum number of bytes which can * be written at once, excluding command bytes. * rd_cmd: Read command. + * wr_cmd: Write command. */ struct spi_slave { unsigned int bus; @@ -68,6 +69,7 @@ struct spi_slave { unsigned int u_page; unsigned int max_write_size; u8 rd_cmd; + u8 wr_cmd; }; /*----------------------------------------------------------------------- diff --git a/include/spi_flash.h b/include/spi_flash.h index 7afa5f76530..09f0cc846de 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -35,17 +35,33 @@ enum spi_con_topology { MODE_DUAL_PARALLEL, }; +/* Write commands */ +#define CMD_PAGE_PROGRAM 0x02 +#define CMD_QUAD_PAGE_PROGRAM 0x32 + +static u32 spi_write_cmds_array[] = { + CMD_PAGE_PROGRAM, + CMD_QUAD_PAGE_PROGRAM, +}; + +enum spi_write_cmds { + PAGE_PROGRAM = 1 << 0, + QUAD_PAGE_PROGRAM = 1 << 1, +}; + /* Read commands */ #define CMD_READ_ARRAY_SLOW 0x03 #define CMD_READ_ARRAY_FAST 0x0b #define CMD_READ_DUAL_OUTPUT_FAST 0x3b #define CMD_READ_DUAL_IO_FAST 0xbb +#define CMD_READ_QUAD_OUTPUT_FAST 0x6b static u32 spi_read_cmds_array[] = { CMD_READ_ARRAY_SLOW, CMD_READ_ARRAY_FAST, CMD_READ_DUAL_OUTPUT_FAST, CMD_READ_DUAL_IO_FAST, + CMD_READ_QUAD_OUTPUT_FAST, }; enum spi_read_cmds { @@ -53,10 +69,11 @@ enum spi_read_cmds { ARRAY_FAST = 1 << 1, DUAL_OUTPUT_FAST = 1 << 2, DUAL_IO_FAST = 1 << 3, + QUAD_OUTPUT_FAST = 1 << 4, }; #define READ_CMD_FULL ARRAY_SLOW | ARRAY_FAST | DUAL_OUTPUT_FAST | \ - DUAL_IO_FAST + DUAL_IO_FAST | QUAD_OUTPUT_FAST struct spi_flash { struct spi_slave *spi; @@ -81,6 +98,8 @@ struct spi_flash { u8 poll_cmd; /* Read command */ u8 read_cmd; + /* Write command */ + u8 write_cmd; void *memory_map; /* Address of read-only SPI flash access */ int (*read)(struct spi_flash *flash, u32 offset, -- 2.47.3