diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/cfi_flash.c | 37 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/mxs_nand_spl.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_base.c | 2 | ||||
-rw-r--r-- | drivers/mtd/spi/sf-uclass.c | 14 | ||||
-rw-r--r-- | drivers/mtd/spi/sf_internal.h | 4 | ||||
-rw-r--r-- | drivers/mtd/spi/sf_probe.c | 8 | ||||
-rw-r--r-- | drivers/mtd/spi/spi-nor-core.c | 11 | ||||
-rw-r--r-- | drivers/mtd/spi/spi-nor-tiny.c | 6 |
8 files changed, 78 insertions, 9 deletions
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index b4512e3a5fc..9642d7c7dc3 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -218,7 +218,7 @@ flash_map(flash_info_t *info, flash_sect_t sect, uint offset) { unsigned int byte_offset = offset * info->portwidth; - return (void *)(info->start[sect] + byte_offset); + return (void *)(info->start[sect] + (byte_offset << info->chip_lsb)); } static inline void flash_unmap(flash_info_t *info, flash_sect_t sect, @@ -1918,12 +1918,27 @@ static int __flash_detect_cfi(flash_info_t *info, struct cfi_qry *qry) flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP, sizeof(struct cfi_qry)); info->interface = le16_to_cpu(qry->interface_desc); + /* Some flash chips can support multiple bus widths. + * In this case, override the interface width and + * limit it to the port width. + */ + if ((info->interface == FLASH_CFI_X8X16) && + (info->portwidth == FLASH_CFI_8BIT)) { + debug("Overriding 16-bit interface width to" + " 8-bit port width\n"); + info->interface = FLASH_CFI_X8; + } else if ((info->interface == FLASH_CFI_X16X32) && + (info->portwidth == FLASH_CFI_16BIT)) { + debug("Overriding 16-bit interface width to" + " 16-bit port width\n"); + info->interface = FLASH_CFI_X16; + } info->cfi_offset = flash_offset_cfi[cfi_offset]; debug("device interface is %d\n", info->interface); - debug("found port %d chip %d ", - info->portwidth, info->chipwidth); + debug("found port %d chip %d chip_lsb %d ", + info->portwidth, info->chipwidth, info->chip_lsb); debug("port %d bits chip %d bits\n", info->portwidth << CFI_FLASH_SHIFT_WIDTH, info->chipwidth << CFI_FLASH_SHIFT_WIDTH); @@ -1962,9 +1977,23 @@ static int flash_detect_cfi(flash_info_t *info, struct cfi_qry *qry) info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) { for (info->chipwidth = FLASH_CFI_BY8; info->chipwidth <= info->portwidth; - info->chipwidth <<= 1) + info->chipwidth <<= 1) { + /* + * First, try detection without shifting the addresses + * for 8bit devices (16bit wide connection) + */ + info->chip_lsb = 0; + if (__flash_detect_cfi(info, qry)) + return 1; + + /* + * Not detected, so let's try with shifting + * for 8bit devices + */ + info->chip_lsb = 1; if (__flash_detect_cfi(info, qry)) return 1; + } } debug("not found\n"); return 0; diff --git a/drivers/mtd/nand/raw/mxs_nand_spl.c b/drivers/mtd/nand/raw/mxs_nand_spl.c index 46dc29df369..17f46ae5e91 100644 --- a/drivers/mtd/nand/raw/mxs_nand_spl.c +++ b/drivers/mtd/nand/raw/mxs_nand_spl.c @@ -282,6 +282,11 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf) return 0; } +struct mtd_info *nand_get_mtd(void) +{ + return mtd; +} + int nand_default_bbt(struct mtd_info *mtd) { return 0; diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 6557faddf94..3679ee727e9 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -3559,6 +3559,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, pr_warn("%s: attempt to erase a bad block at page 0x%08x\n", __func__, page); instr->state = MTD_ERASE_FAILED; + instr->fail_addr = + ((loff_t)page << chip->page_shift); goto erase_exit; } diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c index 12d132152d3..cfce00ef548 100644 --- a/drivers/mtd/spi/sf-uclass.c +++ b/drivers/mtd/spi/sf-uclass.c @@ -31,6 +31,15 @@ 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 @@ -46,11 +55,6 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, return dev_get_uclass_priv(dev); } -void spi_flash_free(struct spi_flash *flash) -{ - device_remove(flash->spi->dev, DM_REMOVE_NORMAL); -} - int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs, unsigned int max_hz, unsigned int spi_mode, struct udevice **devp) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 9ceff0e7c12..786301ba4a9 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -75,6 +75,10 @@ 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); diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 6c874348676..3befbe91cac 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -130,6 +130,13 @@ 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); @@ -153,6 +160,7 @@ 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 e0efebc3555..a6625535a70 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -2647,3 +2647,14 @@ 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 07c8c7b82b1..1d5861d55cd 100644 --- a/drivers/mtd/spi/spi-nor-tiny.c +++ b/drivers/mtd/spi/spi-nor-tiny.c @@ -809,3 +809,9 @@ 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; +} |