diff options
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/spi/spi_flash.c | 12 | ||||
-rw-r--r-- | src/drivers/spi/spi_flash_internal.h | 2 | ||||
-rw-r--r-- | src/drivers/spi/stmicro.c | 30 |
3 files changed, 29 insertions, 15 deletions
diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index ff69a9a1c1..4a86146503 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -368,9 +368,6 @@ static struct { { 0, VENDOR_ID_WINBOND, spi_flash_probe_winbond, }, #endif /* Keep it sorted by best detection */ -#if CONFIG(SPI_FLASH_STMICRO) - { 0, VENDOR_ID_STMICRO_FF, spi_flash_probe_stmicro, }, -#endif #if CONFIG(SPI_FLASH_ADESTO) { 0, VENDOR_ID_ADESTO, spi_flash_probe_adesto, }, #endif @@ -402,6 +399,15 @@ int spi_flash_generic_probe(const struct spi_slave *spi, printk(BIOS_INFO, "Manufacturer: %02x\n", *idp); + /* If no result from RDID command and STMicro parts are enabled attempt + to wake the part from deep sleep and obtain alternative id info. */ + if (CONFIG(SPI_FLASH_STMICRO) && *idp == 0xff) { + if (stmicro_release_deep_sleep_identify(spi, idcode)) + return -1; + idp = idcode; + shift = 0; + } + /* search the table for matches in shift and id */ for (i = 0; i < (int)ARRAY_SIZE(flashes); ++i) if (flashes[i].shift == shift && flashes[i].idcode == *idp) { diff --git a/src/drivers/spi/spi_flash_internal.h b/src/drivers/spi/spi_flash_internal.h index f99c90ed36..58172ce929 100644 --- a/src/drivers/spi/spi_flash_internal.h +++ b/src/drivers/spi/spi_flash_internal.h @@ -81,6 +81,8 @@ int spi_flash_probe_sst(const struct spi_slave *spi, u8 *idcode, struct spi_flash *flash); int spi_flash_probe_stmicro(const struct spi_slave *spi, u8 *idcode, struct spi_flash *flash); +/* Release from deep sleep an provide alternative rdid information. */ +int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, u8 *idcode); int spi_flash_probe_winbond(const struct spi_slave *spi, u8 *idcode, struct spi_flash *flash); int spi_flash_probe_gigadevice(const struct spi_slave *spi, u8 *idcode, diff --git a/src/drivers/spi/stmicro.c b/src/drivers/spi/stmicro.c index 57bd3ddbb5..83d0749311 100644 --- a/src/drivers/spi/stmicro.c +++ b/src/drivers/spi/stmicro.c @@ -289,24 +289,30 @@ static const struct spi_flash_ops spi_flash_ops = { .erase = spi_flash_cmd_erase, }; +int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, u8 *idcode) +{ + if (spi_flash_cmd(spi, CMD_M25PXX_RES, idcode, 4)) + return -1; + + /* Assuming ST parts identify with 0x1X to release from deep + power down and read electronic signature. */ + if ((idcode[3] & 0xf0) != 0x10) + return -1; + + /* Fix up the idcode to mimic rdid jedec instruction. */ + idcode[0] = 0x20; + idcode[1] = 0x20; + idcode[2] = idcode[3] + 1; + + return 0; +} + int spi_flash_probe_stmicro(const struct spi_slave *spi, u8 *idcode, struct spi_flash *flash) { const struct stmicro_spi_flash_params *params; unsigned int i; - if (idcode[0] == 0xff) { - i = spi_flash_cmd(spi, CMD_M25PXX_RES, idcode, 4); - if (i) - return -1; - if ((idcode[3] & 0xf0) == 0x10) { - idcode[0] = 0x20; - idcode[1] = 0x20; - idcode[2] = idcode[3] + 1; - } else - return -1; - } - for (i = 0; i < ARRAY_SIZE(stmicro_spi_flash_table); i++) { params = &stmicro_spi_flash_table[i]; if (params->device_id == (idcode[1] << 8 | idcode[2])) { |