diff options
| author | Bartlomiej Sieka <tur@semihalf.com> | 2006-02-24 09:37:22 +0100 | 
|---|---|---|
| committer | Bartlomiej Sieka <tur@pollux.(none)> | 2006-02-24 09:37:22 +0100 | 
| commit | 038ccac511214b062c56f22b9413f784b86bcd87 (patch) | |
| tree | 9925a8bb04e791550c76e864c5821b12fc478e2e /include/linux/mtd | |
| parent | 84e106c09d324e345f335d2edef246d0b4c9131a (diff) | |
| parent | 8e9655f863246db60c51140153186acc2afdc855 (diff) | |
| download | olio-uboot-2014.01-038ccac511214b062c56f22b9413f784b86bcd87.tar.xz olio-uboot-2014.01-038ccac511214b062c56f22b9413f784b86bcd87.zip | |
Merge with /home/wd/git/u-boot/testing-NAND/ to add new NAND handling.
Diffstat (limited to 'include/linux/mtd')
| -rw-r--r-- | include/linux/mtd/compat.h | 44 | ||||
| -rw-r--r-- | include/linux/mtd/mtd-abi.h | 99 | ||||
| -rw-r--r-- | include/linux/mtd/mtd.h | 214 | ||||
| -rw-r--r-- | include/linux/mtd/nand.h | 5 | ||||
| -rw-r--r-- | include/linux/mtd/nand_ecc.h | 30 | ||||
| -rw-r--r-- | include/linux/mtd/nand_ids.h | 1 | ||||
| -rw-r--r-- | include/linux/mtd/nand_new.h | 469 | 
7 files changed, 861 insertions, 1 deletions
| diff --git a/include/linux/mtd/compat.h b/include/linux/mtd/compat.h new file mode 100644 index 000000000..460cd45c8 --- /dev/null +++ b/include/linux/mtd/compat.h @@ -0,0 +1,44 @@ +#ifndef _LINUX_COMPAT_H_ +#define _LINUX_COMPAT_H_ + +#define __user +#define __iomem + +#define ndelay(x)	udelay(1) + +#define printk	printf + +#define KERN_EMERG +#define KERN_ALERT +#define KERN_CRIT +#define KERN_ERR +#define KERN_WARNING +#define KERN_NOTICE +#define KERN_INFO +#define KERN_DEBUG + +#define kmalloc(size, flags)	malloc(size) +#define kfree(ptr)		free(ptr) + +/* + * ..and if you can't take the strict + * types, you can specify one yourself. + * + * Or not use min/max at all, of course. + */ +#define min_t(type,x,y) \ +	({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) +#define max_t(type,x,y) \ +	({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) + +#define BUG() do { \ +	printf("U-Boot BUG at %s:%d!\n", __FILE__, __LINE__); \ +} while (0) + +#define BUG_ON(condition) do { if (condition) BUG(); } while(0) + +#define likely(x)	__builtin_expect(!!(x), 1) +#define unlikely(x)	__builtin_expect(!!(x), 0) + +#define PAGE_SIZE	4096 +#endif diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h new file mode 100644 index 000000000..3d1d41681 --- /dev/null +++ b/include/linux/mtd/mtd-abi.h @@ -0,0 +1,99 @@ +/* + * $Id: mtd-abi.h,v 1.7 2004/11/23 15:37:32 gleixner Exp $ + * + * Portions of MTD ABI definition which are shared by kernel and user space + */ + +#ifndef __MTD_ABI_H__ +#define __MTD_ABI_H__ + +struct erase_info_user { +	uint32_t start; +	uint32_t length; +}; + +struct mtd_oob_buf { +	uint32_t start; +	uint32_t length; +	unsigned char *ptr; +}; + +#define MTD_ABSENT		0 +#define MTD_RAM			1 +#define MTD_ROM			2 +#define MTD_NORFLASH		3 +#define MTD_NANDFLASH		4 +#define MTD_PEROM		5 +#define MTD_OTHER		14 +#define MTD_UNKNOWN		15 + +#define MTD_CLEAR_BITS		1       /* Bits can be cleared (flash) */ +#define MTD_SET_BITS		2       /* Bits can be set */ +#define MTD_ERASEABLE		4       /* Has an erase function */ +#define MTD_WRITEB_WRITEABLE	8       /* Direct IO is possible */ +#define MTD_VOLATILE		16      /* Set for RAMs */ +#define MTD_XIP			32	/* eXecute-In-Place possible */ +#define MTD_OOB			64	/* Out-of-band data (NAND flash) */ +#define MTD_ECC			128	/* Device capable of automatic ECC */ +#define MTD_NO_VIRTBLOCKS	256	/* Virtual blocks not allowed */ + +/* Some common devices / combinations of capabilities */ +#define MTD_CAP_ROM		0 +#define MTD_CAP_RAM		(MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE) +#define MTD_CAP_NORFLASH        (MTD_CLEAR_BITS|MTD_ERASEABLE) +#define MTD_CAP_NANDFLASH       (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB) +#define MTD_WRITEABLE		(MTD_CLEAR_BITS|MTD_SET_BITS) + + +/* Types of automatic ECC/Checksum available */ +#define MTD_ECC_NONE		0 	/* No automatic ECC available */ +#define MTD_ECC_RS_DiskOnChip	1	/* Automatic ECC on DiskOnChip */ +#define MTD_ECC_SW		2	/* SW ECC for Toshiba & Samsung devices */ + +/* ECC byte placement */ +#define MTD_NANDECC_OFF		0	/* Switch off ECC (Not recommended) */ +#define MTD_NANDECC_PLACE	1	/* Use the given placement in the structure (YAFFS1 legacy mode) */ +#define MTD_NANDECC_AUTOPLACE	2	/* Use the default placement scheme */ +#define MTD_NANDECC_PLACEONLY	3	/* Use the given placement in the structure (Do not store ecc result on read) */ +#define MTD_NANDECC_AUTOPL_USR 	4	/* Use the given autoplacement scheme rather than using the default */ + +struct mtd_info_user { +	uint8_t type; +	uint32_t flags; +	uint32_t size;	 /* Total size of the MTD */ +	uint32_t erasesize; +	uint32_t oobblock;  /* Size of OOB blocks (e.g. 512) */ +	uint32_t oobsize;   /* Amount of OOB data per block (e.g. 16) */ +	uint32_t ecctype; +	uint32_t eccsize; +}; + +struct region_info_user { +	uint32_t offset;		/* At which this region starts, +					 * from the beginning of the MTD */ +	uint32_t erasesize;		/* For this region */ +	uint32_t numblocks;		/* Number of blocks in this region */ +	uint32_t regionindex; +}; + +#define MEMGETINFO              _IOR('M', 1, struct mtd_info_user) +#define MEMERASE                _IOW('M', 2, struct erase_info_user) +#define MEMWRITEOOB             _IOWR('M', 3, struct mtd_oob_buf) +#define MEMREADOOB              _IOWR('M', 4, struct mtd_oob_buf) +#define MEMLOCK                 _IOW('M', 5, struct erase_info_user) +#define MEMUNLOCK               _IOW('M', 6, struct erase_info_user) +#define MEMGETREGIONCOUNT	_IOR('M', 7, int) +#define MEMGETREGIONINFO	_IOWR('M', 8, struct region_info_user) +#define MEMSETOOBSEL		_IOW('M', 9, struct nand_oobinfo) +#define MEMGETOOBSEL		_IOR('M', 10, struct nand_oobinfo) +#define MEMGETBADBLOCK		_IOW('M', 11, loff_t) +#define MEMSETBADBLOCK		_IOW('M', 12, loff_t) + +struct nand_oobinfo { +	uint32_t useecc; +	uint32_t eccbytes; +	uint32_t oobfree[8][2]; +	uint32_t eccpos[32]; +}; + +#endif /* __MTD_ABI_H__ */ diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h new file mode 100644 index 000000000..13e90803a --- /dev/null +++ b/include/linux/mtd/mtd.h @@ -0,0 +1,214 @@ +/* + * $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $ + * + * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al. + * + * Released under GPL + */ + +#ifndef __MTD_MTD_H__ +#define __MTD_MTD_H__ +#include <linux/types.h> +#include <linux/mtd/mtd-abi.h> + +#define MAX_MTD_DEVICES 16 + +#define MTD_ERASE_PENDING      	0x01 +#define MTD_ERASING		0x02 +#define MTD_ERASE_SUSPEND	0x04 +#define MTD_ERASE_DONE          0x08 +#define MTD_ERASE_FAILED        0x10 + +/* If the erase fails, fail_addr might indicate exactly which block failed.  If +   fail_addr = 0xffffffff, the failure was not at the device level or was not +   specific to any particular block. */ +struct erase_info { +	struct mtd_info *mtd; +	u_int32_t addr; +	u_int32_t len; +	u_int32_t fail_addr; +	u_long time; +	u_long retries; +	u_int dev; +	u_int cell; +	void (*callback) (struct erase_info *self); +	u_long priv; +	u_char state; +	struct erase_info *next; +}; + +struct mtd_erase_region_info { +	u_int32_t offset;			/* At which this region starts, from the beginning of the MTD */ +	u_int32_t erasesize;		/* For this region */ +	u_int32_t numblocks;		/* Number of blocks of erasesize in this region */ +}; + +struct mtd_info { +	u_char type; +	u_int32_t flags; +	u_int32_t size;	 /* Total size of the MTD */ + +	/* "Major" erase size for the device. Naïve users may take this +	 * to be the only erase size available, or may use the more detailed +	 * information below if they desire +	 */ +	u_int32_t erasesize; + +	u_int32_t oobblock;  /* Size of OOB blocks (e.g. 512) */ +	u_int32_t oobsize;   /* Amount of OOB data per block (e.g. 16) */ +	u_int32_t oobavail;  /* Number of bytes in OOB area available for fs  */ +	u_int32_t ecctype; +	u_int32_t eccsize; + + +	/* Kernel-only stuff starts here. */ +	char *name; +	int index; + +	/* oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) */ +	struct nand_oobinfo oobinfo; + +	/* Data for variable erase regions. If numeraseregions is zero, +	 * it means that the whole device has erasesize as given above. +	 */ +	int numeraseregions; +	struct mtd_erase_region_info *eraseregions; + +	/* This really shouldn't be here. It can go away in 2.5 */ +	u_int32_t bank_size; + +	int (*erase) (struct mtd_info *mtd, struct erase_info *instr); + +	/* This stuff for eXecute-In-Place */ +	int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); + +	/* We probably shouldn't allow XIP if the unpoint isn't a NULL */ +	void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len); + + +	int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); +	int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); + +	int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); +	int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); + +	int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); +	int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); + +	/* +	 * Methods to access the protection register area, present in some +	 * flash devices. The user data is one time programmable but the +	 * factory data is read only. +	 */ +	int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + +	int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + +	/* This function is not yet implemented */ +	int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); +#if 0 +	/* kvec-based read/write methods. We need these especially for NAND flash, +	   with its limited number of write cycles per erase. +	   NB: The 'count' parameter is the number of _vectors_, each of +	   which contains an (ofs, len) tuple. +	*/ +	int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); +	int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, +		size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); +	int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); +	int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, +		size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); +#endif +	/* Sync */ +	void (*sync) (struct mtd_info *mtd); +#if 0 +	/* Chip-supported device locking */ +	int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); +	int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); + +	/* Power Management functions */ +	int (*suspend) (struct mtd_info *mtd); +	void (*resume) (struct mtd_info *mtd); +#endif +	/* Bad block management functions */ +	int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); +	int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); + +	void *priv; + +	struct module *owner; +	int usecount; +}; + + +	/* Kernel-side ioctl definitions */ + +extern int add_mtd_device(struct mtd_info *mtd); +extern int del_mtd_device (struct mtd_info *mtd); + +extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); + +extern void put_mtd_device(struct mtd_info *mtd); + +#if 0 +struct mtd_notifier { +	void (*add)(struct mtd_info *mtd); +	void (*remove)(struct mtd_info *mtd); +	struct list_head list; +}; + + +extern void register_mtd_user (struct mtd_notifier *new); +extern int unregister_mtd_user (struct mtd_notifier *old); + +int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, +		       unsigned long count, loff_t to, size_t *retlen); + +int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, +		      unsigned long count, loff_t from, size_t *retlen); +#endif + +#define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args) +#define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d)) +#define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg) +#define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args) +#define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args) +#define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args) +#define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args) +#define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args) +#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) +#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) +#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) +#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd);  } while (0) + + +#ifdef CONFIG_MTD_PARTITIONS +void mtd_erase_callback(struct erase_info *instr); +#else +static inline void mtd_erase_callback(struct erase_info *instr) +{ +	if (instr->callback) +		instr->callback(instr); +} +#endif + +/* + * Debugging macro and defines + */ +#define MTD_DEBUG_LEVEL0	(0)	/* Quiet   */ +#define MTD_DEBUG_LEVEL1	(1)	/* Audible */ +#define MTD_DEBUG_LEVEL2	(2)	/* Loud    */ +#define MTD_DEBUG_LEVEL3	(3)	/* Noisy   */ + +#ifdef CONFIG_MTD_DEBUG +#define DEBUG(n, args...)				\ + 	do {						\ +		if (n <= CONFIG_MTD_DEBUG_VERBOSE)	\ +			printk(KERN_INFO args);		\ +	} while(0) +#else /* CONFIG_MTD_DEBUG */ +#define DEBUG(n, args...) do { } while(0) + +#endif /* CONFIG_MTD_DEBUG */ + +#endif /* __MTD_MTD_H__ */ diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 523690495..b0894c5e8 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -36,6 +36,9 @@  #ifndef __LINUX_MTD_NAND_H  #define __LINUX_MTD_NAND_H +#ifdef CONFIG_NEW_NAND_CODE +#include "nand_new.h" +#else  /*   * Standard NAND flash commands   */ @@ -196,5 +199,5 @@ struct nand_flash_dev {  #define NAND_JFFS2_OOB16_FSDALEN	8  unsigned long nand_probe(unsigned long physadr); - +#endif /* !CONFIG_NEW_NAND_CODE */  #endif /* __LINUX_MTD_NAND_H */ diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h new file mode 100644 index 000000000..12c5bc342 --- /dev/null +++ b/include/linux/mtd/nand_ecc.h @@ -0,0 +1,30 @@ +/* + *  drivers/mtd/nand_ecc.h + * + *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) + * + * $Id: nand_ecc.h,v 1.4 2004/06/17 02:35:02 dbrown Exp $ + * + * 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. + * + * This file is the header for the ECC algorithm. + */ + +#ifndef __MTD_NAND_ECC_H__ +#define __MTD_NAND_ECC_H__ + +struct mtd_info; + +/* + * Calculate 3 byte ECC code for 256 byte block + */ +int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); + +/* + * Detect and correct a 1 bit error for 256 byte block + */ +int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); + +#endif /* __MTD_NAND_ECC_H__ */ diff --git a/include/linux/mtd/nand_ids.h b/include/linux/mtd/nand_ids.h index a3d0363a2..75c305b56 100644 --- a/include/linux/mtd/nand_ids.h +++ b/include/linux/mtd/nand_ids.h @@ -49,6 +49,7 @@ static struct nand_flash_dev nand_flash_ids[] = {  	{"Samsung KM29W16000",    NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000, 0},  	{"Samsung K9F5616Q0C",    NAND_MFR_SAMSUNG, 0x45, 25, 0, 2, 0x4000, 1},  	{"Samsung K9K1216Q0C",    NAND_MFR_SAMSUNG, 0x46, 26, 0, 3, 0x4000, 1}, +	{"Samsung K9F1G08U0M",    NAND_MFR_SAMSUNG, 0xf1, 27, 0, 2, 0, 0},  	{NULL,}  }; diff --git a/include/linux/mtd/nand_new.h b/include/linux/mtd/nand_new.h new file mode 100644 index 000000000..7d4b805b9 --- /dev/null +++ b/include/linux/mtd/nand_new.h @@ -0,0 +1,469 @@ +/* + *  linux/include/linux/mtd/nand.h + * + *  Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com> + *                     Steven J. Hill <sjhill@realitydiluted.com> + *		       Thomas Gleixner <tglx@linutronix.de> + * + * $Id: nand.h,v 1.68 2004/11/12 10:40:37 gleixner Exp $ + * + * 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: + *   01-31-2000 DMW     Created + *   09-18-2000 SJH     Moved structure out of the Disk-On-Chip drivers + *			so it can be used by other NAND flash device + *			drivers. I also changed the copyright since none + *			of the original contents of this file are specific + *			to DoC devices. David can whack me with a baseball + *			bat later if I did something naughty. + *   10-11-2000 SJH     Added private NAND flash structure for driver + *   10-24-2000 SJH     Added prototype for 'nand_scan' function + *   10-29-2001 TG	changed nand_chip structure to support + *			hardwarespecific function for accessing control lines + *   02-21-2002 TG	added support for different read/write adress and + *			ready/busy line access function + *   02-26-2002 TG	added chip_delay to nand_chip structure to optimize + *			command delay times for different chips + *   04-28-2002 TG	OOB config defines moved from nand.c to avoid duplicate + *			defines in jffs2/wbuf.c + *   08-07-2002 TG	forced bad block location to byte 5 of OOB, even if + *			CONFIG_MTD_NAND_ECC_JFFS2 is not set + *   08-10-2002 TG	extensions to nand_chip structure to support HW-ECC + * + *   08-29-2002 tglx 	nand_chip structure: data_poi for selecting + *			internal / fs-driver buffer + *			support for 6byte/512byte hardware ECC + *			read_ecc, write_ecc extended for different oob-layout + *			oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB, + *			NAND_YAFFS_OOB + *  11-25-2002 tglx	Added Manufacturer code FUJITSU, NATIONAL + *			Split manufacturer and device ID structures + * + *  02-08-2004 tglx 	added option field to nand structure for chip anomalities + *  05-25-2004 tglx 	added bad block table support, ST-MICRO manufacturer id + *			update of nand_chip structure description + */ +#ifndef __LINUX_MTD_NAND_NEW_H +#define __LINUX_MTD_NAND_NEW_H + +#include <linux/mtd/compat.h> +#include <linux/mtd/mtd.h> + +struct mtd_info; +/* Scan and identify a NAND device */ +extern int nand_scan (struct mtd_info *mtd, int max_chips); +/* Free resources held by the NAND device */ +extern void nand_release (struct mtd_info *mtd); + +/* Read raw data from the device without ECC */ +extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen); + + + +/* 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	64 + +/* + * Constants for hardware specific CLE/ALE/NCE function +*/ +/* Select the chip by setting nCE to low */ +#define NAND_CTL_SETNCE 	1 +/* Deselect the chip by setting nCE to high */ +#define NAND_CTL_CLRNCE		2 +/* Select the command latch by setting CLE to high */ +#define NAND_CTL_SETCLE		3 +/* Deselect the command latch by setting CLE to low */ +#define NAND_CTL_CLRCLE		4 +/* Select the address latch by setting ALE to high */ +#define NAND_CTL_SETALE		5 +/* Deselect the address latch by setting ALE to low */ +#define NAND_CTL_CLRALE		6 +/* Set write protection by setting WP to high. Not used! */ +#define NAND_CTL_SETWP		7 +/* Clear write protection by setting WP to low. Not used! */ +#define NAND_CTL_CLRWP		8 + +/* + * Standard NAND flash commands + */ +#define NAND_CMD_READ0		0 +#define NAND_CMD_READ1		1 +#define NAND_CMD_PAGEPROG	0x10 +#define NAND_CMD_READOOB	0x50 +#define NAND_CMD_ERASE1		0x60 +#define NAND_CMD_STATUS		0x70 +#define NAND_CMD_STATUS_MULTI	0x71 +#define NAND_CMD_SEQIN		0x80 +#define NAND_CMD_READID		0x90 +#define NAND_CMD_ERASE2		0xd0 +#define NAND_CMD_RESET		0xff + +/* Extended commands for large page devices */ +#define NAND_CMD_READSTART	0x30 +#define NAND_CMD_CACHEDPROG	0x15 + +/* 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 + */ + +/* No ECC. Usage is not recommended ! */ +#define NAND_ECC_NONE		0 +/* Software ECC 3 byte ECC per 256 Byte data */ +#define NAND_ECC_SOFT		1 +/* Hardware ECC 3 byte ECC per 256 Byte data */ +#define NAND_ECC_HW3_256	2 +/* Hardware ECC 3 byte ECC per 512 Byte data */ +#define NAND_ECC_HW3_512	3 +/* Hardware ECC 3 byte ECC per 512 Byte data */ +#define NAND_ECC_HW6_512	4 +/* Hardware ECC 8 byte ECC per 512 Byte data */ +#define NAND_ECC_HW8_512	6 +/* Hardware ECC 12 byte ECC per 2048 Byte data */ +#define NAND_ECC_HW12_2048	7 + +/* + * 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 + +/* 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 + +/* 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)) + +/* 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 +/* The hw ecc generator provides a syndrome instead a ecc value on read + * This can only work if we have the ecc bytes directly behind the + * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ +#define NAND_HWECC_SYNDROME	0x00020000 + + +/* Options set by nand scan */ +/* Nand scan has allocated oob_buf */ +#define NAND_OOBBUF_ALLOC	0x40000000 +/* Nand scan has allocated data_buf */ +#define NAND_DATABUF_ALLOC	0x80000000 + + +/* + * nand_state_t - chip states + * Enumeration for NAND flash chip state + */ +typedef enum { +	FL_READY, +	FL_READING, +	FL_WRITING, +	FL_ERASING, +	FL_SYNCING, +	FL_CACHEDPRG, +} nand_state_t; + +/* Keep gcc happy */ +struct nand_chip; + +#if 0 +/** + * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices + * @lock:               protection lock + * @active:		the mtd device which holds the controller currently + */ +struct nand_hw_control { +	spinlock_t	 lock; +	struct nand_chip *active; +}; +#endif + +/** + * struct nand_chip - NAND Private Flash Chip Data + * @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 flash device + * @read_byte:		[REPLACEABLE] read one byte from the chip + * @write_byte:		[REPLACEABLE] write one byte to the chip + * @read_word:		[REPLACEABLE] read one word from the chip + * @write_word:		[REPLACEABLE] write one word to the chip + * @write_buf:		[REPLACEABLE] write data from the buffer to the chip + * @read_buf:		[REPLACEABLE] read data from the chip into the buffer + * @verify_buf:		[REPLACEABLE] verify buffer contents against the chip data + * @select_chip:	[REPLACEABLE] select chip nr + * @block_bad:		[REPLACEABLE] check, if the block is bad + * @block_markbad:	[REPLACEABLE] mark the block bad + * @hwcontrol:		[BOARDSPECIFIC] hardwarespecific function for accesing control-lines + * @dev_ready:		[BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line + *			If set to NULL no access to ready/busy is available and the ready/busy information + *			is read from the chip status register + * @cmdfunc:		[REPLACEABLE] hardwarespecific function for writing commands to the chip + * @waitfunc:		[REPLACEABLE] hardwarespecific function for wait on ready + * @calculate_ecc: 	[REPLACEABLE] function for ecc calculation or readback from ecc hardware + * @correct_data:	[REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw) + * @enable_hwecc:	[BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only + *			be provided if a hardware ECC is available + * @erase_cmd:		[INTERN] erase command write function, selectable due to AND support + * @scan_bbt:		[REPLACEABLE] function to scan bad block table + * @eccmode:		[BOARDSPECIFIC] mode of ecc, see defines + * @eccsize: 		[INTERN] databytes used per ecc-calculation + * @eccbytes: 		[INTERN] number of ecc bytes per ecc-calculation step + * @eccsteps:		[INTERN] number of ecc calculation steps per page + * @chip_delay:		[BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR) + * @chip_lock:		[INTERN] spinlock used to protect access to this structure and the chip + * @wq:			[INTERN] wait queue to sleep on if a NAND operation is in progress + * @state: 		[INTERN] the current state of the NAND device + * @page_shift:		[INTERN] number of address bits in a page (column address bits) + * @phys_erase_shift:	[INTERN] number of address bits in a physical eraseblock + * @bbt_erase_shift:	[INTERN] number of address bits in a bbt entry + * @chip_shift:		[INTERN] number of address bits in one chip + * @data_buf:		[INTERN] internal buffer for one page + oob + * @oob_buf:		[INTERN] oob buffer for one eraseblock + * @oobdirty:		[INTERN] indicates that oob_buf must be reinitialized + * @data_poi:		[INTERN] pointer to a data buffer + * @options:		[BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about + *			special functionality. See the defines for further explanation + * @badblockpos:	[INTERN] position of the bad block marker in the oob area + * @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 + * @pagebuf:		[INTERN] holds the pagenumber which is currently in data_buf + * @autooob:		[REPLACEABLE] the default (auto)placement scheme + * @bbt:		[INTERN] bad block table pointer + * @bbt_td:		[REPLACEABLE] bad block table descriptor for flash lookup + * @bbt_md:		[REPLACEABLE] bad block table mirror descriptor + * @badblock_pattern:	[REPLACEABLE] bad block scan pattern used for initial bad block scan + * @controller:		[OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices + * @priv:		[OPTIONAL] pointer to private chip date + */ + +struct nand_chip { +	void  __iomem	*IO_ADDR_R; +	void  __iomem 	*IO_ADDR_W; + +	u_char		(*read_byte)(struct mtd_info *mtd); +	void		(*write_byte)(struct mtd_info *mtd, u_char byte); +	u16		(*read_word)(struct mtd_info *mtd); +	void		(*write_word)(struct mtd_info *mtd, u16 word); + +	void		(*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); +	void		(*read_buf)(struct mtd_info *mtd, u_char *buf, int len); +	int		(*verify_buf)(struct mtd_info *mtd, const u_char *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_markbad)(struct mtd_info *mtd, loff_t ofs); +	void 		(*hwcontrol)(struct mtd_info *mtd, int cmd); +	int  		(*dev_ready)(struct mtd_info *mtd); +	void 		(*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); +	int 		(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); +	int		(*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); +	int 		(*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); +	void		(*enable_hwecc)(struct mtd_info *mtd, int mode); +	void		(*erase_cmd)(struct mtd_info *mtd, int page); +	int		(*scan_bbt)(struct mtd_info *mtd); +	int		eccmode; +	int		eccsize; +	int		eccbytes; +	int		eccsteps; +	int 		chip_delay; +#if 0 +	spinlock_t	chip_lock; +	wait_queue_head_t wq; +	nand_state_t 	state; +#endif +	int 		page_shift; +	int		phys_erase_shift; +	int		bbt_erase_shift; +	int		chip_shift; +	u_char 		*data_buf; +	u_char		*oob_buf; +	int		oobdirty; +	u_char		*data_poi; +	unsigned int	options; +	int		badblockpos; +	int		numchips; +	unsigned long	chipsize; +	int		pagemask; +	int		pagebuf; +	struct nand_oobinfo	*autooob; +	uint8_t		*bbt; +	struct nand_bbt_descr	*bbt_td; +	struct nand_bbt_descr	*bbt_md; +	struct nand_bbt_descr	*badblock_pattern; +	struct nand_hw_control  *controller; +	void		*priv; +}; + +/* + * 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 + +/** + * struct nand_flash_dev - NAND Flash Device ID Structure + * + * @name:  	Identify the device type + * @id:   	device ID code + * @pagesize:  	Pagesize in bytes. Either 256 or 512 or 0 + *		If the pagesize is 0, then the real pagesize + *		and the eraseize are determined from the + *		extended id bytes in the chip + * @erasesize: 	Size of an erase block in the flash device. + * @chipsize:  	Total chipsize in Mega Bytes + * @options:	Bitfield to store chip relevant options + */ +struct nand_flash_dev { +	char *name; +	int id; +	unsigned long pagesize; +	unsigned long chipsize; +	unsigned long erasesize; +	unsigned long options; +}; + +/** + * struct nand_manufacturers - NAND Flash Manufacturer ID Structure + * @name:	Manufacturer name + * @id: 	manufacturer ID code of device. +*/ +struct nand_manufacturers { +	int id; +	char * name; +}; + +extern struct nand_flash_dev nand_flash_ids[]; +extern struct nand_manufacturers nand_manuf_ids[]; + +/** + * struct nand_bbt_descr - bad block table descriptor + * @options:	options for this descriptor + * @pages:	the page(s) where we find the bbt, used with option BBT_ABSPAGE + *		when bbt is searched, then we store the found bbts pages here. + *		Its an array and supports up to 8 chips now + * @offs:	offset of the pattern in the oob area of the page + * @veroffs:	offset of the bbt version counter in the oob are of the page + * @version:	version read from the bbt page during scan + * @len:	length of the pattern, if 0 no pattern check is performed + * @maxblocks:	maximum number of blocks to search for a bbt. This number of + *		blocks is reserved at the end of the device where the tables are + *		written. + * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than + *              bad) block in the stored bbt + * @pattern:	pattern to identify bad block table or factory marked good / + *		bad blocks, can be NULL, if len = 0 + * + * Descriptor for the bad block table marker and the descriptor for the + * pattern which identifies good and bad blocks. The assumption is made + * that the pattern and the version count are always located in the oob area + * of the first block. + */ +struct nand_bbt_descr { +	int	options; +	int	pages[NAND_MAX_CHIPS]; +	int	offs; +	int	veroffs; +	uint8_t	version[NAND_MAX_CHIPS]; +	int	len; +	int 	maxblocks; +	int	reserved_block_code; +	uint8_t	*pattern; +}; + +/* Options for the bad block table descriptors */ + +/* The number of bits used per block in the bbt on the device */ +#define NAND_BBT_NRBITS_MSK	0x0000000F +#define NAND_BBT_1BIT		0x00000001 +#define NAND_BBT_2BIT		0x00000002 +#define NAND_BBT_4BIT		0x00000004 +#define NAND_BBT_8BIT		0x00000008 +/* The bad block table is in the last good block of the device */ +#define	NAND_BBT_LASTBLOCK	0x00000010 +/* The bbt is at the given page, else we must scan for the bbt */ +#define NAND_BBT_ABSPAGE	0x00000020 +/* The bbt is at the given page, else we must scan for the bbt */ +#define NAND_BBT_SEARCH		0x00000040 +/* bbt is stored per chip on multichip devices */ +#define NAND_BBT_PERCHIP	0x00000080 +/* bbt has a version counter at offset veroffs */ +#define NAND_BBT_VERSION	0x00000100 +/* Create a bbt if none axists */ +#define NAND_BBT_CREATE		0x00000200 +/* Search good / bad pattern through all pages of a block */ +#define NAND_BBT_SCANALLPAGES	0x00000400 +/* Scan block empty during good / bad block scan */ +#define NAND_BBT_SCANEMPTY	0x00000800 +/* Write bbt if neccecary */ +#define NAND_BBT_WRITE		0x00001000 +/* Read and write back block contents when writing bbt */ +#define NAND_BBT_SAVECONTENT	0x00002000 +/* Search good / bad pattern on the first and the second page */ +#define NAND_BBT_SCAN2NDPAGE	0x00004000 + +/* The maximum number of blocks to scan for a bbt */ +#define NAND_BBT_SCAN_MAXBLOCKS	4 + +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_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); + +/* +* Constants for oob configuration +*/ +#define NAND_SMALL_BADBLOCK_POS		5 +#define NAND_LARGE_BADBLOCK_POS		0 + +#endif /* __LINUX_MTD_NAND_NEW_H */ |