From: Jagannadha Sutradharudu Teki Date: Wed, 24 Apr 2013 18:54:48 +0000 (+0530) Subject: sf: Update the qspi dual parallel flash access logic X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=126774ac78440069441a08907e53f640180a09e6;p=thirdparty%2Fu-boot.git sf: Update the qspi dual parallel flash access logic 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 --- diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c index 45c6872f9b3..9243adb2496 100644 --- a/drivers/mtd/spi/spansion.c +++ b/drivers/mtd/spi/spansion.c @@ -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; } diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index c7dc775a5de..ea0f092c9e4 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -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) diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c index b73112c9497..93e9edb987c 100644 --- a/drivers/mtd/spi/stmicro.c +++ b/drivers/mtd/spi/stmicro.c @@ -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; } diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c index 6e9b586fe07..bf4cf383049 100644 --- a/drivers/mtd/spi/winbond.c +++ b/drivers/mtd/spi/winbond.c @@ -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; } diff --git a/drivers/spi/zynq_qspips.c b/drivers/spi/zynq_qspips.c index f8ea139d725..4934eb3b066 100644 --- a/drivers/spi/zynq_qspips.c +++ b/drivers/spi/zynq_qspips.c @@ -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, diff --git a/include/spi_flash.h b/include/spi_flash.h index 2475be5de36..88b302a4a6f 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -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 */