Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

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);