diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/spi/toshiba.c | 167 | ||||
-rw-r--r-- | drivers/mtd/spi/sf-uclass.c | 9 | ||||
-rw-r--r-- | drivers/mtd/spi/sf_internal.h | 14 | ||||
-rw-r--r-- | drivers/mtd/spi/sf_probe.c | 27 | ||||
-rw-r--r-- | drivers/mtd/spi/spi-nor-core.c | 24 | ||||
-rw-r--r-- | drivers/mtd/spi/spi-nor-tiny.c | 6 |
6 files changed, 152 insertions, 95 deletions
diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c index c4beefa617..c2cd3b426b 100644 --- a/drivers/mtd/nand/spi/toshiba.c +++ b/drivers/mtd/nand/spi/toshiba.c @@ -23,13 +23,25 @@ static SPINAND_OP_VARIANTS(read_cache_variants, SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); +static SPINAND_OP_VARIANTS(write_cache_x4_variants, + SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), + SPINAND_PROG_LOAD(true, 0, NULL, 0)); + +static SPINAND_OP_VARIANTS(update_cache_x4_variants, + SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), + SPINAND_PROG_LOAD(false, 0, NULL, 0)); + +/** + * Backward compatibility for 1st generation Serial NAND devices + * which don't support Quad Program Load operation. + */ static SPINAND_OP_VARIANTS(write_cache_variants, SPINAND_PROG_LOAD(true, 0, NULL, 0)); static SPINAND_OP_VARIANTS(update_cache_variants, SPINAND_PROG_LOAD(false, 0, NULL, 0)); -static int tc58cxgxsx_ooblayout_ecc(struct mtd_info *mtd, int section, +static int tx58cxgxsxraix_ooblayout_ecc(struct mtd_info *mtd, int section, struct mtd_oob_region *region) { if (section > 0) @@ -41,7 +53,7 @@ static int tc58cxgxsx_ooblayout_ecc(struct mtd_info *mtd, int section, return 0; } -static int tc58cxgxsx_ooblayout_free(struct mtd_info *mtd, int section, +static int tx58cxgxsxraix_ooblayout_free(struct mtd_info *mtd, int section, struct mtd_oob_region *region) { if (section > 0) @@ -54,12 +66,12 @@ static int tc58cxgxsx_ooblayout_free(struct mtd_info *mtd, int section, return 0; } -static const struct mtd_ooblayout_ops tc58cxgxsx_ooblayout = { - .ecc = tc58cxgxsx_ooblayout_ecc, - .rfree = tc58cxgxsx_ooblayout_free, +static const struct mtd_ooblayout_ops tx58cxgxsxraix_ooblayout = { + .ecc = tx58cxgxsxraix_ooblayout_ecc, + .rfree = tx58cxgxsxraix_ooblayout_free, }; -static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand, +static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand, u8 status) { struct nand_device *nand = spinand_to_nand(spinand); @@ -98,76 +110,151 @@ static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand, } static const struct spinand_info toshiba_spinand_table[] = { - /* 3.3V 1Gb */ - SPINAND_INFO("TC58CVG0S3", 0xC2, + /* 3.3V 1Gb (1st generation) */ + SPINAND_INFO("TC58CVG0S3HRAIG", 0xC2, NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, - tc58cxgxsx_ecc_get_status)), - /* 3.3V 2Gb */ - SPINAND_INFO("TC58CVG1S3", 0xCB, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 3.3V 2Gb (1st generation) */ + SPINAND_INFO("TC58CVG1S3HRAIG", 0xCB, NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, - tc58cxgxsx_ecc_get_status)), - /* 3.3V 4Gb */ - SPINAND_INFO("TC58CVG2S0", 0xCD, - NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), - NAND_ECCREQ(8, 512), - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, - &write_cache_variants, - &update_cache_variants), - 0, - SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, - tc58cxgxsx_ecc_get_status)), - /* 3.3V 4Gb */ - SPINAND_INFO("TC58CVG2S0", 0xED, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 3.3V 4Gb (1st generation) */ + SPINAND_INFO("TC58CVG2S0HRAIG", 0xCD, NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, - tc58cxgxsx_ecc_get_status)), - /* 1.8V 1Gb */ - SPINAND_INFO("TC58CYG0S3", 0xB2, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 1.8V 1Gb (1st generation) */ + SPINAND_INFO("TC58CYG0S3HRAIG", 0xB2, NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, - tc58cxgxsx_ecc_get_status)), - /* 1.8V 2Gb */ - SPINAND_INFO("TC58CYG1S3", 0xBB, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 1.8V 2Gb (1st generation) */ + SPINAND_INFO("TC58CYG1S3HRAIG", 0xBB, NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, - tc58cxgxsx_ecc_get_status)), - /* 1.8V 4Gb */ - SPINAND_INFO("TC58CYG2S0", 0xBD, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 1.8V 4Gb (1st generation) */ + SPINAND_INFO("TC58CYG2S0HRAIG", 0xBD, NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, - tc58cxgxsx_ecc_get_status)), + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + + /* + * 2nd generation serial nand has HOLD_D which is equivalent to + * QE_BIT. + */ + /* 3.3V 1Gb (2nd generation) */ + SPINAND_INFO("TC58CVG0S3HRAIJ", 0xE2, + NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_x4_variants, + &update_cache_x4_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 3.3V 2Gb (2nd generation) */ + SPINAND_INFO("TC58CVG1S3HRAIJ", 0xEB, + NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_x4_variants, + &update_cache_x4_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 3.3V 4Gb (2nd generation) */ + SPINAND_INFO("TC58CVG2S0HRAIJ", 0xED, + NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_x4_variants, + &update_cache_x4_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 3.3V 8Gb (2nd generation) */ + SPINAND_INFO("TH58CVG3S0HRAIJ", 0xE4, + NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_x4_variants, + &update_cache_x4_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 1.8V 1Gb (2nd generation) */ + SPINAND_INFO("TC58CYG0S3HRAIJ", 0xD2, + NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_x4_variants, + &update_cache_x4_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 1.8V 2Gb (2nd generation) */ + SPINAND_INFO("TC58CYG1S3HRAIJ", 0xDB, + NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_x4_variants, + &update_cache_x4_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 1.8V 4Gb (2nd generation) */ + SPINAND_INFO("TC58CYG2S0HRAIJ", 0xDD, + NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_x4_variants, + &update_cache_x4_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), + /* 1.8V 8Gb (2nd generation) */ + SPINAND_INFO("TH58CYG3S0HRAIJ", 0xD4, + NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_x4_variants, + &update_cache_x4_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), }; static int toshiba_spinand_detect(struct spinand_device *spinand) diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c index de369aa001..9ce2ecb99a 100644 --- a/drivers/mtd/spi/sf-uclass.c +++ b/drivers/mtd/spi/sf-uclass.c @@ -30,15 +30,6 @@ int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len) return log_ret(sf_get_ops(dev)->erase(dev, offset, len)); } -int spl_flash_get_sw_write_prot(struct udevice *dev) -{ - struct dm_spi_flash_ops *ops = sf_get_ops(dev); - - if (!ops->get_sw_write_prot) - return -ENOSYS; - return log_ret(ops->get_sw_write_prot(dev)); -} - /* * TODO(sjg@chromium.org): This is an old-style function. We should remove * it when all SPI flash drivers use dm diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index ce0cf4c428..dabd40a4cc 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -75,12 +75,18 @@ extern const struct flash_info spi_nor_ids[]; #define JEDEC_MFR(info) ((info)->id[0]) #define JEDEC_ID(info) (((info)->id[1]) << 8 | ((info)->id[2])) -/* Get software write-protect value (BP bits) */ -int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash); - - #if CONFIG_IS_ENABLED(SPI_FLASH_MTD) int spi_flash_mtd_register(struct spi_flash *flash); void spi_flash_mtd_unregister(void); +#else +static inline int spi_flash_mtd_register(struct spi_flash *flash) +{ + return 0; +} + +static inline void spi_flash_mtd_unregister(void) +{ +} #endif + #endif /* _SF_INTERNAL_H_ */ diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index c2e51f9c68..3548d6319b 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -45,9 +45,8 @@ static int spi_flash_probe_slave(struct spi_flash *flash) if (ret) goto err_read_id; -#if CONFIG_IS_ENABLED(SPI_FLASH_MTD) - ret = spi_flash_mtd_register(flash); -#endif + if (CONFIG_IS_ENABLED(SPI_FLASH_MTD)) + ret = spi_flash_mtd_register(flash); err_read_id: spi_release_bus(spi); @@ -84,9 +83,9 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs, void spi_flash_free(struct spi_flash *flash) { -#if CONFIG_IS_ENABLED(SPI_FLASH_MTD) - spi_flash_mtd_unregister(); -#endif + if (CONFIG_IS_ENABLED(SPI_FLASH_MTD)) + spi_flash_mtd_unregister(); + spi_free_slave(flash->spi); free(flash); } @@ -131,31 +130,22 @@ static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len) return mtd->_erase(mtd, &instr); } -static int spi_flash_std_get_sw_write_prot(struct udevice *dev) -{ - struct spi_flash *flash = dev_get_uclass_priv(dev); - - return spi_flash_cmd_get_sw_write_prot(flash); -} - int spi_flash_std_probe(struct udevice *dev) { struct spi_slave *slave = dev_get_parent_priv(dev); - struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); struct spi_flash *flash; flash = dev_get_uclass_priv(dev); flash->dev = dev; flash->spi = slave; - debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs); return spi_flash_probe_slave(flash); } static int spi_flash_std_remove(struct udevice *dev) { -#if CONFIG_IS_ENABLED(SPI_FLASH_MTD) - spi_flash_mtd_unregister(); -#endif + if (CONFIG_IS_ENABLED(SPI_FLASH_MTD)) + spi_flash_mtd_unregister(); + return 0; } @@ -163,7 +153,6 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = { .read = spi_flash_std_read, .write = spi_flash_std_write, .erase = spi_flash_std_erase, - .get_sw_write_prot = spi_flash_std_get_sw_write_prot, }; static const struct udevice_id spi_flash_std_ids[] = { diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 56b44ebbe8..1e3f51d2ac 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -1235,6 +1235,12 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, size_t page_offset, page_remain, i; ssize_t ret; +#ifdef CONFIG_SPI_FLASH_SST + /* sst nor chips use AAI word program */ + if (nor->info->flags & SST_WRITE) + return sst_write(mtd, to, len, retlen, buf); +#endif + dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); if (!len) @@ -2530,6 +2536,7 @@ int spi_nor_scan(struct spi_nor *nor) mtd->size = params.size; mtd->_erase = spi_nor_erase; mtd->_read = spi_nor_read; + mtd->_write = spi_nor_write; #if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST) /* NOR protection support for STmicro/Micron chips and similar */ @@ -2553,13 +2560,7 @@ int spi_nor_scan(struct spi_nor *nor) nor->flash_unlock = sst26_unlock; nor->flash_is_locked = sst26_is_locked; } - - /* sst nor chips use AAI word program */ - if (info->flags & SST_WRITE) - mtd->_write = sst_write; - else #endif - mtd->_write = spi_nor_write; if (info->flags & USE_FSR) nor->flags |= SNOR_F_USE_FSR; @@ -2640,14 +2641,3 @@ int spi_nor_scan(struct spi_nor *nor) return 0; } - -/* U-Boot specific functions, need to extend MTD to support these */ -int spi_flash_cmd_get_sw_write_prot(struct spi_nor *nor) -{ - int sr = read_sr(nor); - - if (sr < 0) - return sr; - - return (sr >> 2) & 7; -} diff --git a/drivers/mtd/spi/spi-nor-tiny.c b/drivers/mtd/spi/spi-nor-tiny.c index 55f86d5155..9f676c649d 100644 --- a/drivers/mtd/spi/spi-nor-tiny.c +++ b/drivers/mtd/spi/spi-nor-tiny.c @@ -798,9 +798,3 @@ int spi_nor_scan(struct spi_nor *nor) return 0; } - -/* U-Boot specific functions, need to extend MTD to support these */ -int spi_flash_cmd_get_sw_write_prot(struct spi_nor *nor) -{ - return -ENOTSUPP; -} |