]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
sf: Update the qspi dual parallel flash access logic
authorJagannadha Sutradharudu Teki <jaganna@xilinx.com>
Wed, 24 Apr 2013 18:54:48 +0000 (00:24 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Thu, 25 Apr 2013 14:55:47 +0000 (16:55 +0200)
Updated the xilinx qspi dual parallel flash access support
to use 3-byte addressing instead of 4-byte addressing used
from the mtd flash layer.

Instead of sending 4-byte addressing from mtd layer and
then the controller will again divide the offset addr by 2 and
convert the 4-byte address into 3-byte address, With this
new logic the mtd will serve the offset as offset by 2 and
send the 3-byte addressing to controller driver, as the
driver is configured as separate bus with two mem the
controller internal hardware algorithm will take care the
dual parallel functionality.

Below are the changes for dual parallel to work:
- mtd layer -> addr/2, page_size*2, nr_sectors/nr_blocks*2
- driver -> enable SEP_BUS[BIT:29],TWO_MEM[BIT:30] on LQSPI_CFG

Signed-off-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
drivers/mtd/spi/spansion.c
drivers/mtd/spi/spi_flash.c
drivers/mtd/spi/stmicro.c
drivers/mtd/spi/winbond.c
drivers/spi/zynq_qspips.c
include/spi_flash.h

index 45c6872f9b3c9094760d7d1827b8c96c95696242..9243adb2496efeef9b8cd9b6c35936343ef203a4 100644 (file)
@@ -137,14 +137,12 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)
        flash->page_size = 256;
        flash->sector_size = 256 * params->pages_per_sector;
 
-       /* address width is 4 for dual and 3 for single qspi */
+       /* page_size and nr_sectors are double for dual parallel qspi */
        if (flash->spi->is_dual == 1) {
-               flash->addr_width = 4;
+               flash->page_size *= 2;
                flash->size = flash->sector_size * (2 * params->nr_sectors);
-       } else {
-               flash->addr_width = 3;
+       } else
                flash->size = flash->sector_size * params->nr_sectors;
-       }
 
        return flash;
 }
index c7dc775a5de51f4b84b2a6567468b8072bbce2ba..ea0f092c9e4f95a6bbe80d1949963caae0143d4b 100644 (file)
@@ -22,16 +22,9 @@ static void spi_flash_addr(struct spi_flash *flash,
        unsigned long page_addr, unsigned long byte_addr, u8 *cmd)
 {
        /* cmd[0] is actual command */
-       if (flash->addr_width == 4) {
-               cmd[1] = page_addr >> 16;
-               cmd[2] = page_addr >> 8;
-               cmd[3] = page_addr;
-               cmd[4] = byte_addr;
-       } else {
-               cmd[1] = page_addr >> 8;
-               cmd[2] = page_addr;
-               cmd[3] = byte_addr;
-       }
+       cmd[1] = page_addr >> 8;
+       cmd[2] = page_addr;
+       cmd[3] = byte_addr;
 }
 
 static int spi_flash_read_write(struct spi_slave *spi,
@@ -82,13 +75,16 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
        unsigned long page_addr, byte_addr, page_size;
        size_t chunk_len, actual;
        int ret;
-       u8 cmd[flash->addr_width+1];
+       u8 cmd[4];
        u32 start;
        u8 bank_sel;
 
        start = offset;
        page_size = flash->page_size;
 
+       if (flash->spi->is_dual == 1)
+               offset /= 2;
+
        ret = spi_claim_bus(flash->spi);
        if (ret) {
                debug("SF: unable to claim SPI bus\n");
@@ -116,9 +112,8 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
 
                spi_flash_addr(flash, page_addr, byte_addr, cmd);
 
-               debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x0x%02x } \
-                       chunk_len = %zu\n", buf + actual, cmd[0], cmd[1],
-                       cmd[2], cmd[3], cmd[4], chunk_len);
+               debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
+                     buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
 
                ret = spi_flash_cmd_write_enable(flash);
                if (ret < 0) {
@@ -164,7 +159,7 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
                size_t len, void *data)
 {
        unsigned long page_addr, page_size, byte_addr;
-       u8 cmd[flash->addr_width+2];
+       u8 cmd[5];
        u8 bank_sel;
        u32 remain_len, read_len;
        int ret = -1;
@@ -173,6 +168,9 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
        if (flash->memory_map)
                memcpy(data, flash->memory_map + offset, len);
 
+       if (flash->spi->is_dual == 1)
+               offset /= 2;
+
        page_size = flash->page_size;
        cmd[0] = CMD_READ_ARRAY_FAST;
        cmd[sizeof(cmd)-1] = 0x00;
@@ -261,7 +259,7 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len)
        u32 start, end, erase_size;
        int ret;
        unsigned long page_addr;
