xref: /plan9-contrib/sys/src/9/port/flashif.h (revision 047f1f95aa802225c557b6f2f4b096acb12ebb86)
106f6463aSDavid du Colombier typedef struct Flash Flash;
206f6463aSDavid du Colombier typedef struct Flashchip Flashchip;
306f6463aSDavid du Colombier typedef struct Flashpart Flashpart;
406f6463aSDavid du Colombier typedef struct Flashregion Flashregion;
506f6463aSDavid du Colombier 
606f6463aSDavid du Colombier /*
706f6463aSDavid du Colombier  * logical partitions
806f6463aSDavid du Colombier  */
906f6463aSDavid du Colombier enum {
1006f6463aSDavid du Colombier 	Maxflashpart = 8
1106f6463aSDavid du Colombier };
1206f6463aSDavid du Colombier 
1306f6463aSDavid du Colombier struct Flashpart {
1406f6463aSDavid du Colombier 	char*	name;
1506f6463aSDavid du Colombier 	ulong	start;
1606f6463aSDavid du Colombier 	ulong	end;
1706f6463aSDavid du Colombier };
1806f6463aSDavid du Colombier 
1906f6463aSDavid du Colombier enum {
2006f6463aSDavid du Colombier 	Maxflashregion = 4
2106f6463aSDavid du Colombier };
2206f6463aSDavid du Colombier 
2306f6463aSDavid du Colombier /*
2406f6463aSDavid du Colombier  * physical erase block regions
2506f6463aSDavid du Colombier  */
2606f6463aSDavid du Colombier struct Flashregion {
2706f6463aSDavid du Colombier 	int	n;		/* number of blocks in region */
2806f6463aSDavid du Colombier 	ulong	start;		/* physical base address (allowing for banks) */
2906f6463aSDavid du Colombier 	ulong	end;
3006f6463aSDavid du Colombier 	ulong	erasesize;
31*047f1f95SDavid du Colombier 	ulong	eraseshift;	/* log2(erasesize) */
3206f6463aSDavid du Colombier 	ulong	pagesize;	/* if non-0, size of pages within erase block */
33*047f1f95SDavid du Colombier 	ulong	pageshift;	/* log2(pagesize) */
3406f6463aSDavid du Colombier 	ulong	spares;		/* spare bytes per page, for ecc, etc. */
3506f6463aSDavid du Colombier };
3606f6463aSDavid du Colombier 
3706f6463aSDavid du Colombier /*
3806f6463aSDavid du Colombier  * one of a set of chips in a given region
3906f6463aSDavid du Colombier  */
4006f6463aSDavid du Colombier struct Flashchip {
4106f6463aSDavid du Colombier 	int	nr;
4206f6463aSDavid du Colombier 	Flashregion regions[Maxflashregion];
4306f6463aSDavid du Colombier 
4406f6463aSDavid du Colombier 	uchar	id;		/* flash manufacturer ID */
4506f6463aSDavid du Colombier 	ushort	devid;		/* flash device ID */
4606f6463aSDavid du Colombier 	int	width;		/* bytes per flash line */
4706f6463aSDavid du Colombier 	int	maxwb;		/* max write buffer size */
4806f6463aSDavid du Colombier 	ulong	devsize;	/* physical device size */
4906f6463aSDavid du Colombier 	int	alg;		/* programming algorithm (if CFI) */
5006f6463aSDavid du Colombier 	int	protect;	/* software protection */
5106f6463aSDavid du Colombier };
5206f6463aSDavid du Colombier 
5306f6463aSDavid du Colombier /*
5406f6463aSDavid du Colombier  * structure defining a contiguous region of flash memory
5506f6463aSDavid du Colombier  */
5606f6463aSDavid du Colombier struct Flash {
5706f6463aSDavid du Colombier 	QLock;			/* interlock on flash operations */
5806f6463aSDavid du Colombier 	Flash*	next;
5906f6463aSDavid du Colombier 
6006f6463aSDavid du Colombier 	/* following are filled in before calling Flash.reset */
6106f6463aSDavid du Colombier 	char*	type;
6206f6463aSDavid du Colombier 	void*	addr;
6306f6463aSDavid du Colombier 	ulong	size;
6406f6463aSDavid du Colombier 	int	xip;		/* executing in place: don't query */
6506f6463aSDavid du Colombier 	int	(*reset)(Flash*);
6606f6463aSDavid du Colombier 
6706f6463aSDavid du Colombier 	/* following are filled in by the reset routine */
6806f6463aSDavid du Colombier 	int	(*eraseall)(Flash*);
6906f6463aSDavid du Colombier 	int	(*erasezone)(Flash*, Flashregion*, ulong);
7006f6463aSDavid du Colombier 	/* (optional) reads of correct width and alignment */
7106f6463aSDavid du Colombier 	int	(*read)(Flash*, ulong, void*, long);
7206f6463aSDavid du Colombier 	/* writes of correct width and alignment */
7306f6463aSDavid du Colombier 	int	(*write)(Flash*, ulong, void*, long);
7406f6463aSDavid du Colombier 	int	(*suspend)(Flash*);
7506f6463aSDavid du Colombier 	int	(*resume)(Flash*);
7606f6463aSDavid du Colombier 	int	(*attach)(Flash*);
7706f6463aSDavid du Colombier 
7806f6463aSDavid du Colombier 	/* following might be filled in by either archflashreset or reset routine */
7906f6463aSDavid du Colombier 	int	nr;
8006f6463aSDavid du Colombier 	Flashregion regions[Maxflashregion];
8106f6463aSDavid du Colombier 
8206f6463aSDavid du Colombier 	uchar	id;		/* flash manufacturer ID */
8306f6463aSDavid du Colombier 	ushort	devid;		/* flash device ID */
8406f6463aSDavid du Colombier 	int	width;		/* bytes per flash line */
8506f6463aSDavid du Colombier 	int	interleave;	/* addresses are interleaved across set of chips */
8606f6463aSDavid du Colombier 	int	bshift;		/* byte addresses are shifted */
8706f6463aSDavid du Colombier 	ulong	cmask;		/* command mask for interleaving */
8806f6463aSDavid du Colombier 	int	maxwb;		/* max write buffer size */
8906f6463aSDavid du Colombier 	ulong	devsize;	/* physical device size */
9006f6463aSDavid du Colombier 	int	alg;		/* programming algorithm (if CFI) */
9106f6463aSDavid du Colombier 	void*	data;		/* flash type routines' private storage, or nil */
9206f6463aSDavid du Colombier 	Flashpart part[Maxflashpart];	/* logical partitions */
9306f6463aSDavid du Colombier 	int	protect;	/* software protection */
9406f6463aSDavid du Colombier 	char*	sort;		/* "nand", "nor", "serial", nil (unspecified) */
9506f6463aSDavid du Colombier };
9606f6463aSDavid du Colombier 
9706f6463aSDavid du Colombier /*
9806f6463aSDavid du Colombier  * called by link routine of driver for specific flash type: arguments are
9906f6463aSDavid du Colombier  * conventional name for card type/model, and card driver's reset routine.
10006f6463aSDavid du Colombier  */
10106f6463aSDavid du Colombier void	addflashcard(char*, int (*)(Flash*));
10206f6463aSDavid du Colombier 
10306f6463aSDavid du Colombier /*
10406f6463aSDavid du Colombier  * called by devflash.c:/^flashreset; if flash exists,
10506f6463aSDavid du Colombier  * sets type, address, and size in bytes of flash
10606f6463aSDavid du Colombier  * and returns 0; returns -1 if flash doesn't exist
10706f6463aSDavid du Colombier  */
10806f6463aSDavid du Colombier int	archflashreset(int, Flash*);
10906f6463aSDavid du Colombier 
11006f6463aSDavid du Colombier /*
11106f6463aSDavid du Colombier  * enable/disable write protect
11206f6463aSDavid du Colombier  */
11306f6463aSDavid du Colombier void	archflashwp(Flash*, int);
11406f6463aSDavid du Colombier 
11506f6463aSDavid du Colombier /*
11606f6463aSDavid du Colombier  * flash access taking width and interleave into account
11706f6463aSDavid du Colombier  */
11806f6463aSDavid du Colombier int	flashget(Flash*, ulong);
11906f6463aSDavid du Colombier void	flashput(Flash*, ulong, int);
12006f6463aSDavid du Colombier 
12106f6463aSDavid du Colombier /*
12206f6463aSDavid du Colombier  * Architecture specific routines for managing nand devices
12306f6463aSDavid du Colombier  */
12406f6463aSDavid du Colombier 
12506f6463aSDavid du Colombier /*
12606f6463aSDavid du Colombier  * do any device spcific initialisation
12706f6463aSDavid du Colombier  */
12806f6463aSDavid du Colombier void archnand_init(Flash*);
12906f6463aSDavid du Colombier 
13006f6463aSDavid du Colombier /*
13106f6463aSDavid du Colombier  * if claim is 1, claim device exclusively, and enable it (power it up)
13206f6463aSDavid du Colombier  * if claim is 0, release, and disable it (power it down)
13306f6463aSDavid du Colombier  * claiming may be as simple as a qlock per device
13406f6463aSDavid du Colombier  */
13506f6463aSDavid du Colombier void archnand_claim(Flash*, int claim);
13606f6463aSDavid du Colombier 
13706f6463aSDavid du Colombier /*
13806f6463aSDavid du Colombier  * set command latch enable (CLE) and address latch enable (ALE)
13906f6463aSDavid du Colombier  * appropriately
14006f6463aSDavid du Colombier  */
14106f6463aSDavid du Colombier void archnand_setCLEandALE(Flash*, int cle, int ale);
14206f6463aSDavid du Colombier 
14306f6463aSDavid du Colombier /*
14406f6463aSDavid du Colombier  * write a sequence of bytes to the device
14506f6463aSDavid du Colombier  */
14606f6463aSDavid du Colombier void archnand_write(Flash*, void *buf, int len);
14706f6463aSDavid du Colombier 
14806f6463aSDavid du Colombier /*
14906f6463aSDavid du Colombier  * read a sequence of bytes from the device
15006f6463aSDavid du Colombier  * if buf is 0, throw away the data
15106f6463aSDavid du Colombier  */
15206f6463aSDavid du Colombier void archnand_read(Flash*, void *buf, int len);
153