ipq40xx: Support for SPI NOR not listed in vendor ID table

Do generic flash structure initialization, for the devices
not listed in the SPI NOR flash lookup table, so that
we can access the flash even before the support is added.
Block size and density are obtained from smem.

Change-Id: I568eb538615bb36124c43a2509bcfce2e4a1188a
Signed-off-by: Balaji Jagadeesan <bjagadee@codeaurora.org>
This commit is contained in:
Balaji Jagadeesan 2018-03-12 12:25:03 +05:30
parent 6ef13d4878
commit 6086a41473
2 changed files with 95 additions and 12 deletions

View file

@ -566,6 +566,77 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
return ret;
}
#ifdef CONFIG_SPI_NOR_GENERIC
/* When there is no match in the flash lookup table, for the flash
* that is mounted, we do a generic initialization of the flash structure,
* so that we can access the flash.
*/
static int spi_nor_generic_init(struct spi_slave *spi, struct spi_flash *flash,
u8 *idcode)
{
int ret;
unsigned short jedec;
qca_smem_flash_info_t sfi;
jedec = idcode[1] << 8 | idcode[2];
if ((jedec == 0) || (jedec == 0xffff))
return 1;
printf("No match found in the SPI NOR lookup table\n");
/* Flash powers up read-only, so clear BP# bits */
if (idcode[0] == SPI_FLASH_CFI_MFR_ATMEL ||
idcode[0] == SPI_FLASH_CFI_MFR_MACRONIX ||
idcode[0] == SPI_FLASH_CFI_MFR_SST)
write_sr(flash, 0);
/* Get flash parameters from smem */
smem_get_boot_flash(&sfi.flash_type,
&sfi.flash_index,
&sfi.flash_chip_select,
&sfi.flash_block_size,
&sfi.flash_density);
/* Using the default functions and values for initialization
which will work for most of the cases */
flash->write = spi_flash_cmd_write_ops;
flash->erase = spi_flash_cmd_erase_ops;
flash->read = spi_flash_cmd_read_ops;
flash->page_size = 256;
flash->sector_size = sfi.flash_block_size;
flash->size = sfi.flash_density;
flash->memory_map = spi->memory_map;
flash->dual_flash = flash->spi->option;
flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0;
if (flash->sector_size == SZ_4K)
flash->erase_cmd = CMD_ERASE_4K;
else if (flash->sector_size == SZ_32K)
flash->erase_cmd = CMD_ERASE_32K;
else
flash->erase_cmd = CMD_ERASE_64K;
flash->erase_size = flash->sector_size;
flash->read_cmd = CMD_READ_ARRAY_FAST;
flash->write_cmd = CMD_PAGE_PROGRAM;
if (idcode[0] == SPI_FLASH_CFI_MFR_WINBOND)
flash->name = "Winbond";
else if (idcode[0] == SPI_FLASH_CFI_MFR_GIGA)
flash->name = "Giga";
else if (idcode[0] == SPI_FLASH_CFI_MFR_SPANSION)
flash->name = "Spansion";
else if (idcode[0] == SPI_FLASH_CFI_MFR_STMICRO)
flash->name = "ST micro";
else if (idcode[0] == SPI_FLASH_CFI_MFR_MACRONIX)
flash->name = "Macronix";
else
flash->name = "default";
return 0;
}
#endif
#ifdef CONFIG_SPI_FLASH_SST
static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf)
{
@ -1006,6 +1077,12 @@ int spi_flash_scan(struct spi_flash *flash)
flash->addr_width = flash->size > 0x1000000 ? 4 : 3;
goto print_sf_info;
}
#endif
#ifdef CONFIG_SPI_NOR_GENERIC
/* We did not find a match, do generic probe */
ret = spi_nor_generic_init(spi, flash, idcode);
if (!ret)
goto do_generic_probe;
#endif
printf("SF: Unsupported flash IDs: ");
printf("manuf %02x, jedec %04x, ext_jedec %04x\n",
@ -1126,6 +1203,23 @@ int spi_flash_scan(struct spi_flash *flash)
}
}
#ifdef CONFIG_SPI_FLASH_STMICRO
if (params->flags & E_FSR)
flash->flags |= SNOR_F_USE_FSR;
#endif
#if defined CONFIG_SPI_FLASH_SPANSION
if (params->bulkerase_timeout) {
flash->berase = bulk_erase;
flash->berase_timeout = params->bulkerase_timeout;
}
#endif
/* NOTE: Any reference to params variable below this label will break
* the generic initialization functionality. All the manufacturer
* specific initialization should be done before this point.
*/
do_generic_probe:
/* Read dummy_byte: dummy byte is determined based on the
* dummy cycles of a particular command.
* Fast commands - dummy_byte = dummy_cycles/8
@ -1164,10 +1258,6 @@ int spi_flash_scan(struct spi_flash *flash)
}
printf("SPI_ADDR_LEN=%x\n",flash->addr_width);
#ifdef CONFIG_SPI_FLASH_STMICRO
if (params->flags & E_FSR)
flash->flags |= SNOR_F_USE_FSR;
#endif
/* Configure the BAR - discover bank cmds and read current bank */
#ifdef CONFIG_SPI_FLASH_BAR
@ -1204,13 +1294,5 @@ print_sf_info:
puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
}
#endif
#if defined CONFIG_SPI_FLASH_SPANSION
if (params->bulkerase_timeout) {
flash->berase = bulk_erase;
flash->berase_timeout = params->bulkerase_timeout;
}
#endif
return ret;
}

View file

@ -223,6 +223,7 @@ typedef struct {
#define CONFIG_ENV_SECT_SIZE (64 * 1024)
#define CONFIG_SPI_FLASH_USE_4K_SECTORS
#define CONFIG_SPI_NOR_GENERIC
#define CONFIG_SF_DEFAULT_BUS 0
#define CONFIG_SF_DEFAULT_CS 0
#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0