diff options
Diffstat (limited to 'src/drivers/spi/stmicro.c')
-rw-r--r-- | src/drivers/spi/stmicro.c | 269 |
1 files changed, 114 insertions, 155 deletions
diff --git a/src/drivers/spi/stmicro.c b/src/drivers/spi/stmicro.c index 7aa06bd498..2f4e42a630 100644 --- a/src/drivers/spi/stmicro.c +++ b/src/drivers/spi/stmicro.c @@ -64,223 +64,165 @@ #define STM_ID_N25Q128__1E 0xbb18 #define STM_ID_N25Q256__1E 0xbb19 -struct stmicro_spi_flash_params { - u16 device_id; - u8 op_erase; - u16 page_size; - u16 pages_per_sector; - u16 nr_sectors; - const char *name; -}; - -static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = { +static const struct spi_flash_part_id flash_table_se[] = { { - .device_id = STM_ID_M25P10, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 128, - .nr_sectors = 4, + .id = STM_ID_M25P10, .name = "M25P10", + .nr_sectors_shift = 2, + .sector_size_kib_shift = 5, }, { - .device_id = STM_ID_M25P16, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 32, + .id = STM_ID_M25P16, .name = "M25P16", + .nr_sectors_shift = 5, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25P20, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 4, + .id = STM_ID_M25P20, .name = "M25P20", + .nr_sectors_shift = 2, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25P32, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 64, + .id = STM_ID_M25P32, .name = "M25P32", + .nr_sectors_shift = 6, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25P40, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 8, + .id = STM_ID_M25P40, .name = "M25P40", + .nr_sectors_shift = 3, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25P64, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 128, + .id = STM_ID_M25P64, .name = "M25P64", + .nr_sectors_shift = 7, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25P80, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 16, + .id = STM_ID_M25P80, .name = "M25P80", + .nr_sectors_shift = 4, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25P128, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 1024, - .nr_sectors = 64, + .id = STM_ID_M25P128, .name = "M25P128", + .nr_sectors_shift = 6, + .sector_size_kib_shift = 8, }, { - .device_id = STM_ID_M25PX80, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 16, + .id = STM_ID_M25PX80, .name = "M25PX80", + .nr_sectors_shift = 4, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25PX16, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 32, + .id = STM_ID_M25PX16, .name = "M25PX16", + .nr_sectors_shift = 5, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25PX32, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 64, + .id = STM_ID_M25PX32, .name = "M25PX32", + .nr_sectors_shift = 6, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25PX64, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 128, + .id = STM_ID_M25PX64, .name = "M25PX64", + .nr_sectors_shift = 7, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25PE80, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 16, + .id = STM_ID_M25PE80, .name = "M25PE80", + .nr_sectors_shift = 4, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25PE16, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 32, + .id = STM_ID_M25PE16, .name = "M25PE16", + .nr_sectors_shift = 5, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25PE32, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 64, + .id = STM_ID_M25PE32, .name = "M25PE32", + .nr_sectors_shift = 6, + .sector_size_kib_shift = 6, }, { - .device_id = STM_ID_M25PE64, - .op_erase = CMD_M25PXX_SE, - .page_size = 256, - .pages_per_sector = 256, - .nr_sectors = 128, + .id = STM_ID_M25PE64, .name = "M25PE64", + .nr_sectors_shift = 7, + .sector_size_kib_shift = 6, }, +}; + +static const struct spi_flash_part_id flash_table_sse[] = { { - .device_id = STM_ID_N25Q016__3E, - .op_erase = CMD_M25PXX_SSE, - .page_size = 256, - .pages_per_sector = 16, - .nr_sectors = 512, + .id = STM_ID_N25Q016__3E, .name = "N25Q016..3E", + .nr_sectors_shift = 9, + .sector_size_kib_shift = 2, }, { - .device_id = STM_ID_N25Q032__3E, - .op_erase = CMD_M25PXX_SSE, - .page_size = 256, - .pages_per_sector = 16, - .nr_sectors = 1024, + .id = STM_ID_N25Q032__3E, .name = "N25Q032..3E", + .nr_sectors_shift = 10, + .sector_size_kib_shift = 2, }, { - .device_id = STM_ID_N25Q064__3E, - .op_erase = CMD_M25PXX_SSE, - .page_size = 256, - .pages_per_sector = 16, - .nr_sectors = 2048, + .id = STM_ID_N25Q064__3E, .name = "N25Q064..3E", + .nr_sectors_shift = 11, + .sector_size_kib_shift = 2, }, { - .device_id = STM_ID_N25Q128__3E, - .op_erase = CMD_M25PXX_SSE, - .page_size = 256, - .pages_per_sector = 16, - .nr_sectors = 4096, + .id = STM_ID_N25Q128__3E, .name = "N25Q128..3E", + .nr_sectors_shift = 12, + .sector_size_kib_shift = 2, }, { - .device_id = STM_ID_N25Q256__3E, - .op_erase = CMD_M25PXX_SSE, - .page_size = 256, - .pages_per_sector = 16, - .nr_sectors = 8192, + .id = STM_ID_N25Q256__3E, .name = "N25Q256..3E", + .nr_sectors_shift = 13, + .sector_size_kib_shift = 2, }, { - .device_id = STM_ID_N25Q016__1E, - .op_erase = CMD_M25PXX_SSE, - .page_size = 256, - .pages_per_sector = 16, - .nr_sectors = 512, + .id = STM_ID_N25Q016__1E, .name = "N25Q016..1E", + .nr_sectors_shift = 9, + .sector_size_kib_shift = 2, }, { - .device_id = STM_ID_N25Q032__1E, - .op_erase = CMD_M25PXX_SSE, - .page_size = 256, - .pages_per_sector = 16, - .nr_sectors = 1024, + .id = STM_ID_N25Q032__1E, .name = "N25Q032..1E", + .nr_sectors_shift = 10, + .sector_size_kib_shift = 2, }, { - .device_id = STM_ID_N25Q064__1E, - .op_erase = CMD_M25PXX_SSE, - .page_size = 256, - .pages_per_sector = 16, - .nr_sectors = 2048, + .id = STM_ID_N25Q064__1E, .name = "N25Q064..1E", + .nr_sectors_shift = 11, + .sector_size_kib_shift = 2, }, { - .device_id = STM_ID_N25Q128__1E, - .op_erase = CMD_M25PXX_SSE, - .page_size = 256, - .pages_per_sector = 16, - .nr_sectors = 4096, + .id = STM_ID_N25Q128__1E, .name = "N25Q128..1E", + .nr_sectors_shift = 12, + .sector_size_kib_shift = 2, }, { - .device_id = STM_ID_N25Q256__1E, - .op_erase = CMD_M25PXX_SSE, - .page_size = 256, - .pages_per_sector = 16, - .nr_sectors = 8192, + .id = STM_ID_N25Q256__1E, .name = "N25Q256..1E", + .nr_sectors_shift = 13, + .sector_size_kib_shift = 2, }, }; @@ -309,31 +251,30 @@ int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, u8 *idcode) return 0; } -int spi_flash_probe_stmicro(const struct spi_slave *spi, u8 *idcode, - struct spi_flash *flash) +static int match_table(const struct spi_slave *spi, struct spi_flash *flash, u16 id, + const struct spi_flash_part_id *parts, size_t num_parts, + u8 erase_cmd) { - const struct stmicro_spi_flash_params *params; - unsigned int i; + const struct spi_flash_part_id *params; + size_t i; - 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])) { + for (i = 0; i < num_parts; i++) { + params = &parts[i]; + if (params->id == id) break; - } } - if (i == ARRAY_SIZE(stmicro_spi_flash_table)) { - printk(BIOS_WARNING, "SF: Unsupported STMicro ID %02x%02x\n", - idcode[1], idcode[2]); + if (i == num_parts) { + printk(BIOS_WARNING, "SF: Unsupported STMicro ID %04x\n", id); return -1; } memcpy(&flash->spi, spi, sizeof(*spi)); flash->name = params->name; - flash->page_size = params->page_size; - flash->sector_size = params->page_size * params->pages_per_sector; - flash->size = flash->sector_size * params->nr_sectors; - flash->erase_cmd = params->op_erase; + flash->page_size = 256; + flash->sector_size = (1U << params->sector_size_kib_shift) * KiB; + flash->size = flash->sector_size * (1U << params->nr_sectors_shift); + flash->erase_cmd = erase_cmd; flash->status_cmd = CMD_M25PXX_RDSR; flash->pp_cmd = CMD_M25PXX_PP; flash->wren_cmd = CMD_M25PXX_WREN; @@ -342,3 +283,21 @@ int spi_flash_probe_stmicro(const struct spi_slave *spi, u8 *idcode, return 0; } + +int spi_flash_probe_stmicro(const struct spi_slave *spi, u8 *idcode, + struct spi_flash *flash) +{ + u16 id = (idcode[1] << 8) | idcode[2]; + + if (!match_table(spi, flash, id, flash_table_se, ARRAY_SIZE(flash_table_se), + CMD_M25PXX_SE)) { + return 0; + } + + if (!match_table(spi, flash, id, flash_table_sse, ARRAY_SIZE(flash_table_sse), + CMD_M25PXX_SSE)) { + return 0; + } + + return -1; +} |