mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
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:
parent
921da8d0b2
commit
23f9381f86
3 changed files with 43 additions and 13 deletions
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ struct spi_flash {
|
|||
const char *name;
|
||||
u8 dual_flash;
|
||||
u8 shift;
|
||||
u8 addr_width;
|
||||
u16 flags;
|
||||
|
||||
u32 size;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue