]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
sf: Add dual memories support - DUAL_PARALLEL
authorJagannadha Sutradharudu Teki <jaganna@xilinx.com>
Mon, 6 Jan 2014 18:41:35 +0000 (00:11 +0530)
committerJagannadha Sutradharudu Teki <jaganna@xilinx.com>
Sun, 12 Jan 2014 16:10:22 +0000 (21:40 +0530)
This patch added support for accessing dual memories in
parallel connection with single chipselect line from controller.

For more info - see doc/SPI/README.dual-flash

Signed-off-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
doc/SPI/README.dual-flash
drivers/mtd/spi/sf_ops.c
drivers/mtd/spi/sf_probe.c
include/spi.h
include/spi_flash.h

index ba0aa265e0177a393fd3926cc91452acb1777686..6c88d65dd49f86a8e1edcf30d4b5b4ccdc53d0d7 100644 (file)
@@ -54,6 +54,33 @@ SF_DUAL_STACKED_FLASH:
                by default, if U_PAGE is unset lower memory should accessible,
                once user wants to access upper memory need to set U_PAGE.
 
+SPI_FLASH_CONN_DUALPARALLEL:
+       - dual spi/qspi flash memories are connected with a single chipselect
+         line and these two memories are operating parallel with separate buses.
+       - xilinx zynq qspi controller has implemented this feature [1]
+
+  +-------------+           CS         +---------------+
+  |            |---------------------->|               |
+  |            |        I0[3:0]        | Upper Flash   |
+  |            |<=====================>| memory        |
+  |            |          CLK          | (SPI/QSPI)    |
+  |            |---------------------->|               |
+  | Controller |           CS          +---------------+
+  | SPI/QSPI   |---------------------->|               |
+  |            |        I0[3:0]        | Lower Flash   |
+  |            |<=====================>| memory        |
+  |            |          CLK          | (SPI/QSPI)    |
+  |            |---------------------->|               |
+  +-------------+                      +---------------+
+
+       - two memory flash devices should has same hw part attributes (like size,
+         vendor..etc)
+       - Configurations:
+               Need to enable SEP_BUS[BIT:29],TWO_MEM[BIT:30] on LQSPI_CFG register.
+       - Operation:
+               Even bits, i.e. bit 0, 2, 4 ., of a data word is located in the lower memory
+               and odd bits, i.e. bit 1, 3, 5, ., of a data word is located in the upper memory.
+
 Note: Technically there is only one CS line from the controller, but
 zynq qspi controller has an internal hw logic to enable additional CS
 when controller is configured for dual memories.
index e877858a918543501b8d6d7628fe303c532a5913..843f379ef15bd51d940b2eb9c98f204be8d6ac78 100644 (file)
@@ -119,7 +119,7 @@ static int spi_flash_bank(struct spi_flash *flash, u32 offset)
        u8 bank_sel;
        int ret;
 
-       bank_sel = offset / SPI_FLASH_16MB_BOUN;
+       bank_sel = offset / (SPI_FLASH_16MB_BOUN << flash->shift);
 
        ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
        if (ret) {
@@ -142,6 +142,9 @@ static void spi_flash_dual_flash(struct spi_flash *flash, u32 *addr)
                        flash->spi->flags &= ~SPI_XFER_U_PAGE;
                }
                break;
+       case SF_DUAL_PARALLEL_FLASH:
+               *addr >>= flash->shift;
+               break;
        default:
                debug("SF: Unsupported dual_flash=%d\n", flash->dual_flash);
                break;
@@ -388,7 +391,8 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
                if (bank_sel < 0)
                        return ret;
 #endif
-               remain_len = (SPI_FLASH_16MB_BOUN * (bank_sel + 1)) - offset;
+               remain_len = ((SPI_FLASH_16MB_BOUN << flash->shift) *
+                               (bank_sel + 1)) - offset;
                if (len < remain_len)
                        read_len = len;
                else
index b9e14c5a2bb1ac45a2ef3e9b0d4147cbff2a8302..48de7c1986a5eeebd4cb1b34d798bb33c7e78aaa 100644 (file)
@@ -146,19 +146,20 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
        flash->read = spi_flash_cmd_read_ops;
 
        /* Compute the flash size */
-       flash->page_size = (ext_jedec == 0x4d00) ? 512 : 256;
-       flash->sector_size = params->sector_size;
-       flash->size = flash->sector_size * params->nr_sectors;
+       flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0;
+       flash->page_size = ((ext_jedec == 0x4d00) ? 512 : 256) << flash->shift;
+       flash->sector_size = params->sector_size << flash->shift;
+       flash->size = flash->sector_size * params->nr_sectors << flash->shift;
        if (flash->dual_flash & SF_DUAL_STACKED_FLASH)
                flash->size <<= 1;
 
        /* Compute erase sector and command */
        if (params->flags & SECT_4K) {
                flash->erase_cmd = CMD_ERASE_4K;
-               flash->erase_size = 4096;
+               flash->erase_size = 4096 << flash->shift;
        } else if (params->flags & SECT_32K) {
                flash->erase_cmd = CMD_ERASE_32K;
-               flash->erase_size = 32768;
+               flash->erase_size = 32768 << flash->shift;
        } else {
                flash->erase_cmd = CMD_ERASE_64K;
                flash->erase_size = flash->sector_size;
index d214d82923997ea86d5cc3975d0b7c5b8e6d2701..ffd66478b194180e10db2649b96dee8280f77751 100644 (file)
@@ -47,6 +47,7 @@
 
 /* SPI bus connection options */
 #define SPI_CONN_DUAL_SHARED   1 << 0
+#define SPI_CONN_DUAL_SEPARATED        1 << 1
 
 /* Header byte that marks the start of the message */
 #define SPI_PREAMBLE_END_BYTE  0xec
@@ -66,7 +67,7 @@
  * @max_write_size:    If non-zero, the maximum number of bytes which can
  *                     be written at once, excluding command bytes.
  * @memory_map:                Address of read-only SPI flash access.
- * @option:            Varies SPI bus options - separate bus.
+ * @option:            Varies SPI bus options - separate, shared bus.
  * @flags:             Indication of SPI flags.
  */
 struct spi_slave {
index 36f1f033c0c20db78a38c0fe6443ef566190340e..f79f0eacca03b66d6604e1dfe9e3afd4f38bb250 100644 (file)
@@ -40,6 +40,7 @@ enum spi_read_cmds {
 enum spi_dual_flash {
        SF_SINGLE_FLASH = 0,
        SF_DUAL_STACKED_FLASH = 1 << 0,
+       SF_DUAL_PARALLEL_FLASH = 1 << 1,
 };
 
 /**
@@ -70,7 +71,8 @@ extern const struct spi_flash_params spi_flash_params_table[];
  *
  * @spi:               SPI slave
  * @name:              Name of SPI flash
- * @dual_flash:                Indicates dual flash memories - dual stacked
+ * @dual_flash:                Indicates dual flash memories - dual stacked, parallel
+ * @shift:             Flash shift useful in dual parallel
  * @size:              Total flash size
  * @page_size:         Write (page) size
  * @sector_size:       Sector size
@@ -96,6 +98,7 @@ struct spi_flash {
        struct spi_slave *spi;
        const char *name;
        u8 dual_flash;
+       u8 shift;
 
        u32 size;
        u32 page_size;