diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/Kconfig | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 9 | ||||
-rw-r--r-- | drivers/mtd/nand/atmel_nand_ecc.h | 20 | ||||
-rw-r--r-- | drivers/mtd/nand/omap_gpmc.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/tegra_nand.c | 9 | ||||
-rw-r--r-- | drivers/mtd/spi/Kconfig | 14 | ||||
-rw-r--r-- | drivers/mtd/spi/sandbox.c | 12 | ||||
-rw-r--r-- | drivers/mtd/spi/sf_probe.c | 3 | ||||
-rw-r--r-- | drivers/mtd/ubi/build.c | 8 |
9 files changed, 73 insertions, 9 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 415ab4eba9..59278d1eef 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -1 +1,3 @@ source "drivers/mtd/nand/Kconfig" + +source "drivers/mtd/spi/Kconfig" diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 620b6e8ff9..b16e3aa157 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -44,6 +44,7 @@ struct atmel_nand_host { u8 pmecc_corr_cap; u16 pmecc_sector_size; u32 pmecc_index_table_offset; + u32 pmecc_version; int pmecc_bytes_per_sector; int pmecc_sector_number; @@ -486,6 +487,10 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf, int i, err_nbr, eccbytes; uint8_t *buf_pos; + /* SAMA5D4 PMECC IP can correct errors for all 0xff page */ + if (host->pmecc_version >= PMECC_VERSION_SAMA5D4) + goto normal_check; + eccbytes = nand_chip->ecc.bytes; for (i = 0; i < eccbytes; i++) if (ecc[i] != 0xff) @@ -961,6 +966,10 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand, nand->ecc.write_page = atmel_nand_pmecc_write_page; nand->ecc.strength = cap; + /* Check the PMECC ip version */ + host->pmecc_version = pmecc_readl(host->pmerrloc, version); + dev_dbg(host->dev, "PMECC IP version is: %x\n", host->pmecc_version); + atmel_pmecc_core_init(mtd); return 0; diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h index eac860d13c..b2d2682a88 100644 --- a/drivers/mtd/nand/atmel_nand_ecc.h +++ b/drivers/mtd/nand/atmel_nand_ecc.h @@ -123,6 +123,20 @@ struct pmecc_errloc_regs { u32 sigma[25]; /* 0x28-0x88 Error Location Sigma Registers */ u32 el[24]; /* 0x8C-0xE8 Error Location Registers */ u32 reserved1[5]; /* 0xEC-0xFC Reserved */ + + /* + * 0x100-0x1F8: + * Reserved for AT91SAM9X5, AT91SAM9N12. + * HSMC registers for SAMA5D3, SAMA5D4. + */ + u32 reserved2[63]; + + /* + * 0x1FC: + * PMECC version for AT91SAM9X5, AT91SAM9N12. + * HSMC version for SAMA5D3, SAMA5D4. Can refer as PMECC version. + */ + u32 version; }; /* For Error Location Configuration Register */ @@ -137,6 +151,12 @@ struct pmecc_errloc_regs { #define PMERRLOC_ERR_NUM_MASK (0x1f << 8) #define PMERRLOC_CALC_DONE (1 << 0) +/* PMECC IP version */ +#define PMECC_VERSION_SAMA5D4 0x113 +#define PMECC_VERSION_SAMA5D3 0x112 +#define PMECC_VERSION_AT91SAM9N12 0x102 +#define PMECC_VERSION_AT91SAM9X5 0x101 + /* Galois field dimension */ #define PMECC_GF_DIMENSION_13 13 #define PMECC_GF_DIMENSION_14 14 diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index fc64f48144..24123fcfe5 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -989,12 +989,15 @@ int board_nand_init(struct nand_chip *nand) if (err) return err; -#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH /* TODO: Implement for 16-bit bus width */ if (nand->options & NAND_BUSWIDTH_16) nand->read_buf = nand_read_buf16; +#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH else nand->read_buf = omap_nand_read_prefetch8; +#else + else + nand->read_buf = nand_read_buf; #endif nand->dev_ready = omap_dev_ready; diff --git a/drivers/mtd/nand/tegra_nand.c b/drivers/mtd/nand/tegra_nand.c index 163cf29a39..b660f3b206 100644 --- a/drivers/mtd/nand/tegra_nand.c +++ b/drivers/mtd/nand/tegra_nand.c @@ -79,7 +79,7 @@ enum { struct fdt_nand { struct nand_ctlr *reg; int enabled; /* 1 to enable, 0 to disable */ - struct fdt_gpio_state wp_gpio; /* write-protect GPIO */ + struct gpio_desc wp_gpio; /* write-protect GPIO */ s32 width; /* bit width, normally 8 */ u32 timing[FDT_NAND_TIMING_COUNT]; }; @@ -945,8 +945,8 @@ static int fdt_decode_nand(const void *blob, int node, struct fdt_nand *config) config->reg = (struct nand_ctlr *)fdtdec_get_addr(blob, node, "reg"); config->enabled = fdtdec_get_is_enabled(blob, node); config->width = fdtdec_get_int(blob, node, "nvidia,nand-width", 8); - err = fdtdec_decode_gpio(blob, node, "nvidia,wp-gpios", - &config->wp_gpio); + err = gpio_request_by_name_nodev(blob, node, "nvidia,wp-gpios", 0, + &config->wp_gpio, GPIOD_IS_OUT); if (err) return err; err = fdtdec_get_int_array(blob, node, "nvidia,timing", @@ -1009,8 +1009,7 @@ int tegra_nand_init(struct nand_chip *nand, int devnum) /* Adjust timing for NAND device */ setup_timing(config->timing, info->reg); - fdtdec_setup_gpio(&config->wp_gpio); - gpio_direction_output(config->wp_gpio.gpio, 1); + dm_gpio_set_value(&config->wp_gpio, 1); our_mtd = &nand_info[devnum]; our_mtd->priv = nand; diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig new file mode 100644 index 0000000000..2dc46b4b34 --- /dev/null +++ b/drivers/mtd/spi/Kconfig @@ -0,0 +1,14 @@ +config DM_SPI_FLASH + bool "Enable Driver Model for SPI flash" + depends on DM && SPI + help + Enable driver model for SPI flash. This SPI flash interface + (spi_flash_probe(), spi_flash_write(), etc.) is then + implemented by the SPI flash uclass. There is one standard + SPI flash driver which knows how to probe most chips + supported by U-Boot. The uclass interface is defined in + include/spi_flash.h, but is currently fully compatible + with the old interface to avoid confusion and duplication + during the transition parent. SPI and SPI flash must be + enabled together (it is not possible to use driver model + for one and not the other). diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c index 3024b988fe..d576d31243 100644 --- a/drivers/mtd/spi/sandbox.c +++ b/drivers/mtd/spi/sandbox.c @@ -141,8 +141,10 @@ static int sandbox_sf_probe(struct udevice *dev) assert(bus->seq != -1); if (bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS) spec = state->spi[bus->seq][cs].spec; - if (!spec) - return -ENOENT; + if (!spec) { + ret = -ENOENT; + goto error; + } file = strchr(spec, ':'); if (!file) { @@ -196,6 +198,7 @@ static int sandbox_sf_probe(struct udevice *dev) return 0; error: + debug("%s: Got error %d\n", __func__, ret); return ret; } @@ -587,6 +590,11 @@ int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs, void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs) { + struct udevice *dev; + + dev = state->spi[busnum][cs].emul; + device_remove(dev); + device_unbind(dev); state->spi[busnum][cs].emul = NULL; } diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index ce9987fd1a..4103723859 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -481,11 +481,12 @@ int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len) int spi_flash_std_probe(struct udevice *dev) { struct spi_slave *slave = dev_get_parentdata(dev); + struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); struct spi_flash *flash; flash = dev->uclass_priv; flash->dev = dev; - debug("%s: slave=%p, cs=%d\n", __func__, slave, slave->cs); + debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs); return spi_flash_probe_slave(slave, flash); } diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 584cf5f22b..290d524b1b 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1358,6 +1358,10 @@ out_version: out_class: class_destroy(ubi_class); out: +#ifdef __UBOOT__ + /* Reset any globals that the driver depends on being zeroed */ + mtd_devs = 0; +#endif ubi_err("cannot initialize UBI, error %d", err); return err; } @@ -1384,6 +1388,10 @@ void ubi_exit(void) misc_deregister(&ubi_ctrl_cdev); class_remove_file(ubi_class, &ubi_version); class_destroy(ubi_class); +#ifdef __UBOOT__ + /* Reset any globals that the driver depends on being zeroed */ + mtd_devs = 0; +#endif } module_exit(ubi_exit); |