diff options
Diffstat (limited to 'include/linux/mtd/rawnand.h')
-rw-r--r-- | include/linux/mtd/rawnand.h | 122 |
1 files changed, 73 insertions, 49 deletions
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index b7445a44a814..dbfffa5bec7b 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -20,6 +20,7 @@ #include <linux/mtd/flashchip.h> #include <linux/mtd/bbm.h> #include <linux/mtd/jedec.h> +#include <linux/mtd/nand.h> #include <linux/mtd/onfi.h> #include <linux/mutex.h> #include <linux/of.h> @@ -168,6 +169,21 @@ enum nand_ecc_algo { /* Macros to identify the above */ #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ)) +/* + * There are different places where the manufacturer stores the factory bad + * block markers. + * + * Position within the block: Each of these pages needs to be checked for a + * bad block marking pattern. + */ +#define NAND_BBM_FIRSTPAGE 0x01000000 +#define NAND_BBM_SECONDPAGE 0x02000000 +#define NAND_BBM_LASTPAGE 0x04000000 + +/* Position within the OOB data of the page */ +#define NAND_BBM_POS_SMALL 5 +#define NAND_BBM_POS_LARGE 0 + /* Non chip related options */ /* This option skips the bbt scan during initialization. */ #define NAND_SKIP_BBTSCAN 0x00010000 @@ -805,7 +821,7 @@ struct nand_op_parser_pattern { #define NAND_OP_PARSER_PATTERN(_exec, ...) \ { \ .exec = _exec, \ - .elems = (struct nand_op_parser_pattern_elem[]) { __VA_ARGS__ }, \ + .elems = (const struct nand_op_parser_pattern_elem[]) { __VA_ARGS__ }, \ .nelems = sizeof((struct nand_op_parser_pattern_elem[]) { __VA_ARGS__ }) / \ sizeof(struct nand_op_parser_pattern_elem), \ } @@ -831,7 +847,7 @@ struct nand_op_parser { #define NAND_OP_PARSER(...) \ { \ - .patterns = (struct nand_op_parser_pattern[]) { __VA_ARGS__ }, \ + .patterns = (const struct nand_op_parser_pattern[]) { __VA_ARGS__ }, \ .npatterns = sizeof((struct nand_op_parser_pattern[]) { __VA_ARGS__ }) / \ sizeof(struct nand_op_parser_pattern), \ } @@ -860,6 +876,7 @@ struct nand_operation { int nand_op_parser_exec_op(struct nand_chip *chip, const struct nand_op_parser *parser, const struct nand_operation *op, bool check_only); + /** * struct nand_controller_ops - Controller operations * @@ -962,7 +979,7 @@ struct nand_legacy { /** * struct nand_chip - NAND Private Flash Chip Data - * @mtd: MTD device registered to the MTD framework + * @base: Inherit from the generic NAND device * @legacy: All legacy fields/hooks. If you develop a new driver, * don't even try to use any of these fields/hooks, and if * you're modifying an existing driver that is using those @@ -990,37 +1007,26 @@ struct nand_legacy { * @badblockbits: [INTERN] minimum number of set bits in a good block's * bad block marker position; i.e., BBM == 11110111b is * not bad when badblockbits == 7 - * @bits_per_cell: [INTERN] number of bits per cell. i.e., 1 means SLC. - * @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. * @onfi_timing_mode_default: [INTERN] default ONFI timing mode. This field is * set to the actually used ONFI mode if the chip is * ONFI compliant or deduced from the datasheet if * the NAND chip is not ONFI compliant. - * @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 * @data_buf: [INTERN] buffer for data, size is (page size + oobsize). - * @pagebuf: [INTERN] holds the pagenumber which is currently in - * data_buf. - * @pagebuf_bitflips: [INTERN] holds the bitflip count for the page which is - * currently in data_buf. + * @pagecache: Structure containing page cache related fields + * @pagecache.bitflips: Number of bitflips of the cached page + * @pagecache.page: Page number currently in the cache. -1 means no page is + * currently cached * @subpagesize: [INTERN] holds the subpagesize * @id: [INTERN] holds NAND ID * @parameters: [INTERN] holds generic parameters under an easily * readable form. - * @max_bb_per_die: [INTERN] the max number of bad blocks each die of a - * this nand device will encounter their life times. - * @blocks_per_die: [INTERN] The number of PEBs in a die * @data_interface: [INTERN] NAND interface timing information * @cur_cs: currently selected target. -1 means no target selected, * otherwise we should always have cur_cs >= 0 && - * cur_cs < numchips. NAND Controller drivers should not - * modify this value, but they're allowed to read it. + * cur_cs < nanddev_ntargets(). NAND Controller drivers + * should not modify this value, but they're allowed to + * read it. * @read_retries: [INTERN] the number of read retry modes supported * @lock: lock protecting the suspended field. Also used to * serialize accesses to the NAND device. @@ -1041,7 +1047,7 @@ struct nand_legacy { */ struct nand_chip { - struct mtd_info mtd; + struct nand_device base; struct nand_legacy legacy; @@ -1054,24 +1060,21 @@ struct nand_chip { int phys_erase_shift; int bbt_erase_shift; int chip_shift; - int numchips; - uint64_t chipsize; int pagemask; u8 *data_buf; - int pagebuf; - unsigned int pagebuf_bitflips; + + struct { + unsigned int bitflips; + int page; + } pagecache; + int subpagesize; - uint8_t bits_per_cell; - uint16_t ecc_strength_ds; - uint16_t ecc_step_ds; int onfi_timing_mode_default; - int badblockpos; + unsigned int badblockpos; int badblockbits; struct nand_id id; struct nand_parameters parameters; - u16 max_bb_per_die; - u32 blocks_per_die; struct nand_data_interface data_interface; @@ -1105,25 +1108,14 @@ struct nand_chip { extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops; extern const struct mtd_ooblayout_ops nand_ooblayout_lp_ops; -static inline void nand_set_flash_node(struct nand_chip *chip, - struct device_node *np) -{ - mtd_set_of_node(&chip->mtd, np); -} - -static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) -{ - return mtd_get_of_node(&chip->mtd); -} - static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) { - return container_of(mtd, struct nand_chip, mtd); + return container_of(mtd, struct nand_chip, base.mtd); } static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip) { - return &chip->mtd; + return &chip->base.mtd; } static inline void *nand_get_controller_data(struct nand_chip *chip) @@ -1147,6 +1139,17 @@ static inline void *nand_get_manufacturer_data(struct nand_chip *chip) return chip->manufacturer.priv; } +static inline void nand_set_flash_node(struct nand_chip *chip, + struct device_node *np) +{ + mtd_set_of_node(nand_to_mtd(chip), np); +} + +static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) +{ + return mtd_get_of_node(nand_to_mtd(chip)); +} + /* * A helper for defining older NAND chips where the second ID byte fully * defined the chip, including the geometry (chip size, eraseblock size, page @@ -1180,9 +1183,9 @@ static inline void *nand_get_manufacturer_data(struct nand_chip *chip) * @name: a human-readable name of the NAND chip * @dev_id: the device ID (the second byte of the full chip ID array) * @mfr_id: manufecturer ID part of the full chip ID array (refers the same - * memory address as @id[0]) + * memory address as ``id[0]``) * @dev_id: device ID part of the full chip ID array (refers the same memory - * address as @id[1]) + * address as ``id[1]``) * @id: full device ID array * @pagesize: size of the NAND page in bytes; if 0, then the real page size (as * well as the eraseblock size) is determined from the extended NAND @@ -1235,9 +1238,9 @@ int nand_create_bbt(struct nand_chip *chip); */ static inline bool nand_is_slc(struct nand_chip *chip) { - WARN(chip->bits_per_cell == 0, + WARN(nanddev_bits_per_cell(&chip->base) == 0, "chip->bits_per_cell is used uninitialized\n"); - return chip->bits_per_cell == 1; + return nanddev_bits_per_cell(&chip->base) == 1; } /** @@ -1348,4 +1351,25 @@ int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpiod, void nand_select_target(struct nand_chip *chip, unsigned int cs); void nand_deselect_target(struct nand_chip *chip); +/** + * nand_get_data_buf() - Get the internal page buffer + * @chip: NAND chip object + * + * Returns the pre-allocated page buffer after invalidating the cache. This + * function should be used by drivers that do not want to allocate their own + * bounce buffer and still need such a buffer for specific operations (most + * commonly when reading OOB data only). + * + * Be careful to never call this function in the write/write_oob path, because + * the core may have placed the data to be written out in this buffer. + * + * Return: pointer to the page cache buffer + */ +static inline void *nand_get_data_buf(struct nand_chip *chip) +{ + chip->pagecache.page = -1; + + return chip->data_buf; +} + #endif /* __LINUX_MTD_RAWNAND_H */ |