diff options
Diffstat (limited to 'target/linux/brcm47xx/patches-3.3/053-mtd-add-nand-flash-driver.patch')
-rw-r--r-- | target/linux/brcm47xx/patches-3.3/053-mtd-add-nand-flash-driver.patch | 710 |
1 files changed, 0 insertions, 710 deletions
diff --git a/target/linux/brcm47xx/patches-3.3/053-mtd-add-nand-flash-driver.patch b/target/linux/brcm47xx/patches-3.3/053-mtd-add-nand-flash-driver.patch deleted file mode 100644 index 7635d424de..0000000000 --- a/target/linux/brcm47xx/patches-3.3/053-mtd-add-nand-flash-driver.patch +++ /dev/null @@ -1,710 +0,0 @@ ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -536,4 +536,12 @@ config MTD_NAND_FSMC - Enables support for NAND Flash chips on the ST Microelectronics - Flexible Static Memory Controller (FSMC) - -+config MTD_NAND_BCM47XX -+ tristate "bcm47xx nand flash support" -+ default y -+ depends on BCM47XX && BCMA_NFLASH -+ select MTD_PARTITIONS -+ help -+ Support for bcm47xx nand flash -+ - endif # MTD_NAND ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -49,5 +49,6 @@ obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mp - obj-$(CONFIG_MTD_NAND_RICOH) += r852.o - obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o - obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ -+obj-$(CONFIG_MTD_NAND_BCM47XX) += bcm47xx_nand.o - - nand-objs := nand_base.o nand_bbt.o ---- /dev/null -+++ b/drivers/mtd/nand/bcm47xx_nand.c -@@ -0,0 +1,528 @@ -+/* -+ * BCMA nand flash interface -+ * -+ * Copyright (C) 2011-2012 Tathagata Das <tathagata@alumnux.com> -+ * Copyright 2010, Broadcom Corporation -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ */ -+ -+#define pr_fmt(fmt) "bcm47xx_nflash: " fmt -+#include <linux/module.h> -+#include <linux/slab.h> -+#include <linux/ioport.h> -+#include <linux/sched.h> -+#include <linux/mtd/mtd.h> -+#include <linux/mtd/map.h> -+#include <linux/mtd/partitions.h> -+#include <linux/errno.h> -+#include <linux/delay.h> -+#include <linux/platform_device.h> -+#include <bcm47xx.h> -+#include <linux/cramfs_fs.h> -+#include <linux/romfs_fs.h> -+#include <linux/magic.h> -+#include <linux/byteorder/generic.h> -+#include <linux/mtd/bcm47xx_nand.h> -+#include <linux/mtd/nand.h> -+ -+static int bcm47xx_nflash_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip); -+static int bcm47xx_nflash_erase(struct mtd_info *mtd, unsigned int addr, unsigned int len); -+ -+/* Private Global variable */ -+static u32 read_offset = 0; -+static u32 write_offset; -+ -+static int -+nflash_mtd_poll(struct bcm47xx_nflash *nflash, unsigned int offset, int timeout) -+{ -+ unsigned long now = jiffies; -+ int ret = 0; -+ -+ for (;;) { -+ if (!bcma_nflash_poll(nflash->bcc)) { -+ ret = 0; -+ break; -+ } -+ if (time_after(jiffies, now + timeout)) { -+ pr_err("timeout while polling\n"); -+ ret = -ETIMEDOUT; -+ break; -+ } -+ udelay(1); -+ } -+ -+ return ret; -+} -+ -+static int -+bcm47xx_nflash_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) -+{ -+ struct nand_chip *nchip = (struct nand_chip *)mtd->priv; -+ struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; -+ int bytes, ret = 0; -+ u32 extra = 0; -+ u8 *tmpbuf = NULL; -+ int size; -+ u32 offset, blocksize, mask, off; -+ u32 skip_bytes = 0; -+ int need_copy = 0; -+ u8 *ptr = NULL; -+ -+ /* Check address range */ -+ if (!len) -+ return 0; -+ if ((from + len) > mtd->size) -+ return -EINVAL; -+ offset = from; -+ if ((offset & (NFL_SECTOR_SIZE - 1)) != 0) { -+ extra = offset & (NFL_SECTOR_SIZE - 1); -+ offset -= extra; -+ len += extra; -+ need_copy = 1; -+ } -+ size = (len + (NFL_SECTOR_SIZE - 1)) & ~(NFL_SECTOR_SIZE - 1); -+ if (size != len) { -+ need_copy = 1; -+ } -+ if (!need_copy) { -+ ptr = buf; -+ } else { -+ tmpbuf = (u8 *)kmalloc(size, GFP_KERNEL); -+ ptr = tmpbuf; -+ } -+ -+ blocksize = mtd->erasesize; -+ mask = blocksize - 1; -+ *retlen = 0; -+ while (len > 0) { -+ off = offset + skip_bytes; -+ if ((bytes = bcma_nflash_read(nflash->bcc, off, NFL_SECTOR_SIZE, ptr)) < 0) { -+ ret = bytes; -+ goto done; -+ } -+ if (bytes > len) -+ bytes = len; -+ offset += bytes; -+ len -= bytes; -+ ptr += bytes; -+ *retlen += bytes; -+ } -+ -+done: -+ if (tmpbuf) { -+ *retlen -= extra; -+ memcpy(buf, tmpbuf+extra, *retlen); -+ kfree(tmpbuf); -+ } -+ -+ return ret; -+} -+ -+static void bcm47xx_nflash_write(struct mtd_info *mtd, u32 to, const u_char *buf, u32 len) -+{ -+ struct nand_chip *nchip = (struct nand_chip *)mtd->priv; -+ struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; -+ u32 offset, blocksize, mask, off; -+ int read_len; -+ u32 copy_len, write_len, from; -+ u_char *write_ptr, *block; -+ const u_char *ptr; -+ int ret, bytes; -+ -+ /* Check address range */ -+ if (!len) { -+ pr_err("Error: Attempted to write too small data\n"); -+ return; -+ } -+ -+ if (!to) -+ return; -+ -+ if ((to + len) > mtd->size) { -+ pr_err("Error: Attempted to write too large data\n"); -+ return; -+ } -+ -+ ptr = buf; -+ block = NULL; -+ offset = to; -+ blocksize = mtd->erasesize; -+ if (!(block = kmalloc(blocksize, GFP_KERNEL))) -+ return; -+ mask = blocksize - 1; -+ while (len) { -+ /* Align offset */ -+ from = offset & ~mask; -+ /* Copy existing data into holding block if necessary */ -+ if (((offset & (blocksize-1)) != 0) || (len < blocksize)) { -+ if ((ret = bcm47xx_nflash_read(mtd, from, blocksize, &read_len, block))) -+ goto done; -+ if (read_len != blocksize) { -+ ret = -EINVAL; -+ goto done; -+ } -+ } -+ -+ /* Copy input data into holding block */ -+ copy_len = min(len, blocksize - (offset & mask)); -+ memcpy(block + (offset & mask), ptr, copy_len); -+ off = (uint) from; -+ /* Erase block */ -+ if ((ret = bcm47xx_nflash_erase(mtd, off, blocksize)) < 0) -+ goto done; -+ /* Write holding block */ -+ write_ptr = block; -+ write_len = blocksize; -+ if ((bytes = bcma_nflash_write(nflash->bcc, (uint)from, (uint)write_len, (u8 *) write_ptr)) != 0) { -+ ret = bytes; -+ goto done; -+ } -+ offset += copy_len; -+ if (len < copy_len) -+ len = 0; -+ else -+ len -= copy_len; -+ ptr += copy_len; -+ } -+ -+done: -+ if (block) -+ kfree(block); -+ return; -+} -+ -+static int bcm47xx_nflash_erase(struct mtd_info *mtd, unsigned int addr, unsigned int len) -+{ -+ struct nand_chip *nchip = (struct nand_chip *)mtd->priv; -+ struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; -+ -+ /* Check address range */ -+ if (!len) -+ return 1; -+ if ((addr + len) > mtd->size) -+ return 1; -+ -+ if (bcma_nflash_erase(nflash->bcc, addr)) { -+ pr_err("ERASE: nflash erase error\n"); -+ return 1; -+ } -+ -+ if (nflash_mtd_poll(nflash, addr, 10 * HZ)) { -+ pr_err("ERASE: nflash_mtd_poll error\n"); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/* This functions is used by upper layer to checks if device is ready */ -+static int bcm47xx_nflash_dev_ready(struct mtd_info *mtd) -+{ -+ return 1; -+} -+ -+/* Issue a nand flash command */ -+static inline void bcm47xx_nflash_cmd(struct bcma_drv_cc *cc, u32 opcode) -+{ -+ bcma_cc_write32(cc, NAND_CMD_START, opcode); -+ bcma_cc_read32(cc, NAND_CMD_START); -+} -+ -+static void bcm47xx_nflash_command(struct mtd_info *mtd, unsigned command, -+ int column, int page_addr) -+{ -+ struct nand_chip *nchip = (struct nand_chip *)mtd->priv; -+ struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; -+ u32 pagesize = 1 << nchip->page_shift; -+ -+ /* Command pre-processing step */ -+ switch (command) { -+ case NAND_CMD_RESET: -+ bcm47xx_nflash_cmd(nflash->bcc, NCMD_FLASH_RESET); -+ break; -+ -+ case NAND_CMD_STATUS: -+ nflash->next_opcode = NAND_CMD_STATUS; -+ read_offset = 0; -+ write_offset = 0; -+ break; -+ -+ case NAND_CMD_READ0: -+ read_offset = page_addr * pagesize; -+ nflash->next_opcode = 0; -+ break; -+ -+ case NAND_CMD_READOOB: -+ read_offset = page_addr * pagesize; -+ nflash->next_opcode = 0; -+ break; -+ -+ case NAND_CMD_SEQIN: -+ write_offset = page_addr * pagesize; -+ nflash->next_opcode = 0; -+ break; -+ -+ case NAND_CMD_PAGEPROG: -+ nflash->next_opcode = 0; -+ break; -+ -+ case NAND_CMD_READID: -+ read_offset = column; -+ bcm47xx_nflash_cmd(nflash->bcc, NCMD_ID_RD); -+ nflash->next_opcode = NAND_DEVID; -+ break; -+ -+ case NAND_CMD_ERASE1: -+ nflash->next_opcode = 0; -+ bcm47xx_nflash_erase(mtd, page_addr*pagesize, pagesize); -+ break; -+ -+ case NAND_CMD_ERASE2: -+ break; -+ -+ case NAND_CMD_RNDOUT: -+ if (column > mtd->writesize) -+ read_offset += (column - mtd->writesize); -+ else -+ read_offset += column; -+ break; -+ -+ default: -+ pr_err("COMMAND not supported %x\n", command); -+ nflash->next_opcode = 0; -+ break; -+ } -+} -+ -+/* This function is used by upper layer for select and -+ * deselect of the NAND chip. -+ * It is dummy function. */ -+static void bcm47xx_nflash_select_chip(struct mtd_info *mtd, int chip) -+{ -+} -+ -+static u_char bcm47xx_nflash_read_byte(struct mtd_info *mtd) -+{ -+ struct nand_chip *nchip = mtd->priv; -+ struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; -+ uint8_t ret = 0; -+ static u32 id; -+ -+ if (nflash->next_opcode == 0) -+ return ret; -+ -+ if (nflash->next_opcode == NAND_CMD_STATUS) -+ return NAND_STATUS_WP; -+ -+ id = bcma_cc_read32(nflash->bcc, nflash->next_opcode); -+ -+ if (nflash->next_opcode == NAND_DEVID) { -+ ret = (id >> (8*read_offset)) & 0xff; -+ read_offset++; -+ } -+ -+ return ret; -+} -+ -+static uint16_t bcm47xx_nflash_read_word(struct mtd_info *mtd) -+{ -+ loff_t from = read_offset; -+ uint16_t buf = 0; -+ int bytes; -+ -+ bcm47xx_nflash_read(mtd, from, sizeof(buf), &bytes, (u_char *)&buf); -+ return buf; -+} -+ -+/* Write data of length len to buffer buf. The data to be -+ * written on NAND Flash is first copied to RAMbuffer. After the Data Input -+ * Operation by the NFC, the data is written to NAND Flash */ -+static void bcm47xx_nflash_write_buf(struct mtd_info *mtd, -+ const u_char *buf, int len) -+{ -+ bcm47xx_nflash_write(mtd, write_offset, buf, len); -+} -+ -+/* Read the data buffer from the NAND Flash. To read the data from NAND -+ * Flash first the data output cycle is initiated by the NFC, which copies -+ * the data to RAMbuffer. This data of length len is then copied to buffer buf. -+ */ -+static void bcm47xx_nflash_read_buf(struct mtd_info *mtd, u_char *buf, int len) -+{ -+ loff_t from = read_offset; -+ int bytes; -+ -+ bcm47xx_nflash_read(mtd, from, len, &bytes, buf); -+} -+ -+/* Used by the upper layer to verify the data in NAND Flash -+ * with the data in the buf. */ -+static int bcm47xx_nflash_verify_buf(struct mtd_info *mtd, -+ const u_char *buf, int len) -+{ -+ return -EFAULT; -+} -+ -+static int bcm47xx_nflash_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) -+{ -+ struct nand_chip *nchip = mtd->priv; -+ struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; -+ int i; -+ uint off; -+ u32 pagesize = 1 << nchip->page_shift; -+ u32 blocksize = mtd->erasesize; -+ -+ if ((ofs >> 20) >= nflash->size) -+ return 1; -+ if ((ofs & (blocksize - 1)) != 0) -+ return 1; -+ -+ for (i = 0; i < 2; i++) { -+ off = ofs + pagesize; -+ bcma_cc_write32(nflash->bcc, NAND_CMD_ADDR, off); -+ bcm47xx_nflash_cmd(nflash->bcc, NCMD_SPARE_RD); -+ if (bcma_nflash_poll(nflash->bcc) < 0) -+ break; -+ if ((bcma_cc_read32(nflash->bcc, NAND_INTFC_STATUS) & NIST_SPARE_VALID) != NIST_SPARE_VALID) -+ return 1; -+ if ((bcma_cc_read32(nflash->bcc, NAND_SPARE_RD0) & 0xff) != 0xff) -+ return 1; -+ } -+ return 0; -+} -+ -+const char *part_probes[] = { "cmdlinepart", NULL }; -+static int bcm47xx_nflash_probe(struct platform_device *pdev) -+{ -+ struct nand_chip *nchip; -+ struct mtd_info *mtd; -+ struct bcm47xx_nflash *nflash = dev_get_platdata(&pdev->dev); -+ int ret = 0; -+ -+ mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); -+ if (!mtd){ -+ ret = -ENOMEM; -+ goto err_out; -+ } -+ -+ nchip = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); -+ if (!nchip) { -+ ret = -ENOMEM; -+ goto err_free_mtd; -+ } -+ -+ /* Register with MTD */ -+ mtd->priv = nchip; -+ mtd->owner = THIS_MODULE; -+ mtd->dev.parent = &pdev->dev; -+ -+ /* 50 us command delay time */ -+ nchip->chip_delay = 50; -+ -+ nchip->priv = nflash; -+ nchip->dev_ready = bcm47xx_nflash_dev_ready; -+ nchip->cmdfunc = bcm47xx_nflash_command; -+ nchip->select_chip = bcm47xx_nflash_select_chip; -+ nchip->read_byte = bcm47xx_nflash_read_byte; -+ nchip->read_word = bcm47xx_nflash_read_word; -+ nchip->write_buf = bcm47xx_nflash_write_buf; -+ nchip->read_buf = bcm47xx_nflash_read_buf; -+ nchip->verify_buf = bcm47xx_nflash_verify_buf; -+ nchip->block_bad = bcm47xx_nflash_block_bad; -+ nchip->options = NAND_SKIP_BBTSCAN; -+ -+ /* Not known */ -+ nchip->ecc.mode = NAND_ECC_NONE; -+ -+ /* first scan to find the device and get the page size */ -+ if (nand_scan_ident(mtd, 1, NULL)) { -+ pr_err("nand_scan_ident failed\n"); -+ ret = -ENXIO; -+ goto err_free_nchip; -+ } -+ nflash->size = mtd->size; -+ nflash->pagesize = 1 << nchip->page_shift; -+ nflash->blocksize = mtd->erasesize; -+ nflash->mtd = mtd; -+ -+ /* second phase scan */ -+ if (nand_scan_tail(mtd)) { -+ pr_err("nand_scan_tail failed\n"); -+ ret = -ENXIO; -+ goto err_free_nchip; -+ } -+ -+ mtd->name = "bcm47xx-nflash"; -+ mtd->flags |= MTD_WRITEABLE; -+ ret = mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0); -+ -+ if (ret) { -+ pr_err("mtd_device_register failed\n"); -+ goto err_free_nchip; -+ } -+ -+ return 0; -+ -+err_free_nchip: -+ kfree(nchip); -+err_free_mtd: -+ kfree(mtd); -+err_out: -+ return ret; -+} -+ -+static int __devexit bcm47xx_nflash_remove(struct platform_device *pdev) -+{ -+ struct bcm47xx_nflash *nflash = dev_get_platdata(&pdev->dev); -+ struct mtd_info *mtd = nflash->mtd; -+ -+ if (nflash) { -+ /* Release resources, unregister device */ -+ nand_release(mtd); -+ kfree(mtd->priv); -+ kfree(mtd); -+ } -+ -+ return 0; -+} -+ -+static const struct platform_device_id bcm47xx_nflash_table[] = { -+ { "bcm47xx-nflash", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(platform, bcm47xx_nflash_table); -+ -+static struct platform_driver bcm47xx_nflash_driver = { -+ .id_table = bcm47xx_nflash_table, -+ .probe = bcm47xx_nflash_probe, -+ .remove = __devexit_p(bcm47xx_nflash_remove), -+ .driver = { -+ .name = "bcm47xx-nflash", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init init_bcm47xx_nflash(void) -+{ -+ int ret = platform_driver_register(&bcm47xx_nflash_driver); -+ -+ if (ret) -+ pr_err("error registering platform driver: %i\n", ret); -+ return ret; -+} -+ -+static void __exit exit_bcm47xx_nflash(void) -+{ -+ platform_driver_unregister(&bcm47xx_nflash_driver); -+} -+ -+module_init(init_bcm47xx_nflash); -+module_exit(exit_bcm47xx_nflash); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("BCM47XX NAND flash driver"); ---- /dev/null -+++ b/include/linux/mtd/bcm47xx_nand.h -@@ -0,0 +1,152 @@ -+/* -+ * Broadcom chipcommon NAND flash interface -+ * -+ * Copyright (C) 2011-2012 Tathagata Das <tathagata@alumnux.com> -+ * Copyright (C) 2009, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ */ -+ -+#ifndef LINUX_MTD_BCM47XX_NAND_H_ -+#define LINUX_MTD_BCM47XX_NAND_H_ -+ -+#include <linux/mtd/mtd.h> -+ -+#define NAND_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ -+ -+/* nand_cmd_start commands */ -+#define NCMD_NULL 0 -+#define NCMD_PAGE_RD 1 -+#define NCMD_SPARE_RD 2 -+#define NCMD_STATUS_RD 3 -+#define NCMD_PAGE_PROG 4 -+#define NCMD_SPARE_PROG 5 -+#define NCMD_COPY_BACK 6 -+#define NCMD_ID_RD 7 -+#define NCMD_BLOCK_ERASE 8 -+#define NCMD_FLASH_RESET 9 -+#define NCMD_LOCK 0xa -+#define NCMD_LOCK_DOWN 0xb -+#define NCMD_UNLOCK 0xc -+#define NCMD_LOCK_STATUS 0xd -+ -+/* nand_acc_control */ -+#define NAC_RD_ECC_EN 0x80000000 -+#define NAC_WR_ECC_EN 0x40000000 -+#define NAC_RD_ECC_BLK0_EN 0x20000000 -+#define NAC_FAST_PGM_RDIN 0x10000000 -+#define NAC_RD_ERASED_ECC_EN 0x08000000 -+#define NAC_PARTIAL_PAGE_EN 0x04000000 -+#define NAC_PAGE_HIT_EN 0x01000000 -+#define NAC_ECC_LEVEL0 0x00f00000 -+#define NAC_ECC_LEVEL 0x000f0000 -+#define NAC_SPARE_SIZE0 0x00003f00 -+#define NAC_SPARE_SIZE 0x0000003f -+ -+/* nand_config */ -+#define NCF_CONFIG_LOCK 0x80000000 -+#define NCF_BLOCK_SIZE_MASK 0x70000000 -+#define NCF_BLOCK_SIZE_SHIFT 28 -+#define NCF_DEVICE_SIZE_MASK 0x0f000000 -+#define NCF_DEVICE_SIZE_SHIFT 24 -+#define NCF_DEVICE_WIDTH 0x00800000 -+#define NCF_PAGE_SIZE_MASK 0x00300000 -+#define NCF_PAGE_SIZE_SHIFT 20 -+#define NCF_FULL_ADDR_BYTES_MASK 0x00070000 -+#define NCF_FULL_ADDR_BYTES_SHIFT 16 -+#define NCF_COL_ADDR_BYTES_MASK 0x00007000 -+#define NCF_COL_ADDR_BYTES_SHIFT 12 -+#define NCF_BLK_ADDR_BYTES_MASK 0x00000700 -+#define NCF_BLK_ADDR_BYTES_SHIFT 8 -+ -+/* nand_intfc_status */ -+#define NIST_CTRL_READY 0x80000000 -+#define NIST_FLASH_READY 0x40000000 -+#define NIST_CACHE_VALID 0x20000000 -+#define NIST_SPARE_VALID 0x10000000 -+#define NIST_ERASED 0x08000000 -+#define NIST_STATUS 0x000000ff -+ -+#define NFL_SECTOR_SIZE 512 -+ -+#define NFL_TABLE_END 0xffffffff -+#define NFL_BOOT_SIZE 0x200000 -+#define NFL_BOOT_OS_SIZE 0x2000000 -+ -+/* Nand flash MLC controller registers (corerev >= 38) */ -+#define NAND_REVISION 0xC00 -+#define NAND_CMD_START 0xC04 -+#define NAND_CMD_ADDR_X 0xC08 -+#define NAND_CMD_ADDR 0xC0C -+#define NAND_CMD_END_ADDR 0xC10 -+#define NAND_CS_NAND_SELECT 0xC14 -+#define NAND_CS_NAND_XOR 0xC18 -+#define NAND_SPARE_RD0 0xC20 -+#define NAND_SPARE_RD4 0xC24 -+#define NAND_SPARE_RD8 0xC28 -+#define NAND_SPARE_RD12 0xC2C -+#define NAND_SPARE_WR0 0xC30 -+#define NAND_SPARE_WR4 0xC34 -+#define NAND_SPARE_WR8 0xC38 -+#define NAND_SPARE_WR12 0xC3C -+#define NAND_ACC_CONTROL 0xC40 -+#define NAND_CONFIG 0xC48 -+#define NAND_TIMING_1 0xC50 -+#define NAND_TIMING_2 0xC54 -+#define NAND_SEMAPHORE 0xC58 -+#define NAND_DEVID 0xC60 -+#define NAND_DEVID_X 0xC64 -+#define NAND_BLOCK_LOCK_STATUS 0xC68 -+#define NAND_INTFC_STATUS 0xC6C -+#define NAND_ECC_CORR_ADDR_X 0xC70 -+#define NAND_ECC_CORR_ADDR 0xC74 -+#define NAND_ECC_UNC_ADDR_X 0xC78 -+#define NAND_ECC_UNC_ADDR 0xC7C -+#define NAND_READ_ERROR_COUNT 0xC80 -+#define NAND_CORR_STAT_THRESHOLD 0xC84 -+#define NAND_READ_ADDR_X 0xC90 -+#define NAND_READ_ADDR 0xC94 -+#define NAND_PAGE_PROGRAM_ADDR_X 0xC98 -+#define NAND_PAGE_PROGRAM_ADDR 0xC9C -+#define NAND_COPY_BACK_ADDR_X 0xCA0 -+#define NAND_COPY_BACK_ADDR 0xCA4 -+#define NAND_BLOCK_ERASE_ADDR_X 0xCA8 -+#define NAND_BLOCK_ERASE_ADDR 0xCAC -+#define NAND_INV_READ_ADDR_X 0xCB0 -+#define NAND_INV_READ_ADDR 0xCB4 -+#define NAND_BLK_WR_PROTECT 0xCC0 -+#define NAND_ACC_CONTROL_CS1 0xCD0 -+#define NAND_CONFIG_CS1 0xCD4 -+#define NAND_TIMING_1_CS1 0xCD8 -+#define NAND_TIMING_2_CS1 0xCDC -+#define NAND_SPARE_RD16 0xD30 -+#define NAND_SPARE_RD20 0xD34 -+#define NAND_SPARE_RD24 0xD38 -+#define NAND_SPARE_RD28 0xD3C -+#define NAND_CACHE_ADDR 0xD40 -+#define NAND_CACHE_DATA 0xD44 -+#define NAND_CTRL_CONFIG 0xD48 -+#define NAND_CTRL_STATUS 0xD4C -+ -+struct bcma_drv_cc; -+ -+struct bcm47xx_nflash { -+ struct bcma_drv_cc *bcc; -+ -+ bool present; -+ bool boot; /* This is the flash the SoC boots from */ -+ u32 blocksize; /* Block size */ -+ u32 pagesize; /* Page size */ -+ -+ u32 size; /* Total size in bytes */ -+ u32 next_opcode; /* Next expected command from upper NAND layer */ -+ -+ struct mtd_info *mtd; -+}; -+ -+#endif /* LINUX_MTD_BCM47XX_NAND_H_ */ |