ipq807x: Add 4byte mode support for Winbond nor flash

Change-Id: I4f31612091bff4f03527fbfd41f02f4a7267f248
Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org>
This commit is contained in:
Sham Muthayyan 2017-10-23 12:47:28 +05:30 committed by Gerrit - the friendly Code Review server
parent 921da8d0b2
commit 23f9381f86
3 changed files with 43 additions and 13 deletions

View file

@ -54,7 +54,7 @@ enum spi_nor_option_flags {
};
#define SPI_FLASH_3B_ADDR_LEN 3
#define SPI_FLASH_CMD_LEN (1 + SPI_FLASH_3B_ADDR_LEN)
#define SPI_FLASH_4B_ADDR_LEN 4
#define SPI_FLASH_16MB_BOUN 0x1000000
/* CFI Manufacture ID's */

View file

@ -21,12 +21,19 @@
DECLARE_GLOBAL_DATA_PTR;
static void spi_flash_addr(u32 addr, u8 *cmd)
static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd)
{
/* cmd[0] is actual command */
cmd[1] = addr >> 16;
cmd[2] = addr >> 8;
cmd[3] = addr >> 0;
cmd[1] = addr >> (flash->addr_width * 8 - 8);
cmd[2] = addr >> (flash->addr_width * 8 - 16);
cmd[3] = addr >> (flash->addr_width * 8 - 24);
if (flash->addr_width == SPI_FLASH_4B_ADDR_LEN)
cmd[4] = addr >> (flash->addr_width * 8 - 32);
}
static int spi_flash_cmdsz(struct spi_flash *flash)
{
return 1 + flash->addr_width;
}
/* Read commands array */
@ -122,6 +129,7 @@ static int write_cr(struct spi_flash *flash, u8 wc)
#endif
#ifdef CONFIG_SPI_FLASH_BAR
static int spi_flash_write_bar(struct spi_flash *flash, u32 offset)
{
u8 cmd, bank_sel;
@ -302,7 +310,7 @@ int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
{
u32 erase_size, erase_addr;
u8 cmd[SPI_FLASH_CMD_LEN];
u8 *cmd, cmdsz;
int ret = -1;
erase_size = flash->erase_size;
@ -319,6 +327,13 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
}
}
cmdsz = spi_flash_cmdsz(flash);
cmd = calloc(1, cmdsz);
if (!cmd) {
debug("SF: Failed to allocate cmd\n");
return -ENOMEM;
}
cmd[0] = flash->erase_cmd;
while (len) {
erase_addr = offset;
@ -332,12 +347,12 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
if (ret < 0)
return ret;
#endif
spi_flash_addr(erase_addr, cmd);
spi_flash_addr(flash, erase_addr, cmd);
debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
cmd[2], cmd[3], erase_addr);
ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0);
ret = spi_flash_write_common(flash, cmd, cmdsz, NULL, 0);
if (ret < 0) {
debug("SF: erase failed\n");
break;
@ -356,7 +371,7 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
unsigned long byte_addr, page_size;
u32 write_addr;
size_t chunk_len, actual;
u8 cmd[SPI_FLASH_CMD_LEN];
u8 *cmd, cmdsz;
int ret = -1;
page_size = flash->page_size;
@ -369,6 +384,13 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
}
}
cmdsz = spi_flash_cmdsz(flash);
cmd = calloc(1, cmdsz);
if (!cmd) {
debug("SF: Failed to allocate cmd\n");
return -ENOMEM;
}
cmd[0] = flash->write_cmd;
for (actual = 0; actual < len; actual += chunk_len) {
write_addr = offset;
@ -389,12 +411,12 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
chunk_len = min(chunk_len,
(size_t)flash->spi->max_write_size);
spi_flash_addr(write_addr, cmd);
spi_flash_addr(flash, write_addr, cmd);
debug("SF: 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_write_common(flash, cmd, sizeof(cmd),
ret = spi_flash_write_common(flash, cmd, cmdsz,
buf + actual, chunk_len);
if (ret < 0) {
debug("SF: write failed\n");
@ -457,7 +479,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
return 0;
}
cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte;
cmdsz = spi_flash_cmdsz(flash) + flash->dummy_byte;
cmd = calloc(1, cmdsz);
if (!cmd) {
debug("SF: Failed to allocate cmd\n");
@ -485,7 +507,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
else
read_len = remain_len;
spi_flash_addr(read_addr, cmd);
spi_flash_addr(flash, read_addr, cmd);
ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len);
if (ret < 0) {
@ -1071,6 +1093,13 @@ int spi_flash_scan(struct spi_flash *flash)
flash->dummy_byte = 1;
}
flash->addr_width = SPI_FLASH_3B_ADDR_LEN;
printf("SPI_ADDR_LEN=%x\n",get_smem_spi_addr_len());
if ((flash->size > SPI_FLASH_16MB_BOUN) &&
(get_smem_spi_addr_len() == SPI_FLASH_4B_ADDR_LEN)) {
if (idcode[0] == SPI_FLASH_CFI_MFR_WINBOND)
flash->addr_width = SPI_FLASH_4B_ADDR_LEN;
}
#ifdef CONFIG_SPI_FLASH_STMICRO
if (params->flags & E_FSR)
flash->flags |= SNOR_F_USE_FSR;

View file

@ -73,6 +73,7 @@ struct spi_flash {
const char *name;
u8 dual_flash;
u8 shift;
u8 addr_width;
u16 flags;
u32 size;