diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/altera_qspi.c | 2 | ||||
-rw-r--r-- | drivers/mtd/cfi_flash.c | 2 | ||||
-rw-r--r-- | drivers/mtd/dataflash.c | 12 | ||||
-rw-r--r-- | drivers/mtd/nand/Kconfig | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/Makefile | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/mpc5121_nfc.c | 656 | ||||
-rw-r--r-- | drivers/mtd/nand/s3c2410_nand.c | 175 | ||||
-rw-r--r-- | drivers/mtd/nand/sunxi_nand.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/tegra_nand.c | 4 | ||||
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 6 | ||||
-rw-r--r-- | drivers/mtd/onenand/onenand_spl.c | 36 | ||||
-rw-r--r-- | drivers/mtd/pic32_flash.c | 2 | ||||
-rw-r--r-- | drivers/mtd/spi/Kconfig | 7 | ||||
-rw-r--r-- | drivers/mtd/spi/sandbox.c | 6 | ||||
-rw-r--r-- | drivers/mtd/spi/spi_flash.c | 7 |
15 files changed, 61 insertions, 862 deletions
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c index e04964b558..fb33cef13f 100644 --- a/drivers/mtd/altera_qspi.c +++ b/drivers/mtd/altera_qspi.c @@ -362,7 +362,7 @@ static int altera_qspi_ofdata_to_platdata(struct udevice *dev) * match with reg-names. */ parent = fdt_parent_offset(blob, node); - of_bus_default_count_cells(blob, parent, &addrc, &sizec); + fdt_support_default_count_cells(blob, parent, &addrc, &sizec); list = fdt_getprop(blob, node, "reg-names", &len); if (!list) return -ENOENT; diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index d440f5ccd9..048a51785e 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -2448,7 +2448,7 @@ static int cfi_flash_probe(struct udevice *dev) int len, idx; parent = fdt_parent_offset(blob, node); - of_bus_default_count_cells(blob, parent, &addrc, &sizec); + fdt_support_default_count_cells(blob, parent, &addrc, &sizec); /* decode regs, there may be multiple reg tuples. */ cell = fdt_getprop(blob, node, "reg", &len); if (!cell) diff --git a/drivers/mtd/dataflash.c b/drivers/mtd/dataflash.c index 3fb6ed6df7..2d2c318adf 100644 --- a/drivers/mtd/dataflash.c +++ b/drivers/mtd/dataflash.c @@ -49,7 +49,7 @@ int AT91F_DataflashInit (void) dataflash_info[i].Desc.DataFlash_state = IDLE; dataflash_info[i].logical_address = cs[i].addr; dataflash_info[i].id = dfcode; - found[i] += dfcode;; + found[i] += dfcode; break; case AT45DB081: @@ -61,7 +61,7 @@ int AT91F_DataflashInit (void) dataflash_info[i].Desc.DataFlash_state = IDLE; dataflash_info[i].logical_address = cs[i].addr; dataflash_info[i].id = dfcode; - found[i] += dfcode;; + found[i] += dfcode; break; case AT45DB161: @@ -73,7 +73,7 @@ int AT91F_DataflashInit (void) dataflash_info[i].Desc.DataFlash_state = IDLE; dataflash_info[i].logical_address = cs[i].addr; dataflash_info[i].id = dfcode; - found[i] += dfcode;; + found[i] += dfcode; break; case AT45DB321: @@ -85,7 +85,7 @@ int AT91F_DataflashInit (void) dataflash_info[i].Desc.DataFlash_state = IDLE; dataflash_info[i].logical_address = cs[i].addr; dataflash_info[i].id = dfcode; - found[i] += dfcode;; + found[i] += dfcode; break; case AT45DB642: @@ -97,7 +97,7 @@ int AT91F_DataflashInit (void) dataflash_info[i].Desc.DataFlash_state = IDLE; dataflash_info[i].logical_address = cs[i].addr; dataflash_info[i].id = dfcode; - found[i] += dfcode;; + found[i] += dfcode; break; case AT45DB128: @@ -109,7 +109,7 @@ int AT91F_DataflashInit (void) dataflash_info[i].Desc.DataFlash_state = IDLE; dataflash_info[i].logical_address = cs[i].addr; dataflash_info[i].id = dfcode; - found[i] += dfcode;; + found[i] += dfcode; break; default: diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index a7b76f4218..ce8ba99c82 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -33,11 +33,11 @@ config NAND_DENALI_SPARE_AREA_SKIP_BYTES used to preserve the bad block marker in the OOB area. config NAND_VF610_NFC - bool "Support for Freescale NFC for VF610/MPC5125" + bool "Support for Freescale NFC for VF610" select SYS_NAND_SELF_INIT help Enables support for NAND Flash Controller on some Freescale - processors like the VF610, MPC5125, MCF54418 or Kinetis K70. + processors like the VF610, MCF54418 or Kinetis K70. The driver supports a maximum 2k page size. The driver currently does not support hardware ECC. diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 82358f674b..c3d4a996f3 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -53,13 +53,11 @@ obj-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o obj-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o obj-$(CONFIG_NAND_LPC32XX_MLC) += lpc32xx_nand_mlc.o obj-$(CONFIG_NAND_LPC32XX_SLC) += lpc32xx_nand_slc.o -obj-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o obj-$(CONFIG_NAND_MXC) += mxc_nand.o obj-$(CONFIG_NAND_MXS) += mxs_nand.o obj-$(CONFIG_NAND_NDFC) += ndfc.o obj-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o -obj-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o obj-$(CONFIG_NAND_SPEAR) += spr_nand.o obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c deleted file mode 100644 index 7faabddbf2..0000000000 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Copyright 2004-2008 Freescale Semiconductor, Inc. - * Copyright 2009 Semihalf. - * (C) Copyright 2009 Stefan Roese <sr@denx.de> - * - * Based on original driver from Freescale Semiconductor - * written by John Rigby <jrigby@freescale.com> on basis - * of drivers/mtd/nand/mxc_nand.c. Reworked and extended - * Piotr Ziecik <kosmo@semihalf.com>. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> - -#include <linux/mtd/mtd.h> -#include <linux/mtd/nand.h> -#include <linux/mtd/nand_ecc.h> -#include <linux/compat.h> - -#include <linux/errno.h> -#include <asm/io.h> -#include <asm/processor.h> -#include <nand.h> - -#define DRV_NAME "mpc5121_nfc" - -/* Timeouts */ -#define NFC_RESET_TIMEOUT 1000 /* 1 ms */ -#define NFC_TIMEOUT 2000 /* 2000 us */ - -/* Addresses for NFC MAIN RAM BUFFER areas */ -#define NFC_MAIN_AREA(n) ((n) * 0x200) - -/* Addresses for NFC SPARE BUFFER areas */ -#define NFC_SPARE_BUFFERS 8 -#define NFC_SPARE_LEN 0x40 -#define NFC_SPARE_AREA(n) (0x1000 + ((n) * NFC_SPARE_LEN)) - -/* MPC5121 NFC registers */ -#define NFC_BUF_ADDR 0x1E04 -#define NFC_FLASH_ADDR 0x1E06 -#define NFC_FLASH_CMD 0x1E08 -#define NFC_CONFIG 0x1E0A -#define NFC_ECC_STATUS1 0x1E0C -#define NFC_ECC_STATUS2 0x1E0E -#define NFC_SPAS 0x1E10 -#define NFC_WRPROT 0x1E12 -#define NFC_NF_WRPRST 0x1E18 -#define NFC_CONFIG1 0x1E1A -#define NFC_CONFIG2 0x1E1C -#define NFC_UNLOCKSTART_BLK0 0x1E20 -#define NFC_UNLOCKEND_BLK0 0x1E22 -#define NFC_UNLOCKSTART_BLK1 0x1E24 -#define NFC_UNLOCKEND_BLK1 0x1E26 -#define NFC_UNLOCKSTART_BLK2 0x1E28 -#define NFC_UNLOCKEND_BLK2 0x1E2A -#define NFC_UNLOCKSTART_BLK3 0x1E2C -#define NFC_UNLOCKEND_BLK3 0x1E2E - -/* Bit Definitions: NFC_BUF_ADDR */ -#define NFC_RBA_MASK (7 << 0) -#define NFC_ACTIVE_CS_SHIFT 5 -#define NFC_ACTIVE_CS_MASK (3 << NFC_ACTIVE_CS_SHIFT) - -/* Bit Definitions: NFC_CONFIG */ -#define NFC_BLS_UNLOCKED (1 << 1) - -/* Bit Definitions: NFC_CONFIG1 */ -#define NFC_ECC_4BIT (1 << 0) -#define NFC_FULL_PAGE_DMA (1 << 1) -#define NFC_SPARE_ONLY (1 << 2) -#define NFC_ECC_ENABLE (1 << 3) -#define NFC_INT_MASK (1 << 4) -#define NFC_BIG_ENDIAN (1 << 5) -#define NFC_RESET (1 << 6) -#define NFC_CE (1 << 7) -#define NFC_ONE_CYCLE (1 << 8) -#define NFC_PPB_32 (0 << 9) -#define NFC_PPB_64 (1 << 9) -#define NFC_PPB_128 (2 << 9) -#define NFC_PPB_256 (3 << 9) -#define NFC_PPB_MASK (3 << 9) -#define NFC_FULL_PAGE_INT (1 << 11) - -/* Bit Definitions: NFC_CONFIG2 */ -#define NFC_COMMAND (1 << 0) -#define NFC_ADDRESS (1 << 1) -#define NFC_INPUT (1 << 2) -#define NFC_OUTPUT (1 << 3) -#define NFC_ID (1 << 4) -#define NFC_STATUS (1 << 5) -#define NFC_CMD_FAIL (1 << 15) -#define NFC_INT (1 << 15) - -/* Bit Definitions: NFC_WRPROT */ -#define NFC_WPC_LOCK_TIGHT (1 << 0) -#define NFC_WPC_LOCK (1 << 1) -#define NFC_WPC_UNLOCK (1 << 2) - -struct mpc5121_nfc_prv { - struct nand_chip chip; - int irq; - void __iomem *regs; - struct clk *clk; - uint column; - int spareonly; - int chipsel; -}; - -int mpc5121_nfc_chip = 0; - -static void mpc5121_nfc_done(struct mtd_info *mtd); - -/* Read NFC register */ -static inline u16 nfc_read(struct mtd_info *mtd, uint reg) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); - - return in_be16(prv->regs + reg); -} - -/* Write NFC register */ -static inline void nfc_write(struct mtd_info *mtd, uint reg, u16 val) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); - - out_be16(prv->regs + reg, val); -} - -/* Set bits in NFC register */ -static inline void nfc_set(struct mtd_info *mtd, uint reg, u16 bits) -{ - nfc_write(mtd, reg, nfc_read(mtd, reg) | bits); -} - -/* Clear bits in NFC register */ -static inline void nfc_clear(struct mtd_info *mtd, uint reg, u16 bits) -{ - nfc_write(mtd, reg, nfc_read(mtd, reg) & ~bits); -} - -/* Invoke address cycle */ -static inline void mpc5121_nfc_send_addr(struct mtd_info *mtd, u16 addr) -{ - nfc_write(mtd, NFC_FLASH_ADDR, addr); - nfc_write(mtd, NFC_CONFIG2, NFC_ADDRESS); - mpc5121_nfc_done(mtd); -} - -/* Invoke command cycle */ -static inline void mpc5121_nfc_send_cmd(struct mtd_info *mtd, u16 cmd) -{ - nfc_write(mtd, NFC_FLASH_CMD, cmd); - nfc_write(mtd, NFC_CONFIG2, NFC_COMMAND); - mpc5121_nfc_done(mtd); -} - -/* Send data from NFC buffers to NAND flash */ -static inline void mpc5121_nfc_send_prog_page(struct mtd_info *mtd) -{ - nfc_clear(mtd, NFC_BUF_ADDR, NFC_RBA_MASK); - nfc_write(mtd, NFC_CONFIG2, NFC_INPUT); - mpc5121_nfc_done(mtd); -} - -/* Receive data from NAND flash */ -static inline void mpc5121_nfc_send_read_page(struct mtd_info *mtd) -{ - nfc_clear(mtd, NFC_BUF_ADDR, NFC_RBA_MASK); - nfc_write(mtd, NFC_CONFIG2, NFC_OUTPUT); - mpc5121_nfc_done(mtd); -} - -/* Receive ID from NAND flash */ -static inline void mpc5121_nfc_send_read_id(struct mtd_info *mtd) -{ - nfc_clear(mtd, NFC_BUF_ADDR, NFC_RBA_MASK); - nfc_write(mtd, NFC_CONFIG2, NFC_ID); - mpc5121_nfc_done(mtd); -} - -/* Receive status from NAND flash */ -static inline void mpc5121_nfc_send_read_status(struct mtd_info *mtd) -{ - nfc_clear(mtd, NFC_BUF_ADDR, NFC_RBA_MASK); - nfc_write(mtd, NFC_CONFIG2, NFC_STATUS); - mpc5121_nfc_done(mtd); -} - -static void mpc5121_nfc_done(struct mtd_info *mtd) -{ - int max_retries = NFC_TIMEOUT; - - while (1) { - max_retries--; - if (nfc_read(mtd, NFC_CONFIG2) & NFC_INT) - break; - udelay(1); - } - - if (max_retries <= 0) - printk(KERN_WARNING DRV_NAME - ": Timeout while waiting for completion.\n"); -} - -/* Do address cycle(s) */ -static void mpc5121_nfc_addr_cycle(struct mtd_info *mtd, int column, int page) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - u32 pagemask = chip->pagemask; - - if (column != -1) { - mpc5121_nfc_send_addr(mtd, column); - if (mtd->writesize > 512) - mpc5121_nfc_send_addr(mtd, column >> 8); - } - - if (page != -1) { - do { - mpc5121_nfc_send_addr(mtd, page & 0xFF); - page >>= 8; - pagemask >>= 8; - } while (pagemask); - } -} - -/* Control chip select signals */ - -/* - * Selecting the active device: - * - * This is different than the linux version. Switching between chips - * is done via board_nand_select_device(). The Linux select_chip - * function used here in U-Boot has only 2 valid chip numbers: - * 0 select - * -1 deselect - */ - -/* - * Implement it as a weak default, so that boards with a specific - * chip-select routine can use their own function. - */ -void __mpc5121_nfc_select_chip(struct mtd_info *mtd, int chip) -{ - if (chip < 0) { - nfc_clear(mtd, NFC_CONFIG1, NFC_CE); - return; - } - - nfc_clear(mtd, NFC_BUF_ADDR, NFC_ACTIVE_CS_MASK); - nfc_set(mtd, NFC_BUF_ADDR, (chip << NFC_ACTIVE_CS_SHIFT) & - NFC_ACTIVE_CS_MASK); - nfc_set(mtd, NFC_CONFIG1, NFC_CE); -} -void mpc5121_nfc_select_chip(struct mtd_info *mtd, int chip) - __attribute__((weak, alias("__mpc5121_nfc_select_chip"))); - -void board_nand_select_device(struct nand_chip *nand, int chip) -{ - /* - * Only save this chip number in global variable here. This - * will be used later in mpc5121_nfc_select_chip(). - */ - mpc5121_nfc_chip = chip; -} - -/* Read NAND Ready/Busy signal */ -static int mpc5121_nfc_dev_ready(struct mtd_info *mtd) -{ - /* - * NFC handles ready/busy signal internally. Therefore, this function - * always returns status as ready. - */ - return 1; -} - -/* Write command to NAND flash */ -static void mpc5121_nfc_command(struct mtd_info *mtd, unsigned command, - int column, int page) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); - - prv->column = (column >= 0) ? column : 0; - prv->spareonly = 0; - - switch (command) { - case NAND_CMD_PAGEPROG: - mpc5121_nfc_send_prog_page(mtd); - break; - /* - * NFC does not support sub-page reads and writes, - * so emulate them using full page transfers. - */ - case NAND_CMD_READ0: - column = 0; - break; - - case NAND_CMD_READ1: - prv->column += 256; - command = NAND_CMD_READ0; - column = 0; - break; - - case NAND_CMD_READOOB: - prv->spareonly = 1; - command = NAND_CMD_READ0; - column = 0; - break; - - case NAND_CMD_SEQIN: - mpc5121_nfc_command(mtd, NAND_CMD_READ0, column, page); - column = 0; - break; - - case NAND_CMD_ERASE1: - case NAND_CMD_ERASE2: - case NAND_CMD_READID: - case NAND_CMD_STATUS: - case NAND_CMD_RESET: - break; - - default: - return; - } - - mpc5121_nfc_send_cmd(mtd, command); - mpc5121_nfc_addr_cycle(mtd, column, page); - - switch (command) { - case NAND_CMD_READ0: - if (mtd->writesize > 512) - mpc5121_nfc_send_cmd(mtd, NAND_CMD_READSTART); - mpc5121_nfc_send_read_page(mtd); - break; - - case NAND_CMD_READID: - mpc5121_nfc_send_read_id(mtd); - break; - - case NAND_CMD_STATUS: - mpc5121_nfc_send_read_status(mtd); - if (chip->options & NAND_BUSWIDTH_16) - prv->column = 1; - else - prv->column = 0; - break; - } -} - -/* Copy data from/to NFC spare buffers. */ -static void mpc5121_nfc_copy_spare(struct mtd_info *mtd, uint offset, - u8 * buffer, uint size, int wr) -{ - struct nand_chip *nand = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = nand_get_controller_data(nand); - uint o, s, sbsize, blksize; - - /* - * NAND spare area is available through NFC spare buffers. - * The NFC divides spare area into (page_size / 512) chunks. - * Each chunk is placed into separate spare memory area, using - * first (spare_size / num_of_chunks) bytes of the buffer. - * - * For NAND device in which the spare area is not divided fully - * by the number of chunks, number of used bytes in each spare - * buffer is rounded down to the nearest even number of bytes, - * and all remaining bytes are added to the last used spare area. - * - * For more information read section 26.6.10 of MPC5121e - * Microcontroller Reference Manual, Rev. 3. - */ - - /* Calculate number of valid bytes in each spare buffer */ - sbsize = (mtd->oobsize / (mtd->writesize / 512)) & ~1; - - while (size) { - /* Calculate spare buffer number */ - s = offset / sbsize; - if (s > NFC_SPARE_BUFFERS - 1) - s = NFC_SPARE_BUFFERS - 1; - - /* - * Calculate offset to requested data block in selected spare - * buffer and its size. - */ - o = offset - (s * sbsize); - blksize = min(sbsize - o, size); - - if (wr) - memcpy_toio(prv->regs + NFC_SPARE_AREA(s) + o, - buffer, blksize); - else - memcpy_fromio(buffer, - prv->regs + NFC_SPARE_AREA(s) + o, - blksize); - - buffer += blksize; - offset += blksize; - size -= blksize; - }; -} - -/* Copy data from/to NFC main and spare buffers */ -static void mpc5121_nfc_buf_copy(struct mtd_info *mtd, u_char * buf, int len, - int wr) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); - uint c = prv->column; - uint l; - - /* Handle spare area access */ - if (prv->spareonly || c >= mtd->writesize) { - /* Calculate offset from beginning of spare area */ - if (c >= mtd->writesize) - c -= mtd->writesize; - - prv->column += len; - mpc5121_nfc_copy_spare(mtd, c, buf, len, wr); - return; - } - - /* - * Handle main area access - limit copy length to prevent - * crossing main/spare boundary. - */ - l = min((uint) len, mtd->writesize - c); - prv->column += l; - - if (wr) - memcpy_toio(prv->regs + NFC_MAIN_AREA(0) + c, buf, l); - else - memcpy_fromio(buf, prv->regs + NFC_MAIN_AREA(0) + c, l); - - /* Handle crossing main/spare boundary */ - if (l != len) { - buf += l; - len -= l; - mpc5121_nfc_buf_copy(mtd, buf, len, wr); - } -} - -/* Read data from NFC buffers */ -static void mpc5121_nfc_read_buf(struct mtd_info *mtd, u_char * buf, int len) -{ - mpc5121_nfc_buf_copy(mtd, buf, len, 0); -} - -/* Write data to NFC buffers */ -static void mpc5121_nfc_write_buf(struct mtd_info *mtd, - const u_char * buf, int len) -{ - mpc5121_nfc_buf_copy(mtd, (u_char *) buf, len, 1); -} - -/* Read byte from NFC buffers */ -static u8 mpc5121_nfc_read_byte(struct mtd_info *mtd) -{ - u8 tmp; - - mpc5121_nfc_read_buf(mtd, &tmp, sizeof(tmp)); - - return tmp; -} - -/* Read word from NFC buffers */ -static u16 mpc5121_nfc_read_word(struct mtd_info *mtd) -{ - u16 tmp; - - mpc5121_nfc_read_buf(mtd, (u_char *) & tmp, sizeof(tmp)); - - return tmp; -} - -/* - * Read NFC configuration from Reset Config Word - * - * NFC is configured during reset in basis of information stored - * in Reset Config Word. There is no other way to set NAND block - * size, spare size and bus width. - */ -static int mpc5121_nfc_read_hw_config(struct mtd_info *mtd) -{ - immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - struct nand_chip *chip = mtd_to_nand(mtd); - uint rcw_pagesize = 0; - uint rcw_sparesize = 0; - uint rcw_width; - uint rcwh; - uint romloc, ps; - - rcwh = in_be32(&(im->reset.rcwh)); - - /* Bit 6: NFC bus width */ - rcw_width = ((rcwh >> 6) & 0x1) ? 2 : 1; - - /* Bit 7: NFC Page/Spare size */ - ps = (rcwh >> 7) & 0x1; - - /* Bits [22:21]: ROM Location */ - romloc = (rcwh >> 21) & 0x3; - - /* Decode RCW bits */ - switch ((ps << 2) | romloc) { - case 0x00: - case 0x01: - rcw_pagesize = 512; - rcw_sparesize = 16; - break; - case 0x02: - case 0x03: - rcw_pagesize = 4096; - rcw_sparesize = 128; - break; - case 0x04: - case 0x05: - rcw_pagesize = 2048; - rcw_sparesize = 64; - break; - case 0x06: - case 0x07: - rcw_pagesize = 4096; - rcw_sparesize = 218; - break; - } - - mtd->writesize = rcw_pagesize; - mtd->oobsize = rcw_sparesize; - if (rcw_width == 2) - chip->options |= NAND_BUSWIDTH_16; - - debug(KERN_NOTICE DRV_NAME ": Configured for " - "%u-bit NAND, page size %u with %u spare.\n", - rcw_width * 8, rcw_pagesize, rcw_sparesize); - return 0; -} - -int board_nand_init(struct nand_chip *chip) -{ - struct mpc5121_nfc_prv *prv; - struct mtd_info *mtd; - int resettime = 0; - int retval = 0; - int rev; - - /* - * Check SoC revision. This driver supports only NFC - * in MPC5121 revision 2. - */ - rev = (mfspr(SPRN_SVR) >> 4) & 0xF; - if (rev != 2) { - printk(KERN_ERR DRV_NAME - ": SoC revision %u is not supported!\n", rev); - return -ENXIO; - } - - prv = malloc(sizeof(*prv)); - if (!prv) { - printk(KERN_ERR DRV_NAME ": Memory exhausted!\n"); - return -ENOMEM; - } - - mtd = &chip->mtd; - nand_set_controller_data(chip, prv); - - /* Read NFC configuration from Reset Config Word */ - retval = mpc5121_nfc_read_hw_config(mtd); - if (retval) { - printk(KERN_ERR DRV_NAME ": Unable to read NFC config!\n"); - return retval; - } - - prv->regs = (void __iomem *)CONFIG_SYS_NAND_BASE; - chip->dev_ready = mpc5121_nfc_dev_ready; - chip->cmdfunc = mpc5121_nfc_command; - chip->read_byte = mpc5121_nfc_read_byte; - chip->read_word = mpc5121_nfc_read_word; - chip->read_buf = mpc5121_nfc_read_buf; - chip->write_buf = mpc5121_nfc_write_buf; - chip->select_chip = mpc5121_nfc_select_chip; - chip->bbt_options = NAND_BBT_USE_FLASH; - chip->ecc.mode = NAND_ECC_SOFT; - - /* Reset NAND Flash controller */ - nfc_set(mtd, NFC_CONFIG1, NFC_RESET); - while (nfc_read(mtd, NFC_CONFIG1) & NFC_RESET) { - if (resettime++ >= NFC_RESET_TIMEOUT) { - printk(KERN_ERR DRV_NAME - ": Timeout while resetting NFC!\n"); - retval = -EINVAL; - goto error; - } - - udelay(1); - } - - /* Enable write to NFC memory */ - nfc_write(mtd, NFC_CONFIG, NFC_BLS_UNLOCKED); - - /* Enable write to all NAND pages */ - nfc_write(mtd, NFC_UNLOCKSTART_BLK0, 0x0000); - nfc_write(mtd, NFC_UNLOCKEND_BLK0, 0xFFFF); - nfc_write(mtd, NFC_WRPROT, NFC_WPC_UNLOCK); - - /* - * Setup NFC: - * - Big Endian transfers, - * - Interrupt after full page read/write. - */ - nfc_write(mtd, NFC_CONFIG1, NFC_BIG_ENDIAN | NFC_INT_MASK | - NFC_FULL_PAGE_INT); - - /* Set spare area size */ - nfc_write(mtd, NFC_SPAS, mtd->oobsize >> 1); - - /* Detect NAND chips */ - if (nand_scan(mtd, 1)) { - printk(KERN_ERR DRV_NAME ": NAND Flash not found !\n"); - retval = -ENXIO; - goto error; - } - - /* Set erase block size */ - switch (mtd->erasesize / mtd->writesize) { - case 32: - nfc_set(mtd, NFC_CONFIG1, NFC_PPB_32); - break; - - case 64: - nfc_set(mtd, NFC_CONFIG1, NFC_PPB_64); - break; - - case 128: - nfc_set(mtd, NFC_CONFIG1, NFC_PPB_128); - break; - - case 256: - nfc_set(mtd, NFC_CONFIG1, NFC_PPB_256); - break; - - default: - printk(KERN_ERR DRV_NAME ": Unsupported NAND flash!\n"); - retval = -ENXIO; - goto error; - } - - return 0; -error: - return retval; -} diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c deleted file mode 100644 index dd742a6351..0000000000 --- a/drivers/mtd/nand/s3c2410_nand.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * (C) Copyright 2006 OpenMoko, Inc. - * Author: Harald Welte <laforge@openmoko.org> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> - -#include <nand.h> -#include <asm/arch/s3c24x0_cpu.h> -#include <asm/io.h> - -#define S3C2410_NFCONF_EN (1<<15) -#define S3C2410_NFCONF_512BYTE (1<<14) -#define S3C2410_NFCONF_4STEP (1<<13) -#define S3C2410_NFCONF_INITECC (1<<12) -#define S3C2410_NFCONF_nFCE (1<<11) -#define S3C2410_NFCONF_TACLS(x) ((x)<<8) -#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4) -#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0) - -#define S3C2410_ADDR_NALE 4 -#define S3C2410_ADDR_NCLE 8 - -#ifdef CONFIG_NAND_SPL - -/* in the early stage of NAND flash booting, printf() is not available */ -#define printf(fmt, args...) - -static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) -{ - int i; - struct nand_chip *this = mtd_to_nand(mtd); - - for (i = 0; i < len; i++) - buf[i] = readb(this->IO_ADDR_R); -} -#endif - -static void s3c24x0_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); - - debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl); - - if (ctrl & NAND_CTRL_CHANGE) { - ulong IO_ADDR_W = (ulong)nand; - - if (!(ctrl & NAND_CLE)) - IO_ADDR_W |= S3C2410_ADDR_NCLE; - if (!(ctrl & NAND_ALE)) - IO_ADDR_W |= S3C2410_ADDR_NALE; - - chip->IO_ADDR_W = (void *)IO_ADDR_W; - - if (ctrl & NAND_NCE) - writel(readl(&nand->nfconf) & ~S3C2410_NFCONF_nFCE, - &nand->nfconf); - else - writel(readl(&nand->nfconf) | S3C2410_NFCONF_nFCE, - &nand->nfconf); - } - - if (cmd != NAND_CMD_NONE) - writeb(cmd, chip->IO_ADDR_W); -} - -static int s3c24x0_dev_ready(struct mtd_info *mtd) -{ - struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); - debug("dev_ready\n"); - return readl(&nand->nfstat) & 0x01; -} - -#ifdef CONFIG_S3C2410_NAND_HWECC -void s3c24x0_nand_enable_hwecc(struct mtd_info *mtd, int mode) -{ - struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); - debug("s3c24x0_nand_enable_hwecc(%p, %d)\n", mtd, mode); - writel(readl(&nand->nfconf) | S3C2410_NFCONF_INITECC, &nand->nfconf); -} - -static int s3c24x0_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, - u_char *ecc_code) -{ - struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); - ecc_code[0] = readb(&nand->nfecc); - ecc_code[1] = readb(&nand->nfecc + 1); - ecc_code[2] = readb(&nand->nfecc + 2); - debug("s3c24x0_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", - mtd , ecc_code[0], ecc_code[1], ecc_code[2]); - - return 0; -} - -static int s3c24x0_nand_correct_data(struct mtd_info *mtd, u_char *dat, - u_char *read_ecc, u_char *calc_ecc) -{ - if (read_ecc[0] == calc_ecc[0] && - read_ecc[1] == calc_ecc[1] && - read_ecc[2] == calc_ecc[2]) - return 0; - - printf("s3c24x0_nand_correct_data: not implemented\n"); - return -EBADMSG; -} -#endif - -int board_nand_init(struct nand_chip *nand) -{ - u_int32_t cfg; - u_int8_t tacls, twrph0, twrph1; - struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - struct s3c24x0_nand *nand_reg = s3c24x0_get_base_nand(); - - debug("board_nand_init()\n"); - - writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon); - - /* initialize hardware */ -#if defined(CONFIG_S3C24XX_CUSTOM_NAND_TIMING) - tacls = CONFIG_S3C24XX_TACLS; - twrph0 = CONFIG_S3C24XX_TWRPH0; - twrph1 = CONFIG_S3C24XX_TWRPH1; -#else - tacls = 4; - twrph0 = 8; - twrph1 = 8; -#endif - - cfg = S3C2410_NFCONF_EN; - cfg |= S3C2410_NFCONF_TACLS(tacls - 1); - cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); - cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); - writel(cfg, &nand_reg->nfconf); - - /* initialize nand_chip data structure */ - nand->IO_ADDR_R = (void *)&nand_reg->nfdata; - nand->IO_ADDR_W = (void *)&nand_reg->nfdata; - - nand->select_chip = NULL; - - /* read_buf and write_buf are default */ - /* read_byte and write_byte are default */ -#ifdef CONFIG_NAND_SPL - nand->read_buf = nand_read_buf; -#endif - - /* hwcontrol always must be implemented */ - nand->cmd_ctrl = s3c24x0_hwcontrol; - - nand->dev_ready = s3c24x0_dev_ready; - -#ifdef CONFIG_S3C2410_NAND_HWECC - nand->ecc.hwctl = s3c24x0_nand_enable_hwecc; - nand->ecc.calculate = s3c24x0_nand_calculate_ecc; - nand->ecc.correct = s3c24x0_nand_correct_data; - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; - nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; - nand->ecc.strength = 1; -#else - nand->ecc.mode = NAND_ECC_SOFT; -#endif - -#ifdef CONFIG_S3C2410_NAND_BBT - nand->bbt_options |= NAND_BBT_USE_FLASH; -#endif - - debug("end of nand_init\n"); - - return 0; -} diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index c4e2cd7f55..8bc3828854 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -1663,7 +1663,7 @@ static int sunxi_nand_chip_init(int node, struct sunxi_nfc *nfc, int devnum) chip->sels[i].rb.type = RB_NATIVE; chip->sels[i].rb.info.nativeid = tmp; } else { - ret = gpio_request_by_name_nodev(blob, node, + ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "rb-gpios", i, &chip->sels[i].rb.info.gpio, GPIOD_IS_IN); diff --git a/drivers/mtd/nand/tegra_nand.c b/drivers/mtd/nand/tegra_nand.c index 5c9b485b08..c03c9cb178 100644 --- a/drivers/mtd/nand/tegra_nand.c +++ b/drivers/mtd/nand/tegra_nand.c @@ -894,8 +894,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 = gpio_request_by_name_nodev(blob, node, "nvidia,wp-gpios", 0, - &config->wp_gpio, GPIOD_IS_OUT); + err = gpio_request_by_name_nodev(offset_to_ofnode(node), + "nvidia,wp-gpios", 0, &config->wp_gpio, GPIOD_IS_OUT); if (err) return err; err = fdtdec_get_int_array(blob, node, "nvidia,timing", diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 2e3d0e5c9a..8282f683a5 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1919,6 +1919,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) */ int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs) { + struct onenand_chip *this = mtd->priv; int ret; ret = onenand_block_isbad(mtd, ofs); @@ -1929,7 +1930,10 @@ int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs) return ret; } - ret = mtd_block_markbad(mtd, ofs); + onenand_get_device(mtd, FL_WRITING); + ret = this->block_markbad(mtd, ofs); + onenand_release_device(mtd); + return ret; } diff --git a/drivers/mtd/onenand/onenand_spl.c b/drivers/mtd/onenand/onenand_spl.c index 1925f41d8a..0b78067a23 100644 --- a/drivers/mtd/onenand/onenand_spl.c +++ b/drivers/mtd/onenand/onenand_spl.c @@ -23,11 +23,29 @@ enum onenand_spl_pagesize { PAGE_4K = 4096, }; +static unsigned int density_mask; + #define ONENAND_PAGES_PER_BLOCK 64 -#define onenand_block_address(block) (block) #define onenand_sector_address(page) (page << 2) #define onenand_buffer_address() ((1 << 3) << 8) -#define onenand_bufferram_address(block) (0) + +static inline int onenand_block_address(int block) +{ + /* Device Flash Core select, NAND Flash Block Address */ + if (block & density_mask) + return ONENAND_DDP_CHIP1 | (block ^ density_mask); + + return block; +} + +static inline int onenand_bufferram_address(int block) +{ + /* Device BufferRAM Select */ + if (block & density_mask) + return ONENAND_DDP_CHIP1; + + return ONENAND_DDP_CHIP0; +} static inline uint16_t onenand_readw(uint32_t addr) { @@ -41,7 +59,7 @@ static inline void onenand_writew(uint16_t value, uint32_t addr) static enum onenand_spl_pagesize onenand_spl_get_geometry(void) { - uint32_t dev_id, density; + unsigned int dev_id, density, size; if (!onenand_readw(ONENAND_REG_TECHNOLOGY)) { dev_id = onenand_readw(ONENAND_REG_DEVICE_ID); @@ -51,8 +69,11 @@ static enum onenand_spl_pagesize onenand_spl_get_geometry(void) if (density < ONENAND_DEVICE_DENSITY_4Gb) return PAGE_2K; - if (dev_id & ONENAND_DEVICE_IS_DDP) + if (dev_id & ONENAND_DEVICE_IS_DDP) { + size = onenand_readw(ONENAND_REG_DATA_BUFFER_SIZE); + density_mask = 1 << (18 + density - ffs(size)); return PAGE_2K; + } } return PAGE_4K; @@ -110,9 +131,12 @@ static u8 scratch_buf[PAGE_4K]; */ int onenand_spl_read_block(int block, int offset, int len, void *dst) { - int page, read, psize; + int page, read; + static int psize; + + if (!psize) + psize = onenand_spl_get_geometry(); - psize = onenand_spl_get_geometry(); /* Calculate the page number */ page = offset / psize; /* Offset to the start of a flash page */ diff --git a/drivers/mtd/pic32_flash.c b/drivers/mtd/pic32_flash.c index 8ed7874cc9..e1a8d3bc4b 100644 --- a/drivers/mtd/pic32_flash.c +++ b/drivers/mtd/pic32_flash.c @@ -384,7 +384,7 @@ static int pic32_flash_probe(struct udevice *dev) * match with reg-names. */ parent = fdt_parent_offset(blob, node); - of_bus_default_count_cells(blob, parent, &addrc, &sizec); + fdt_support_default_count_cells(blob, parent, &addrc, &sizec); list = fdt_getprop(blob, node, "reg-names", &len); if (!list) return -ENOENT; diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 5ca0a712d8..5700859ff2 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -42,6 +42,13 @@ config SPI_FLASH_BAR Bank/Extended address registers are used to access the flash which has size > 16MiB in 3-byte addressing. +config SF_DUAL_FLASH + bool "SPI DUAL flash memory support" + depends on SPI_FLASH + help + Enable this option to support two flash memories connected to a single + controller. Currently Xilinx Zynq qspi supports this. + if SPI_FLASH config SPI_FLASH_ATMEL diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c index a53f4ebc68..1ba6815232 100644 --- a/drivers/mtd/spi/sandbox.c +++ b/drivers/mtd/spi/sandbox.c @@ -515,11 +515,9 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen, int sandbox_sf_ofdata_to_platdata(struct udevice *dev) { struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev); - const void *blob = gd->fdt_blob; - int node = dev_of_offset(dev); - pdata->filename = fdt_getprop(blob, node, "sandbox,filename", NULL); - pdata->device_name = fdt_getprop(blob, node, "compatible", NULL); + pdata->filename = dev_read_string(dev, "sandbox,filename"); + pdata->device_name = dev_read_string(dev, "compatible"); if (!pdata->filename || !pdata->device_name) { debug("%s: Missing properties, filename=%s, device_name=%s\n", __func__, pdata->filename, pdata->device_name); diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index ab7910bc14..0034a28d5f 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -914,14 +914,13 @@ static int set_quad_mode(struct spi_flash *flash, } #if CONFIG_IS_ENABLED(OF_CONTROL) -int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) +int spi_flash_decode_fdt(struct spi_flash *flash) { #ifdef CONFIG_DM_SPI_FLASH fdt_addr_t addr; fdt_size_t size; - int node = dev_of_offset(flash->dev); - addr = fdtdec_get_addr_size(blob, node, "memory-map", &size); + addr = dev_read_addr_size(flash->dev, "memory-map", &size); if (addr == FDT_ADDR_T_NONE) { debug("%s: Cannot decode address\n", __func__); return 0; @@ -1081,7 +1080,7 @@ int spi_flash_scan(struct spi_flash *flash) #endif #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) - ret = spi_flash_decode_fdt(gd->fdt_blob, flash); + ret = spi_flash_decode_fdt(flash); if (ret) { debug("SF: FDT decode error\n"); return -EINVAL; |