From e90f7bde15358125d1fd6555b6ce3ae69c7efb70 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 28 Aug 2012 15:13:37 +0000 Subject: sf: spansion: Add Spansion S25FL064P IDs This is a S25FL064A successor. It supports up to 104MHz bus speed. Signed-off-by: Marek Vasut Cc: Heiko Schocher Cc: Mike Frysinger Cc: Scott Wood Cc: Wolfgang Denk Reviewed-by: Jagannadha Sutradharudu Teki diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c index bc558c4..307b852 100644 --- a/drivers/mtd/spi/spansion.c +++ b/drivers/mtd/spi/spansion.c @@ -90,6 +90,13 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = { .name = "S25FL032P", }, { + .idcode1 = 0x0216, + .idcode2 = 0x4d00, + .pages_per_sector = 256, + .nr_sectors = 128, + .name = "S25FL064P", + }, + { .idcode1 = 0x2018, .idcode2 = 0x4d01, .pages_per_sector = 256, -- cgit v0.10.2 From 47ccaa2e7d8c5eab10bf108337fda52fb68bb430 Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki Date: Sat, 23 Feb 2013 01:39:01 +0000 Subject: sf: winbond: Add support for W25Q256 Add support for Winbond W25Q256 SPI flash. Signed-off-by: Jagannadha Sutradharudu Teki Reviewed-by: Jagannadha Sutradharudu Teki diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c index 2716209..3b39ba7 100644 --- a/drivers/mtd/spi/winbond.c +++ b/drivers/mtd/spi/winbond.c @@ -63,6 +63,11 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = { .name = "W25Q128", }, { + .id = 0x4019, + .nr_blocks = 512, + .name = "W25Q256", + }, + { .id = 0x5014, .nr_blocks = 128, .name = "W25Q80", -- cgit v0.10.2 From ed03f41778c7a11adf81816278c92dfae23d6d77 Mon Sep 17 00:00:00 2001 From: Kuo-Jung Su Date: Thu, 23 May 2013 15:09:49 +0000 Subject: sf: winbond: Add support for W25PXX SPI flash Add support for Winbond's W25PXX SPI flash. These devices is used on Faraday A369 evaluation board. Signed-off-by: Kuo-Jung Su CC: Jagannadha Sutradharudu Teki CC: Tom Rini Reviewed-by: Jagannadha Sutradharudu Teki diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c index 3b39ba7..cb57ce0 100644 --- a/drivers/mtd/spi/winbond.c +++ b/drivers/mtd/spi/winbond.c @@ -18,6 +18,21 @@ struct winbond_spi_flash_params { static const struct winbond_spi_flash_params winbond_spi_flash_table[] = { { + .id = 0x2014, + .nr_blocks = 16, + .name = "W25P80", + }, + { + .id = 0x2015, + .nr_blocks = 32, + .name = "W25P16", + }, + { + .id = 0x2016, + .nr_blocks = 64, + .name = "W25P32", + }, + { .id = 0x3013, .nr_blocks = 8, .name = "W25X40", @@ -109,7 +124,7 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode) } flash->page_size = 256; - flash->sector_size = 4096; + flash->sector_size = (idcode[1] == 0x20) ? 65536 : 4096; flash->size = 4096 * 16 * params->nr_blocks; return flash; -- cgit v0.10.2 From bb786b84bdbcfe0474d53a54c82c5695494a6ab5 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Tue, 28 May 2013 20:10:37 +0000 Subject: spi: Add support for preamble bytes A SPI slave may take time to react to a request. For SPI flash devices this time is defined as one bit time, or a whole byte for 'fast read' mode. If the SPI slave is another CPU, then the time it takes to react may vary. It is convenient to allow the slave device to tag the start of the actual reply so that the host can determine when this 'preamble' finishes and the actual message starts. Add a preamble flag to the available SPI flags. If supported by the driver then it will ignore any received bytes before the preamble on each transaction. This ensures that reliable communication with the slave is possible. Signed-off-by: Simon Glass Signed-off-by: Rajeshwari Shinde Reviewed-by: Jagannadha Sutradharudu Teki diff --git a/include/spi.h b/include/spi.h index 3fe2e1e..1638b50 100644 --- a/include/spi.h +++ b/include/spi.h @@ -37,11 +37,16 @@ #define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */ #define SPI_3WIRE 0x10 /* SI/SO signals shared */ #define SPI_LOOP 0x20 /* loopback mode */ +#define SPI_SLAVE 0x40 /* slave mode */ +#define SPI_PREAMBLE 0x80 /* Skip preamble bytes */ /* SPI transfer flags */ #define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */ #define SPI_XFER_END 0x02 /* Deassert CS after transfer */ +/* Header byte that marks the start of the message */ +#define SPI_PREAMBLE_END_BYTE 0xec + /*----------------------------------------------------------------------- * Representation of a SPI slave, i.e. what we're communicating with. * -- cgit v0.10.2 From e4eaef8910df805d511b1cb9b2caafa7d2827fdc Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Tue, 28 May 2013 20:10:38 +0000 Subject: spi: exynos: Support SPI_PREAMBLE mode Support interfaces with a preamble before each received message. We handle this when the client has requested a SPI_XFER_END, meaning that we must close of the transaction. In this case we read until we see the preamble (or a timeout occurs), skipping all data before and including the preamble. The client will receive only data bytes after the preamble. Signed-off-by: Simon Glass Signed-off-by: Rajeshwari Shinde Reviewed-by: Jagannadha Sutradharudu Teki diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c index 607e1cd..01378d0 100644 --- a/drivers/spi/exynos_spi.c +++ b/drivers/spi/exynos_spi.c @@ -51,6 +51,7 @@ struct exynos_spi_slave { unsigned int mode; enum periph_id periph_id; /* Peripheral ID for this device */ unsigned int fifo_size; + int skip_preamble; }; static struct spi_bus *spi_get_bus(unsigned dev_index) @@ -105,6 +106,8 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, else spi_slave->fifo_size = 256; + spi_slave->skip_preamble = 0; + spi_slave->freq = bus->frequency; if (max_hz) spi_slave->freq = min(max_hz, spi_slave->freq); @@ -217,17 +220,23 @@ static void spi_request_bytes(struct exynos_spi *regs, int count) writel(count | SPI_PACKET_CNT_EN, ®s->pkt_cnt); } -static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, - void **dinp, void const **doutp) +static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, + void **dinp, void const **doutp, unsigned long flags) { struct exynos_spi *regs = spi_slave->regs; uchar *rxp = *dinp; const uchar *txp = *doutp; int rx_lvl, tx_lvl; uint out_bytes, in_bytes; + int toread; + unsigned start = get_timer(0); + int stopping; out_bytes = in_bytes = todo; + stopping = spi_slave->skip_preamble && (flags & SPI_XFER_END) && + !(spi_slave->mode & SPI_SLAVE); + /* * If there's something to send, do a software reset and set a * transaction size. @@ -238,6 +247,8 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, * Bytes are transmitted/received in pairs. Wait to receive all the * data because then transmission will be done as well. */ + toread = in_bytes; + while (in_bytes) { int temp; @@ -248,15 +259,43 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, writel(temp, ®s->tx_data); out_bytes--; } - if (rx_lvl > 0 && in_bytes) { + if (rx_lvl > 0) { temp = readl(®s->rx_data); - if (rxp) - *rxp++ = temp; - in_bytes--; + if (spi_slave->skip_preamble) { + if (temp == SPI_PREAMBLE_END_BYTE) { + spi_slave->skip_preamble = 0; + stopping = 0; + } + } else { + if (rxp || stopping) + *rxp++ = temp; + in_bytes--; + } + toread--; + } else if (!toread) { + /* + * We have run out of input data, but haven't read + * enough bytes after the preamble yet. Read some more, + * and make sure that we transmit dummy bytes too, to + * keep things going. + */ + assert(!out_bytes); + out_bytes = in_bytes; + toread = in_bytes; + txp = NULL; + spi_request_bytes(regs, toread); + } + if (spi_slave->skip_preamble && get_timer(start) > 100) { + printf("SPI timeout: in_bytes=%d, out_bytes=%d, ", + in_bytes, out_bytes); + return -1; } } + *dinp = rxp; *doutp = txp; + + return 0; } /** @@ -276,6 +315,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, struct exynos_spi_slave *spi_slave = to_exynos_spi(slave); int upto, todo; int bytelen; + int ret = 0; /* spi core configured to do 8 bit transfers */ if (bitlen % 8) { @@ -289,16 +329,24 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, /* Exynos SPI limits each transfer to 65535 bytes */ bytelen = bitlen / 8; - for (upto = 0; upto < bytelen; upto += todo) { + for (upto = 0; !ret && upto < bytelen; upto += todo) { todo = min(bytelen - upto, (1 << 16) - 1); - spi_rx_tx(spi_slave, todo, &din, &dout); + ret = spi_rx_tx(spi_slave, todo, &din, &dout, flags); + if (ret) + break; } /* Stop the transaction, if necessary. */ - if ((flags & SPI_XFER_END)) + if ((flags & SPI_XFER_END) && !(spi_slave->mode & SPI_SLAVE)) { spi_cs_deactivate(slave); + if (spi_slave->skip_preamble) { + assert(!spi_slave->skip_preamble); + debug("Failed to complete premable transaction\n"); + ret = -1; + } + } - return 0; + return ret; } /** @@ -325,6 +373,7 @@ void spi_cs_activate(struct spi_slave *slave) clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT); debug("Activate CS, bus %d\n", spi_slave->slave.bus); + spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE; } /** -- cgit v0.10.2 From 0d3b596aa35fd828f2147c6d3c86d4e2730f7b29 Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki Date: Mon, 27 May 2013 10:14:14 +0000 Subject: sf: Fix sf read for memory-mapped SPI flashes Missing return after memcpy is done for memory-mapped SPI flashes, hence added retun 0 after memcpy done. The return is missing in below patch "sf: Enable FDT-based configuration and memory mapping" (sha1: bb8215f437a7c948eec82a6abe754c226978bd6d) Signed-off-by: Jagannadha Sutradharudu Teki Acked-by: Simon Glass diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 111185a..6fa932c 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -150,8 +150,10 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, u8 cmd[5]; /* Handle memory-mapped SPI */ - if (flash->memory_map) + if (flash->memory_map) { memcpy(data, flash->memory_map + offset, len); + return 0; + } cmd[0] = CMD_READ_ARRAY_FAST; spi_flash_addr(offset, cmd); -- cgit v0.10.2 From 96bbf55651fc2bedc175830d22179e384d640d99 Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki Date: Sun, 26 May 2013 01:35:21 +0530 Subject: cmd_sf: Add print mesg for 'sf erase' command This patch adds a print messages while using 'sf erase' command to make sure that how many bytes erased in flash device. Signed-off-by: Jagannadha Sutradharudu Teki Acked-by: Tom Rini diff --git a/common/cmd_sf.c b/common/cmd_sf.c index 0a17782..7f12a49 100644 --- a/common/cmd_sf.c +++ b/common/cmd_sf.c @@ -305,12 +305,10 @@ static int do_spi_flash_erase(int argc, char * const argv[]) } ret = spi_flash_erase(flash, offset, len); - if (ret) { - printf("SPI flash %s failed\n", argv[0]); - return 1; - } + printf("SF: %zu bytes @ %#x Erased: %s\n", (size_t)len, (u32)offset, + ret ? "ERROR" : "OK"); - return 0; + return ret == 0 ? 0 : 1; } #ifdef CONFIG_CMD_SF_TEST diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 6fa932c..de6fd58 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -207,7 +207,7 @@ int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len) { - u32 start, end, erase_size; + u32 end, erase_size; int ret; u8 cmd[4]; @@ -227,8 +227,7 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len) cmd[0] = CMD_ERASE_4K; else cmd[0] = CMD_ERASE_64K; - start = offset; - end = start + len; + end = offset + len; while (offset < end) { spi_flash_addr(offset, cmd); @@ -250,8 +249,6 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len) goto out; } - debug("SF: Successfully erased %zu bytes @ %#x\n", len, start); - out: spi_release_bus(flash->spi); return ret; -- cgit v0.10.2 From 60b6614ac8d189b8e31b9a7564fe5babb374bffa Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki Date: Sun, 26 May 2013 14:52:52 +0530 Subject: cmd_sf: Add print mesgs on sf read/write commands This patch adds a print messages while using 'sf read' and 'sf write' commands to make sure that how many bytes read/written from/into flash device. Signed-off-by: Jagannadha Sutradharudu Teki Acked-by: Tom Rini diff --git a/common/cmd_sf.c b/common/cmd_sf.c index 7f12a49..19b0dc9 100644 --- a/common/cmd_sf.c +++ b/common/cmd_sf.c @@ -234,7 +234,7 @@ static int do_spi_flash_read_write(int argc, char * const argv[]) unsigned long len; void *buf; char *endp; - int ret; + int ret = 1; if (argc < 4) return -1; @@ -264,19 +264,23 @@ static int do_spi_flash_read_write(int argc, char * const argv[]) if (strcmp(argv[0], "update") == 0) ret = spi_flash_update(flash, offset, len, buf); - else if (strcmp(argv[0], "read") == 0) - ret = spi_flash_read(flash, offset, len, buf); - else - ret = spi_flash_write(flash, offset, len, buf); + else if (strncmp(argv[0], "read", 4) == 0 || + strncmp(argv[0], "write", 5) == 0) { + int read; + + read = strncmp(argv[0], "read", 4) == 0; + if (read) + ret = spi_flash_read(flash, offset, len, buf); + else + ret = spi_flash_write(flash, offset, len, buf); + + printf("SF: %zu bytes @ %#x %s: %s\n", (size_t)len, (u32)offset, + read ? "Read" : "Written", ret ? "ERROR" : "OK"); + } unmap_physmem(buf, len); - if (ret) { - printf("SPI flash %s failed\n", argv[0]); - return 1; - } - - return 0; + return ret == 0 ? 0 : 1; } static int do_spi_flash_erase(int argc, char * const argv[]) diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index de6fd58..0e38f59 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -124,9 +124,6 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset, } } - debug("SF: program %s %zu bytes @ %#x\n", - ret ? "failure" : "success", len, offset); - spi_release_bus(flash->spi); return ret; } -- cgit v0.10.2 From 0368292954c70d0413f849cb3d45b403beffeaa6 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 11 Jun 2013 21:57:31 +0800 Subject: spi: armada100_spi: Remove unnecessary NULL test for dout and din Signed-off-by: Axel Lin Reviewed-by: Marek Vasut Acked-by: Ajay Bhargav Reviewed-by: Jagannadha Sutradharudu Teki diff --git a/drivers/spi/armada100_spi.c b/drivers/spi/armada100_spi.c index afdbe05..b237c7c 100644 --- a/drivers/spi/armada100_spi.c +++ b/drivers/spi/armada100_spi.c @@ -182,15 +182,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, goto done; } - if (dout) - pss->tx = dout; - else - pss->tx = NULL; - - if (din) - pss->rx = din; - else - pss->rx = NULL; + pss->tx = dout; + pss->rx = din; if (flags & SPI_XFER_BEGIN) { spi_cs_activate(slave); -- cgit v0.10.2 From d6f64d4a11c2aa4318b20eeda04c564728705080 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 13 Jun 2013 16:17:47 +0800 Subject: spi: tegra114_spi: Convert to use spi_alloc_slave() Signed-off-by: Axel Lin Acked-by: Marek Vasut Reviewed-by: Jagannadha Sutradharudu Teki diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c index b11a0a1..4d2af48 100644 --- a/drivers/spi/tegra114_spi.c +++ b/drivers/spi/tegra114_spi.c @@ -152,13 +152,11 @@ struct spi_slave *tegra114_spi_setup_slave(unsigned int bus, unsigned int cs, return NULL; } - spi = malloc(sizeof(struct tegra_spi_slave)); + spi = spi_alloc_slave(struct tegra_spi_slave, bus, cs); if (!spi) { printf("SPI error: malloc of SPI structure failed\n"); return NULL; } - spi->slave.bus = bus; - spi->slave.cs = cs; spi->ctrl = &spi_ctrls[bus]; if (!spi->ctrl) { printf("SPI error: could not find controller for bus %d\n", -- cgit v0.10.2 From ba1d1c2d9b187bbbba3301e01aa8e84f56cd4d00 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 13 Jun 2013 16:21:42 +0800 Subject: spi: tegra20_sflash: Remove redundant code to set bus and cs of struct spi_slave It's done in spi_alloc_slave(), thus remove the redundant code. Signed-off-by: Axel Lin Acked-by: Marek Vasut Reviewed-by: Jagannadha Sutradharudu Teki diff --git a/drivers/spi/tegra20_sflash.c b/drivers/spi/tegra20_sflash.c index 9322ce7..7c3a3fc 100644 --- a/drivers/spi/tegra20_sflash.c +++ b/drivers/spi/tegra20_sflash.c @@ -132,8 +132,6 @@ struct spi_slave *tegra20_spi_setup_slave(unsigned int bus, unsigned int cs, printf("SPI error: malloc of SPI structure failed\n"); return NULL; } - spi->slave.bus = bus; - spi->slave.cs = cs; spi->ctrl = &spi_ctrls[bus]; if (!spi->ctrl) { printf("SPI error: could not find controller for bus %d\n", -- cgit v0.10.2 From 59120ca36568cb6c8dfb8c1e427c4432ccbdf894 Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki Date: Sat, 25 May 2013 23:03:11 +0530 Subject: sf: spansion: Update the name for S25FL256S flash As the per the ID tabl the flash is under Uniform 64-kB sector architecture, hence updated with proper name. Signed-off-by: Jagannadha Sutradharudu Teki diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c index 307b852..2218e2f 100644 --- a/drivers/mtd/spi/spansion.c +++ b/drivers/mtd/spi/spansion.c @@ -108,7 +108,7 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = { .idcode2 = 0x4d01, .pages_per_sector = 256, .nr_sectors = 512, - .name = "S25FL256S", + .name = "S25FL256S_64K", }, }; -- cgit v0.10.2 From fc2d721992269cde9b67fc38ccf9eeda01bd24ef Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki Date: Mon, 27 May 2013 12:50:50 +0530 Subject: sf: winbond: Add support for W25Q80BW Add support for Winbond W25Q80BW SPI flash. This patch corrected the flash name, nr_blocks and also commit message header from below patch. "sf: winbond: add W25Q32" (sha1: c969abc47033d6f810d3c9dbdb994ea9d691d038) Signed-off-by: Jagannadha Sutradharudu Teki diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c index cb57ce0..a7cd51f 100644 --- a/drivers/mtd/spi/winbond.c +++ b/drivers/mtd/spi/winbond.c @@ -84,8 +84,8 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = { }, { .id = 0x5014, - .nr_blocks = 128, - .name = "W25Q80", + .nr_blocks = 16, + .name = "W25Q80BW", }, { .id = 0x6016, -- cgit v0.10.2 From ea7fcc5aeb10d2cbb5589e91f36b205dcaf4b7a8 Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki Date: Sat, 25 May 2013 02:13:41 +0530 Subject: sf: winbond: Correct the nr_blocks used for W25Q32DW This patch corrected the nr_blocks used for W25Q32DW SPI flash. nr_blcoks are incorrectly assigned on below patch "sf: winbond: add W25Q32DW" (sha1: 772ba15474f73adc942e817cc072b6e9750836cc) Signed-off-by: Jagannadha Sutradharudu Teki diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c index a7cd51f..8457808 100644 --- a/drivers/mtd/spi/winbond.c +++ b/drivers/mtd/spi/winbond.c @@ -89,7 +89,7 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = { }, { .id = 0x6016, - .nr_blocks = 512, + .nr_blocks = 64, .name = "W25Q32DW", }, { -- cgit v0.10.2