153 lines
3.8 KiB
C
153 lines
3.8 KiB
C
![]() |
typedef struct Flash Flash;
|
||
|
typedef struct Flashchip Flashchip;
|
||
|
typedef struct Flashpart Flashpart;
|
||
|
typedef struct Flashregion Flashregion;
|
||
|
|
||
|
/*
|
||
|
* logical partitions
|
||
|
*/
|
||
|
enum {
|
||
|
Maxflashpart = 8
|
||
|
};
|
||
|
|
||
|
struct Flashpart {
|
||
|
char* name;
|
||
|
ulong start;
|
||
|
ulong end;
|
||
|
};
|
||
|
|
||
|
enum {
|
||
|
Maxflashregion = 4
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* physical erase block regions
|
||
|
*/
|
||
|
struct Flashregion {
|
||
|
int n; /* number of blocks in region */
|
||
|
ulong start; /* physical base address (allowing for banks) */
|
||
|
ulong end;
|
||
|
ulong erasesize;
|
||
|
ulong eraseshift; /* log2(erasesize) */
|
||
|
ulong pagesize; /* if non-0, size of pages within erase block */
|
||
|
ulong pageshift; /* log2(pagesize) */
|
||
|
ulong spares; /* spare bytes per page, for ecc, etc. */
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* one of a set of chips in a given region
|
||
|
*/
|
||
|
struct Flashchip {
|
||
|
int nr;
|
||
|
Flashregion regions[Maxflashregion];
|
||
|
|
||
|
uchar id; /* flash manufacturer ID */
|
||
|
ushort devid; /* flash device ID */
|
||
|
int width; /* bytes per flash line */
|
||
|
int maxwb; /* max write buffer size */
|
||
|
ulong devsize; /* physical device size */
|
||
|
int alg; /* programming algorithm (if CFI) */
|
||
|
int protect; /* software protection */
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* structure defining a contiguous region of flash memory
|
||
|
*/
|
||
|
struct Flash {
|
||
|
QLock; /* interlock on flash operations */
|
||
|
Flash* next;
|
||
|
|
||
|
/* following are filled in before calling Flash.reset */
|
||
|
char* type;
|
||
|
void* addr;
|
||
|
ulong size;
|
||
|
int xip; /* executing in place: don't query */
|
||
|
int (*reset)(Flash*);
|
||
|
|
||
|
/* following are filled in by the reset routine */
|
||
|
int (*eraseall)(Flash*);
|
||
|
int (*erasezone)(Flash*, Flashregion*, ulong);
|
||
|
/* (optional) reads of correct width and alignment */
|
||
|
int (*read)(Flash*, ulong, void*, long);
|
||
|
/* writes of correct width and alignment */
|
||
|
int (*write)(Flash*, ulong, void*, long);
|
||
|
int (*suspend)(Flash*);
|
||
|
int (*resume)(Flash*);
|
||
|
int (*attach)(Flash*);
|
||
|
|
||
|
/* following might be filled in by either archflashreset or reset routine */
|
||
|
int nr;
|
||
|
Flashregion regions[Maxflashregion];
|
||
|
|
||
|
uchar id; /* flash manufacturer ID */
|
||
|
ushort devid; /* flash device ID */
|
||
|
int width; /* bytes per flash line */
|
||
|
int interleave; /* addresses are interleaved across set of chips */
|
||
|
int bshift; /* byte addresses are shifted */
|
||
|
ulong cmask; /* command mask for interleaving */
|
||
|
int maxwb; /* max write buffer size */
|
||
|
ulong devsize; /* physical device size */
|
||
|
int alg; /* programming algorithm (if CFI) */
|
||
|
void* data; /* flash type routines' private storage, or nil */
|
||
|
Flashpart part[Maxflashpart]; /* logical partitions */
|
||
|
int protect; /* software protection */
|
||
|
char* sort; /* "nand", "nor", "serial", nil (unspecified) */
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* called by link routine of driver for specific flash type: arguments are
|
||
|
* conventional name for card type/model, and card driver's reset routine.
|
||
|
*/
|
||
|
void addflashcard(char*, int (*)(Flash*));
|
||
|
|
||
|
/*
|
||
|
* called by devflash.c:/^flashreset; if flash exists,
|
||
|
* sets type, address, and size in bytes of flash
|
||
|
* and returns 0; returns -1 if flash doesn't exist
|
||
|
*/
|
||
|
int archflashreset(int, Flash*);
|
||
|
|
||
|
/*
|
||
|
* enable/disable write protect
|
||
|
*/
|
||
|
void archflashwp(Flash*, int);
|
||
|
|
||
|
/*
|
||
|
* flash access taking width and interleave into account
|
||
|
*/
|
||
|
int flashget(Flash*, ulong);
|
||
|
void flashput(Flash*, ulong, int);
|
||
|
|
||
|
/*
|
||
|
* Architecture specific routines for managing nand devices
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* do any device spcific initialisation
|
||
|
*/
|
||
|
void archnand_init(Flash*);
|
||
|
|
||
|
/*
|
||
|
* if claim is 1, claim device exclusively, and enable it (power it up)
|
||
|
* if claim is 0, release, and disable it (power it down)
|
||
|
* claiming may be as simple as a qlock per device
|
||
|
*/
|
||
|
void archnand_claim(Flash*, int claim);
|
||
|
|
||
|
/*
|
||
|
* set command latch enable (CLE) and address latch enable (ALE)
|
||
|
* appropriately
|
||
|
*/
|
||
|
void archnand_setCLEandALE(Flash*, int cle, int ale);
|
||
|
|
||
|
/*
|
||
|
* write a sequence of bytes to the device
|
||
|
*/
|
||
|
void archnand_write(Flash*, void *buf, int len);
|
||
|
|
||
|
/*
|
||
|
* read a sequence of bytes from the device
|
||
|
* if buf is 0, throw away the data
|
||
|
*/
|
||
|
void archnand_read(Flash*, void *buf, int len);
|