From: Jagannadha Sutradharudu Teki Date: Tue, 20 Aug 2013 06:26:21 +0000 (+0530) Subject: sf: Add extended read commands support X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6a72a489871f24f996a8e35c24ddeb935134e0d1;p=thirdparty%2Fu-boot.git sf: Add extended read commands support Current sf uses FAST_READ command, this patch adds support to use the different/extended read command. This implementation will determine the fastest command by taking the supported commands from the flash and the controller, controller is always been a priority. Added rd_cmd support to S25FL256S_64K SPI flash. Signed-off-by: Jagannadha Sutradharudu Teki --- diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c index 7f3ab8d15b2..b2452064ebc 100644 --- a/drivers/mtd/spi/spansion.c +++ b/drivers/mtd/spi/spansion.c @@ -36,6 +36,7 @@ struct spansion_spi_flash_params { u16 idcode2; u16 pages_per_sector; u16 nr_sectors; + u8 rd_cmd; const char *name; }; @@ -108,6 +109,7 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = { .idcode2 = 0x4d01, .pages_per_sector = 256, .nr_sectors = 512, + .rd_cmd = READ_CMD_FULL, .name = "S25FL256S_64K", }, { @@ -132,6 +134,7 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode) struct spi_flash *flash; unsigned int i; unsigned short jedec, ext_jedec; + u8 cmd; jedec = idcode[1] << 8 | idcode[2]; ext_jedec = idcode[3] << 8 | idcode[4]; @@ -155,6 +158,13 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode) return NULL; } + /* Look for the fastest read cmd */ + cmd = fls(params->rd_cmd & flash->spi->rd_cmd); + if (cmd) { + cmd = spi_read_cmds_array[cmd - 1]; + flash->read_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 4db1bbe0545..832372ec5cd 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -318,7 +318,7 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, if (is_dual == MODE_DUAL_PARALLEL) bank_boun = SPI_FLASH_16MB_BOUN << 1; - cmd[0] = CMD_READ_ARRAY_FAST; + cmd[0] = flash->read_cmd; cmd[4] = 0x00; while (len) { @@ -659,6 +659,9 @@ void *spi_flash_do_alloc(int offset, int size, struct spi_slave *spi, flash->write = spi_flash_cmd_write_multi; flash->erase = spi_flash_cmd_erase; + /* Go for default command - if caller don't have any addons */ + flash->read_cmd = CMD_READ_ARRAY_FAST; + return flash; } diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index 0ad2c5e0475..2000cbc1fb8 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -993,6 +993,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->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 a80d0f06829..e0ac5794e3f 100644 --- a/include/spi.h +++ b/include/spi.h @@ -59,6 +59,7 @@ * u_page: Indicates the upper memory page, in dual stacked connection. * max_write_size: If non-zero, the maximum number of bytes which can * be written at once, excluding command bytes. + * rd_cmd: Read command. */ struct spi_slave { unsigned int bus; @@ -66,6 +67,7 @@ struct spi_slave { unsigned int is_dual; unsigned int u_page; unsigned int max_write_size; + u8 rd_cmd; }; /*----------------------------------------------------------------------- diff --git a/include/spi_flash.h b/include/spi_flash.h index ebe537fb86f..7afa5f76530 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -35,6 +35,29 @@ enum spi_con_topology { MODE_DUAL_PARALLEL, }; +/* 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 + +static u32 spi_read_cmds_array[] = { + CMD_READ_ARRAY_SLOW, + CMD_READ_ARRAY_FAST, + CMD_READ_DUAL_OUTPUT_FAST, + CMD_READ_DUAL_IO_FAST, +}; + +enum spi_read_cmds { + ARRAY_SLOW = 1 << 0, + ARRAY_FAST = 1 << 1, + DUAL_OUTPUT_FAST = 1 << 2, + DUAL_IO_FAST = 1 << 3, +}; + +#define READ_CMD_FULL ARRAY_SLOW | ARRAY_FAST | DUAL_OUTPUT_FAST | \ + DUAL_IO_FAST + struct spi_flash { struct spi_slave *spi; @@ -56,6 +79,8 @@ struct spi_flash { #endif /* Poll cmd - for flash erase/program */ u8 poll_cmd; + /* Read command */ + u8 read_cmd; void *memory_map; /* Address of read-only SPI flash access */ int (*read)(struct spi_flash *flash, u32 offset,