xref: /rk3399_rockchip-uboot/include/linux/mtd/mtd.h (revision c45912d8abc52de796b9059a58faf7c4166eab58)
1932394acSWolfgang Denk /*
2932394acSWolfgang Denk  * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
3932394acSWolfgang Denk  *
4932394acSWolfgang Denk  * Released under GPL
5932394acSWolfgang Denk  */
6932394acSWolfgang Denk 
7932394acSWolfgang Denk #ifndef __MTD_MTD_H__
8932394acSWolfgang Denk #define __MTD_MTD_H__
9cfa460adSWilliam Juul 
10932394acSWolfgang Denk #include <linux/types.h>
11932394acSWolfgang Denk #include <linux/mtd/mtd-abi.h>
12932394acSWolfgang Denk 
13cfa460adSWilliam Juul #define MTD_CHAR_MAJOR 90
14cfa460adSWilliam Juul #define MTD_BLOCK_MAJOR 31
15cfa460adSWilliam Juul #define MAX_MTD_DEVICES 32
16932394acSWolfgang Denk 
17932394acSWolfgang Denk #define MTD_ERASE_PENDING	0x01
18932394acSWolfgang Denk #define MTD_ERASING		0x02
19932394acSWolfgang Denk #define MTD_ERASE_SUSPEND	0x04
20932394acSWolfgang Denk #define MTD_ERASE_DONE          0x08
21932394acSWolfgang Denk #define MTD_ERASE_FAILED        0x10
22932394acSWolfgang Denk 
23d438d508SKyungmin Park /*
24d438d508SKyungmin Park  * Enumeration for NAND/OneNAND flash chip state
25d438d508SKyungmin Park  */
26d438d508SKyungmin Park enum {
27d438d508SKyungmin Park 	FL_READY,
28d438d508SKyungmin Park 	FL_READING,
29d438d508SKyungmin Park 	FL_WRITING,
30d438d508SKyungmin Park 	FL_ERASING,
31d438d508SKyungmin Park 	FL_SYNCING,
32d438d508SKyungmin Park 	FL_CACHEDPRG,
33d438d508SKyungmin Park 	FL_RESETING,
34d438d508SKyungmin Park 	FL_UNLOCKING,
35d438d508SKyungmin Park 	FL_LOCKING,
36d438d508SKyungmin Park 	FL_PM_SUSPENDED,
37d438d508SKyungmin Park };
38d438d508SKyungmin Park 
39932394acSWolfgang Denk /* If the erase fails, fail_addr might indicate exactly which block failed.  If
40932394acSWolfgang Denk    fail_addr = 0xffffffff, the failure was not at the device level or was not
41932394acSWolfgang Denk    specific to any particular block. */
42932394acSWolfgang Denk struct erase_info {
43932394acSWolfgang Denk 	struct mtd_info *mtd;
44932394acSWolfgang Denk 	u_int32_t addr;
45932394acSWolfgang Denk 	u_int32_t len;
46932394acSWolfgang Denk 	u_int32_t fail_addr;
47932394acSWolfgang Denk 	u_long time;
48932394acSWolfgang Denk 	u_long retries;
49932394acSWolfgang Denk 	u_int dev;
50932394acSWolfgang Denk 	u_int cell;
51932394acSWolfgang Denk 	void (*callback) (struct erase_info *self);
52932394acSWolfgang Denk 	u_long priv;
53932394acSWolfgang Denk 	u_char state;
54932394acSWolfgang Denk 	struct erase_info *next;
55932394acSWolfgang Denk };
56932394acSWolfgang Denk 
57932394acSWolfgang Denk struct mtd_erase_region_info {
58932394acSWolfgang Denk 	u_int32_t offset;			/* At which this region starts, from the beginning of the MTD */
59932394acSWolfgang Denk 	u_int32_t erasesize;		/* For this region */
60932394acSWolfgang Denk 	u_int32_t numblocks;		/* Number of blocks of erasesize in this region */
61cfa460adSWilliam Juul 	unsigned long *lockmap;		/* If keeping bitmap of locks */
62cfa460adSWilliam Juul };
63cfa460adSWilliam Juul 
64cfa460adSWilliam Juul /*
65cfa460adSWilliam Juul  * oob operation modes
66cfa460adSWilliam Juul  *
67cfa460adSWilliam Juul  * MTD_OOB_PLACE:	oob data are placed at the given offset
68cfa460adSWilliam Juul  * MTD_OOB_AUTO:	oob data are automatically placed at the free areas
69cfa460adSWilliam Juul  *			which are defined by the ecclayout
70cfa460adSWilliam Juul  * MTD_OOB_RAW:		mode to read raw data+oob in one chunk. The oob data
71cfa460adSWilliam Juul  *			is inserted into the data. Thats a raw image of the
72cfa460adSWilliam Juul  *			flash contents.
73cfa460adSWilliam Juul  */
74cfa460adSWilliam Juul typedef enum {
75cfa460adSWilliam Juul 	MTD_OOB_PLACE,
76cfa460adSWilliam Juul 	MTD_OOB_AUTO,
77cfa460adSWilliam Juul 	MTD_OOB_RAW,
78cfa460adSWilliam Juul } mtd_oob_mode_t;
79cfa460adSWilliam Juul 
80cfa460adSWilliam Juul /**
81cfa460adSWilliam Juul  * struct mtd_oob_ops - oob operation operands
82cfa460adSWilliam Juul  * @mode:	operation mode
83cfa460adSWilliam Juul  *
84cfa460adSWilliam Juul  * @len:	number of data bytes to write/read
85cfa460adSWilliam Juul  *
86cfa460adSWilliam Juul  * @retlen:	number of data bytes written/read
87cfa460adSWilliam Juul  *
88cfa460adSWilliam Juul  * @ooblen:	number of oob bytes to write/read
89cfa460adSWilliam Juul  * @oobretlen:	number of oob bytes written/read
90cfa460adSWilliam Juul  * @ooboffs:	offset of oob data in the oob area (only relevant when
91cfa460adSWilliam Juul  *		mode = MTD_OOB_PLACE)
92cfa460adSWilliam Juul  * @datbuf:	data buffer - if NULL only oob data are read/written
93cfa460adSWilliam Juul  * @oobbuf:	oob data buffer
94cfa460adSWilliam Juul  *
95cfa460adSWilliam Juul  * Note, it is allowed to read more then one OOB area at one go, but not write.
96cfa460adSWilliam Juul  * The interface assumes that the OOB write requests program only one page's
97cfa460adSWilliam Juul  * OOB area.
98cfa460adSWilliam Juul  */
99cfa460adSWilliam Juul struct mtd_oob_ops {
100cfa460adSWilliam Juul 	mtd_oob_mode_t	mode;
101cfa460adSWilliam Juul 	size_t		len;
102cfa460adSWilliam Juul 	size_t		retlen;
103cfa460adSWilliam Juul 	size_t		ooblen;
104cfa460adSWilliam Juul 	size_t		oobretlen;
105cfa460adSWilliam Juul 	uint32_t	ooboffs;
106cfa460adSWilliam Juul 	uint8_t		*datbuf;
107cfa460adSWilliam Juul 	uint8_t		*oobbuf;
108932394acSWolfgang Denk };
109932394acSWolfgang Denk 
110932394acSWolfgang Denk struct mtd_info {
111932394acSWolfgang Denk 	u_char type;
112932394acSWolfgang Denk 	u_int32_t flags;
1134b070809SWolfgang Denk 	u_int32_t size;	 /* Total size of the MTD */
114932394acSWolfgang Denk 
115cfa460adSWilliam Juul 	/* "Major" erase size for the device. Naïve users may take this
116932394acSWolfgang Denk 	 * to be the only erase size available, or may use the more detailed
117932394acSWolfgang Denk 	 * information below if they desire
118932394acSWolfgang Denk 	 */
119932394acSWolfgang Denk 	u_int32_t erasesize;
120cfa460adSWilliam Juul 	/* Minimal writable flash unit size. In case of NOR flash it is 1 (even
121cfa460adSWilliam Juul 	 * though individual bits can be cleared), in case of NAND flash it is
122cfa460adSWilliam Juul 	 * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
123cfa460adSWilliam Juul 	 * it is of ECC block size, etc. It is illegal to have writesize = 0.
124cfa460adSWilliam Juul 	 * Any driver registering a struct mtd_info must ensure a writesize of
125cfa460adSWilliam Juul 	 * 1 or larger.
126cfa460adSWilliam Juul 	 */
127cfa460adSWilliam Juul 	u_int32_t writesize;
128932394acSWolfgang Denk 
1294b070809SWolfgang Denk 	u_int32_t oobsize;   /* Amount of OOB data per block (e.g. 16) */
1304b070809SWolfgang Denk 	u_int32_t oobavail;  /* Available OOB bytes per block */
131932394acSWolfgang Denk 
1324b070809SWolfgang Denk 	/* Kernel-only stuff starts here. */
133*c45912d8SScott Wood 	const char *name;
134932394acSWolfgang Denk 	int index;
135932394acSWolfgang Denk 
136cfa460adSWilliam Juul 	/* ecc layout structure pointer - read only ! */
137cfa460adSWilliam Juul 	struct nand_ecclayout *ecclayout;
138932394acSWolfgang Denk 
139932394acSWolfgang Denk 	/* Data for variable erase regions. If numeraseregions is zero,
140932394acSWolfgang Denk 	 * it means that the whole device has erasesize as given above.
141932394acSWolfgang Denk 	 */
142932394acSWolfgang Denk 	int numeraseregions;
143932394acSWolfgang Denk 	struct mtd_erase_region_info *eraseregions;
144932394acSWolfgang Denk 
145*c45912d8SScott Wood 	/*
146*c45912d8SScott Wood 	 * Erase is an asynchronous operation.  Device drivers are supposed
147*c45912d8SScott Wood 	 * to call instr->callback() whenever the operation completes, even
148*c45912d8SScott Wood 	 * if it completes with a failure.
149*c45912d8SScott Wood 	 * Callers are supposed to pass a callback function and wait for it
150*c45912d8SScott Wood 	 * to be called before writing to the block.
151*c45912d8SScott Wood 	 */
152932394acSWolfgang Denk 	int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
153932394acSWolfgang Denk 
154932394acSWolfgang Denk 	/* This stuff for eXecute-In-Place */
155*c45912d8SScott Wood 	/* phys is optional and may be set to NULL */
156*c45912d8SScott Wood 	int (*point) (struct mtd_info *mtd, loff_t from, size_t len,
157*c45912d8SScott Wood 			size_t *retlen, void **virt, phys_addr_t *phys);
158932394acSWolfgang Denk 
159932394acSWolfgang Denk 	/* We probably shouldn't allow XIP if the unpoint isn't a NULL */
160*c45912d8SScott Wood 	void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
161932394acSWolfgang Denk 
162932394acSWolfgang Denk 
163932394acSWolfgang Denk 	int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
164932394acSWolfgang Denk 	int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
165932394acSWolfgang Denk 
166*c45912d8SScott Wood 	/* In blackbox flight recorder like scenarios we want to make successful
167*c45912d8SScott Wood 	   writes in interrupt context. panic_write() is only intended to be
168*c45912d8SScott Wood 	   called when its known the kernel is about to panic and we need the
169*c45912d8SScott Wood 	   write to succeed. Since the kernel is not going to be running for much
170*c45912d8SScott Wood 	   longer, this function can break locks and delay to ensure the write
171*c45912d8SScott Wood 	   succeeds (but not sleep). */
172*c45912d8SScott Wood 
173*c45912d8SScott Wood 	int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
174*c45912d8SScott Wood 
175cfa460adSWilliam Juul 	int (*read_oob) (struct mtd_info *mtd, loff_t from,
176cfa460adSWilliam Juul 			 struct mtd_oob_ops *ops);
177cfa460adSWilliam Juul 	int (*write_oob) (struct mtd_info *mtd, loff_t to,
178cfa460adSWilliam Juul 			 struct mtd_oob_ops *ops);
179932394acSWolfgang Denk 
180932394acSWolfgang Denk 	/*
181932394acSWolfgang Denk 	 * Methods to access the protection register area, present in some
182932394acSWolfgang Denk 	 * flash devices. The user data is one time programmable but the
183932394acSWolfgang Denk 	 * factory data is read only.
184932394acSWolfgang Denk 	 */
185cfa460adSWilliam Juul 	int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
186932394acSWolfgang Denk 	int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
187cfa460adSWilliam Juul 	int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
188cfa460adSWilliam Juul 	int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
189932394acSWolfgang Denk 	int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
190cfa460adSWilliam Juul 	int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
191cfa460adSWilliam Juul 
192cfa460adSWilliam Juul /* XXX U-BOOT XXX */
193932394acSWolfgang Denk #if 0
194cfa460adSWilliam Juul 	/* kvec-based read/write methods.
195932394acSWolfgang Denk 	   NB: The 'count' parameter is the number of _vectors_, each of
196932394acSWolfgang Denk 	   which contains an (ofs, len) tuple.
197932394acSWolfgang Denk 	*/
198932394acSWolfgang Denk 	int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
199932394acSWolfgang Denk #endif
200cfa460adSWilliam Juul 
201932394acSWolfgang Denk 	/* Sync */
202932394acSWolfgang Denk 	void (*sync) (struct mtd_info *mtd);
203cfa460adSWilliam Juul 
204932394acSWolfgang Denk 	/* Chip-supported device locking */
205932394acSWolfgang Denk 	int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len);
206932394acSWolfgang Denk 	int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len);
207932394acSWolfgang Denk 
208932394acSWolfgang Denk 	/* Power Management functions */
209932394acSWolfgang Denk 	int (*suspend) (struct mtd_info *mtd);
210932394acSWolfgang Denk 	void (*resume) (struct mtd_info *mtd);
211cfa460adSWilliam Juul 
212932394acSWolfgang Denk 	/* Bad block management functions */
213932394acSWolfgang Denk 	int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
214932394acSWolfgang Denk 	int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
215932394acSWolfgang Denk 
216cfa460adSWilliam Juul /* XXX U-BOOT XXX */
217cfa460adSWilliam Juul #if 0
218cfa460adSWilliam Juul 	struct notifier_block reboot_notifier;  /* default mode before reboot */
219cfa460adSWilliam Juul #endif
220cfa460adSWilliam Juul 
221cfa460adSWilliam Juul 	/* ECC status information */
222cfa460adSWilliam Juul 	struct mtd_ecc_stats ecc_stats;
223cfa460adSWilliam Juul 	/* Subpage shift (NAND) */
224cfa460adSWilliam Juul 	int subpage_sft;
225cfa460adSWilliam Juul 
226932394acSWolfgang Denk 	void *priv;
227932394acSWolfgang Denk 
228932394acSWolfgang Denk 	struct module *owner;
229932394acSWolfgang Denk 	int usecount;
230cfa460adSWilliam Juul 
231cfa460adSWilliam Juul 	/* If the driver is something smart, like UBI, it may need to maintain
232cfa460adSWilliam Juul 	 * its own reference counting. The below functions are only for driver.
233cfa460adSWilliam Juul 	 * The driver may register its callbacks. These callbacks are not
234cfa460adSWilliam Juul 	 * supposed to be called by MTD users */
235cfa460adSWilliam Juul 	int (*get_device) (struct mtd_info *mtd);
236cfa460adSWilliam Juul 	void (*put_device) (struct mtd_info *mtd);
237932394acSWolfgang Denk };
238932394acSWolfgang Denk 
239932394acSWolfgang Denk 
240932394acSWolfgang Denk 	/* Kernel-side ioctl definitions */
241932394acSWolfgang Denk 
242932394acSWolfgang Denk extern int add_mtd_device(struct mtd_info *mtd);
243932394acSWolfgang Denk extern int del_mtd_device (struct mtd_info *mtd);
244932394acSWolfgang Denk 
245932394acSWolfgang Denk extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
246cfa460adSWilliam Juul extern struct mtd_info *get_mtd_device_nm(const char *name);
247932394acSWolfgang Denk 
248932394acSWolfgang Denk extern void put_mtd_device(struct mtd_info *mtd);
249932394acSWolfgang Denk 
250cfa460adSWilliam Juul /* XXX U-BOOT XXX */
251932394acSWolfgang Denk #if 0
252932394acSWolfgang Denk struct mtd_notifier {
253932394acSWolfgang Denk 	void (*add)(struct mtd_info *mtd);
254932394acSWolfgang Denk 	void (*remove)(struct mtd_info *mtd);
255932394acSWolfgang Denk 	struct list_head list;
256932394acSWolfgang Denk };
257932394acSWolfgang Denk 
258932394acSWolfgang Denk extern void register_mtd_user (struct mtd_notifier *new);
259932394acSWolfgang Denk extern int unregister_mtd_user (struct mtd_notifier *old);
260932394acSWolfgang Denk 
261932394acSWolfgang Denk int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
262932394acSWolfgang Denk 		       unsigned long count, loff_t to, size_t *retlen);
263932394acSWolfgang Denk 
264932394acSWolfgang Denk int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
265932394acSWolfgang Denk 		      unsigned long count, loff_t from, size_t *retlen);
266932394acSWolfgang Denk #endif
267932394acSWolfgang Denk 
268932394acSWolfgang Denk #ifdef CONFIG_MTD_PARTITIONS
269932394acSWolfgang Denk void mtd_erase_callback(struct erase_info *instr);
270932394acSWolfgang Denk #else
271932394acSWolfgang Denk static inline void mtd_erase_callback(struct erase_info *instr)
272932394acSWolfgang Denk {
273932394acSWolfgang Denk 	if (instr->callback)
274932394acSWolfgang Denk 		instr->callback(instr);
275932394acSWolfgang Denk }
276932394acSWolfgang Denk #endif
277932394acSWolfgang Denk 
278932394acSWolfgang Denk /*
279932394acSWolfgang Denk  * Debugging macro and defines
280932394acSWolfgang Denk  */
281932394acSWolfgang Denk #define MTD_DEBUG_LEVEL0	(0)	/* Quiet   */
282932394acSWolfgang Denk #define MTD_DEBUG_LEVEL1	(1)	/* Audible */
283932394acSWolfgang Denk #define MTD_DEBUG_LEVEL2	(2)	/* Loud    */
284932394acSWolfgang Denk #define MTD_DEBUG_LEVEL3	(3)	/* Noisy   */
285932394acSWolfgang Denk 
286932394acSWolfgang Denk #ifdef CONFIG_MTD_DEBUG
2873167c538SScott Wood #define MTDDEBUG(n, args...)				\
288932394acSWolfgang Denk 	do {						\
289932394acSWolfgang Denk 		if (n <= CONFIG_MTD_DEBUG_VERBOSE)	\
290932394acSWolfgang Denk 			printk(KERN_INFO args);		\
291932394acSWolfgang Denk 	} while(0)
292932394acSWolfgang Denk #else /* CONFIG_MTD_DEBUG */
293*c45912d8SScott Wood #define MTDDEBUG(n, args...)				\
294*c45912d8SScott Wood 	do {						\
295*c45912d8SScott Wood 		if (0)					\
296*c45912d8SScott Wood 			printk(KERN_INFO args);		\
297*c45912d8SScott Wood 	} while(0)
298932394acSWolfgang Denk #endif /* CONFIG_MTD_DEBUG */
299932394acSWolfgang Denk 
300932394acSWolfgang Denk #endif /* __MTD_MTD_H__ */
301