From: Kuo-Jung Su <dant...@faraday-tech.com> Faraday FTNANDC021 is a integrated NAND flash controller. It use a build-in command table to abstract the underlying NAND flash control logic.
For example: Issuing a command 0x10 to FTNANDC021 would result in a page write + a read status operation. Signed-off-by: Kuo-Jung Su <dant...@faraday-tech.com> --- drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/ftnandc021.c | 550 +++++++++++++++++++++++++++++++++++++++++ drivers/mtd/nand/ftnandc021.h | 165 +++++++++++++ 3 files changed, 716 insertions(+) create mode 100644 drivers/mtd/nand/ftnandc021.c create mode 100644 drivers/mtd/nand/ftnandc021.h diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index c77c0c4..16b5016 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -63,6 +63,7 @@ COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o COBJS-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o COBJS-$(CONFIG_NAND_FSMC) += fsmc_nand.o +COBJS-$(CONFIG_NAND_FTNANDC021) += ftnandc021.o COBJS-$(CONFIG_NAND_JZ4740) += jz4740_nand.o COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o diff --git a/drivers/mtd/nand/ftnandc021.c b/drivers/mtd/nand/ftnandc021.c new file mode 100644 index 0000000..095206a --- /dev/null +++ b/drivers/mtd/nand/ftnandc021.c @@ -0,0 +1,550 @@ +/* + * Faraday NAND Flash Controller + * + * (C) Copyright 2010 Faraday Technology + * Dante Su <dant...@faraday-tech.com> + * + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + */ + +#include <common.h> +#include <nand.h> +#include <malloc.h> + +#include "ftnandc021.h" + +/* common bitmask of nand flash status register */ +#define NAND_IOSTATUS_ERROR BIT(0) +#define NAND_IOSTATUS_READY BIT(6) +#define NAND_IOSTATUS_UNPROTCT BIT(7) + +struct ftnandc021_chip { + void *iobase; + unsigned int cmd; + + unsigned int pgidx; + + unsigned int off; + uint8_t buf[256]; + + unsigned int adrc; /* address cycle */ + unsigned int pgsz; /* page size */ + unsigned int bksz; /* block size */ +}; + +/* Register access macros */ +#define NAND_REG32(priv, off) \ + *(volatile uint32_t *)((uint32_t)((priv)->iobase) + (off)) + +static struct nand_ecclayout ftnandc021_oob_2k = { + .eccbytes = 24, + .eccpos = { + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63 + }, + .oobfree = { + { + .offset = 9, + .length = 3 + } + } +}; + +static int +ftnandc021_reset(struct nand_chip *chip) +{ + struct ftnandc021_chip *priv = chip->priv; + uint32_t bk = 2; /* 64 pages */ + uint32_t pg = 1; /* 2k */ + uint32_t ac = 2; /* 5 */ + uint32_t mask = NANDC_NANDC_SW_RESET | NANDC_BMC_SW_RESET | NANDC_ECC_SW_RESET; + +#ifdef CONFIG_FTNANDC021_ACTIMING_1 + NAND_REG32(priv, REG_AC1_CONTROL) = CONFIG_FTNANDC021_ACTIMING_1; +#endif +#ifdef CONFIG_FTNANDC021_ACTIMING_2 + NAND_REG32(priv, REG_AC2_CONTROL) = CONFIG_FTNANDC021_ACTIMING_2; +#endif + + NAND_REG32(priv, REG_INT_EN) = 0; + NAND_REG32(priv, REG_PAGE_INDEX) = 0; + NAND_REG32(priv, REG_WRITE_BI) = 0xff; + NAND_REG32(priv, REG_WRITE_LSN_CRC) = 0xffffffff; + if (chip->options & NAND_BUSWIDTH_16) + NAND_REG32(priv, REG_FLOW_CONTROL) = BIT(8) | BIT(7) | NANDC_IO_WIDTH_16BIT; + else + NAND_REG32(priv, REG_FLOW_CONTROL) = BIT(8) | BIT(7) | NANDC_IO_WIDTH_8BIT; + + /* chip reset */ + NAND_REG32(priv, REG_MLC_SW_RESET) = mask; + + /* wait until chip ready */ + while (NAND_REG32(priv, REG_MLC_SW_RESET) & BIT(0)) + ; + + switch (priv->bksz / priv->pgsz) { + case 16: + bk = 0; + break; + case 32: + bk = 1; + break; + case 64: + bk = 2; + break; + case 128: + bk = 3; + break; + } + + switch (priv->pgsz) { + case 512: + pg = 0; + break; + case 2048: + pg = 1; + break; + case 4096: + pg = 2; + break; + } + + switch (priv->adrc) { + case 3: + ac = 0; + break; + case 4: + ac = 1; + break; + case 5: + ac = 2; + break; + } + + NAND_REG32(priv, REG_MEMORY_CONFIG) = NANDC_MS_32GB | NANDC_MOD0_ENABLE + | (bk << 16) | (pg << 8) | (ac << 10); + + /* PIO mode */ + NAND_REG32(priv, REG_BMC_PIO_MODE_READY) = 0; + + return 0; +} + +static inline int +ftnandc021_ckst(struct ftnandc021_chip *priv) +{ + uint32_t st = NAND_REG32(priv, REG_DEV_ID_BYTE47); + + if (st & NAND_IOSTATUS_ERROR) + return -NAND_IOSTATUS_ERROR; + + if (!(st & NAND_IOSTATUS_READY)) + return -NAND_IOSTATUS_READY; + + if (!(st & NAND_IOSTATUS_UNPROTCT)) + return -NAND_IOSTATUS_UNPROTCT; + + return 0; +} + +static inline int +ftnandc021_wait(struct ftnandc021_chip *priv) +{ + uint32_t t; + int rc = -1; + + for (t = get_timer(0); get_timer(t) < 200; ) { + if (!(NAND_REG32(priv, REG_ACCESS_CONTROL) & NANDC_CMD_LAUNCH)) { + rc = 0; + break; + } + } + + return rc; +} + +static int +ftnandc021_command(struct ftnandc021_chip *priv, uint32_t cmd) +{ + int rc = 0; + + NAND_REG32(priv, REG_ACCESS_CONTROL) = NANDC_CMD_LAUNCH | (cmd << NANDC_CMD_OFFSET); + + /* + * pgread : (We have queued data at the IO port) + * pgwrite : nand_ckst (We have queued data at the IO port) + * bkerase : nand_wait + nand_ckst + * oobwr : nand_wait + nand_ckst + * otherwise : nand_wait + */ + switch (cmd) { + case NANDC_CMD_PAGE_READ: + break; + case NANDC_CMD_PAGE_WRITE_RS: + rc = ftnandc021_ckst(priv); + break; + case NANDC_CMD_BLK_ERASE_RS: + case NANDC_CMD_SPARE_WRITE_RS: + rc = ftnandc021_wait(priv) || ftnandc021_ckst(priv); + break; + default: + rc = ftnandc021_wait(priv); + } + + return rc; +} + +/* + * Check hardware register for wait status. Returns 1 if device is ready, + * 0 if it is still busy. + */ +static int +ftnandc021_dev_ready(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + struct ftnandc021_chip *priv = chip->priv; + int rc = 1; + + if (ftnandc021_wait(priv) || ftnandc021_ckst(priv)) + rc = 0; + + return rc; +} + +static void +ftnandc021_read_oob(struct mtd_info *mtd, uint8_t * buf, int len) +{ + struct nand_chip *chip = mtd->priv; + struct ftnandc021_chip *priv = chip->priv; + uint32_t tmp; + + /* + * Bad Block Information: + * 1. Large Page(2048, 4096): off=0, len=2 + * 2. Small Page(512): off=5, len=1 + */ + buf[0] = NAND_REG32(priv, REG_READ_BI) & 0xFF; + buf[1] = 0xFF; + + tmp = NAND_REG32(priv, REG_READ_LSN_CRC); + buf[8] = (tmp >> 0) & 0xFF; + buf[9] = (tmp >> 8) & 0xFF; + if (mtd->writesize >= 4096) { + buf[12] = (tmp >> 16) & 0xFF; + buf[13] = (tmp >> 24) & 0xFF; + } + + tmp = NAND_REG32(priv, REG_READ_LSN); + buf[10] = (tmp >> 0) & 0xFF; + buf[11] = (tmp >> 8) & 0xFF; + if (mtd->writesize >= 4096) { + buf[14] = (tmp >> 16) & 0xFF; + buf[15] = (tmp >> 24) & 0xFF; + } +} + +static void +ftnandc021_write_oob(struct mtd_info *mtd, const uint8_t * buf, int len) +{ + struct nand_chip *chip = mtd->priv; + struct ftnandc021_chip *priv = chip->priv; + uint32_t tmp; + + NAND_REG32(priv, REG_WRITE_BI) = buf[0]; + + tmp = buf[8] | (buf[9] << 8); + if (mtd->writesize >= 4096) + tmp |= (buf[12] << 16) | (buf[13] << 24); + NAND_REG32(priv, REG_WRITE_LSN_CRC) = tmp; + + tmp = buf[10] | (buf[11] << 8); + if (mtd->writesize >= 4096) + tmp |= (buf[14] << 16) | (buf[15] << 24); + NAND_REG32(priv, REG_LSN_CONTROL) = tmp; +} + +static uint8_t +ftnandc021_read_byte(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + struct ftnandc021_chip *priv = chip->priv; + uint8_t rc = 0xFF; + + switch (priv->cmd) { + case NAND_CMD_READID: + case NAND_CMD_READOOB: + rc = priv->buf[priv->off % 256]; + priv->off += 1; + break; + case NAND_CMD_STATUS: + rc = (uint8_t)(NAND_REG32(priv, REG_DEV_ID_BYTE47) & 0xFF); + break; + default: + printf("ftnandc021_read_byte...not supported cmd(0x%02X)!?\n", priv->cmd); + break; + } + + return rc; +} + +static uint16_t +ftnandc021_read_word(struct mtd_info *mtd) +{ + uint16_t rc = 0xFFFF; + uint8_t *buf = (uint8_t *)&rc; + + buf[0] = ftnandc021_read_byte(mtd); + buf[1] = ftnandc021_read_byte(mtd); + + return rc; +} + +/** + * Read data from NAND controller into buffer + * @mtd: MTD device structure + * @buf: buffer to store date + * @len: number of bytes to read + */ +static void +ftnandc021_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ + struct nand_chip *chip = mtd->priv; + struct ftnandc021_chip *priv = chip->priv; + uint32_t off; + + if ((uint32_t)buf & 0x03) { + printf("ftnandc021_read_buf: buf@0x%08X is not aligned\n", (uint32_t)buf); + return; + } + + /* oob read */ + if (len <= mtd->oobsize) { + ftnandc021_read_oob(mtd, buf, len); + return; + } + + /* page read */ + for (off = 0; len > 0; len -= 4, off += 4) { + ulong ts = get_timer(0); + do { + if (NAND_REG32(priv, 0x208) & BIT(0)) + break; + } while (get_timer(ts) < CONFIG_SYS_HZ); + + if (!(NAND_REG32(priv, 0x208) & BIT(0))) { + printf("ftnandc021_read_buf: data timeout (cmd=0x%02X)\n", priv->cmd); + return; + } + *(uint32_t *)(buf + off) = NAND_REG32(priv, REG_BMC_DATA_PORT); + } + + if (ftnandc021_wait(priv)) + printf("ftnandc021_read_buf: command timeout (cmd=0x%02X)\n", priv->cmd); +} + +/** + * Write buffer to NAND controller + * @mtd: MTD device structure + * @buf: data buffer + * @len: number of bytes to write + */ +static void +ftnandc021_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) +{ + struct nand_chip *chip = mtd->priv; + struct ftnandc021_chip *priv = chip->priv; + uint32_t off; + + if ((uint32_t)buf & 0x03) { + printf("ftnandc021_write_buf: buf@0x%08X is not aligned\n", (uint32_t)buf); + return; + } + + /* 1. oob write */ + if (len <= mtd->oobsize) + return; + + /* 2. page write */ + for (off = 0; len > 0; len -= 4, off += 4) { + while (!(NAND_REG32(priv, 0x208) & BIT(0))) + ; + NAND_REG32(priv, REG_BMC_DATA_PORT) = *(uint32_t *)(buf + off); + } + + /* 3. wait until command finish */ + if (ftnandc021_wait(priv)) + printf("ftnandc021_write_buf: write fail\n"); +} + +/** + * Verify chip data against buffer + * @mtd: MTD device structure + * @buf: buffer containing the data to compare + * @len: number of bytes to compare + */ +static int +ftnandc021_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) +{ + int rc = 0; + uint8_t *tmp; + + len = min_t(int, len, mtd->writesize); + tmp = malloc(mtd->writesize); + + if (tmp == NULL) { + printf("ftnandc021_verify_buf: out of memory\n"); + return -1; + } else { + ftnandc021_read_buf(mtd, tmp, len); + if (memcmp(tmp, buf, len)) + rc = -2; + } + + free(tmp); + + if (rc) + printf("ftnandc021_verify_buf...failed (buf@%p, len=%d)\n", buf, len); + + return rc; +} + +static void +ftnandc021_cmdfunc(struct mtd_info *mtd, unsigned cmd, int column, int pgidx) +{ + struct nand_chip *chip = mtd->priv; + struct ftnandc021_chip *priv = chip->priv; + + priv->cmd = cmd; + priv->pgidx = pgidx; + + switch (cmd) { + case NAND_CMD_READID: /* 0x90 */ + if (ftnandc021_command(priv, NANDC_CMD_READ_ID)) { + printf("ftnandc021_cmdfunc: RDID failed.\n"); + } else { + uint32_t tmp; + tmp = NAND_REG32(priv, REG_DEV_ID_BYTE03); + memcpy(priv->buf + 0, &tmp, 4); + tmp = NAND_REG32(priv, REG_DEV_ID_BYTE47); + memcpy(priv->buf + 4, &tmp, 4); + priv->off = 0; + } + break; + + case NAND_CMD_READ0: /* 0x00 */ + NAND_REG32(priv, REG_PAGE_INDEX) = pgidx; + NAND_REG32(priv, REG_PAGE_COUNT) = 1; + if (ftnandc021_command(priv, NANDC_CMD_PAGE_READ)) + printf("ftnandc021_cmdfunc: PGREAD failed.\n"); + break; + + case NAND_CMD_READOOB: /* 0x50 */ + NAND_REG32(priv, REG_PAGE_INDEX) = pgidx; + NAND_REG32(priv, REG_PAGE_COUNT) = 1; + if (ftnandc021_command(priv, NANDC_CMD_SPARE_READ)) { + printf("ftnandc021_cmdfunc: OOBREAD failed.\n"); + } else { + ftnandc021_read_oob(mtd, priv->buf, mtd->oobsize); + priv->off = 0; + } + break; + + case NAND_CMD_ERASE1: /* 0x60 */ + NAND_REG32(priv, REG_PAGE_INDEX) = pgidx; + NAND_REG32(priv, REG_PAGE_COUNT) = 1; + break; + + case NAND_CMD_ERASE2: /* 0xD0 */ + if (ftnandc021_command(priv, NANDC_CMD_BLK_ERASE_RS)) + printf("ftnandc021_cmdfunc: ERASE failed, pgidx=%d\n", pgidx); + break; + + case NAND_CMD_STATUS: /* 0x70 */ + if (ftnandc021_command(priv, NANDC_CMD_READ_STS)) + printf("ftnandc021_cmdfunc: STREAD failed.\n"); + break; + + case NAND_CMD_SEQIN: /* 0x80 (Write Stage 1.) */ + ftnandc021_write_oob(mtd, chip->oob_poi, mtd->writesize); + + NAND_REG32(priv, REG_PAGE_INDEX) = pgidx; + NAND_REG32(priv, REG_PAGE_COUNT) = 1; + if (column >= mtd->writesize) { + if (ftnandc021_command(priv, NANDC_CMD_SPARE_WRITE_RS)) + printf("ftnandc021_cmdfunc: oob write failed..\n"); + } else { + if (ftnandc021_command(priv, NANDC_CMD_PAGE_WRITE_RS)) + printf("ftnandc021_cmdfunc: page write failed..\n"); + } + break; + + case NAND_CMD_PAGEPROG: /* 0x10 (Write Stage 2.) */ + break; + + case NAND_CMD_RESET: /* 0xFF */ + if (ftnandc021_command(priv, NANDC_CMD_RESET)) + printf("ftnandc021_cmdfunc: RESET failed.\n"); + break; + + default: + printf("ftnandc021_cmdfunc: error, unsupported command (0x%x).\n", cmd); + } +} + +/** + * hardware specific access to control-lines + * @mtd: MTD device structure + * @cmd: command to device + * @ctrl: + * NAND_NCE: bit 0 -> don't care + * NAND_CLE: bit 1 -> Command Latch + * NAND_ALE: bit 2 -> Address Latch + * + * NOTE: boards may use different bits for these!! + */ +static void +ftnandc021_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ +} + +int +ftnandc021_probe(struct nand_chip *chip) +{ + struct ftnandc021_chip *priv; + + priv = malloc(sizeof(struct ftnandc021_chip)); + if (!priv) + return -1; + + memset(priv, 0, sizeof(*priv)); + priv->iobase = (void *)CONFIG_NAND_FTNANDC021_BASE; + priv->adrc = (unsigned int)chip->priv; + priv->pgsz = 1 << chip->page_shift; + priv->bksz = 1 << chip->phys_erase_shift; + + chip->priv = priv; + chip->cmd_ctrl = ftnandc021_hwcontrol; + chip->cmdfunc = ftnandc021_cmdfunc; + chip->dev_ready = ftnandc021_dev_ready; + chip->chip_delay = 0; + + chip->read_byte = ftnandc021_read_byte; + chip->read_word = ftnandc021_read_word; + chip->read_buf = ftnandc021_read_buf; + chip->write_buf = ftnandc021_write_buf; + chip->verify_buf = ftnandc021_verify_buf; + + chip->ecc.mode = NAND_ECC_NONE; + chip->ecc.layout = &ftnandc021_oob_2k; + + chip->options |= NAND_NO_AUTOINCR; + + ftnandc021_reset(chip); + + debug("ftnandc021: pg=%dK, bk=%dK, adrc=%d\n", + priv->pgsz >> 10, priv->bksz >> 10, priv->adrc); + + return 0; +} diff --git a/drivers/mtd/nand/ftnandc021.h b/drivers/mtd/nand/ftnandc021.h new file mode 100644 index 0000000..cf5d955 --- /dev/null +++ b/drivers/mtd/nand/ftnandc021.h @@ -0,0 +1,165 @@ +/* + * Faraday NAND Flash Controller + * + * (C) Copyright 2010 Faraday Technology + * Dante Su <dant...@faraday-tech.com> + * + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + */ + +#ifndef __FTNANDC021_H +#define __FTNANDC021_H + +#ifndef BIT +#define BIT(nr) (1UL << (nr)) +#endif + +/* SMC Register Offset Definitions */ +/** ECC control register **/ +#define REG_ECC_PARITY0 0x00 +#define REG_ECC_PARITY1 0x04 +#define REG_ECC_PARITY2 0x08 +#define REG_ECC_PARITY3 0x0C +#define REG_ECC_STATUS 0x10 + +/** NANDC control register **/ +#define REG_HOST_STATUS 0x100 +#define REG_ACCESS_CONTROL 0x104 +#define REG_FLOW_CONTROL 0x108 +#define REG_PAGE_INDEX 0x10C +#define REG_MEMORY_CONFIG 0x110 +#define REG_AC1_CONTROL 0x114 +#define REG_AC2_CONTROL 0x118 +#define REG_TARGET_PAGE_INDEX 0x11C +#define REG_DEV_ID_BYTE03 0x120 +#define REG_DEV_ID_BYTE47 0x124 +#define REG_INT_EN 0x128 +#define REG_INT_STS_CLEAR 0x12C +#define REG_FLASH0_BLK_OFFSET 0x130 +#define REG_FLASH1_BLK_OFFSET 0x134 +#define REG_FLASH2_BLK_OFFSET 0x138 +#define REG_FLASH3_BLK_OFFSET 0x13C +#define REG_WRITE_BI 0x140 +#define REG_WRITE_LSN 0x144 +#define REG_WRITE_LSN_CRC 0x148 +#define REG_LSN_CONTROL 0x14C +#define REG_READ_BI 0x150 +#define REG_READ_LSN 0x154 +#define REG_READ_LSN_CRC 0x158 + +#define REG_F0_CB_TGT_BLK_OFFSET 0x160 +#define REG_F1_CB_TGT_BLK_OFFSET 0x164 +#define REG_F2_CB_TGT_BLK_OFFSET 0x168 +#define REG_F3_CB_TGT_BLK_OFFSET 0x16c + +#define REG_F0_LSN_INIT 0x170 +#define REG_F1_LSN_INIT 0x174 +#define REG_F2_LSN_INIT 0x178 +#define REG_F3_LSN_INIT 0x17C + +/** BMC control register **/ +#define REG_BMC_INT 0x204 +#define REG_BMC_BURST_TX_MODE 0x208 +#define REG_BMC_PIO_MODE_READY 0x20C + +/** MISC register **/ +#define REG_BMC_DATA_PORT 0x300 +#define REG_MLC_INT_CONTROL 0x304 +#define REG_PAGE_COUNT 0x308 +#define REG_MLC_SW_RESET 0x30C +#define REG_REVISION 0x3F8 +#define REG_CONFIGURATION 0x3FC + + +#define NANDC_MLC_ECC_EN BIT(8) +#define NANDC_NANDC_SW_RESET BIT(2) +#define NANDC_BMC_SW_RESET BIT(1) +#define NANDC_ECC_SW_RESET BIT(0) + +/* 0x10: ECC status register */ +#define NANDC_ECC_CORR_FAIL BIT(3) +#define NANDC_ECC_ERR_OCCUR BIT(2) +#define NANDC_ECC_DEC_CP BIT(1) +#define NANDC_ECC_ENC_CP BIT(0) + +/* 0x100: NAND flash host controller status register */ +#define NANDC_BLANK_CHECK_FAIL BIT(7) +#define NANDC_ECC_FAIL_TIMEOUT BIT(5) +#define NANDC_STS_FAIL BIT(4) +#define NANDC_LSN_CRC_FAIL BIT(3) +#define NANDC_CMD_CP BIT(2) +#define NANDC_BUSY BIT(1) +#define NANDC_CHIP_ENABLE BIT(0) + +/* 0x104: Access control register */ +#define NANDC_CMD_READ_ID 1 +#define NANDC_CMD_RESET 2 +#define NANDC_CMD_READ_STS 4 +#define NANDC_CMD_READ_EDC_STS 11 +#define NANDC_CMD_PAGE_READ 5 +#define NANDC_CMD_SPARE_READ 6 +#define NANDC_CMD_BLANK_CHK 28 +#define NANDC_CMD_PAGE_WRITE_RS 16 +#define NANDC_CMD_BLK_ERASE_RS 17 +#define NANDC_CMD_COPY_BACK_RS 18 +#define NANDC_CMD_SPARE_WRITE_RS 19 +#define NANDC_CMD_2P_PAGE_WRITE_RS 24 +#define NANDC_CMD_2P_BLK_ERASE_RS 25 +#define NANDC_CMD_2P_COPY_BACK_RS 26 +#ifdef FLASH_PAGE_4K +#define NANDC_CMD_SPARE_READALL 14 +#endif + +#define NANDC_CMD_OFFSET 8 + +#define NANDC_CMD_LAUNCH BIT(7) + +/* 0x108: Flow control register */ +#define NANDC_IO_WIDTH_16BIT BIT(4) +#define NANDC_WP BIT(3) +#define NANDC_PASS_STATUS_CHK_FAIL BIT(2) +#define NANDC_MICRON_CMD BIT(1) +#define NANDC_SKIP_ZERO_BLANK_CHK BIT(0) +#define NANDC_IO_WIDTH_8BIT 0 + +/* 0x110: Memory module configuration register */ +#define NANDC_BS_16P 0 +#define NANDC_BS_32P (1 << 16) +#define NANDC_BS_64P (2 << 16) +#define NANDC_BS_128P (3 << 16) + +#define NANDC_MA_SINGLE 0 +#define NANDC_MA_TWO_PLANE (1 << 14) + +#define NANDC_IT_NI 0 +#define NANDC_IT_TWO (1 << 12) +#define NANDC_IT_FOUR (2 << 12) + +#define NANDC_AP_3C 0 +#define NANDC_AP_4C (1 << 10) +#define NANDC_AP_5C (2 << 10) + +#define NANDC_PS_512 0 +#define NANDC_PS_2K (1 << 8) +#define NANDC_PS_4K (2 << 8) + +#define NANDC_MS_16MB 0 +#define NANDC_MS_32MB (1 << 4) +#define NANDC_MS_64MB (2 << 4) +#define NANDC_MS_128MB (3 << 4) +#define NANDC_MS_256MB (4 << 4) +#define NANDC_MS_512MB (5 << 4) +#define NANDC_MS_1GB (6 << 4) +#define NANDC_MS_2GB (7 << 4) +#define NANDC_MS_4GB (8 << 4) +#define NANDC_MS_8GB (9 << 4) +#define NANDC_MS_16GB (10 << 4) +#define NANDC_MS_32GB (11 << 4) + +#define NANDC_MOD0_ENABLE BIT(0) +#define NANDC_MOD1_ENABLE BIT(1) +#define NANDC_MOD2_ENABLE BIT(2) +#define NANDC_MOD3_ENABLE BIT(3) + +#endif /* EOF */ -- 1.7.9.5 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot