|
|
|
|
@@ -16,20 +16,12 @@
|
|
|
|
|
#ifndef __LINUX_MTD_NAND_H
|
|
|
|
|
#define __LINUX_MTD_NAND_H
|
|
|
|
|
|
|
|
|
|
#ifndef __UBOOT__
|
|
|
|
|
#include <linux/wait.h>
|
|
|
|
|
#include <linux/spinlock.h>
|
|
|
|
|
#include <linux/mtd/mtd.h>
|
|
|
|
|
#include <linux/mtd/flashchip.h>
|
|
|
|
|
#include <linux/mtd/bbm.h>
|
|
|
|
|
#else
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
|
|
#include "linux/compat.h"
|
|
|
|
|
#include "linux/mtd/mtd.h"
|
|
|
|
|
#include "linux/mtd/flashchip.h"
|
|
|
|
|
#include "linux/mtd/bbm.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
struct mtd_info;
|
|
|
|
|
struct nand_flash_dev;
|
|
|
|
|
@@ -49,24 +41,13 @@ extern void nand_release(struct mtd_info *mtd);
|
|
|
|
|
/* Internal helper for board drivers which need to override command function */
|
|
|
|
|
extern void nand_wait_ready(struct mtd_info *mtd);
|
|
|
|
|
|
|
|
|
|
#ifndef __UBOOT__
|
|
|
|
|
/* locks all blocks present in the device */
|
|
|
|
|
extern int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
|
|
|
|
|
|
|
|
|
|
/* unlocks specified locked blocks */
|
|
|
|
|
extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
|
|
|
|
|
|
|
|
|
|
/* The maximum number of NAND chips in an array */
|
|
|
|
|
#define NAND_MAX_CHIPS 8
|
|
|
|
|
#else
|
|
|
|
|
/*
|
|
|
|
|
* 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 744
|
|
|
|
|
#define NAND_MAX_PAGESIZE 8192
|
|
|
|
|
#endif
|
|
|
|
|
#define NAND_MAX_OOBSIZE 1216
|
|
|
|
|
#define NAND_MAX_PAGESIZE 16384
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Constants for hardware specific CLE/ALE/NCE function
|
|
|
|
|
@@ -473,9 +454,6 @@ struct nand_jedec_params {
|
|
|
|
|
struct nand_hw_control {
|
|
|
|
|
spinlock_t lock;
|
|
|
|
|
struct nand_chip *active;
|
|
|
|
|
#ifndef __UBOOT__
|
|
|
|
|
wait_queue_head_t wq;
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -494,8 +472,21 @@ struct nand_hw_control {
|
|
|
|
|
* 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)
|
|
|
|
|
* @read_page_raw: function to read a raw page without ECC
|
|
|
|
|
* @write_page_raw: function to write a raw page without ECC
|
|
|
|
|
* @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
|
|
|
|
|
* out-of-band data even if they're not stored
|
|
|
|
|
* contiguously on the NAND chip (e.g.
|
|
|
|
|
* NAND_ECC_HW_SYNDROME interleaves in-band and
|
|
|
|
|
* out-of-band data).
|
|
|
|
|
* @write_page_raw: function to write a raw page without ECC. This function
|
|
|
|
|
* should hide the specific layout used by the ECC
|
|
|
|
|
* controller and consider the passed data as contiguous
|
|
|
|
|
* in-band and out-of-band data. ECC controller is
|
|
|
|
|
* responsible for doing the appropriate transformations
|
|
|
|
|
* to adapt to its specific layout (e.g.
|
|
|
|
|
* NAND_ECC_HW_SYNDROME interleaves in-band and
|
|
|
|
|
* out-of-band data).
|
|
|
|
|
* @read_page: function to read a page according to the ECC generator
|
|
|
|
|
* requirements; returns maximum number of bitflips corrected in
|
|
|
|
|
* any single ECC step, 0 if bitflips uncorrectable, -EIO hw error
|
|
|
|
|
@@ -557,16 +548,10 @@ struct nand_ecc_ctrl {
|
|
|
|
|
* consecutive order.
|
|
|
|
|
*/
|
|
|
|
|
struct nand_buffers {
|
|
|
|
|
#ifndef __UBOOT__
|
|
|
|
|
uint8_t *ecccalc;
|
|
|
|
|
uint8_t *ecccode;
|
|
|
|
|
uint8_t *databuf;
|
|
|
|
|
#else
|
|
|
|
|
uint8_t ecccalc[ALIGN(NAND_MAX_OOBSIZE, ARCH_DMA_MINALIGN)];
|
|
|
|
|
uint8_t ecccode[ALIGN(NAND_MAX_OOBSIZE, ARCH_DMA_MINALIGN)];
|
|
|
|
|
uint8_t databuf[ALIGN(NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE,
|
|
|
|
|
ARCH_DMA_MINALIGN)];
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -603,8 +588,7 @@ struct nand_buffers {
|
|
|
|
|
* @ecc: [BOARDSPECIFIC] ECC control structure
|
|
|
|
|
* @buffers: buffer structure for read/write
|
|
|
|
|
* @hwcontrol: platform-specific hardware control structure
|
|
|
|
|
* @erase_cmd: [INTERN] erase command write function, selectable due
|
|
|
|
|
* to AND support.
|
|
|
|
|
* @erase: [REPLACEABLE] erase function
|
|
|
|
|
* @scan_bbt: [REPLACEABLE] function to scan bad block table
|
|
|
|
|
* @chip_delay: [BOARDSPECIFIC] chip dependent delay for transferring
|
|
|
|
|
* data from array to read regs (tR).
|
|
|
|
|
@@ -634,6 +618,11 @@ struct nand_buffers {
|
|
|
|
|
* @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
|
|
|
|
|
* either deduced from the datasheet if the NAND
|
|
|
|
|
* chip is not ONFI compliant or set to 0 if it is
|
|
|
|
|
* (an ONFI chip is always configured in mode 0
|
|
|
|
|
* after a NAND reset)
|
|
|
|
|
* @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
|
|
|
|
|
@@ -688,7 +677,7 @@ struct nand_chip {
|
|
|
|
|
void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column,
|
|
|
|
|
int page_addr);
|
|
|
|
|
int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
|
|
|
|
|
void (*erase_cmd)(struct mtd_info *mtd, int page);
|
|
|
|
|
int (*erase)(struct mtd_info *mtd, int page);
|
|
|
|
|
int (*scan_bbt)(struct mtd_info *mtd);
|
|
|
|
|
int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state,
|
|
|
|
|
int status, int page);
|
|
|
|
|
@@ -718,6 +707,7 @@ struct nand_chip {
|
|
|
|
|
uint8_t bits_per_cell;
|
|
|
|
|
uint16_t ecc_strength_ds;
|
|
|
|
|
uint16_t ecc_step_ds;
|
|
|
|
|
int onfi_timing_mode_default;
|
|
|
|
|
int badblockpos;
|
|
|
|
|
int badblockbits;
|
|
|
|
|
|
|
|
|
|
@@ -734,9 +724,7 @@ struct nand_chip {
|
|
|
|
|
|
|
|
|
|
uint8_t *oob_poi;
|
|
|
|
|
struct nand_hw_control *controller;
|
|
|
|
|
#ifdef __UBOOT__
|
|
|
|
|
struct nand_ecclayout *ecclayout;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
struct nand_ecc_ctrl ecc;
|
|
|
|
|
struct nand_buffers *buffers;
|
|
|
|
|
@@ -767,6 +755,7 @@ struct nand_chip {
|
|
|
|
|
#define NAND_MFR_EON 0x92
|
|
|
|
|
#define NAND_MFR_SANDISK 0x45
|
|
|
|
|
#define NAND_MFR_INTEL 0x89
|
|
|
|
|
#define NAND_MFR_ATO 0x9b
|
|
|
|
|
|
|
|
|
|
/* The maximum expected count of bytes in the NAND ID sequence */
|
|
|
|
|
#define NAND_MAX_ID_LEN 8
|
|
|
|
|
@@ -816,12 +805,17 @@ struct nand_chip {
|
|
|
|
|
* @options: stores various chip bit options
|
|
|
|
|
* @id_len: The valid length of the @id.
|
|
|
|
|
* @oobsize: OOB size
|
|
|
|
|
* @ecc: ECC correctability and step information from the datasheet.
|
|
|
|
|
* @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).
|
|
|
|
|
* @onfi_timing_mode_default: the default ONFI timing mode entered after a NAND
|
|
|
|
|
* reset. Should be deduced from timings described
|
|
|
|
|
* in the datasheet.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
struct nand_flash_dev {
|
|
|
|
|
char *name;
|
|
|
|
|
@@ -842,6 +836,7 @@ struct nand_flash_dev {
|
|
|
|
|
uint16_t strength_ds;
|
|
|
|
|
uint16_t step_ds;
|
|
|
|
|
} ecc;
|
|
|
|
|
int onfi_timing_mode_default;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -860,19 +855,18 @@ 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);
|
|
|
|
|
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);
|
|
|
|
|
extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
|
|
|
|
|
size_t *retlen, uint8_t *buf);
|
|
|
|
|
|
|
|
|
|
#ifdef __UBOOT__
|
|
|
|
|
/*
|
|
|
|
|
* Constants for oob configuration
|
|
|
|
|
*/
|
|
|
|
|
#define NAND_SMALL_BADBLOCK_POS 5
|
|
|
|
|
#define NAND_LARGE_BADBLOCK_POS 0
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* struct platform_nand_chip - chip level device structure
|
|
|
|
|
@@ -1008,12 +1002,62 @@ static inline int jedec_feature(struct nand_chip *chip)
|
|
|
|
|
: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef __UBOOT__
|
|
|
|
|
/* Standard NAND functions from nand_base.c */
|
|
|
|
|
void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
|
|
|
|
|
void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len);
|
|
|
|
|
void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
|
|
|
|
|
void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);
|
|
|
|
|
uint8_t nand_read_byte(struct mtd_info *mtd);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* struct nand_sdr_timings - SDR NAND chip timings
|
|
|
|
|
*
|
|
|
|
|
* This struct defines the timing requirements of a SDR NAND chip.
|
|
|
|
|
* These informations can be found in every NAND datasheets and the timings
|
|
|
|
|
* meaning are described in the ONFI specifications:
|
|
|
|
|
* www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing
|
|
|
|
|
* Parameters)
|
|
|
|
|
*
|
|
|
|
|
* All these timings are expressed in picoseconds.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
struct nand_sdr_timings {
|
|
|
|
|
u32 tALH_min;
|
|
|
|
|
u32 tADL_min;
|
|
|
|
|
u32 tALS_min;
|
|
|
|
|
u32 tAR_min;
|
|
|
|
|
u32 tCEA_max;
|
|
|
|
|
u32 tCEH_min;
|
|
|
|
|
u32 tCH_min;
|
|
|
|
|
u32 tCHZ_max;
|
|
|
|
|
u32 tCLH_min;
|
|
|
|
|
u32 tCLR_min;
|
|
|
|
|
u32 tCLS_min;
|
|
|
|
|
u32 tCOH_min;
|
|
|
|
|
u32 tCS_min;
|
|
|
|
|
u32 tDH_min;
|
|
|
|
|
u32 tDS_min;
|
|
|
|
|
u32 tFEAT_max;
|
|
|
|
|
u32 tIR_min;
|
|
|
|
|
u32 tITC_max;
|
|
|
|
|
u32 tRC_min;
|
|
|
|
|
u32 tREA_max;
|
|
|
|
|
u32 tREH_min;
|
|
|
|
|
u32 tRHOH_min;
|
|
|
|
|
u32 tRHW_min;
|
|
|
|
|
u32 tRHZ_max;
|
|
|
|
|
u32 tRLOH_min;
|
|
|
|
|
u32 tRP_min;
|
|
|
|
|
u32 tRR_min;
|
|
|
|
|
u64 tRST_max;
|
|
|
|
|
u32 tWB_max;
|
|
|
|
|
u32 tWC_min;
|
|
|
|
|
u32 tWH_min;
|
|
|
|
|
u32 tWHR_min;
|
|
|
|
|
u32 tWP_min;
|
|
|
|
|
u32 tWW_min;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* get timing characteristics from ONFI timing mode. */
|
|
|
|
|
const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode);
|
|
|
|
|
#endif /* __LINUX_MTD_NAND_H */
|
|
|
|
|
|