/* * linux/include/linux/mtd/nand.h * * Copyright (c) 2000 David Woodhouse * Steven J. Hill * Thomas Gleixner * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Info: * Contains standard defines and IDs for NAND flash devices * * Changelog: * See git changelog. */ #ifndef __LINUX_MTD_NAND_H #define __LINUX_MTD_NAND_H #include #include #define NAND_K9F2G08 0xecda /* This constant declares the max. oobsize / page, which * is supported now. If you add a chip with bigger oobsize/page * adjust this accordingly. */ #define NAND_MAX_OOBSIZE 218 #define NAND_MAX_PAGESIZE 4096 /* * Constants for hardware specific CLE/ALE/NCE function * * These are bits which can be or'ed to set/clear multiple * bits in one go. */ /* Select the chip by setting nCE to low */ #define NAND_NCE 0x01 /* Select the command latch by setting CLE to high */ #define NAND_CLE 0x02 /* Select the address latch by setting ALE to high */ #define NAND_ALE 0x04 #define NAND_CTRL_CLE (NAND_NCE | NAND_CLE) #define NAND_CTRL_ALE (NAND_NCE | NAND_ALE) #define NAND_CTRL_CHANGE 0x80 /* * Standard NAND flash commands */ #define NAND_CMD_READ0 0x00 /*Page read period 1*/ #define NAND_CMD_READSTART 0x30 /*Page read period 2, for large page*/ #define NAND_CMD_READID 0x90 /*Read production ID*/ #define NAND_CMD_SEQIN 0x80 /*Page write period 1*/ #define NAND_CMD_PAGEPROG 0x10 /*Page write period 2*/ #define NAND_CMD_ERASE1 0x60 /*Block erase period 1*/ #define NAND_CMD_ERASE2 0xd0 /*Block erase period 2*/ #define NAND_CMD_STATUS 0x70 /*Read status command*/ #define NAND_CMD_RESET 0xff /*Nandflash reset command*/ #define NAND_CMD_READ1 1 #define NAND_CMD_RNDOUT 0x05 /*Page random read period 1*/ #define NAND_CMD_RNDOUTSTART 0xE0 /*Page random read period 2*/ #define NAND_CMD_RNDIN 0x85 /*Page random write*/ #define NAND_CMD_READOOB 0x50 #define NAND_CMD_STATUS_MULTI 0x71 /* Extended commands for large page devices */ #define NAND_CMD_CACHEDPROG 0x15 /* Extended commands for AG-AND device */ /* * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but * there is no way to distinguish that from NAND_CMD_READ0 * until the remaining sequence of commands has been completed * so add a high order bit and mask it off in the command. */ #define NAND_CMD_DEPLETE1 0x100 #define NAND_CMD_DEPLETE2 0x38 #define NAND_CMD_STATUS_MULTI 0x71 #define NAND_CMD_STATUS_ERROR 0x72 /* multi-bank error status (banks 0-3) */ #define NAND_CMD_STATUS_ERROR0 0x73 #define NAND_CMD_STATUS_ERROR1 0x74 #define NAND_CMD_STATUS_ERROR2 0x75 #define NAND_CMD_STATUS_ERROR3 0x76 #define NAND_CMD_STATUS_RESET 0x7f #define NAND_CMD_STATUS_CLEAR 0xff #define NAND_CMD_NONE -1 /* Status bits */ #define NAND_STATUS_FAIL 0x01 #define NAND_STATUS_FAIL_N1 0x02 #define NAND_STATUS_TRUE_READY 0x20 #define NAND_STATUS_READY 0x40 #define NAND_STATUS_WP 0x80 /* * Constants for ECC_MODES */ typedef enum { NAND_ECC_NONE, NAND_ECC_SOFT, NAND_ECC_HW, NAND_ECC_HW_SYNDROME, NAND_ECC_HW_OOB_FIRST, } nand_ecc_modes_t; /* * Constants for Hardware ECC */ /* Reset Hardware ECC for read */ #define NAND_ECC_READ 0 /* Reset Hardware ECC for write */ #define NAND_ECC_WRITE 1 /* Enable Hardware ECC before syndrom is read back from flash */ #define NAND_ECC_READSYN 2 /* Bit mask for flags passed to do_nand_read_ecc */ #define NAND_GET_DEVICE 0x80 /* Option constants for bizarre disfunctionality and real * features */ /* Chip can not auto increment pages */ #define NAND_NO_AUTOINCR 0x00000001 /* Buswitdh is 16 bit */ #define NAND_BUSWIDTH_16 0x00000002 /* Device supports partial programming without padding */ #define NAND_NO_PADDING 0x00000004 /* Chip has cache program function */ #define NAND_CACHEPRG 0x00000008 /* Chip has copy back function */ #define NAND_COPYBACK 0x00000010 /* AND Chip which has 4 banks and a confusing page / block * assignment. See Renesas datasheet for further information */ #define NAND_IS_AND 0x00000020 /* Chip has a array of 4 pages which can be read without * additional ready /busy waits */ #define NAND_4PAGE_ARRAY 0x00000040 /* Chip requires that BBT is periodically rewritten to prevent * bits from adjacent blocks from 'leaking' in altering data. * This happens with the Renesas AG-AND chips, possibly others. */ #define BBT_AUTO_REFRESH 0x00000080 /* Chip does not require ready check on read. True * for all large page devices, as they do not support * autoincrement.*/ #define NAND_NO_READRDY 0x00000100 /* Chip does not allow subpage writes */ #define NAND_NO_SUBPAGE_WRITE 0x00000200 /* Options valid for Samsung large page devices */ #define NAND_SAMSUNG_LP_OPTIONS \ (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK) /* Macros to identify the above */ #define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR)) #define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING)) #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) #define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK)) /* Large page NAND with SOFT_ECC should support subpage reads */ #define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \ && (chip->page_shift > 9)) /* Mask to zero out the chip options, which come from the id table */ #define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR) /* Non chip related options */ /* Use a flash based bad block table. This option is passed to the * default bad block table function. */ #define NAND_USE_FLASH_BBT 0x00010000 /* This option skips the bbt scan during initialization. */ #define NAND_SKIP_BBTSCAN 0x00020000 /* This option is defined if the board driver allocates its own buffers (e.g. because it needs them DMA-coherent */ #define NAND_OWN_BUFFERS 0x00040000 /* Options set by nand scan */ /* bbt has already been read */ #define NAND_BBT_SCANNED 0x40000000 /* Nand scan has allocated controller struct */ #define NAND_CONTROLLER_ALLOC 0x80000000 /* Cell info constants */ #define NAND_CI_CHIPNR_MSK 0x03 #define NAND_CI_CELLTYPE_MSK 0x0C /* * NAND Flash Manufacturer ID Codes */ #define NAND_MFR_TOSHIBA 0x98 #define NAND_MFR_SAMSUNG 0xec #define NAND_MFR_FUJITSU 0x04 #define NAND_MFR_NATIONAL 0x8f #define NAND_MFR_RENESAS 0x07 #define NAND_MFR_STMICRO 0x20 #define NAND_MFR_HYNIX 0xad #define NAND_MFR_MICRON 0x2c #define NAND_MFR_AMD 0x01 /* * Constants for oob configuration */ #define NAND_SMALL_BADBLOCK_POS 5 #define NAND_LARGE_BADBLOCK_POS 0 #if defined(CONFIG_S3C2410) #define REG_NFCONF __REGi(ELFIN_NAND_BASE + 0x0) #define REG_NFCMD __REGb(ELFIN_NAND_BASE + 0x4) #define REG_NFADDR __REGb(ELFIN_NAND_BASE + 0x8) #define REG_NFDATA __REGb(ELFIN_NAND_BASE + 0xc) #define REG_NFSTAT __REGb(ELFIN_NAND_BASE + 0x10) #define NFSTAT_BUSY 1 #define nand_select() (REG_NFCONF &= ~0x800) /*Clear bit 11*/ #define nand_deselect() (REG_NFCONF |= 0x800) #define nand_clear_RnB() do {} while (0) #define nand_detect_RnB() do {} while (0) #define nand_wait_RnB() do {} while (0) #elif defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442) #define REG_NFCONF __REGi(ELFIN_NAND_BASE + 0x0) #define REG_NFCONT __REGi(ELFIN_NAND_BASE + 0x4) #define REG_NFCMD __REGb(ELFIN_NAND_BASE + 0x8) #define REG_NFADDR __REGb(ELFIN_NAND_BASE + 0xc) #define REG_NFDATA __REGb(ELFIN_NAND_BASE + 0x10) #define REG_NFDATA16 __REGw(ELFIN_NAND_BASE + 0x10) #define REG_NFSTAT __REGb(ELFIN_NAND_BASE + 0x20) #define NFSTAT_BUSY 1 #define nand_select() (REG_NFCONT &= ~(1 << 1)) #define nand_deselect() (REG_NFCONT |= (1 << 1)) #define nand_clear_RnB() (REG_NFSTAT |= (1 << 2)) #define nand_detect_RnB() {while(!(REG_NFSTAT&(1<<2)));} /*Wait Read & Busy signal goto high(not busy)*/ #define nand_wait_RnB() {while(!(REG_NFSTAT&(1<<0)));} /*Wait nand flash not busy, wait bit[0] goes to 1*/ #endif #define SKIP_BAD_BLOCK 1 #define NOT_SKIP_BAD_BLOCK 0 struct boot_nand_t { int page_size; int spare_size; int block_size; int block_num; int bad_block_offset; int id; // unsigned long size; }; int nand_init(struct boot_nand_t *nand); int nand_read_page(struct boot_nand_t *nand, ulong page_num, ulong offset, char *data, ulong size); int nand_write_page(struct boot_nand_t *nand, ulong page_num, ulong offset, char *data, ulong size); int is_bad_block(struct boot_nand_t *nand, ulong addr); int mark_bad_block(struct boot_nand_t *nand, ulong addr); int nand_erase_block(struct boot_nand_t *nand, ulong block_num); int nand_erase(struct boot_nand_t *nand, ulong start_addr, ulong size, int skip_bad); void nand_scrub(struct boot_nand_t *nand); int nand_read_spare(struct boot_nand_t *nand, ulong page_addr, int size, char *buf); int nand_write_spare(struct boot_nand_t *nand, ulong page_addr, int size, char *buf); int nand_read(struct boot_nand_t *nand, ulong start_addr, ulong size, char *buf); int nand_write(struct boot_nand_t *nand, ulong start_addr, ulong size, char *buf); #endif /* __LINUX_MTD_NAND_H */