diff options
Diffstat (limited to 'include/linux/mtd/nand.h')
-rw-r--r-- | include/linux/mtd/nand.h | 83 |
1 files changed, 78 insertions, 5 deletions
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index ab6363443ce8..ac8e89d5a792 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -56,7 +56,7 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); * is supported now. If you add a chip with bigger oobsize/page * adjust this accordingly. */ -#define NAND_MAX_OOBSIZE 640 +#define NAND_MAX_OOBSIZE 744 #define NAND_MAX_PAGESIZE 8192 /* @@ -202,6 +202,10 @@ typedef enum { /* Keep gcc happy */ struct nand_chip; +/* ONFI features */ +#define ONFI_FEATURE_16_BIT_BUS (1 << 0) +#define ONFI_FEATURE_EXT_PARAM_PAGE (1 << 7) + /* ONFI timing mode, used in both asynchronous and synchronous mode */ #define ONFI_TIMING_MODE_0 (1 << 0) #define ONFI_TIMING_MODE_1 (1 << 1) @@ -217,6 +221,9 @@ struct nand_chip; /* ONFI subfeature parameters length */ #define ONFI_SUBFEATURE_PARAM_LEN 4 +/* ONFI optional commands SET/GET FEATURES supported? */ +#define ONFI_OPT_CMD_SET_GET_FEATURES (1 << 2) + struct nand_onfi_params { /* rev info and features block */ /* 'O' 'N' 'F' 'I' */ @@ -224,7 +231,10 @@ struct nand_onfi_params { __le16 revision; __le16 features; __le16 opt_cmd; - u8 reserved[22]; + u8 reserved0[2]; + __le16 ext_param_page_length; /* since ONFI 2.1 */ + u8 num_of_param_pages; /* since ONFI 2.1 */ + u8 reserved1[17]; /* manufacturer information block */ char manufacturer[12]; @@ -281,6 +291,40 @@ struct nand_onfi_params { #define ONFI_CRC_BASE 0x4F4E +/* Extended ECC information Block Definition (since ONFI 2.1) */ +struct onfi_ext_ecc_info { + u8 ecc_bits; + u8 codeword_size; + __le16 bb_per_lun; + __le16 block_endurance; + u8 reserved[2]; +} __packed; + +#define ONFI_SECTION_TYPE_0 0 /* Unused section. */ +#define ONFI_SECTION_TYPE_1 1 /* for additional sections. */ +#define ONFI_SECTION_TYPE_2 2 /* for ECC information. */ +struct onfi_ext_section { + u8 type; + u8 length; +} __packed; + +#define ONFI_EXT_SECTION_MAX 8 + +/* Extended Parameter Page Definition (since ONFI 2.1) */ +struct onfi_ext_param_page { + __le16 crc; + u8 sig[4]; /* 'E' 'P' 'P' 'S' */ + u8 reserved0[10]; + struct onfi_ext_section sections[ONFI_EXT_SECTION_MAX]; + + /* + * The actual size of the Extended Parameter Page is in + * @ext_param_page_length of nand_onfi_params{}. + * The following are the variable length sections. + * So we do not add any fields below. Please see the ONFI spec. + */ +} __packed; + /** * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices * @lock: protection lock @@ -390,8 +434,8 @@ struct nand_buffers { * @write_buf: [REPLACEABLE] write data from the buffer to the chip * @read_buf: [REPLACEABLE] read data from the chip into the buffer * @select_chip: [REPLACEABLE] select chip nr - * @block_bad: [REPLACEABLE] check, if the block is bad - * @block_markbad: [REPLACEABLE] mark the block bad + * @block_bad: [REPLACEABLE] check if a block is bad, using OOB markers + * @block_markbad: [REPLACEABLE] mark a block bad * @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific function for controlling * ALE/CLE/nCE. Also used to write command and address * @init_size: [BOARDSPECIFIC] hardwarespecific function for setting @@ -434,6 +478,12 @@ struct nand_buffers { * bad block marker position; i.e., BBM == 11110111b is * not bad when badblockbits == 7 * @cellinfo: [INTERN] MLC/multichip data from chip ident + * @ecc_strength_ds: [INTERN] ECC correctability from the datasheet. + * Minimum amount of bit errors per @ecc_step_ds guaranteed + * to be correctable. If unknown, set to zero. + * @ecc_step_ds: [INTERN] ECC step required by the @ecc_strength_ds, + * also from the datasheet. It is the recommended ECC step + * size, if known; if unknown, set to zero. * @numchips: [INTERN] number of physical chips * @chipsize: [INTERN] the size of one chip for multichip arrays * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 @@ -510,6 +560,8 @@ struct nand_chip { unsigned int pagebuf_bitflips; int subpagesize; uint8_t cellinfo; + uint16_t ecc_strength_ds; + uint16_t ecc_step_ds; int badblockpos; int badblockbits; @@ -576,6 +628,11 @@ struct nand_chip { { .name = (nm), {{ .dev_id = (devid) }}, .chipsize = (chipsz), \ .options = (opts) } +#define NAND_ECC_INFO(_strength, _step) \ + { .strength_ds = (_strength), .step_ds = (_step) } +#define NAND_ECC_STRENGTH(type) ((type)->ecc.strength_ds) +#define NAND_ECC_STEP(type) ((type)->ecc.step_ds) + /** * struct nand_flash_dev - NAND Flash Device ID Structure * @name: a human-readable name of the NAND chip @@ -593,6 +650,12 @@ struct nand_chip { * @options: stores various chip bit options * @id_len: The valid length of the @id. * @oobsize: OOB size + * @ecc.strength_ds: The ECC correctability from the datasheet, same as the + * @ecc_strength_ds in nand_chip{}. + * @ecc.step_ds: The ECC step required by the @ecc.strength_ds, same as the + * @ecc_step_ds in nand_chip{}, also from the datasheet. + * For example, the "4bit ECC for each 512Byte" can be set with + * NAND_ECC_INFO(4, 512). */ struct nand_flash_dev { char *name; @@ -609,6 +672,10 @@ struct nand_flash_dev { unsigned int options; uint16_t id_len; uint16_t oobsize; + struct { + uint16_t strength_ds; + uint16_t step_ds; + } ecc; }; /** @@ -625,8 +692,8 @@ extern struct nand_flash_dev nand_flash_ids[]; extern struct nand_manufacturers nand_manuf_ids[]; extern int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd); -extern int nand_update_bbt(struct mtd_info *mtd, loff_t offs); extern int nand_default_bbt(struct mtd_info *mtd); +extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs); extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt); extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, int allowbbt); @@ -708,6 +775,12 @@ struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd) return chip->priv; } +/* return the supported features. */ +static inline int onfi_feature(struct nand_chip *chip) +{ + return chip->onfi_version ? le16_to_cpu(chip->onfi_params.features) : 0; +} + /* return the supported asynchronous timing mode. */ static inline int onfi_get_async_timing_mode(struct nand_chip *chip) { |