diff options
author | Tom Rini <trini@konsulko.com> | 2016-06-04 08:49:47 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-06-04 08:49:47 -0400 |
commit | 715b3a9b2486e8d7a32365d817c77209b35ee796 (patch) | |
tree | 5daa126a15d2e0d60156664d19adbf451324d098 /include | |
parent | c41c649c2fdec7bf6ef84173597cc3feabdb7828 (diff) | |
parent | 667067faa18334f1e28c01b47530b5cce1b6182f (diff) | |
download | u-boot-715b3a9b2486e8d7a32365d817c77209b35ee796.tar.gz u-boot-715b3a9b2486e8d7a32365d817c77209b35ee796.tar.bz2 u-boot-715b3a9b2486e8d7a32365d817c77209b35ee796.zip |
Merge git://git.denx.de/u-boot-nand-flash
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/mtd/docg4.h | 132 | ||||
-rw-r--r-- | include/linux/mtd/mtd.h | 5 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 92 | ||||
-rw-r--r-- | include/linux/mtd/nand_bch.h | 10 | ||||
-rw-r--r-- | include/nand.h | 43 |
5 files changed, 96 insertions, 186 deletions
diff --git a/include/linux/mtd/docg4.h b/include/linux/mtd/docg4.h deleted file mode 100644 index 741fc0db46..0000000000 --- a/include/linux/mtd/docg4.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __DOCG4_H__ -#define __DOCG4_H__ - -#include <common.h> -#include <linux/mtd/nand.h> - -extern int docg4_nand_init(struct mtd_info *mtd, - struct nand_chip *nand, int devnum); - -/* SPL-related definitions */ -#define DOCG4_IPL_LOAD_BLOCK_COUNT 2 /* number of blocks that IPL loads */ -#define DOCG4_BLOCK_CAPACITY_SPL 0x10000 /* reliable mode; redundant pages */ - -#define DOC_IOSPACE_DATA 0x0800 - -/* register offsets */ -#define DOC_CHIPID 0x1000 -#define DOC_DEVICESELECT 0x100a -#define DOC_ASICMODE 0x100c -#define DOC_DATAEND 0x101e -#define DOC_NOP 0x103e - -#define DOC_FLASHSEQUENCE 0x1032 -#define DOC_FLASHCOMMAND 0x1034 -#define DOC_FLASHADDRESS 0x1036 -#define DOC_FLASHCONTROL 0x1038 -#define DOC_ECCCONF0 0x1040 -#define DOC_ECCCONF1 0x1042 -#define DOC_HAMMINGPARITY 0x1046 -#define DOC_BCH_SYNDROM(idx) (0x1048 + idx) - -#define DOC_ASICMODECONFIRM 0x1072 -#define DOC_CHIPID_INV 0x1074 -#define DOC_POWERMODE 0x107c - -#define DOCG4_MYSTERY_REG 0x1050 - -/* apparently used only to write oob bytes 6 and 7 */ -#define DOCG4_OOB_6_7 0x1052 - -/* DOC_FLASHSEQUENCE register commands */ -#define DOC_SEQ_RESET 0x00 -#define DOCG4_SEQ_PAGE_READ 0x03 -#define DOCG4_SEQ_FLUSH 0x29 -#define DOCG4_SEQ_PAGEWRITE 0x16 -#define DOCG4_SEQ_PAGEPROG 0x1e -#define DOCG4_SEQ_BLOCKERASE 0x24 - -/* DOC_FLASHCOMMAND register commands */ -#define DOCG4_CMD_PAGE_READ 0x00 -#define DOC_CMD_ERASECYCLE2 0xd0 -#define DOCG4_CMD_FLUSH 0x70 -#define DOCG4_CMD_READ2 0x30 -#define DOC_CMD_PROG_BLOCK_ADDR 0x60 -#define DOCG4_CMD_PAGEWRITE 0x80 -#define DOC_CMD_PROG_CYCLE2 0x10 -#define DOC_CMD_RESET 0xff - -/* DOC_POWERMODE register bits */ -#define DOC_POWERDOWN_READY 0x80 - -/* DOC_FLASHCONTROL register bits */ -#define DOC_CTRL_CE 0x10 -#define DOC_CTRL_UNKNOWN 0x40 -#define DOC_CTRL_FLASHREADY 0x01 - -/* DOC_ECCCONF0 register bits */ -#define DOC_ECCCONF0_READ_MODE 0x8000 -#define DOC_ECCCONF0_UNKNOWN 0x2000 -#define DOC_ECCCONF0_ECC_ENABLE 0x1000 -#define DOC_ECCCONF0_DATA_BYTES_MASK 0x07ff - -/* DOC_ECCCONF1 register bits */ -#define DOC_ECCCONF1_BCH_SYNDROM_ERR 0x80 -#define DOC_ECCCONF1_ECC_ENABLE 0x07 -#define DOC_ECCCONF1_PAGE_IS_WRITTEN 0x20 - -/* DOC_ASICMODE register bits */ -#define DOC_ASICMODE_RESET 0x00 -#define DOC_ASICMODE_NORMAL 0x01 -#define DOC_ASICMODE_POWERDOWN 0x02 -#define DOC_ASICMODE_MDWREN 0x04 -#define DOC_ASICMODE_BDETCT_RESET 0x08 -#define DOC_ASICMODE_RSTIN_RESET 0x10 -#define DOC_ASICMODE_RAM_WE 0x20 - -/* good status values read after read/write/erase operations */ -#define DOCG4_PROGSTATUS_GOOD 0x51 -#define DOCG4_PROGSTATUS_GOOD_2 0xe0 - -/* - * On read operations (page and oob-only), the first byte read from I/O reg is a - * status. On error, it reads 0x73; otherwise, it reads either 0x71 (first read - * after reset only) or 0x51, so bit 1 is presumed to be an error indicator. - */ -#define DOCG4_READ_ERROR 0x02 /* bit 1 indicates read error */ - -/* anatomy of the device */ -#define DOCG4_CHIP_SIZE 0x8000000 -#define DOCG4_PAGE_SIZE 0x200 -#define DOCG4_PAGES_PER_BLOCK 0x200 -#define DOCG4_BLOCK_SIZE (DOCG4_PAGES_PER_BLOCK * DOCG4_PAGE_SIZE) -#define DOCG4_NUMBLOCKS (DOCG4_CHIP_SIZE / DOCG4_BLOCK_SIZE) -#define DOCG4_OOB_SIZE 0x10 -#define DOCG4_CHIP_SHIFT 27 /* log_2(DOCG4_CHIP_SIZE) */ -#define DOCG4_PAGE_SHIFT 9 /* log_2(DOCG4_PAGE_SIZE) */ -#define DOCG4_ERASE_SHIFT 18 /* log_2(DOCG4_BLOCK_SIZE) */ - -/* all but the last byte is included in ecc calculation */ -#define DOCG4_BCH_SIZE (DOCG4_PAGE_SIZE + DOCG4_OOB_SIZE - 1) - -#define DOCG4_USERDATA_LEN 520 /* 512 byte page plus 8 oob avail to user */ - -/* expected values from the ID registers */ -#define DOCG4_IDREG1_VALUE 0x0400 -#define DOCG4_IDREG2_VALUE 0xfbff - -/* primitive polynomial used to build the Galois field used by hw ecc gen */ -#define DOCG4_PRIMITIVE_POLY 0x4443 - -#define DOCG4_M 14 /* Galois field is of order 2^14 */ -#define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */ - -#define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ - -#endif /* __DOCG4_H__ */ diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 9da77ec144..cf20674549 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -278,6 +278,11 @@ struct mtd_info { int usecount; }; +static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops) +{ + return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize; +} + int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); #ifndef __UBOOT__ int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 23072fdfc3..b5a02c3382 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -25,6 +25,8 @@ struct mtd_info; struct nand_flash_dev; +struct device_node; + /* Scan and identify a NAND device */ extern int nand_scan(struct mtd_info *mtd, int max_chips); /* @@ -144,6 +146,14 @@ typedef enum { /* Enable Hardware ECC before syndrome is read back from flash */ #define NAND_ECC_READSYN 2 +/* + * Enable generic NAND 'page erased' check. This check is only done when + * ecc.correct() returns -EBADMSG. + * Set this flag if your implementation does not fix bitflips in erased + * pages and you want to rely on the default implementation. + */ +#define NAND_ECC_GENERIC_ERASED_CHECK BIT(0) + /* Bit mask for flags passed to do_nand_read_ecc */ #define NAND_GET_DEVICE 0x80 @@ -179,6 +189,12 @@ typedef enum { /* Device supports subpage reads */ #define NAND_SUBPAGE_READ 0x00001000 +/* + * Some MLC NANDs need data scrambling to limit bitflips caused by repeated + * patterns. + */ +#define NAND_NEED_SCRAMBLING 0x00002000 + /* Options valid for Samsung large page devices */ #define NAND_SAMSUNG_LP_OPTIONS NAND_CACHEPRG @@ -203,6 +219,11 @@ typedef enum { * before calling nand_scan_tail. */ #define NAND_BUSWIDTH_AUTO 0x00080000 +/* + * This option could be defined by controller drivers to protect against + * kmap'ed, vmalloc'ed highmem buffers being passed from upper layers + */ +#define NAND_USE_BOUNCE_BUFFER 0x00100000 /* Options set by nand scan */ /* bbt has already been read */ @@ -292,15 +313,15 @@ struct nand_onfi_params { __le16 t_r; __le16 t_ccs; __le16 src_sync_timing_mode; - __le16 src_ssync_features; + u8 src_ssync_features; __le16 clk_pin_capacitance_typ; __le16 io_pin_capacitance_typ; __le16 input_pin_capacitance_typ; u8 input_pin_capacitance_max; u8 driver_strength_support; __le16 t_int_r; - __le16 t_ald; - u8 reserved4[7]; + __le16 t_adl; + u8 reserved4[8]; /* vendor */ __le16 vendor_revision; @@ -423,7 +444,7 @@ struct nand_jedec_params { __le16 input_pin_capacitance_typ; __le16 clk_pin_capacitance_typ; u8 driver_strength_support; - __le16 t_ald; + __le16 t_adl; u8 reserved4[36]; /* ECC and endurance block */ @@ -466,12 +487,19 @@ struct nand_hw_control { * @total: total number of ECC bytes per page * @prepad: padding information for syndrome based ECC generators * @postpad: padding information for syndrome based ECC generators + * @options: ECC specific options (see NAND_ECC_XXX flags defined above) * @layout: ECC layout control struct pointer * @priv: pointer to private ECC control data * @hwctl: function to control hardware ECC generator. Must only * be provided if an hardware ECC is available * @calculate: function for ECC calculation or readback from ECC hardware - * @correct: function for ECC correction, matching to ECC generator (sw/hw) + * @correct: function for ECC correction, matching to ECC generator (sw/hw). + * Should return a positive number representing the number of + * corrected bitflips, -EBADMSG if the number of bitflips exceed + * ECC strength, or any other error code if the error is not + * directly related to correction. + * If -EBADMSG is returned the input buffers should be left + * untouched. * @read_page_raw: function to read a raw page without ECC. This function * should hide the specific layout used by the ECC * controller and always return contiguous in-band and @@ -509,6 +537,7 @@ struct nand_ecc_ctrl { int strength; int prepad; int postpad; + unsigned int options; struct nand_ecclayout *layout; void *priv; void (*hwctl)(struct mtd_info *mtd, int mode); @@ -519,16 +548,16 @@ struct nand_ecc_ctrl { int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page); int (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip, - const uint8_t *buf, int oob_required); + const uint8_t *buf, int oob_required, int page); int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page); int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip, uint32_t offs, uint32_t len, uint8_t *buf, int page); int (*write_subpage)(struct mtd_info *mtd, struct nand_chip *chip, uint32_t offset, uint32_t data_len, - const uint8_t *data_buf, int oob_required); + const uint8_t *data_buf, int oob_required, int page); int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, - const uint8_t *buf, int oob_required); + const uint8_t *buf, int oob_required, int page); int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip, int page); int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip, @@ -556,6 +585,7 @@ struct nand_buffers { /** * struct nand_chip - NAND Private Flash Chip Data + * @mtd: MTD device registered to the MTD framework * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the * flash device * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the @@ -571,10 +601,6 @@ struct nand_buffers { * @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 - * mtd->oobsize, mtd->writesize and so on. - * @id_data contains the 8 bytes values of NAND_CMD_READID. - * Return with the bus width. * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accessing * device ready/busy line. If set to NULL no access to * ready/busy is available and the ready/busy information @@ -659,6 +685,7 @@ struct nand_buffers { */ struct nand_chip { + struct mtd_info mtd; void __iomem *IO_ADDR_R; void __iomem *IO_ADDR_W; @@ -668,11 +695,9 @@ struct nand_chip { void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len); void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len); void (*select_chip)(struct mtd_info *mtd, int chip); - int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); + int (*block_bad)(struct mtd_info *mtd, loff_t ofs); int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl); - int (*init_size)(struct mtd_info *mtd, struct nand_chip *this, - u8 *id_data); int (*dev_ready)(struct mtd_info *mtd); void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); @@ -739,6 +764,26 @@ struct nand_chip { void *priv; }; +static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) +{ + return container_of(mtd, struct nand_chip, mtd); +} + +static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip) +{ + return &chip->mtd; +} + +static inline void *nand_get_controller_data(struct nand_chip *chip) +{ + return chip->priv; +} + +static inline void nand_set_controller_data(struct nand_chip *chip, void *priv) +{ + chip->priv = priv; +} + /* * NAND Flash Manufacturer ID Codes */ @@ -852,7 +897,6 @@ struct nand_manufacturers { 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_default_bbt(struct mtd_info *mtd); extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs); extern int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs); @@ -877,7 +921,6 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, * @chip_delay: R/B delay value in us * @options: Option flags, e.g. 16bit buswidth * @bbt_options: BBT option flags, e.g. NAND_BBT_USE_FLASH - * @ecclayout: ECC layout info structure * @part_probe_types: NULL-terminated array of probe types */ struct platform_nand_chip { @@ -885,7 +928,6 @@ struct platform_nand_chip { int chip_offset; int nr_partitions; struct mtd_partition *partitions; - struct nand_ecclayout *ecclayout; int chip_delay; unsigned int options; unsigned int bbt_options; @@ -934,15 +976,6 @@ struct platform_nand_data { struct platform_nand_ctrl ctrl; }; -/* Some helpers to access the data structures */ -static inline -struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd->priv; - - return chip->priv; -} - #ifdef CONFIG_SYS_NAND_ONFI_DETECTION /* return the supported features. */ static inline int onfi_feature(struct nand_chip *chip) @@ -1060,4 +1093,9 @@ struct nand_sdr_timings { /* get timing characteristics from ONFI timing mode. */ const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode); + +int nand_check_erased_ecc_chunk(void *data, int datalen, + void *ecc, int ecclen, + void *extraoob, int extraooblen, + int threshold); #endif /* __LINUX_MTD_NAND_H */ diff --git a/include/linux/mtd/nand_bch.h b/include/linux/mtd/nand_bch.h index d8754dd8c8..8ea6b04cc3 100644 --- a/include/linux/mtd/nand_bch.h +++ b/include/linux/mtd/nand_bch.h @@ -32,9 +32,7 @@ int nand_bch_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, /* * Initialize BCH encoder/decoder */ -struct nand_bch_control * -nand_bch_init(struct mtd_info *mtd, unsigned int eccsize, - unsigned int eccbytes, struct nand_ecclayout **ecclayout); +struct nand_bch_control *nand_bch_init(struct mtd_info *mtd); /* * Release BCH encoder/decoder resources */ @@ -55,12 +53,10 @@ static inline int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, unsigned char *read_ecc, unsigned char *calc_ecc) { - return -1; + return -ENOTSUPP; } -static inline struct nand_bch_control * -nand_bch_init(struct mtd_info *mtd, unsigned int eccsize, - unsigned int eccbytes, struct nand_ecclayout **ecclayout) +static inline struct nand_bch_control *nand_bch_init(struct mtd_info *mtd) { return NULL; } diff --git a/include/nand.h b/include/nand.h index 7cbbbd327a..a4f0f9253d 100644 --- a/include/nand.h +++ b/include/nand.h @@ -33,34 +33,36 @@ extern void nand_init(void); #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> +int nand_mtd_to_devnum(struct mtd_info *mtd); + #ifdef CONFIG_SYS_NAND_SELF_INIT void board_nand_init(void); -int nand_register(int devnum); +int nand_register(int devnum, struct mtd_info *mtd); #else extern int board_nand_init(struct nand_chip *nand); #endif -typedef struct mtd_info nand_info_t; - extern int nand_curr_device; -extern nand_info_t nand_info[]; +extern struct mtd_info *nand_info[]; -static inline int nand_read(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf) +static inline int nand_read(struct mtd_info *info, loff_t ofs, size_t *len, + u_char *buf) { return mtd_read(info, ofs, *len, (size_t *)len, buf); } -static inline int nand_write(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf) +static inline int nand_write(struct mtd_info *info, loff_t ofs, size_t *len, + u_char *buf) { return mtd_write(info, ofs, *len, (size_t *)len, buf); } -static inline int nand_block_isbad(nand_info_t *info, loff_t ofs) +static inline int nand_block_isbad(struct mtd_info *info, loff_t ofs) { return mtd_block_isbad(info, ofs); } -static inline int nand_erase(nand_info_t *info, loff_t off, size_t size) +static inline int nand_erase(struct mtd_info *info, loff_t off, size_t size) { struct erase_info instr; @@ -96,27 +98,28 @@ struct nand_erase_options { typedef struct nand_erase_options nand_erase_options_t; -int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, +int nand_read_skip_bad(struct mtd_info *mtd, loff_t offset, size_t *length, size_t *actual, loff_t lim, u_char *buffer); #define WITH_DROP_FFS (1 << 0) /* drop trailing all-0xff pages */ #define WITH_WR_VERIFY (1 << 1) /* verify data was written correctly */ -int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, +int nand_write_skip_bad(struct mtd_info *mtd, loff_t offset, size_t *length, size_t *actual, loff_t lim, u_char *buffer, int flags); -int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); -int nand_torture(nand_info_t *nand, loff_t offset); -int nand_verify_page_oob(nand_info_t *nand, struct mtd_oob_ops *ops, - loff_t ofs); -int nand_verify(nand_info_t *nand, loff_t ofs, size_t len, u_char *buf); +int nand_erase_opts(struct mtd_info *mtd, + const nand_erase_options_t *opts); +int nand_torture(struct mtd_info *mtd, loff_t offset); +int nand_verify_page_oob(struct mtd_info *mtd, struct mtd_oob_ops *ops, + loff_t ofs); +int nand_verify(struct mtd_info *mtd, loff_t ofs, size_t len, u_char *buf); #define NAND_LOCK_STATUS_TIGHT 0x01 #define NAND_LOCK_STATUS_UNLOCK 0x04 -int nand_lock(nand_info_t *meminfo, int tight); -int nand_unlock(nand_info_t *meminfo, loff_t start, size_t length, - int allexcept); -int nand_get_lock_status(nand_info_t *meminfo, loff_t offset); +int nand_lock(struct mtd_info *mtd, int tight); +int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length, + int allexcept); +int nand_get_lock_status(struct mtd_info *mtd, loff_t offset); int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst); void nand_deselect(void); @@ -135,6 +138,6 @@ __attribute__((noreturn)) void nand_boot(void); #define ENV_OOB_MARKER_OLD 0x30564e45 /*"ENV0" in little-endian -- offset is stored as byte number */ #define ENV_OFFSET_SIZE 8 -int get_nand_env_oob(nand_info_t *nand, unsigned long *result); +int get_nand_env_oob(struct mtd_info *mtd, unsigned long *result); #endif int spl_nand_erase_one(int block, int page); |