-       u8 cmd[flash->addr_width+1];
+       u8 cmd[4];
        u8 bank_sel;
 
        erase_size = flash->sector_size;
@@ -270,6 +268,9 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len)
                return -1;
        }
 
+       if (flash->spi->is_dual == 1)
+               offset /= 2;
+
        ret = spi_claim_bus(flash->spi);
        if (ret) {
                debug("SF: Unable to claim SPI bus\n");
@@ -296,8 +297,8 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len)
                page_addr = (offset & SPI_FLASH_16MB_MASK) / flash->page_size;
                spi_flash_addr(flash, page_addr, 0, cmd);
 
-               debug("SF: erase %2x %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
-                       cmd[2], cmd[3], cmd[4], offset);
+               debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+                     cmd[2], cmd[3], offset);
 
                ret = spi_flash_cmd_write_enable(flash);
                if (ret)
index b73112c94972bf0e7b94d1ef8e9e7af09c551c33..93e9edb987c7358551cd5bbe5b3d0dc84508d22d 100644 (file)
@@ -185,14 +185,12 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
        flash->page_size = 256;
        flash->sector_size = 256 * params->pages_per_sector;
 
-       /* address width is 4 for dual and 3 for single qspi */
+       /* page_size and nr_sectors are double for dual parallel qspi */
        if (flash->spi->is_dual == 1) {
-               flash->addr_width = 4;
+               flash->page_size *= 2;
                flash->size = flash->sector_size * (2 * params->nr_sectors);
-       } else {
-               flash->addr_width = 3;
+       } else
                flash->size = flash->sector_size * params->nr_sectors;
-       }
 
        return flash;
 }
index 6e9b586fe07a6010b573b0f3852c1bb779a9f034..bf4cf383049a32a940cf0ddbf45439aaa0a25609 100644 (file)
@@ -106,14 +106,12 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
        flash->page_size = 256;
        flash->sector_size = 4096;
 
-       /* address width is 4 for dual and 3 for single qspi */
+       /* page_size and nr_blocks are double for dual parallel qspi */
        if (flash->spi->is_dual == 1) {
-               flash->addr_width = 4;
+               flash->page_size *= 2;
                flash->size = 4096 * 16 * (2 * params->nr_blocks);
-       } else {
-               flash->addr_width = 3;
+       } else
                flash->size = 4096 * 16 * params->nr_blocks;
-       }
 
        return flash;
 }
index f8ea139d725afeb2a84b60e7ebc6f822073f70c0..4934eb3b06635cd8419565df2506ceffe60c0d87 100644 (file)
@@ -657,32 +657,6 @@ static int xqspips_start_transfer(struct spi_device *qspi,
                xqspi->curr_inst = &flash_inst[index];
                xqspi->inst_response = 1;
 
-               /*
-                * In case of dual memories, convert 25 bit address to 24 bit
-                * address before transmitting to the 2 memories
-                */
-               if ((xqspi->is_dual == MODE_DUAL_PARALLEL) &&
-                   ((instruction == XQSPIPS_FLASH_OPCODE_PP) ||
-                   (instruction == XQSPIPS_FLASH_OPCODE_SE) ||
-                   (instruction == XQSPIPS_FLASH_OPCODE_BE_32K) ||
-                   (instruction == XQSPIPS_FLASH_OPCODE_BE_4K) ||
-                   (instruction == XQSPIPS_FLASH_OPCODE_BE) ||
-                   (instruction == XQSPIPS_FLASH_OPCODE_NORM_READ) ||
-                   (instruction == XQSPIPS_FLASH_OPCODE_FAST_READ) ||
-                   (instruction == XQSPIPS_FLASH_OPCODE_DUAL_READ) ||
-                   (instruction == XQSPIPS_FLASH_OPCODE_QUAD_READ))) {
-
-                       u8 *ptr = (u8 *) (xqspi->txbuf);
-                       data = ((u32) ptr[1] << 24) | ((u32) ptr[2] << 16) |
-                               ((u32) ptr[3] << 8) | ((u32) ptr[4]);
-                       data = data/2;
-                       ptr[1] = (u8) (data >> 16);
-                       ptr[2] = (u8) (data >> 8);
-                       ptr[3] = (u8) (data);
-                       xqspi->bytes_to_transfer -= 1;
-                       xqspi->bytes_to_receive -= 1;
-               }
-
                /* Get the instruction */
                data = 0;
                xqspips_copy_write_data(xqspi, &data,
index 2475be5de36b4fb026431aeb03290c0e5765d28e..88b302a4a6f566bc7f09cc0e6bc05e6d63c4f92d 100644 (file)
@@ -38,8 +38,6 @@ struct spi_flash {
        u32             page_size;
        /* Erase (sector) size */
        u32             sector_size;
-       /* To find whether single/dual spi device */
-       u8              addr_width;
        /* ID code0 */
        u8              idcode0;
        /* Current bank */