|
@@ -0,0 +1,149 @@
|
|
|
+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 pagesize; /* if non-0, size of pages within erase block */
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * 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);
|