From 932394ac43e2e778e664eeb6e456fecd0fae6e59 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 17 Aug 2005 12:55:25 +0200 Subject: [PATCH 001/102] Rewrite of NAND code based on what is in 2.6.12 Linux kernel Patch by Ladislav Michl, 29 Jun 2005 --- CHANGELOG | 7 + common/cmd_nand.c | 2099 ++++---------------------- drivers/nand/Makefile | 17 + drivers/nand/diskonchip.c | 1782 ++++++++++++++++++++++ drivers/nand/nand.c | 71 + drivers/nand/nand_base.c | 2630 +++++++++++++++++++++++++++++++++ drivers/nand/nand_bbt.c | 1056 +++++++++++++ drivers/nand/nand_ecc.c | 244 +++ drivers/nand/nand_ids.c | 127 ++ fs/jffs2/jffs2_nand_1pass.c | 1045 +++++++++++++ fs/jffs2/jffs2_nand_private.h | 133 ++ include/linux/mtd/compat.h | 44 + include/linux/mtd/mtd-abi.h | 99 ++ include/linux/mtd/mtd.h | 214 +++ include/linux/mtd/nand.h | 503 +++++-- include/linux/mtd/nand_ecc.h | 30 + include/linux/mtd/nand_ids.h | 1 + include/nand.h | 56 + 18 files changed, 8250 insertions(+), 1908 deletions(-) create mode 100644 drivers/nand/Makefile create mode 100644 drivers/nand/diskonchip.c create mode 100644 drivers/nand/nand.c create mode 100644 drivers/nand/nand_base.c create mode 100644 drivers/nand/nand_bbt.c create mode 100644 drivers/nand/nand_ecc.c create mode 100644 drivers/nand/nand_ids.c create mode 100644 fs/jffs2/jffs2_nand_1pass.c create mode 100644 fs/jffs2/jffs2_nand_private.h create mode 100644 include/linux/mtd/compat.h create mode 100644 include/linux/mtd/mtd-abi.h create mode 100644 include/linux/mtd/mtd.h create mode 100644 include/linux/mtd/nand_ecc.h create mode 100644 include/nand.h diff --git a/CHANGELOG b/CHANGELOG index cd2697abb7..5e7016137a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +====================================================================== +Changes for U-Boot 1.1.4: +====================================================================== + +* Rewrite of NAND code based on what is in 2.6.12 Linux kernel + Patch by Ladislav Michl, 29 Jun 2005 + ====================================================================== Changes for U-Boot 1.1.3: ====================================================================== diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 449991785c..ae4c68ac1f 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -1,18 +1,15 @@ /* - * Driver for NAND support, Rick Bronson - * borrowed heavily from: - * (c) 1999 Machine Vision Holdings, Inc. - * (c) 1999, 2000 David Woodhouse - * - * Added 16-bit nand support - * (C) 2004 Texas Instruments + * Rick Bronson and Pantelis Antoniou */ #include + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) + #include -#include -#include #include +#include +#include #ifdef CONFIG_SHOW_BOOT_PROGRESS # include @@ -21,289 +18,311 @@ # define SHOW_BOOT_PROGRESS(arg) #endif -#if (CONFIG_COMMANDS & CFG_CMD_NAND) - -#include -#include #include +#include -#ifdef CONFIG_OMAP1510 -void archflashwp(void *archdata, int wp); -#endif +extern nand_info_t nand_info[]; /* info for NAND chips */ -#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) +static int nand_dump_oob(nand_info_t *nand, ulong off) +{ + return 0; +} -/* - * Definition of the out of band configuration structure - */ -struct nand_oob_config { - int ecc_pos[6]; /* position of ECC bytes inside oob */ - int badblock_pos; /* position of bad block flag inside oob -1 = inactive */ - int eccvalid_pos; /* position of ECC valid flag inside oob -1 = inactive */ -} oob_config = { {0}, 0, 0}; +static int nand_dump(nand_info_t *nand, ulong off) +{ + int i; + u_char *buf, *p; -#undef NAND_DEBUG -#undef PSYCHO_DEBUG + buf = malloc(nand->oobblock + nand->oobsize); + if (!buf) { + puts("No memory for page buffer\n"); + return 1; + } + off &= ~(nand->oobblock - 1); + i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize); + if (i < 0) { + printf("Error (%d) reading page %08x\n", i, off); + free(buf); + return 1; + } + printf("Page %08x dump:\n", off); + i = nand->oobblock >> 4; p = buf; + while (i--) { + printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x" + " %02x %02x %02x %02x %02x %02x %02x %02x\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); + p += 16; + } + puts("OOB:\n"); + i = nand->oobsize >> 3; + while (i--) { + printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + p += 8; + } + free(buf); -/* ****************** WARNING ********************* - * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will - * erase (or at least attempt to erase) blocks that are marked - * bad. This can be very handy if you are _sure_ that the block - * is OK, say because you marked a good block bad to test bad - * block handling and you are done testing, or if you have - * accidentally marked blocks bad. - * - * Erasing factory marked bad blocks is a _bad_ idea. If the - * erase succeeds there is no reliable way to find them again, - * and attempting to program or erase bad blocks can affect - * the data in _other_ (good) blocks. - */ -#define ALLOW_ERASE_BAD_DEBUG 0 - -#define CONFIG_MTD_NAND_ECC /* enable ECC */ -#define CONFIG_MTD_NAND_ECC_JFFS2 - -/* bits for nand_rw() `cmd'; or together as needed */ -#define NANDRW_READ 0x01 -#define NANDRW_WRITE 0x00 -#define NANDRW_JFFS2 0x02 -#define NANDRW_JFFS2_SKIP 0x04 - -/* - * Function Prototypes - */ -static void nand_print(struct nand_chip *nand); -int nand_rw (struct nand_chip* nand, int cmd, - size_t start, size_t len, - size_t * retlen, u_char * buf); -int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean); -static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len, - size_t * retlen, u_char *buf, u_char *ecc_code); -static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len, - size_t * retlen, const u_char * buf, u_char * ecc_code); -static void nand_print_bad(struct nand_chip *nand); -static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, - size_t * retlen, u_char * buf); -static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, - size_t * retlen, const u_char * buf); -static int NanD_WaitReady(struct nand_chip *nand, int ale_wait); -#ifdef CONFIG_MTD_NAND_ECC -static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); -static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); -#endif - -struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}}; - -/* Current NAND Device */ -static int curr_device = -1; + return 0; +} /* ------------------------------------------------------------------------- */ -int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static void +arg_off_size(int argc, char *argv[], ulong *off, ulong *size, ulong totsize) { - int rcode = 0; + *off = 0; + *size = 0; - switch (argc) { - case 0: - case 1: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - case 2: - if (strcmp(argv[1],"info") == 0) { - int i; +#if defined(CONFIG_JFFS2_NAND) && defined(CFG_JFFS_CUSTOM_PART) + if (argc >= 1 && strcmp(argv[0], "partition") == 0) { + int part_num; + struct part_info *part; + const char *partstr; - putc ('\n'); + if (argc >= 2) + partstr = argv[1]; + else + partstr = getenv("partition"); - for (i=0; i= CFG_MAX_NAND_DEVICE)) { - puts ("\nno devices available\n"); - return 1; - } - printf ("\nDevice %d: ", curr_device); - nand_print(&nand_dev_desc[curr_device]); - return 0; - - } else if (strcmp(argv[1],"bad") == 0) { - if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) { - puts ("\nno devices available\n"); - return 1; - } - printf ("\nDevice %d bad blocks:\n", curr_device); - nand_print_bad(&nand_dev_desc[curr_device]); - return 0; - - } - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - case 3: - if (strcmp(argv[1],"device") == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - printf ("\nDevice %d: ", dev); - if (dev >= CFG_MAX_NAND_DEVICE) { - puts ("unknown device\n"); - return 1; - } - nand_print(&nand_dev_desc[dev]); - /*nand_print (dev);*/ - - if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) { - return 1; - } - - curr_device = dev; - - puts ("... is now current device\n"); - - return 0; - } - else if (strcmp(argv[1],"erase") == 0 && strcmp(argv[2], "clean") == 0) { - struct nand_chip* nand = &nand_dev_desc[curr_device]; - ulong off = 0; - ulong size = nand->totlen; - int ret; - - printf ("\nNAND erase: device %d offset %ld, size %ld ... ", - curr_device, off, size); - - ret = nand_erase (nand, off, size, 1); - - printf("%s\n", ret ? "ERROR" : "OK"); - - return ret; - } - - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - default: - /* at least 4 args */ - - if (strncmp(argv[1], "read", 4) == 0 || - strncmp(argv[1], "write", 5) == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong off = simple_strtoul(argv[3], NULL, 16); - ulong size = simple_strtoul(argv[4], NULL, 16); - int cmd = (strncmp(argv[1], "read", 4) == 0) ? - NANDRW_READ : NANDRW_WRITE; - int ret, total; - char* cmdtail = strchr(argv[1], '.'); - - if (cmdtail && !strncmp(cmdtail, ".oob", 2)) { - /* read out-of-band data */ - if (cmd & NANDRW_READ) { - ret = nand_read_oob(nand_dev_desc + curr_device, - off, size, &total, - (u_char*)addr); - } - else { - ret = nand_write_oob(nand_dev_desc + curr_device, - off, size, &total, - (u_char*)addr); - } - return ret; - } - else if (cmdtail && !strncmp(cmdtail, ".jffs2", 2)) - cmd |= NANDRW_JFFS2; /* skip bad blocks */ - else if (cmdtail && !strncmp(cmdtail, ".jffs2s", 2)) { - cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ - if (cmd & NANDRW_READ) - cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ - } -#ifdef SXNI855T - /* need ".e" same as ".j" for compatibility with older units */ - else if (cmdtail && !strcmp(cmdtail, ".e")) - cmd |= NANDRW_JFFS2; /* skip bad blocks */ + *size = part->size; + *off = (ulong)part->offset; + } else #endif -#ifdef CFG_NAND_SKIP_BAD_DOT_I - /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */ - /* ".i" for image -> read skips bad block (no 0xff) */ - else if (cmdtail && !strcmp(cmdtail, ".i")) - cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ - if (cmd & NANDRW_READ) - cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ -#endif /* CFG_NAND_SKIP_BAD_DOT_I */ - else if (cmdtail) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } + { + if (argc >= 1) + *off = (ulong)simple_strtoul(argv[0], NULL, 16); + else + *off = 0; - printf ("\nNAND %s: device %d offset %ld, size %ld ... ", - (cmd & NANDRW_READ) ? "read" : "write", - curr_device, off, size); + if (argc >= 2) + *size = (ulong)simple_strtoul(argv[1], NULL, 16); + else + *size = totsize - *off; - ret = nand_rw(nand_dev_desc + curr_device, cmd, off, size, - &total, (u_char*)addr); - - printf (" %d bytes %s: %s\n", total, - (cmd & NANDRW_READ) ? "read" : "written", - ret ? "ERROR" : "OK"); - - return ret; - } else if (strcmp(argv[1],"erase") == 0 && - (argc == 4 || strcmp("clean", argv[2]) == 0)) { - int clean = argc == 5; - ulong off = simple_strtoul(argv[2 + clean], NULL, 16); - ulong size = simple_strtoul(argv[3 + clean], NULL, 16); - int ret; - - printf ("\nNAND erase: device %d offset %ld, size %ld ... ", - curr_device, off, size); - - ret = nand_erase (nand_dev_desc + curr_device, off, size, clean); - - printf("%s\n", ret ? "ERROR" : "OK"); - - return ret; - } else { - printf ("Usage:\n%s\n", cmdtp->usage); - rcode = 1; } - return rcode; - } } -U_BOOT_CMD( - nand, 5, 1, do_nand, +int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + int i, dev, ret; + ulong addr, off, size; + char *cmd, *s; + nand_info_t *nand; + + /* at least two arguments please */ + if (argc < 2) + goto usage; + + cmd = argv[1]; + + if (strcmp(cmd, "info") == 0) { + + putc('\n'); + for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { + if (nand_info[i].name) + printf("Device %d: %s\n", i, nand_info[i].name); + } + return 0; + } + + if (strcmp(cmd, "device") == 0) { + + if (argc < 3) { + if ((nand_curr_device < 0) || + (nand_curr_device >= CFG_MAX_NAND_DEVICE)) + puts("\nno devices available\n"); + else + printf("\nDevice %d: %s\n", nand_curr_device, + nand_info[nand_curr_device].name); + return 0; + } + dev = (int)simple_strtoul(argv[2], NULL, 10); + if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { + puts("No such device\n"); + return 1; + } + printf("Device %d: %s", dev, nand_info[dev].name); + puts("... is now current device\n"); + nand_curr_device = dev; + return 0; + } + + if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && + strncmp(cmd, "dump", 4) != 0 && + strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 +#ifdef CONFIG_MTD_NAND_UNSAFE + && strcmp(cmd, "scrub") != 0 && strcmp(cmd, "biterr") != 0 + && strcmp(cmd, "markbad") != 0 +#endif + ) + goto usage; + + /* the following commands operate on the current device */ + if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE || + !nand_info[nand_curr_device].name) { + puts("\nno devices available\n"); + return 1; + } + nand = &nand_info[nand_curr_device]; + + if (strcmp(cmd, "bad") == 0) { + printf("\nDevice %d bad blocks:\n", nand_curr_device); + for (off = 0; off < nand->size; off += nand->erasesize) + if (nand_block_isbad(nand, off)) + printf(" %08x\n", off); + return 0; + } + + if (strcmp(cmd, "erase") == 0 +#ifdef CONFIG_MTD_NAND_UNSAFE + || strcmp(cmd, "scrub") == 0 +#endif + ) { + +#ifdef CONFIG_MTD_NAND_UNSAFE + i = strcmp(cmd, "scrub") == 0; /* 1 scrub, 0 = erase */ +#endif + + arg_off_size(argc - 2, argv + 2, &off, &size, nand->size); + if (off == 0 && size == 0) + return 1; + + printf("\nNAND %s: device %d offset 0x%x, size 0x%x ", +#ifdef CONFIG_MTD_NAND_UNSAFE + i ? "scrub" : +#endif + "erase", + nand_curr_device, off, size); + +#ifdef CONFIG_MTD_NAND_UNSAFE + if (i) + ret = nand_scrub(nand, off, size); + else +#endif + ret = nand_erase(nand, off, size); + + printf("%s\n", ret ? "ERROR" : "OK"); + + return ret == 0 ? 0 : 1; + } + + if (strncmp(cmd, "dump", 4) == 0) { + if (argc < 3) + goto usage; + + s = strchr(cmd, '.'); + off = (int)simple_strtoul(argv[2], NULL, 16); + + if (s != NULL && strcmp(s, ".oob") == 0) + ret = nand_dump_oob(nand, off); + else + ret = nand_dump(nand, off); + + return ret == 0 ? 1 : 0; + + } + + /* read write */ + if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { + if (argc < 4) + goto usage; +/* + s = strchr(cmd, '.'); + clean = CLEAN_NONE; + if (s != NULL) { + if (strcmp(s, ".jffs2") == 0 || strcmp(s, ".e") == 0 + || strcmp(s, ".i")) + clean = CLEAN_JFFS2; + } +*/ + addr = (ulong)simple_strtoul(argv[2], NULL, 16); + + arg_off_size(argc - 3, argv + 3, &off, &size, nand->size); + if (off == 0 && size == 0) + return 1; + + i = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ + printf("\nNAND %s: device %d offset %u, size %u ... ", + i ? "read" : "write", nand_curr_device, off, size); + + if (i) + ret = nand_read(nand, off, &size, (u_char *)addr); + else + ret = nand_write(nand, off, &size, (u_char *)addr); + + printf(" %d bytes %s: %s\n", size, + i ? "read" : "written", ret ? "ERROR" : "OK"); + + return ret == 0 ? 0 : 1; + } +#ifdef CONFIG_MTD_NAND_UNSAFE + if (strcmp(cmd, "markbad") == 0 || strcmp(cmd, "biterr") == 0) { + if (argc < 3) + goto usage; + + i = strcmp(cmd, "biterr") == 0; + + off = (int)simple_strtoul(argv[2], NULL, 16); + + if (i) + ret = nand_make_bit_error(nand, off); + else + ret = nand_mark_bad(nand, off); + + return ret == 0 ? 0 : 1; + } +#endif + +usage: + printf("Usage:\n%s\n", cmdtp->usage); + return 1; +} + +U_BOOT_CMD(nand, 5, 1, do_nand, "nand - NAND sub-system\n", - "info - show available NAND devices\n" - "nand device [dev] - show or set current device\n" - "nand read[.jffs2[s]] addr off size\n" - "nand write[.jffs2] addr off size - read/write `size' bytes starting\n" + "info - show available NAND devices\n" + "nand device [dev] - show or set current device\n" + "nand read[.jffs2] - addr off size\n" + "nand write[.jffs2] - addr off size - read/write `size' bytes starting\n" " at offset `off' to/from memory address `addr'\n" "nand erase [clean] [off size] - erase `size' bytes from\n" " offset `off' (entire device if not specified)\n" "nand bad - show bad blocks\n" - "nand read.oob addr off size - read out-of-band data\n" - "nand write.oob addr off size - read out-of-band data\n" -); + "nand dump[.oob] off - dump page\n" + "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n" + "nand markbad off - mark bad block at offset (UNSAFE)\n" + "nand biterr off - make a bit error at offset (UNSAFE)\n"); -int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { char *boot_device = NULL; char *ep; int dev; - ulong cnt; - ulong addr; - ulong offset = 0; + int r; + ulong addr, cnt, offset = 0; image_header_t *hdr; - int rcode = 0; + nand_info_t *nand; + switch (argc) { case 1: addr = CFG_LOAD_ADDR; - boot_device = getenv ("bootdevice"); + boot_device = getenv("bootdevice"); break; case 2: addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv ("bootdevice"); + boot_device = getenv("bootdevice"); break; case 3: addr = simple_strtoul(argv[1], NULL, 16); @@ -315,55 +334,53 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) offset = simple_strtoul(argv[3], NULL, 16); break; default: - printf ("Usage:\n%s\n", cmdtp->usage); - SHOW_BOOT_PROGRESS (-1); + printf("Usage:\n%s\n", cmdtp->usage); + SHOW_BOOT_PROGRESS(-1); return 1; } if (!boot_device) { - puts ("\n** No boot device **\n"); - SHOW_BOOT_PROGRESS (-1); + puts("\n** No boot device **\n"); + SHOW_BOOT_PROGRESS(-1); return 1; } dev = simple_strtoul(boot_device, &ep, 16); - if ((dev >= CFG_MAX_NAND_DEVICE) || - (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) { - printf ("\n** Device %d not available\n", dev); - SHOW_BOOT_PROGRESS (-1); + if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { + printf("\n** Device %d not available\n", dev); + SHOW_BOOT_PROGRESS(-1); return 1; } - printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n", - dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR, - offset); + nand = &nand_info[dev]; + printf("\nLoading from device %d: %s (offset 0x%lx)\n", + dev, nand->name, offset); - if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset, - SECTORSIZE, NULL, (u_char *)addr)) { - printf ("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS (-1); + cnt = nand->oobblock; + r = nand_read(nand, offset, &cnt, (u_char *) addr); + if (r) { + printf("** Read error on %d\n", dev); + SHOW_BOOT_PROGRESS(-1); return 1; } - hdr = (image_header_t *)addr; + hdr = (image_header_t *) addr; - if (ntohl(hdr->ih_magic) == IH_MAGIC) { - - print_image_hdr (hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); - cnt -= SECTORSIZE; - } else { - printf ("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); - SHOW_BOOT_PROGRESS (-1); + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); + SHOW_BOOT_PROGRESS(-1); return 1; } - if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset + SECTORSIZE, cnt, - NULL, (u_char *)(addr+SECTORSIZE))) { - printf ("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS (-1); + print_image_hdr(hdr); + + cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t)); + + r = nand_read(nand, offset, &cnt, (u_char *) addr); + if (r) { + printf("** Read error on %d\n", dev); + SHOW_BOOT_PROGRESS(-1); return 1; } @@ -372,1526 +389,24 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) load_addr = addr; /* Check if we should attempt an auto-start */ - if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { + if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) { char *local_args[2]; - extern int do_bootm (cmd_tbl_t *, int, int, char *[]); + extern int do_bootm(cmd_tbl_t *, int, int, char *[]); local_args[0] = argv[0]; local_args[1] = NULL; - printf ("Automatic boot of image at addr 0x%08lx ...\n", addr); + printf("Automatic boot of image at addr 0x%08lx ...\n", addr); - do_bootm (cmdtp, 0, 1, local_args); - rcode = 1; - } - return rcode; -} - -U_BOOT_CMD( - nboot, 4, 1, do_nandboot, - "nboot - boot from NAND device\n", - "loadAddr dev\n" -); - -/* returns 0 if block containing pos is OK: - * valid erase block and - * not marked bad, or no bad mark position is specified - * returns 1 if marked bad or otherwise invalid - */ -int check_block (struct nand_chip *nand, unsigned long pos) -{ - int retlen; - uint8_t oob_data; - uint16_t oob_data16[6]; - int page0 = pos & (-nand->erasesize); - int page1 = page0 + nand->oobblock; - int badpos = oob_config.badblock_pos; - - if (pos >= nand->totlen) + do_bootm(cmdtp, 0, 1, local_args); return 1; - - if (badpos < 0) - return 0; /* no way to check, assume OK */ - - if (nand->bus16) { - if (nand_read_oob(nand, (page0 + 0), 12, &retlen, (uint8_t *)oob_data16) - || (oob_data16[2] & 0xff00) != 0xff00) - return 1; - if (nand_read_oob(nand, (page1 + 0), 12, &retlen, (uint8_t *)oob_data16) - || (oob_data16[2] & 0xff00) != 0xff00) - return 1; - } else { - /* Note - bad block marker can be on first or second page */ - if (nand_read_oob(nand, page0 + badpos, 1, &retlen, &oob_data) - || oob_data != 0xff - || nand_read_oob (nand, page1 + badpos, 1, &retlen, &oob_data) - || oob_data != 0xff) - return 1; } - return 0; } -/* print bad blocks in NAND flash */ -static void nand_print_bad(struct nand_chip* nand) -{ - unsigned long pos; +U_BOOT_CMD(nboot, 4, 1, do_nandboot, + "nboot - boot from NAND device\n", "loadAddr dev\n"); - for (pos = 0; pos < nand->totlen; pos += nand->erasesize) { - if (check_block(nand, pos)) - printf(" 0x%8.8lx\n", pos); - } - puts("\n"); -} -/* cmd: 0: NANDRW_WRITE write, fail on bad block - * 1: NANDRW_READ read, fail on bad block - * 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks - * 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks - * 7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks - */ -int nand_rw (struct nand_chip* nand, int cmd, - size_t start, size_t len, - size_t * retlen, u_char * buf) -{ - int ret = 0, n, total = 0; - char eccbuf[6]; - /* eblk (once set) is the start of the erase block containing the - * data being processed. - */ - unsigned long eblk = ~0; /* force mismatch on first pass */ - unsigned long erasesize = nand->erasesize; +#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ - while (len) { - if ((start & (-erasesize)) != eblk) { - /* have crossed into new erase block, deal with - * it if it is sure marked bad. - */ - eblk = start & (-erasesize); /* start of block */ - if (check_block(nand, eblk)) { - if (cmd == (NANDRW_READ | NANDRW_JFFS2)) { - while (len > 0 && - start - eblk < erasesize) { - *(buf++) = 0xff; - ++start; - ++total; - --len; - } - continue; - } else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) { - start += erasesize; - continue; - } else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) { - /* skip bad block */ - start += erasesize; - continue; - } else { - ret = 1; - break; - } - } - } - /* The ECC will not be calculated correctly if - less than 512 is written or read */ - /* Is request at least 512 bytes AND it starts on a proper boundry */ - if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200)) - printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n"); - - if (cmd & NANDRW_READ) { - ret = nand_read_ecc(nand, start, - min(len, eblk + erasesize - start), - &n, (u_char*)buf, eccbuf); - } else { - ret = nand_write_ecc(nand, start, - min(len, eblk + erasesize - start), - &n, (u_char*)buf, eccbuf); - } - - if (ret) - break; - - start += n; - buf += n; - total += n; - len -= n; - } - if (retlen) - *retlen = total; - - return ret; -} - -static void nand_print(struct nand_chip *nand) -{ - if (nand->numchips > 1) { - printf("%s at 0x%lx,\n" - "\t %d chips %s, size %d MB, \n" - "\t total size %ld MB, sector size %ld kB\n", - nand->name, nand->IO_ADDR, nand->numchips, - nand->chips_name, 1 << (nand->chipshift - 20), - nand->totlen >> 20, nand->erasesize >> 10); - } - else { - printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR); - print_size(nand->totlen, ", "); - print_size(nand->erasesize, " sector)\n"); - } -} - -/* ------------------------------------------------------------------------- */ - -static int NanD_WaitReady(struct nand_chip *nand, int ale_wait) -{ - /* This is inline, to optimise the common case, where it's ready instantly */ - int ret = 0; - -#ifdef NAND_NO_RB /* in config file, shorter delays currently wrap accesses */ - if(ale_wait) - NAND_WAIT_READY(nand); /* do the worst case 25us wait */ - else - udelay(10); -#else /* has functional r/b signal */ - NAND_WAIT_READY(nand); -#endif - return ret; -} - -/* NanD_Command: Send a flash command to the flash chip */ - -static inline int NanD_Command(struct nand_chip *nand, unsigned char command) -{ - unsigned long nandptr = nand->IO_ADDR; - - /* Assert the CLE (Command Latch Enable) line to the flash chip */ - NAND_CTL_SETCLE(nandptr); - - /* Send the command */ - WRITE_NAND_COMMAND(command, nandptr); - - /* Lower the CLE line */ - NAND_CTL_CLRCLE(nandptr); - -#ifdef NAND_NO_RB - if(command == NAND_CMD_RESET){ - u_char ret_val; - NanD_Command(nand, NAND_CMD_STATUS); - do { - ret_val = READ_NAND(nandptr);/* wait till ready */ - } while((ret_val & 0x40) != 0x40); - } -#endif - return NanD_WaitReady(nand, 0); -} - -/* NanD_Address: Set the current address for the flash chip */ - -static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs) -{ - unsigned long nandptr; - int i; - - nandptr = nand->IO_ADDR; - - /* Assert the ALE (Address Latch Enable) line to the flash chip */ - NAND_CTL_SETALE(nandptr); - - /* Send the address */ - /* Devices with 256-byte page are addressed as: - * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31) - * there is no device on the market with page256 - * and more than 24 bits. - * Devices with 512-byte page are addressed as: - * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31) - * 25-31 is sent only if the chip support it. - * bit 8 changes the read command to be sent - * (NAND_CMD_READ0 or NAND_CMD_READ1). - */ - - if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) - WRITE_NAND_ADDRESS(ofs, nandptr); - - ofs = ofs >> nand->page_shift; - - if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) { - for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) { - WRITE_NAND_ADDRESS(ofs, nandptr); - } - } - - /* Lower the ALE line */ - NAND_CTL_CLRALE(nandptr); - - /* Wait for the chip to respond */ - return NanD_WaitReady(nand, 1); -} - -/* NanD_SelectChip: Select a given flash chip within the current floor */ - -static inline int NanD_SelectChip(struct nand_chip *nand, int chip) -{ - /* Wait for it to be ready */ - return NanD_WaitReady(nand, 0); -} - -/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */ - -static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip) -{ - int mfr, id, i; - - NAND_ENABLE_CE(nand); /* set pin low */ - /* Reset the chip */ - if (NanD_Command(nand, NAND_CMD_RESET)) { -#ifdef NAND_DEBUG - printf("NanD_Command (reset) for %d,%d returned true\n", - floor, chip); -#endif - NAND_DISABLE_CE(nand); /* set pin high */ - return 0; - } - - /* Read the NAND chip ID: 1. Send ReadID command */ - if (NanD_Command(nand, NAND_CMD_READID)) { -#ifdef NAND_DEBUG - printf("NanD_Command (ReadID) for %d,%d returned true\n", - floor, chip); -#endif - NAND_DISABLE_CE(nand); /* set pin high */ - return 0; - } - - /* Read the NAND chip ID: 2. Send address byte zero */ - NanD_Address(nand, ADDR_COLUMN, 0); - - /* Read the manufacturer and device id codes from the device */ - - mfr = READ_NAND(nand->IO_ADDR); - - id = READ_NAND(nand->IO_ADDR); - - NAND_DISABLE_CE(nand); /* set pin high */ - -#ifdef NAND_DEBUG - printf("NanD_Command (ReadID) got %x %x\n", mfr, id); -#endif - if (mfr == 0xff || mfr == 0) { - /* No response - return failure */ - return 0; - } - - /* Check it's the same as the first chip we identified. - * M-Systems say that any given nand_chip device should only - * contain _one_ type of flash part, although that's not a - * hardware restriction. */ - if (nand->mfr) { - if (nand->mfr == mfr && nand->id == id) { - return 1; /* This is another the same the first */ - } else { - printf("Flash chip at floor %d, chip %d is different:\n", - floor, chip); - } - } - - /* Print and store the manufacturer and ID codes. */ - for (i = 0; nand_flash_ids[i].name != NULL; i++) { - if (mfr == nand_flash_ids[i].manufacture_id && - id == nand_flash_ids[i].model_id) { -#ifdef NAND_DEBUG - printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, " - "Chip ID: 0x%2.2X (%s)\n", mfr, id, - nand_flash_ids[i].name); -#endif - if (!nand->mfr) { - nand->mfr = mfr; - nand->id = id; - nand->chipshift = - nand_flash_ids[i].chipshift; - nand->page256 = nand_flash_ids[i].page256; - nand->eccsize = 256; - if (nand->page256) { - nand->oobblock = 256; - nand->oobsize = 8; - nand->page_shift = 8; - } else { - nand->oobblock = 512; - nand->oobsize = 16; - nand->page_shift = 9; - } - nand->pageadrlen = nand_flash_ids[i].pageadrlen; - nand->erasesize = nand_flash_ids[i].erasesize; - nand->chips_name = nand_flash_ids[i].name; - nand->bus16 = nand_flash_ids[i].bus16; - return 1; - } - return 0; - } - } - - -#ifdef NAND_DEBUG - /* We haven't fully identified the chip. Print as much as we know. */ - printf("Unknown flash chip found: %2.2X %2.2X\n", - id, mfr); -#endif - - return 0; -} - -/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */ - -static void NanD_ScanChips(struct nand_chip *nand) -{ - int floor, chip; - int numchips[NAND_MAX_FLOORS]; - int maxchips = NAND_MAX_CHIPS; - int ret = 1; - - nand->numchips = 0; - nand->mfr = 0; - nand->id = 0; - - - /* For each floor, find the number of valid chips it contains */ - for (floor = 0; floor < NAND_MAX_FLOORS; floor++) { - ret = 1; - numchips[floor] = 0; - for (chip = 0; chip < maxchips && ret != 0; chip++) { - - ret = NanD_IdentChip(nand, floor, chip); - if (ret) { - numchips[floor]++; - nand->numchips++; - } - } - } - - /* If there are none at all that we recognise, bail */ - if (!nand->numchips) { -#ifdef NAND_DEBUG - puts ("No NAND flash chips recognised.\n"); -#endif - return; - } - - /* Allocate an array to hold the information for each chip */ - nand->chips = malloc(sizeof(struct Nand) * nand->numchips); - if (!nand->chips) { - puts ("No memory for allocating chip info structures\n"); - return; - } - - ret = 0; - - /* Fill out the chip array with {floor, chipno} for each - * detected chip in the device. */ - for (floor = 0; floor < NAND_MAX_FLOORS; floor++) { - for (chip = 0; chip < numchips[floor]; chip++) { - nand->chips[ret].floor = floor; - nand->chips[ret].chip = chip; - nand->chips[ret].curadr = 0; - nand->chips[ret].curmode = 0x50; - ret++; - } - } - - /* Calculate and print the total size of the device */ - nand->totlen = nand->numchips * (1 << nand->chipshift); - -#ifdef NAND_DEBUG - printf("%d flash chips found. Total nand_chip size: %ld MB\n", - nand->numchips, nand->totlen >> 20); -#endif -} - -/* we need to be fast here, 1 us per read translates to 1 second per meg */ -static void NanD_ReadBuf (struct nand_chip *nand, u_char * data_buf, int cntr) -{ - unsigned long nandptr = nand->IO_ADDR; - - NanD_Command (nand, NAND_CMD_READ0); - - if (nand->bus16) { - u16 val; - - while (cntr >= 16) { - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - cntr -= 16; - } - - while (cntr > 0) { - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - cntr -= 2; - } - } else { - while (cntr >= 16) { - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - cntr -= 16; - } - - while (cntr > 0) { - *data_buf++ = READ_NAND (nandptr); - cntr--; - } - } -} - -/* - * NAND read with ECC - */ -static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len, - size_t * retlen, u_char *buf, u_char *ecc_code) -{ - int col, page; - int ecc_status = 0; -#ifdef CONFIG_MTD_NAND_ECC - int j; - int ecc_failed = 0; - u_char *data_poi; - u_char ecc_calc[6]; -#endif - - /* Do not allow reads past end of device */ - if ((start + len) > nand->totlen) { - printf ("%s: Attempt read beyond end of device %x %x %x\n", - __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen); - *retlen = 0; - return -1; - } - - /* First we calculate the starting page */ - /*page = shr(start, nand->page_shift);*/ - page = start >> nand->page_shift; - - /* Get raw starting column */ - col = start & (nand->oobblock - 1); - - /* Initialize return value */ - *retlen = 0; - - /* Select the NAND device */ - NAND_ENABLE_CE(nand); /* set pin low */ - - /* Loop until all data read */ - while (*retlen < len) { - -#ifdef CONFIG_MTD_NAND_ECC - /* Do we have this page in cache ? */ - if (nand->cache_page == page) - goto readdata; - /* Send the read command */ - NanD_Command(nand, NAND_CMD_READ0); - if (nand->bus16) { - NanD_Address(nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address(nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - - /* Read in a page + oob data */ - NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize); - - /* copy data into cache, for read out of cache and if ecc fails */ - if (nand->data_cache) { - memcpy (nand->data_cache, nand->data_buf, - nand->oobblock + nand->oobsize); - } - - /* Pick the ECC bytes out of the oob data */ - for (j = 0; j < 6; j++) { - ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])]; - } - - /* Calculate the ECC and verify it */ - /* If block was not written with ECC, skip ECC */ - if (oob_config.eccvalid_pos != -1 && - (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) { - - nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]); - switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) { - case -1: - printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page); - ecc_failed++; - break; - case 1: - case 2: /* transfer ECC corrected data to cache */ - if (nand->data_cache) - memcpy (nand->data_cache, nand->data_buf, 256); - break; - } - } - - if (oob_config.eccvalid_pos != -1 && - nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) { - - nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]); - switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) { - case -1: - printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page); - ecc_failed++; - break; - case 1: - case 2: /* transfer ECC corrected data to cache */ - if (nand->data_cache) - memcpy (&nand->data_cache[256], &nand->data_buf[256], 256); - break; - } - } -readdata: - /* Read the data from ECC data buffer into return buffer */ - data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf; - data_poi += col; - if ((*retlen + (nand->oobblock - col)) >= len) { - memcpy (buf + *retlen, data_poi, len - *retlen); - *retlen = len; - } else { - memcpy (buf + *retlen, data_poi, nand->oobblock - col); - *retlen += nand->oobblock - col; - } - /* Set cache page address, invalidate, if ecc_failed */ - nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1; - - ecc_status += ecc_failed; - ecc_failed = 0; - -#else - /* Send the read command */ - NanD_Command(nand, NAND_CMD_READ0); - if (nand->bus16) { - NanD_Address(nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address(nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - - /* Read the data directly into the return buffer */ - if ((*retlen + (nand->oobblock - col)) >= len) { - NanD_ReadBuf(nand, buf + *retlen, len - *retlen); - *retlen = len; - /* We're done */ - continue; - } else { - NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col); - *retlen += nand->oobblock - col; - } -#endif - /* For subsequent reads align to page boundary. */ - col = 0; - /* Increment page address */ - page++; - } - - /* De-select the NAND device */ - NAND_DISABLE_CE(nand); /* set pin high */ - - /* - * Return success, if no ECC failures, else -EIO - * fs driver will take care of that, because - * retlen == desired len and result == -EIO - */ - return ecc_status ? -1 : 0; -} - -/* - * Nand_page_program function is used for write and writev ! - */ -static int nand_write_page (struct nand_chip *nand, - int page, int col, int last, u_char * ecc_code) -{ - - int i; - unsigned long nandptr = nand->IO_ADDR; - -#ifdef CONFIG_MTD_NAND_ECC -#ifdef CONFIG_MTD_NAND_VERIFY_WRITE - int ecc_bytes = (nand->oobblock == 512) ? 6 : 3; -#endif -#endif - /* pad oob area */ - for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++) - nand->data_buf[i] = 0xff; - -#ifdef CONFIG_MTD_NAND_ECC - /* Zero out the ECC array */ - for (i = 0; i < 6; i++) - ecc_code[i] = 0x00; - - /* Read back previous written data, if col > 0 */ - if (col) { - NanD_Command (nand, NAND_CMD_READ0); - if (nand->bus16) { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - - if (nand->bus16) { - u16 val; - - for (i = 0; i < col; i += 2) { - val = READ_NAND (nandptr); - nand->data_buf[i] = val & 0xff; - nand->data_buf[i + 1] = val >> 8; - } - } else { - for (i = 0; i < col; i++) - nand->data_buf[i] = READ_NAND (nandptr); - } - } - - /* Calculate and write the ECC if we have enough data */ - if ((col < nand->eccsize) && (last >= nand->eccsize)) { - nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0])); - for (i = 0; i < 3; i++) { - nand->data_buf[(nand->oobblock + - oob_config.ecc_pos[i])] = ecc_code[i]; - } - if (oob_config.eccvalid_pos != -1) { - nand->data_buf[nand->oobblock + - oob_config.eccvalid_pos] = 0xf0; - } - } - - /* Calculate and write the second ECC if we have enough data */ - if ((nand->oobblock == 512) && (last == nand->oobblock)) { - nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3])); - for (i = 3; i < 6; i++) { - nand->data_buf[(nand->oobblock + - oob_config.ecc_pos[i])] = ecc_code[i]; - } - if (oob_config.eccvalid_pos != -1) { - nand->data_buf[nand->oobblock + - oob_config.eccvalid_pos] &= 0x0f; - } - } -#endif - /* Prepad for partial page programming !!! */ - for (i = 0; i < col; i++) - nand->data_buf[i] = 0xff; - - /* Postpad for partial page programming !!! oob is already padded */ - for (i = last; i < nand->oobblock; i++) - nand->data_buf[i] = 0xff; - - /* Send command to begin auto page programming */ - NanD_Command (nand, NAND_CMD_READ0); - NanD_Command (nand, NAND_CMD_SEQIN); - if (nand->bus16) { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - - /* Write out complete page of data */ - if (nand->bus16) { - for (i = 0; i < (nand->oobblock + nand->oobsize); i += 2) { - WRITE_NAND (nand->data_buf[i] + - (nand->data_buf[i + 1] << 8), - nand->IO_ADDR); - } - } else { - for (i = 0; i < (nand->oobblock + nand->oobsize); i++) - WRITE_NAND (nand->data_buf[i], nand->IO_ADDR); - } - - /* Send command to actually program the data */ - NanD_Command (nand, NAND_CMD_PAGEPROG); - NanD_Command (nand, NAND_CMD_STATUS); -#ifdef NAND_NO_RB - { - u_char ret_val; - - do { - ret_val = READ_NAND (nandptr); /* wait till ready */ - } while ((ret_val & 0x40) != 0x40); - } -#endif - /* See if device thinks it succeeded */ - if (READ_NAND (nand->IO_ADDR) & 0x01) { - printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, - page); - return -1; - } -#ifdef CONFIG_MTD_NAND_VERIFY_WRITE - /* - * The NAND device assumes that it is always writing to - * a cleanly erased page. Hence, it performs its internal - * write verification only on bits that transitioned from - * 1 to 0. The device does NOT verify the whole page on a - * byte by byte basis. It is possible that the page was - * not completely erased or the page is becoming unusable - * due to wear. The read with ECC would catch the error - * later when the ECC page check fails, but we would rather - * catch it early in the page write stage. Better to write - * no data than invalid data. - */ - - /* Send command to read back the page */ - if (col < nand->eccsize) - NanD_Command (nand, NAND_CMD_READ0); - else - NanD_Command (nand, NAND_CMD_READ1); - if (nand->bus16) { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - - /* Loop through and verify the data */ - if (nand->bus16) { - for (i = col; i < last; i = +2) { - if ((nand->data_buf[i] + - (nand->data_buf[i + 1] << 8)) != READ_NAND (nand->IO_ADDR)) { - printf ("%s: Failed write verify, page 0x%08x ", - __FUNCTION__, page); - return -1; - } - } - } else { - for (i = col; i < last; i++) { - if (nand->data_buf[i] != READ_NAND (nand->IO_ADDR)) { - printf ("%s: Failed write verify, page 0x%08x ", - __FUNCTION__, page); - return -1; - } - } - } - -#ifdef CONFIG_MTD_NAND_ECC - /* - * We also want to check that the ECC bytes wrote - * correctly for the same reasons stated above. - */ - NanD_Command (nand, NAND_CMD_READOOB); - if (nand->bus16) { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - if (nand->bus16) { - for (i = 0; i < nand->oobsize; i += 2) { - u16 val; - - val = READ_NAND (nand->IO_ADDR); - nand->data_buf[i] = val & 0xff; - nand->data_buf[i + 1] = val >> 8; - } - } else { - for (i = 0; i < nand->oobsize; i++) { - nand->data_buf[i] = READ_NAND (nand->IO_ADDR); - } - } - for (i = 0; i < ecc_bytes; i++) { - if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) { - printf ("%s: Failed ECC write " - "verify, page 0x%08x, " - "%6i bytes were succesful\n", - __FUNCTION__, page, i); - return -1; - } - } -#endif /* CONFIG_MTD_NAND_ECC */ -#endif /* CONFIG_MTD_NAND_VERIFY_WRITE */ - return 0; -} - -static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len, - size_t * retlen, const u_char * buf, u_char * ecc_code) -{ - int i, page, col, cnt, ret = 0; - - /* Do not allow write past end of device */ - if ((to + len) > nand->totlen) { - printf ("%s: Attempt to write past end of page\n", __FUNCTION__); - return -1; - } - - /* Shift to get page */ - page = ((int) to) >> nand->page_shift; - - /* Get the starting column */ - col = to & (nand->oobblock - 1); - - /* Initialize return length value */ - *retlen = 0; - - /* Select the NAND device */ -#ifdef CONFIG_OMAP1510 - archflashwp(0,0); -#endif -#ifdef CFG_NAND_WP - NAND_WP_OFF(); -#endif - - NAND_ENABLE_CE(nand); /* set pin low */ - - /* Check the WP bit */ - NanD_Command(nand, NAND_CMD_STATUS); - if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { - printf ("%s: Device is write protected!!!\n", __FUNCTION__); - ret = -1; - goto out; - } - - /* Loop until all data is written */ - while (*retlen < len) { - /* Invalidate cache, if we write to this page */ - if (nand->cache_page == page) - nand->cache_page = -1; - - /* Write data into buffer */ - if ((col + len) >= nand->oobblock) { - for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++) { - nand->data_buf[i] = buf[(*retlen + cnt)]; - } - } else { - for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++) { - nand->data_buf[i] = buf[(*retlen + cnt)]; - } - } - /* We use the same function for write and writev !) */ - ret = nand_write_page (nand, page, col, i, ecc_code); - if (ret) - goto out; - - /* Next data start at page boundary */ - col = 0; - - /* Update written bytes count */ - *retlen += cnt; - - /* Increment page address */ - page++; - } - - /* Return happy */ - *retlen = len; - -out: - /* De-select the NAND device */ - NAND_DISABLE_CE(nand); /* set pin high */ -#ifdef CONFIG_OMAP1510 - archflashwp(0,1); -#endif -#ifdef CFG_NAND_WP - NAND_WP_ON(); -#endif - - return ret; -} - -/* read from the 16 bytes of oob data that correspond to a 512 byte - * page or 2 256-byte pages. - */ -static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, - size_t * retlen, u_char * buf) -{ - int len256 = 0; - struct Nand *mychip; - int ret = 0; - - mychip = &nand->chips[ofs >> nand->chipshift]; - - /* update address for 2M x 8bit devices. OOB starts on the second */ - /* page to maintain compatibility with nand_read_ecc. */ - if (nand->page256) { - if (!(ofs & 0x8)) - ofs += 0x100; - else - ofs -= 0x8; - } - - NAND_ENABLE_CE(nand); /* set pin low */ - NanD_Command(nand, NAND_CMD_READOOB); - if (nand->bus16) { - NanD_Address(nand, ADDR_COLUMN_PAGE, - ((ofs >> nand->page_shift) << nand->page_shift) + - ((ofs & (nand->oobblock - 1)) >> 1)); - } else { - NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); - } - - /* treat crossing 8-byte OOB data for 2M x 8bit devices */ - /* Note: datasheet says it should automaticaly wrap to the */ - /* next OOB block, but it didn't work here. mf. */ - if (nand->page256 && ofs + len > (ofs | 0x7) + 1) { - len256 = (ofs | 0x7) + 1 - ofs; - NanD_ReadBuf(nand, buf, len256); - - NanD_Command(nand, NAND_CMD_READOOB); - NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff)); - } - - NanD_ReadBuf(nand, &buf[len256], len - len256); - - *retlen = len; - /* Reading the full OOB data drops us off of the end of the page, - * causing the flash device to go into busy mode, so we need - * to wait until ready 11.4.1 and Toshiba TC58256FT nands */ - - ret = NanD_WaitReady(nand, 1); - NAND_DISABLE_CE(nand); /* set pin high */ - - return ret; - -} - -/* write to the 16 bytes of oob data that correspond to a 512 byte - * page or 2 256-byte pages. - */ -static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, - size_t * retlen, const u_char * buf) -{ - int len256 = 0; - int i; - unsigned long nandptr = nand->IO_ADDR; - -#ifdef PSYCHO_DEBUG - printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n", - (long)ofs, len, buf[0], buf[1], buf[2], buf[3], - buf[8], buf[9], buf[14],buf[15]); -#endif - - NAND_ENABLE_CE(nand); /* set pin low to enable chip */ - - /* Reset the chip */ - NanD_Command(nand, NAND_CMD_RESET); - - /* issue the Read2 command to set the pointer to the Spare Data Area. */ - NanD_Command(nand, NAND_CMD_READOOB); - if (nand->bus16) { - NanD_Address(nand, ADDR_COLUMN_PAGE, - ((ofs >> nand->page_shift) << nand->page_shift) + - ((ofs & (nand->oobblock - 1)) >> 1)); - } else { - NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); - } - - /* update address for 2M x 8bit devices. OOB starts on the second */ - /* page to maintain compatibility with nand_read_ecc. */ - if (nand->page256) { - if (!(ofs & 0x8)) - ofs += 0x100; - else - ofs -= 0x8; - } - - /* issue the Serial Data In command to initial the Page Program process */ - NanD_Command(nand, NAND_CMD_SEQIN); - if (nand->bus16) { - NanD_Address(nand, ADDR_COLUMN_PAGE, - ((ofs >> nand->page_shift) << nand->page_shift) + - ((ofs & (nand->oobblock - 1)) >> 1)); - } else { - NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); - } - - /* treat crossing 8-byte OOB data for 2M x 8bit devices */ - /* Note: datasheet says it should automaticaly wrap to the */ - /* next OOB block, but it didn't work here. mf. */ - if (nand->page256 && ofs + len > (ofs | 0x7) + 1) { - len256 = (ofs | 0x7) + 1 - ofs; - for (i = 0; i < len256; i++) - WRITE_NAND(buf[i], nandptr); - - NanD_Command(nand, NAND_CMD_PAGEPROG); - NanD_Command(nand, NAND_CMD_STATUS); -#ifdef NAND_NO_RB - { u_char ret_val; - do { - ret_val = READ_NAND(nandptr); /* wait till ready */ - } while ((ret_val & 0x40) != 0x40); - } -#endif - if (READ_NAND(nandptr) & 1) { - puts ("Error programming oob data\n"); - /* There was an error */ - NAND_DISABLE_CE(nand); /* set pin high */ - *retlen = 0; - return -1; - } - NanD_Command(nand, NAND_CMD_SEQIN); - NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff)); - } - - if (nand->bus16) { - for (i = len256; i < len; i += 2) { - WRITE_NAND(buf[i] + (buf[i+1] << 8), nandptr); - } - } else { - for (i = len256; i < len; i++) - WRITE_NAND(buf[i], nandptr); - } - - NanD_Command(nand, NAND_CMD_PAGEPROG); - NanD_Command(nand, NAND_CMD_STATUS); -#ifdef NAND_NO_RB - { u_char ret_val; - do { - ret_val = READ_NAND(nandptr); /* wait till ready */ - } while ((ret_val & 0x40) != 0x40); - } -#endif - if (READ_NAND(nandptr) & 1) { - puts ("Error programming oob data\n"); - /* There was an error */ - NAND_DISABLE_CE(nand); /* set pin high */ - *retlen = 0; - return -1; - } - - NAND_DISABLE_CE(nand); /* set pin high */ - *retlen = len; - return 0; - -} - -int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean) -{ - /* This is defined as a structure so it will work on any system - * using native endian jffs2 (the default). - */ - static struct jffs2_unknown_node clean_marker = { - JFFS2_MAGIC_BITMASK, - JFFS2_NODETYPE_CLEANMARKER, - 8 /* 8 bytes in this node */ - }; - unsigned long nandptr; - struct Nand *mychip; - int ret = 0; - - if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) { - printf ("Offset and size must be sector aligned, erasesize = %d\n", - (int) nand->erasesize); - return -1; - } - - nandptr = nand->IO_ADDR; - - /* Select the NAND device */ -#ifdef CONFIG_OMAP1510 - archflashwp(0,0); -#endif -#ifdef CFG_NAND_WP - NAND_WP_OFF(); -#endif - NAND_ENABLE_CE(nand); /* set pin low */ - - /* Check the WP bit */ - NanD_Command(nand, NAND_CMD_STATUS); - if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { - printf ("nand_write_ecc: Device is write protected!!!\n"); - ret = -1; - goto out; - } - - /* Check the WP bit */ - NanD_Command(nand, NAND_CMD_STATUS); - if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { - printf ("%s: Device is write protected!!!\n", __FUNCTION__); - ret = -1; - goto out; - } - - /* FIXME: Do nand in the background. Use timers or schedule_task() */ - while(len) { - /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/ - mychip = &nand->chips[ofs >> nand->chipshift]; - - /* always check for bad block first, genuine bad blocks - * should _never_ be erased. - */ - if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) { - /* Select the NAND device */ - NAND_ENABLE_CE(nand); /* set pin low */ - - NanD_Command(nand, NAND_CMD_ERASE1); - NanD_Address(nand, ADDR_PAGE, ofs); - NanD_Command(nand, NAND_CMD_ERASE2); - - NanD_Command(nand, NAND_CMD_STATUS); - -#ifdef NAND_NO_RB - { u_char ret_val; - do { - ret_val = READ_NAND(nandptr); /* wait till ready */ - } while ((ret_val & 0x40) != 0x40); - } -#endif - if (READ_NAND(nandptr) & 1) { - printf ("%s: Error erasing at 0x%lx\n", - __FUNCTION__, (long)ofs); - /* There was an error */ - ret = -1; - goto out; - } - if (clean) { - int n; /* return value not used */ - int p, l; - - /* clean marker position and size depend - * on the page size, since 256 byte pages - * only have 8 bytes of oob data - */ - if (nand->page256) { - p = NAND_JFFS2_OOB8_FSDAPOS; - l = NAND_JFFS2_OOB8_FSDALEN; - } else { - p = NAND_JFFS2_OOB16_FSDAPOS; - l = NAND_JFFS2_OOB16_FSDALEN; - } - - ret = nand_write_oob(nand, ofs + p, l, &n, - (u_char *)&clean_marker); - /* quit here if write failed */ - if (ret) - goto out; - } - } - ofs += nand->erasesize; - len -= nand->erasesize; - } - -out: - /* De-select the NAND device */ - NAND_DISABLE_CE(nand); /* set pin high */ -#ifdef CONFIG_OMAP1510 - archflashwp(0,1); -#endif -#ifdef CFG_NAND_WP - NAND_WP_ON(); -#endif - - return ret; -} - -static inline int nandcheck(unsigned long potential, unsigned long physadr) -{ - return 0; -} - -unsigned long nand_probe(unsigned long physadr) -{ - struct nand_chip *nand = NULL; - int i = 0, ChipID = 1; - -#ifdef CONFIG_MTD_NAND_ECC_JFFS2 - oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0; - oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1; - oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2; - oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3; - oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4; - oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5; - oob_config.eccvalid_pos = 4; -#else - oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0; - oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1; - oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2; - oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3; - oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4; - oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5; - oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS; -#endif - oob_config.badblock_pos = 5; - - for (i=0; iIO_ADDR = physadr; - nand->cache_page = -1; /* init the cache page */ - NanD_ScanChips(nand); - - if (nand->totlen == 0) { - /* no chips found, clean up and quit */ - memset((char *)nand, 0, sizeof(struct nand_chip)); - nand->ChipID = NAND_ChipID_UNKNOWN; - return (0); - } - - nand->ChipID = ChipID; - if (curr_device == -1) - curr_device = i; - - nand->data_buf = malloc (nand->oobblock + nand->oobsize); - if (!nand->data_buf) { - puts ("Cannot allocate memory for data structures.\n"); - return (0); - } - - return (nand->totlen); -} - -#ifdef CONFIG_MTD_NAND_ECC -/* - * Pre-calculated 256-way 1 byte column parity - */ -static const u_char nand_ecc_precalc_table[] = { - 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, - 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, - 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, - 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, - 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, - 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, - 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, - 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, - 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, - 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, - 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, - 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, - 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, - 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, - 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, - 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, - 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, - 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, - 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, - 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, - 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, - 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, - 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, - 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, - 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, - 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, - 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, - 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, - 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, - 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, - 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, - 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 -}; - - -/* - * Creates non-inverted ECC code from line parity - */ -static void nand_trans_result(u_char reg2, u_char reg3, - u_char *ecc_code) -{ - u_char a, b, i, tmp1, tmp2; - - /* Initialize variables */ - a = b = 0x80; - tmp1 = tmp2 = 0; - - /* Calculate first ECC byte */ - for (i = 0; i < 4; i++) { - if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ - tmp1 |= b; - b >>= 1; - if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */ - tmp1 |= b; - b >>= 1; - a >>= 1; - } - - /* Calculate second ECC byte */ - b = 0x80; - for (i = 0; i < 4; i++) { - if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */ - tmp2 |= b; - b >>= 1; - if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */ - tmp2 |= b; - b >>= 1; - a >>= 1; - } - - /* Store two of the ECC bytes */ - ecc_code[0] = tmp1; - ecc_code[1] = tmp2; -} - -/* - * Calculate 3 byte ECC code for 256 byte block - */ -static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code) -{ - u_char idx, reg1, reg3; - int j; - - /* Initialize variables */ - reg1 = reg3 = 0; - ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; - - /* Build up column parity */ - for(j = 0; j < 256; j++) { - - /* Get CP0 - CP5 from table */ - idx = nand_ecc_precalc_table[dat[j]]; - reg1 ^= idx; - - /* All bit XOR = 1 ? */ - if (idx & 0x40) { - reg3 ^= (u_char) j; - } - } - - /* Create non-inverted ECC code from line parity */ - nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code); - - /* Calculate final ECC code */ - ecc_code[0] = ~ecc_code[0]; - ecc_code[1] = ~ecc_code[1]; - ecc_code[2] = ((~reg1) << 2) | 0x03; -} - -/* - * Detect and correct a 1 bit error for 256 byte block - */ -static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc) -{ - u_char a, b, c, d1, d2, d3, add, bit, i; - - /* Do error detection */ - d1 = calc_ecc[0] ^ read_ecc[0]; - d2 = calc_ecc[1] ^ read_ecc[1]; - d3 = calc_ecc[2] ^ read_ecc[2]; - - if ((d1 | d2 | d3) == 0) { - /* No errors */ - return 0; - } else { - a = (d1 ^ (d1 >> 1)) & 0x55; - b = (d2 ^ (d2 >> 1)) & 0x55; - c = (d3 ^ (d3 >> 1)) & 0x54; - - /* Found and will correct single bit error in the data */ - if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { - c = 0x80; - add = 0; - a = 0x80; - for (i=0; i<4; i++) { - if (d1 & c) - add |= a; - c >>= 2; - a >>= 1; - } - c = 0x80; - for (i=0; i<4; i++) { - if (d2 & c) - add |= a; - c >>= 2; - a >>= 1; - } - bit = 0; - b = 0x04; - c = 0x80; - for (i=0; i<3; i++) { - if (d3 & c) - bit |= b; - c >>= 2; - b >>= 1; - } - b = 0x01; - a = dat[add]; - a ^= (b << bit); - dat[add] = a; - return 1; - } - else { - i = 0; - while (d1) { - if (d1 & 0x01) - ++i; - d1 >>= 1; - } - while (d2) { - if (d2 & 0x01) - ++i; - d2 >>= 1; - } - while (d3) { - if (d3 & 0x01) - ++i; - d3 >>= 1; - } - if (i == 1) { - /* ECC Code Error Correction */ - read_ecc[0] = calc_ecc[0]; - read_ecc[1] = calc_ecc[1]; - read_ecc[2] = calc_ecc[2]; - return 2; - } - else { - /* Uncorrectable Error */ - return -1; - } - } - } - - /* Should never happen */ - return -1; -} - -#endif - -#ifdef CONFIG_JFFS2_NAND - -int read_jffs2_nand(size_t start, size_t len, - size_t * retlen, u_char * buf, int nanddev) -{ - return nand_rw(nand_dev_desc + nanddev, NANDRW_READ | NANDRW_JFFS2, - start, len, retlen, buf); -} - -#endif /* CONFIG_JFFS2_NAND */ - - -#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ diff --git a/drivers/nand/Makefile b/drivers/nand/Makefile new file mode 100644 index 0000000000..3906bf951d --- /dev/null +++ b/drivers/nand/Makefile @@ -0,0 +1,17 @@ +include $(TOPDIR)/config.mk + +LIB := libnand.a + +OBJS := nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o +all: $(LIB) + +$(LIB): $(OBJS) + $(AR) crv $@ $(OBJS) + +######################################################################### + +.depend: Makefile $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ + +sinclude .depend + diff --git a/drivers/nand/diskonchip.c b/drivers/nand/diskonchip.c new file mode 100644 index 0000000000..02135c3ac2 --- /dev/null +++ b/drivers/nand/diskonchip.c @@ -0,0 +1,1782 @@ +/* + * drivers/mtd/nand/diskonchip.c + * + * (C) 2003 Red Hat, Inc. + * (C) 2004 Dan Brown + * (C) 2004 Kalev Lember + * + * Author: David Woodhouse + * Additional Diskonchip 2000 and Millennium support by Dan Brown + * Diskonchip Millennium Plus support by Kalev Lember + * + * Error correction code lifted from the old docecc code + * Author: Fabrice Bellard (fabrice.bellard@netgem.com) + * Copyright (C) 2000 Netgem S.A. + * converted to the generic Reed-Solomon library by Thomas Gleixner + * + * Interface to generic NAND code for M-Systems DiskOnChip devices + * + * $Id: diskonchip.c,v 1.45 2005/01/05 18:05:14 dwmw2 Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* Where to look for the devices? */ +#ifndef CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS +#define CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS 0 +#endif + +static unsigned long __initdata doc_locations[] = { +#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) +#ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH + 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, + 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, + 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, + 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, + 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000, +#else /* CONFIG_MTD_DOCPROBE_HIGH */ + 0xc8000, 0xca000, 0xcc000, 0xce000, + 0xd0000, 0xd2000, 0xd4000, 0xd6000, + 0xd8000, 0xda000, 0xdc000, 0xde000, + 0xe0000, 0xe2000, 0xe4000, 0xe6000, + 0xe8000, 0xea000, 0xec000, 0xee000, +#endif /* CONFIG_MTD_DOCPROBE_HIGH */ +#elif defined(__PPC__) + 0xe4000000, +#elif defined(CONFIG_MOMENCO_OCELOT) + 0x2f000000, + 0xff000000, +#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C) + 0xff000000, +##else +#warning Unknown architecture for DiskOnChip. No default probe locations defined +#endif + 0xffffffff }; + +static struct mtd_info *doclist = NULL; + +struct doc_priv { + void __iomem *virtadr; + unsigned long physadr; + u_char ChipID; + u_char CDSNControl; + int chips_per_floor; /* The number of chips detected on each floor */ + int curfloor; + int curchip; + int mh0_page; + int mh1_page; + struct mtd_info *nextdoc; +}; + +/* Max number of eraseblocks to scan (from start of device) for the (I)NFTL + MediaHeader. The spec says to just keep going, I think, but that's just + silly. */ +#define MAX_MEDIAHEADER_SCAN 8 + +/* This is the syndrome computed by the HW ecc generator upon reading an empty + page, one with all 0xff for data and stored ecc code. */ +static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a }; +/* This is the ecc value computed by the HW ecc generator upon writing an empty + page, one with all 0xff for data. */ +static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 }; + +#define INFTL_BBT_RESERVED_BLOCKS 4 + +#define DoC_is_MillenniumPlus(doc) ((doc)->ChipID == DOC_ChipID_DocMilPlus16 || (doc)->ChipID == DOC_ChipID_DocMilPlus32) +#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil) +#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k) + +static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd); +static void doc200x_select_chip(struct mtd_info *mtd, int chip); + +static int debug=0; +module_param(debug, int, 0); + +static int try_dword=1; +module_param(try_dword, int, 0); + +static int no_ecc_failures=0; +module_param(no_ecc_failures, int, 0); + +#ifdef CONFIG_MTD_PARTITIONS +static int no_autopart=0; +module_param(no_autopart, int, 0); +#endif + +#ifdef MTD_NAND_DISKONCHIP_BBTWRITE +static int inftl_bbt_write=1; +#else +static int inftl_bbt_write=0; +#endif +module_param(inftl_bbt_write, int, 0); + +static unsigned long doc_config_location = CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS; +module_param(doc_config_location, ulong, 0); +MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip"); + + +/* Sector size for HW ECC */ +#define SECTOR_SIZE 512 +/* The sector bytes are packed into NB_DATA 10 bit words */ +#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / 10) +/* Number of roots */ +#define NROOTS 4 +/* First consective root */ +#define FCR 510 +/* Number of symbols */ +#define NN 1023 + +/* the Reed Solomon control structure */ +static struct rs_control *rs_decoder; + +/* + * The HW decoder in the DoC ASIC's provides us a error syndrome, + * which we must convert to a standard syndrom usable by the generic + * Reed-Solomon library code. + * + * Fabrice Bellard figured this out in the old docecc code. I added + * some comments, improved a minor bit and converted it to make use + * of the generic Reed-Solomon libary. tglx + */ +static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) +{ + int i, j, nerr, errpos[8]; + uint8_t parity; + uint16_t ds[4], s[5], tmp, errval[8], syn[4]; + + /* Convert the ecc bytes into words */ + ds[0] = ((ecc[4] & 0xff) >> 0) | ((ecc[5] & 0x03) << 8); + ds[1] = ((ecc[5] & 0xfc) >> 2) | ((ecc[2] & 0x0f) << 6); + ds[2] = ((ecc[2] & 0xf0) >> 4) | ((ecc[3] & 0x3f) << 4); + ds[3] = ((ecc[3] & 0xc0) >> 6) | ((ecc[0] & 0xff) << 2); + parity = ecc[1]; + + /* Initialize the syndrom buffer */ + for (i = 0; i < NROOTS; i++) + s[i] = ds[0]; + /* + * Evaluate + * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0] + * where x = alpha^(FCR + i) + */ + for(j = 1; j < NROOTS; j++) { + if(ds[j] == 0) + continue; + tmp = rs->index_of[ds[j]]; + for(i = 0; i < NROOTS; i++) + s[i] ^= rs->alpha_to[rs_modnn(rs, tmp + (FCR + i) * j)]; + } + + /* Calc s[i] = s[i] / alpha^(v + i) */ + for (i = 0; i < NROOTS; i++) { + if (syn[i]) + syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i)); + } + /* Call the decoder library */ + nerr = decode_rs16(rs, NULL, NULL, 1019, syn, 0, errpos, 0, errval); + + /* Incorrectable errors ? */ + if (nerr < 0) + return nerr; + + /* + * Correct the errors. The bitpositions are a bit of magic, + * but they are given by the design of the de/encoder circuit + * in the DoC ASIC's. + */ + for(i = 0;i < nerr; i++) { + int index, bitpos, pos = 1015 - errpos[i]; + uint8_t val; + if (pos >= NB_DATA && pos < 1019) + continue; + if (pos < NB_DATA) { + /* extract bit position (MSB first) */ + pos = 10 * (NB_DATA - 1 - pos) - 6; + /* now correct the following 10 bits. At most two bytes + can be modified since pos is even */ + index = (pos >> 3) ^ 1; + bitpos = pos & 7; + if ((index >= 0 && index < SECTOR_SIZE) || + index == (SECTOR_SIZE + 1)) { + val = (uint8_t) (errval[i] >> (2 + bitpos)); + parity ^= val; + if (index < SECTOR_SIZE) + data[index] ^= val; + } + index = ((pos >> 3) + 1) ^ 1; + bitpos = (bitpos + 10) & 7; + if (bitpos == 0) + bitpos = 8; + if ((index >= 0 && index < SECTOR_SIZE) || + index == (SECTOR_SIZE + 1)) { + val = (uint8_t)(errval[i] << (8 - bitpos)); + parity ^= val; + if (index < SECTOR_SIZE) + data[index] ^= val; + } + } + } + /* If the parity is wrong, no rescue possible */ + return parity ? -1 : nerr; +} + +static void DoC_Delay(struct doc_priv *doc, unsigned short cycles) +{ + volatile char dummy; + int i; + + for (i = 0; i < cycles; i++) { + if (DoC_is_Millennium(doc)) + dummy = ReadDOC(doc->virtadr, NOP); + else if (DoC_is_MillenniumPlus(doc)) + dummy = ReadDOC(doc->virtadr, Mplus_NOP); + else + dummy = ReadDOC(doc->virtadr, DOCStatus); + } + +} + +#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1) + +/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ +static int _DoC_WaitReady(struct doc_priv *doc) +{ + void __iomem *docptr = doc->virtadr; + unsigned long timeo = jiffies + (HZ * 10); + + if(debug) printk("_DoC_WaitReady...\n"); + /* Out-of-line routine to wait for chip response */ + if (DoC_is_MillenniumPlus(doc)) { + while ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) { + if (time_after(jiffies, timeo)) { + printk("_DoC_WaitReady timed out.\n"); + return -EIO; + } + udelay(1); + cond_resched(); + } + } else { + while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) { + if (time_after(jiffies, timeo)) { + printk("_DoC_WaitReady timed out.\n"); + return -EIO; + } + udelay(1); + cond_resched(); + } + } + + return 0; +} + +static inline int DoC_WaitReady(struct doc_priv *doc) +{ + void __iomem *docptr = doc->virtadr; + int ret = 0; + + if (DoC_is_MillenniumPlus(doc)) { + DoC_Delay(doc, 4); + + if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) + /* Call the out-of-line routine to wait */ + ret = _DoC_WaitReady(doc); + } else { + DoC_Delay(doc, 4); + + if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) + /* Call the out-of-line routine to wait */ + ret = _DoC_WaitReady(doc); + DoC_Delay(doc, 2); + } + + if(debug) printk("DoC_WaitReady OK\n"); + return ret; +} + +static void doc2000_write_byte(struct mtd_info *mtd, u_char datum) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + + if(debug)printk("write_byte %02x\n", datum); + WriteDOC(datum, docptr, CDSNSlowIO); + WriteDOC(datum, docptr, 2k_CDSN_IO); +} + +static u_char doc2000_read_byte(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + u_char ret; + + ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(doc, 2); + ret = ReadDOC(docptr, 2k_CDSN_IO); + if (debug) printk("read_byte returns %02x\n", ret); + return ret; +} + +static void doc2000_writebuf(struct mtd_info *mtd, + const u_char *buf, int len) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int i; + if (debug)printk("writebuf of %d bytes: ", len); + for (i=0; i < len; i++) { + WriteDOC_(buf[i], docptr, DoC_2k_CDSN_IO + i); + if (debug && i < 16) + printk("%02x ", buf[i]); + } + if (debug) printk("\n"); +} + +static void doc2000_readbuf(struct mtd_info *mtd, + u_char *buf, int len) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int i; + + if (debug)printk("readbuf of %d bytes: ", len); + + for (i=0; i < len; i++) { + buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i); + } +} + +static void doc2000_readbuf_dword(struct mtd_info *mtd, + u_char *buf, int len) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int i; + + if (debug) printk("readbuf_dword of %d bytes: ", len); + + if (unlikely((((unsigned long)buf)|len) & 3)) { + for (i=0; i < len; i++) { + *(uint8_t *)(&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i); + } + } else { + for (i=0; i < len; i+=4) { + *(uint32_t*)(&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i); + } + } +} + +static int doc2000_verifybuf(struct mtd_info *mtd, + const u_char *buf, int len) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int i; + + for (i=0; i < len; i++) + if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO)) + return -EFAULT; + return 0; +} + +static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + uint16_t ret; + + doc200x_select_chip(mtd, nr); + doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); + this->write_byte(mtd, NAND_CMD_READID); + doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); + doc200x_hwcontrol(mtd, NAND_CTL_SETALE); + this->write_byte(mtd, 0); + doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); + + ret = this->read_byte(mtd) << 8; + ret |= this->read_byte(mtd); + + if (doc->ChipID == DOC_ChipID_Doc2k && try_dword && !nr) { + /* First chip probe. See if we get same results by 32-bit access */ + union { + uint32_t dword; + uint8_t byte[4]; + } ident; + void __iomem *docptr = doc->virtadr; + + doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); + doc2000_write_byte(mtd, NAND_CMD_READID); + doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); + doc200x_hwcontrol(mtd, NAND_CTL_SETALE); + doc2000_write_byte(mtd, 0); + doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); + + ident.dword = readl(docptr + DoC_2k_CDSN_IO); + if (((ident.byte[0] << 8) | ident.byte[1]) == ret) { + printk(KERN_INFO "DiskOnChip 2000 responds to DWORD access\n"); + this->read_buf = &doc2000_readbuf_dword; + } + } + + return ret; +} + +static void __init doc2000_count_chips(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + uint16_t mfrid; + int i; + + /* Max 4 chips per floor on DiskOnChip 2000 */ + doc->chips_per_floor = 4; + + /* Find out what the first chip is */ + mfrid = doc200x_ident_chip(mtd, 0); + + /* Find how many chips in each floor. */ + for (i = 1; i < 4; i++) { + if (doc200x_ident_chip(mtd, i) != mfrid) + break; + } + doc->chips_per_floor = i; + printk(KERN_DEBUG "Detected %d chips per floor.\n", i); +} + +static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state) +{ + struct doc_priv *doc = this->priv; + + int status; + + DoC_WaitReady(doc); + this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); + DoC_WaitReady(doc); + status = (int)this->read_byte(mtd); + + return status; +} + +static void doc2001_write_byte(struct mtd_info *mtd, u_char datum) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + + WriteDOC(datum, docptr, CDSNSlowIO); + WriteDOC(datum, docptr, Mil_CDSN_IO); + WriteDOC(datum, docptr, WritePipeTerm); +} + +static u_char doc2001_read_byte(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + + //ReadDOC(docptr, CDSNSlowIO); + /* 11.4.5 -- delay twice to allow extended length cycle */ + DoC_Delay(doc, 2); + ReadDOC(docptr, ReadPipeInit); + //return ReadDOC(docptr, Mil_CDSN_IO); + return ReadDOC(docptr, LastDataRead); +} + +static void doc2001_writebuf(struct mtd_info *mtd, + const u_char *buf, int len) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int i; + + for (i=0; i < len; i++) + WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i); + /* Terminate write pipeline */ + WriteDOC(0x00, docptr, WritePipeTerm); +} + +static void doc2001_readbuf(struct mtd_info *mtd, + u_char *buf, int len) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int i; + + /* Start read pipeline */ + ReadDOC(docptr, ReadPipeInit); + + for (i=0; i < len-1; i++) + buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff)); + + /* Terminate read pipeline */ + buf[i] = ReadDOC(docptr, LastDataRead); +} + +static int doc2001_verifybuf(struct mtd_info *mtd, + const u_char *buf, int len) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int i; + + /* Start read pipeline */ + ReadDOC(docptr, ReadPipeInit); + + for (i=0; i < len-1; i++) + if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) { + ReadDOC(docptr, LastDataRead); + return i; + } + if (buf[i] != ReadDOC(docptr, LastDataRead)) + return i; + return 0; +} + +static u_char doc2001plus_read_byte(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + u_char ret; + + ReadDOC(docptr, Mplus_ReadPipeInit); + ReadDOC(docptr, Mplus_ReadPipeInit); + ret = ReadDOC(docptr, Mplus_LastDataRead); + if (debug) printk("read_byte returns %02x\n", ret); + return ret; +} + +static void doc2001plus_writebuf(struct mtd_info *mtd, + const u_char *buf, int len) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int i; + + if (debug)printk("writebuf of %d bytes: ", len); + for (i=0; i < len; i++) { + WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i); + if (debug && i < 16) + printk("%02x ", buf[i]); + } + if (debug) printk("\n"); +} + +static void doc2001plus_readbuf(struct mtd_info *mtd, + u_char *buf, int len) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int i; + + if (debug)printk("readbuf of %d bytes: ", len); + + /* Start read pipeline */ + ReadDOC(docptr, Mplus_ReadPipeInit); + ReadDOC(docptr, Mplus_ReadPipeInit); + + for (i=0; i < len-2; i++) { + buf[i] = ReadDOC(docptr, Mil_CDSN_IO); + if (debug && i < 16) + printk("%02x ", buf[i]); + } + + /* Terminate read pipeline */ + buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead); + if (debug && i < 16) + printk("%02x ", buf[len-2]); + buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead); + if (debug && i < 16) + printk("%02x ", buf[len-1]); + if (debug) printk("\n"); +} + +static int doc2001plus_verifybuf(struct mtd_info *mtd, + const u_char *buf, int len) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int i; + + if (debug)printk("verifybuf of %d bytes: ", len); + + /* Start read pipeline */ + ReadDOC(docptr, Mplus_ReadPipeInit); + ReadDOC(docptr, Mplus_ReadPipeInit); + + for (i=0; i < len-2; i++) + if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) { + ReadDOC(docptr, Mplus_LastDataRead); + ReadDOC(docptr, Mplus_LastDataRead); + return i; + } + if (buf[len-2] != ReadDOC(docptr, Mplus_LastDataRead)) + return len-2; + if (buf[len-1] != ReadDOC(docptr, Mplus_LastDataRead)) + return len-1; + return 0; +} + +static void doc2001plus_select_chip(struct mtd_info *mtd, int chip) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int floor = 0; + + if(debug)printk("select chip (%d)\n", chip); + + if (chip == -1) { + /* Disable flash internally */ + WriteDOC(0, docptr, Mplus_FlashSelect); + return; + } + + floor = chip / doc->chips_per_floor; + chip -= (floor * doc->chips_per_floor); + + /* Assert ChipEnable and deassert WriteProtect */ + WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect); + this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + + doc->curchip = chip; + doc->curfloor = floor; +} + +static void doc200x_select_chip(struct mtd_info *mtd, int chip) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int floor = 0; + + if(debug)printk("select chip (%d)\n", chip); + + if (chip == -1) + return; + + floor = chip / doc->chips_per_floor; + chip -= (floor * doc->chips_per_floor); + + /* 11.4.4 -- deassert CE before changing chip */ + doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE); + + WriteDOC(floor, docptr, FloorSelect); + WriteDOC(chip, docptr, CDSNDeviceSelect); + + doc200x_hwcontrol(mtd, NAND_CTL_SETNCE); + + doc->curchip = chip; + doc->curfloor = floor; +} + +static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + + switch(cmd) { + case NAND_CTL_SETNCE: + doc->CDSNControl |= CDSN_CTRL_CE; + break; + case NAND_CTL_CLRNCE: + doc->CDSNControl &= ~CDSN_CTRL_CE; + break; + case NAND_CTL_SETCLE: + doc->CDSNControl |= CDSN_CTRL_CLE; + break; + case NAND_CTL_CLRCLE: + doc->CDSNControl &= ~CDSN_CTRL_CLE; + break; + case NAND_CTL_SETALE: + doc->CDSNControl |= CDSN_CTRL_ALE; + break; + case NAND_CTL_CLRALE: + doc->CDSNControl &= ~CDSN_CTRL_ALE; + break; + case NAND_CTL_SETWP: + doc->CDSNControl |= CDSN_CTRL_WP; + break; + case NAND_CTL_CLRWP: + doc->CDSNControl &= ~CDSN_CTRL_WP; + break; + } + if (debug)printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl); + WriteDOC(doc->CDSNControl, docptr, CDSNControl); + /* 11.4.3 -- 4 NOPs after CSDNControl write */ + DoC_Delay(doc, 4); +} + +static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + + /* + * Must terminate write pipeline before sending any commands + * to the device. + */ + if (command == NAND_CMD_PAGEPROG) { + WriteDOC(0x00, docptr, Mplus_WritePipeTerm); + WriteDOC(0x00, docptr, Mplus_WritePipeTerm); + } + + /* + * Write out the command to the device. + */ + if (command == NAND_CMD_SEQIN) { + int readcmd; + + if (column >= mtd->oobblock) { + /* OOB area */ + column -= mtd->oobblock; + readcmd = NAND_CMD_READOOB; + } else if (column < 256) { + /* First 256 bytes --> READ0 */ + readcmd = NAND_CMD_READ0; + } else { + column -= 256; + readcmd = NAND_CMD_READ1; + } + WriteDOC(readcmd, docptr, Mplus_FlashCmd); + } + WriteDOC(command, docptr, Mplus_FlashCmd); + WriteDOC(0, docptr, Mplus_WritePipeTerm); + WriteDOC(0, docptr, Mplus_WritePipeTerm); + + if (column != -1 || page_addr != -1) { + /* Serially input address */ + if (column != -1) { + /* Adjust columns for 16 bit buswidth */ + if (this->options & NAND_BUSWIDTH_16) + column >>= 1; + WriteDOC(column, docptr, Mplus_FlashAddress); + } + if (page_addr != -1) { + WriteDOC((unsigned char) (page_addr & 0xff), docptr, Mplus_FlashAddress); + WriteDOC((unsigned char) ((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress); + /* One more address cycle for higher density devices */ + if (this->chipsize & 0x0c000000) { + WriteDOC((unsigned char) ((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress); + printk("high density\n"); + } + } + WriteDOC(0, docptr, Mplus_WritePipeTerm); + WriteDOC(0, docptr, Mplus_WritePipeTerm); + /* deassert ALE */ + if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || command == NAND_CMD_READOOB || command == NAND_CMD_READID) + WriteDOC(0, docptr, Mplus_FlashControl); + } + + /* + * program and erase have their own busy handlers + * status and sequential in needs no delay + */ + switch (command) { + + case NAND_CMD_PAGEPROG: + case NAND_CMD_ERASE1: + case NAND_CMD_ERASE2: + case NAND_CMD_SEQIN: + case NAND_CMD_STATUS: + return; + + case NAND_CMD_RESET: + if (this->dev_ready) + break; + udelay(this->chip_delay); + WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd); + WriteDOC(0, docptr, Mplus_WritePipeTerm); + WriteDOC(0, docptr, Mplus_WritePipeTerm); + while ( !(this->read_byte(mtd) & 0x40)); + return; + + /* This applies to read commands */ + default: + /* + * If we don't have access to the busy pin, we apply the given + * command delay + */ + if (!this->dev_ready) { + udelay (this->chip_delay); + return; + } + } + + /* Apply this short delay always to ensure that we do wait tWB in + * any case on any machine. */ + ndelay (100); + /* wait until command is processed */ + while (!this->dev_ready(mtd)); +} + +static int doc200x_dev_ready(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + + if (DoC_is_MillenniumPlus(doc)) { + /* 11.4.2 -- must NOP four times before checking FR/B# */ + DoC_Delay(doc, 4); + if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) { + if(debug) + printk("not ready\n"); + return 0; + } + if (debug)printk("was ready\n"); + return 1; + } else { + /* 11.4.2 -- must NOP four times before checking FR/B# */ + DoC_Delay(doc, 4); + if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) { + if(debug) + printk("not ready\n"); + return 0; + } + /* 11.4.2 -- Must NOP twice if it's ready */ + DoC_Delay(doc, 2); + if (debug)printk("was ready\n"); + return 1; + } +} + +static int doc200x_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) +{ + /* This is our last resort if we couldn't find or create a BBT. Just + pretend all blocks are good. */ + return 0; +} + +static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + + /* Prime the ECC engine */ + switch(mode) { + case NAND_ECC_READ: + WriteDOC(DOC_ECC_RESET, docptr, ECCConf); + WriteDOC(DOC_ECC_EN, docptr, ECCConf); + break; + case NAND_ECC_WRITE: + WriteDOC(DOC_ECC_RESET, docptr, ECCConf); + WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); + break; + } +} + +static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + + /* Prime the ECC engine */ + switch(mode) { + case NAND_ECC_READ: + WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); + WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf); + break; + case NAND_ECC_WRITE: + WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); + WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf); + break; + } +} + +/* This code is only called on write */ +static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, + unsigned char *ecc_code) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + int i; + int emptymatch = 1; + + /* flush the pipeline */ + if (DoC_is_2000(doc)) { + WriteDOC(doc->CDSNControl & ~CDSN_CTRL_FLASH_IO, docptr, CDSNControl); + WriteDOC(0, docptr, 2k_CDSN_IO); + WriteDOC(0, docptr, 2k_CDSN_IO); + WriteDOC(0, docptr, 2k_CDSN_IO); + WriteDOC(doc->CDSNControl, docptr, CDSNControl); + } else if (DoC_is_MillenniumPlus(doc)) { + WriteDOC(0, docptr, Mplus_NOP); + WriteDOC(0, docptr, Mplus_NOP); + WriteDOC(0, docptr, Mplus_NOP); + } else { + WriteDOC(0, docptr, NOP); + WriteDOC(0, docptr, NOP); + WriteDOC(0, docptr, NOP); + } + + for (i = 0; i < 6; i++) { + if (DoC_is_MillenniumPlus(doc)) + ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); + else + ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); + if (ecc_code[i] != empty_write_ecc[i]) + emptymatch = 0; + } + if (DoC_is_MillenniumPlus(doc)) + WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); + else + WriteDOC(DOC_ECC_DIS, docptr, ECCConf); +#if 0 + /* If emptymatch=1, we might have an all-0xff data buffer. Check. */ + if (emptymatch) { + /* Note: this somewhat expensive test should not be triggered + often. It could be optimized away by examining the data in + the writebuf routine, and remembering the result. */ + for (i = 0; i < 512; i++) { + if (dat[i] == 0xff) continue; + emptymatch = 0; + break; + } + } + /* If emptymatch still =1, we do have an all-0xff data buffer. + Return all-0xff ecc value instead of the computed one, so + it'll look just like a freshly-erased page. */ + if (emptymatch) memset(ecc_code, 0xff, 6); +#endif + return 0; +} + +static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) +{ + int i, ret = 0; + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + void __iomem *docptr = doc->virtadr; + volatile u_char dummy; + int emptymatch = 1; + + /* flush the pipeline */ + if (DoC_is_2000(doc)) { + dummy = ReadDOC(docptr, 2k_ECCStatus); + dummy = ReadDOC(docptr, 2k_ECCStatus); + dummy = ReadDOC(docptr, 2k_ECCStatus); + } else if (DoC_is_MillenniumPlus(doc)) { + dummy = ReadDOC(docptr, Mplus_ECCConf); + dummy = ReadDOC(docptr, Mplus_ECCConf); + dummy = ReadDOC(docptr, Mplus_ECCConf); + } else { + dummy = ReadDOC(docptr, ECCConf); + dummy = ReadDOC(docptr, ECCConf); + dummy = ReadDOC(docptr, ECCConf); + } + + /* Error occured ? */ + if (dummy & 0x80) { + for (i = 0; i < 6; i++) { + if (DoC_is_MillenniumPlus(doc)) + calc_ecc[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); + else + calc_ecc[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); + if (calc_ecc[i] != empty_read_syndrome[i]) + emptymatch = 0; + } + /* If emptymatch=1, the read syndrome is consistent with an + all-0xff data and stored ecc block. Check the stored ecc. */ + if (emptymatch) { + for (i = 0; i < 6; i++) { + if (read_ecc[i] == 0xff) continue; + emptymatch = 0; + break; + } + } + /* If emptymatch still =1, check the data block. */ + if (emptymatch) { + /* Note: this somewhat expensive test should not be triggered + often. It could be optimized away by examining the data in + the readbuf routine, and remembering the result. */ + for (i = 0; i < 512; i++) { + if (dat[i] == 0xff) continue; + emptymatch = 0; + break; + } + } + /* If emptymatch still =1, this is almost certainly a freshly- + erased block, in which case the ECC will not come out right. + We'll suppress the error and tell the caller everything's + OK. Because it is. */ + if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc); + if (ret > 0) + printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); + } + if (DoC_is_MillenniumPlus(doc)) + WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); + else + WriteDOC(DOC_ECC_DIS, docptr, ECCConf); + if (no_ecc_failures && (ret == -1)) { + printk(KERN_ERR "suppressing ECC failure\n"); + ret = 0; + } + return ret; +} + +//u_char mydatabuf[528]; + +static struct nand_oobinfo doc200x_oobinfo = { + .useecc = MTD_NANDECC_AUTOPLACE, + .eccbytes = 6, + .eccpos = {0, 1, 2, 3, 4, 5}, + .oobfree = { {8, 8} } +}; + +/* Find the (I)NFTL Media Header, and optionally also the mirror media header. + On sucessful return, buf will contain a copy of the media header for + further processing. id is the string to scan for, and will presumably be + either "ANAND" or "BNAND". If findmirror=1, also look for the mirror media + header. The page #s of the found media headers are placed in mh0_page and + mh1_page in the DOC private structure. */ +static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, + const char *id, int findmirror) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + unsigned offs, end = (MAX_MEDIAHEADER_SCAN << this->phys_erase_shift); + int ret; + size_t retlen; + + end = min(end, mtd->size); // paranoia + for (offs = 0; offs < end; offs += mtd->erasesize) { + ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf); + if (retlen != mtd->oobblock) continue; + if (ret) { + printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n", + offs); + } + if (memcmp(buf, id, 6)) continue; + printk(KERN_INFO "Found DiskOnChip %s Media Header at 0x%x\n", id, offs); + if (doc->mh0_page == -1) { + doc->mh0_page = offs >> this->page_shift; + if (!findmirror) return 1; + continue; + } + doc->mh1_page = offs >> this->page_shift; + return 2; + } + if (doc->mh0_page == -1) { + printk(KERN_WARNING "DiskOnChip %s Media Header not found.\n", id); + return 0; + } + /* Only one mediaheader was found. We want buf to contain a + mediaheader on return, so we'll have to re-read the one we found. */ + offs = doc->mh0_page << this->page_shift; + ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf); + if (retlen != mtd->oobblock) { + /* Insanity. Give up. */ + printk(KERN_ERR "Read DiskOnChip Media Header once, but can't reread it???\n"); + return 0; + } + return 1; +} + +static inline int __init nftl_partscan(struct mtd_info *mtd, + struct mtd_partition *parts) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + int ret = 0; + u_char *buf; + struct NFTLMediaHeader *mh; + const unsigned psize = 1 << this->page_shift; + unsigned blocks, maxblocks; + int offs, numheaders; + + buf = kmalloc(mtd->oobblock, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n"); + return 0; + } + if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out; + mh = (struct NFTLMediaHeader *) buf; + +//#ifdef CONFIG_MTD_DEBUG_VERBOSE +// if (CONFIG_MTD_DEBUG_VERBOSE >= 2) + printk(KERN_INFO " DataOrgID = %s\n" + " NumEraseUnits = %d\n" + " FirstPhysicalEUN = %d\n" + " FormattedSize = %d\n" + " UnitSizeFactor = %d\n", + mh->DataOrgID, mh->NumEraseUnits, + mh->FirstPhysicalEUN, mh->FormattedSize, + mh->UnitSizeFactor); +//#endif + + blocks = mtd->size >> this->phys_erase_shift; + maxblocks = min(32768U, mtd->erasesize - psize); + + if (mh->UnitSizeFactor == 0x00) { + /* Auto-determine UnitSizeFactor. The constraints are: + - There can be at most 32768 virtual blocks. + - There can be at most (virtual block size - page size) + virtual blocks (because MediaHeader+BBT must fit in 1). + */ + mh->UnitSizeFactor = 0xff; + while (blocks > maxblocks) { + blocks >>= 1; + maxblocks = min(32768U, (maxblocks << 1) + psize); + mh->UnitSizeFactor--; + } + printk(KERN_WARNING "UnitSizeFactor=0x00 detected. Correct value is assumed to be 0x%02x.\n", mh->UnitSizeFactor); + } + + /* NOTE: The lines below modify internal variables of the NAND and MTD + layers; variables with have already been configured by nand_scan. + Unfortunately, we didn't know before this point what these values + should be. Thus, this code is somewhat dependant on the exact + implementation of the NAND layer. */ + if (mh->UnitSizeFactor != 0xff) { + this->bbt_erase_shift += (0xff - mh->UnitSizeFactor); + mtd->erasesize <<= (0xff - mh->UnitSizeFactor); + printk(KERN_INFO "Setting virtual erase size to %d\n", mtd->erasesize); + blocks = mtd->size >> this->bbt_erase_shift; + maxblocks = min(32768U, mtd->erasesize - psize); + } + + if (blocks > maxblocks) { + printk(KERN_ERR "UnitSizeFactor of 0x%02x is inconsistent with device size. Aborting.\n", mh->UnitSizeFactor); + goto out; + } + + /* Skip past the media headers. */ + offs = max(doc->mh0_page, doc->mh1_page); + offs <<= this->page_shift; + offs += mtd->erasesize; + + //parts[0].name = " DiskOnChip Boot / Media Header partition"; + //parts[0].offset = 0; + //parts[0].size = offs; + + parts[0].name = " DiskOnChip BDTL partition"; + parts[0].offset = offs; + parts[0].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift; + + offs += parts[0].size; + if (offs < mtd->size) { + parts[1].name = " DiskOnChip Remainder partition"; + parts[1].offset = offs; + parts[1].size = mtd->size - offs; + ret = 2; + goto out; + } + ret = 1; +out: + kfree(buf); + return ret; +} + +/* This is a stripped-down copy of the code in inftlmount.c */ +static inline int __init inftl_partscan(struct mtd_info *mtd, + struct mtd_partition *parts) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + int ret = 0; + u_char *buf; + struct INFTLMediaHeader *mh; + struct INFTLPartition *ip; + int numparts = 0; + int blocks; + int vshift, lastvunit = 0; + int i; + int end = mtd->size; + + if (inftl_bbt_write) + end -= (INFTL_BBT_RESERVED_BLOCKS << this->phys_erase_shift); + + buf = kmalloc(mtd->oobblock, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n"); + return 0; + } + + if (!find_media_headers(mtd, buf, "BNAND", 0)) goto out; + doc->mh1_page = doc->mh0_page + (4096 >> this->page_shift); + mh = (struct INFTLMediaHeader *) buf; + + mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks); + mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions); + mh->NoOfBDTLPartitions = le32_to_cpu(mh->NoOfBDTLPartitions); + mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits); + mh->FormatFlags = le32_to_cpu(mh->FormatFlags); + mh->PercentUsed = le32_to_cpu(mh->PercentUsed); + +//#ifdef CONFIG_MTD_DEBUG_VERBOSE +// if (CONFIG_MTD_DEBUG_VERBOSE >= 2) + printk(KERN_INFO " bootRecordID = %s\n" + " NoOfBootImageBlocks = %d\n" + " NoOfBinaryPartitions = %d\n" + " NoOfBDTLPartitions = %d\n" + " BlockMultiplerBits = %d\n" + " FormatFlgs = %d\n" + " OsakVersion = %d.%d.%d.%d\n" + " PercentUsed = %d\n", + mh->bootRecordID, mh->NoOfBootImageBlocks, + mh->NoOfBinaryPartitions, + mh->NoOfBDTLPartitions, + mh->BlockMultiplierBits, mh->FormatFlags, + ((unsigned char *) &mh->OsakVersion)[0] & 0xf, + ((unsigned char *) &mh->OsakVersion)[1] & 0xf, + ((unsigned char *) &mh->OsakVersion)[2] & 0xf, + ((unsigned char *) &mh->OsakVersion)[3] & 0xf, + mh->PercentUsed); +//#endif + + vshift = this->phys_erase_shift + mh->BlockMultiplierBits; + + blocks = mtd->size >> vshift; + if (blocks > 32768) { + printk(KERN_ERR "BlockMultiplierBits=%d is inconsistent with device size. Aborting.\n", mh->BlockMultiplierBits); + goto out; + } + + blocks = doc->chips_per_floor << (this->chip_shift - this->phys_erase_shift); + if (inftl_bbt_write && (blocks > mtd->erasesize)) { + printk(KERN_ERR "Writeable BBTs spanning more than one erase block are not yet supported. FIX ME!\n"); + goto out; + } + + /* Scan the partitions */ + for (i = 0; (i < 4); i++) { + ip = &(mh->Partitions[i]); + ip->virtualUnits = le32_to_cpu(ip->virtualUnits); + ip->firstUnit = le32_to_cpu(ip->firstUnit); + ip->lastUnit = le32_to_cpu(ip->lastUnit); + ip->flags = le32_to_cpu(ip->flags); + ip->spareUnits = le32_to_cpu(ip->spareUnits); + ip->Reserved0 = le32_to_cpu(ip->Reserved0); + +//#ifdef CONFIG_MTD_DEBUG_VERBOSE +// if (CONFIG_MTD_DEBUG_VERBOSE >= 2) + printk(KERN_INFO " PARTITION[%d] ->\n" + " virtualUnits = %d\n" + " firstUnit = %d\n" + " lastUnit = %d\n" + " flags = 0x%x\n" + " spareUnits = %d\n", + i, ip->virtualUnits, ip->firstUnit, + ip->lastUnit, ip->flags, + ip->spareUnits); +//#endif + +/* + if ((i == 0) && (ip->firstUnit > 0)) { + parts[0].name = " DiskOnChip IPL / Media Header partition"; + parts[0].offset = 0; + parts[0].size = mtd->erasesize * ip->firstUnit; + numparts = 1; + } +*/ + + if (ip->flags & INFTL_BINARY) + parts[numparts].name = " DiskOnChip BDK partition"; + else + parts[numparts].name = " DiskOnChip BDTL partition"; + parts[numparts].offset = ip->firstUnit << vshift; + parts[numparts].size = (1 + ip->lastUnit - ip->firstUnit) << vshift; + numparts++; + if (ip->lastUnit > lastvunit) lastvunit = ip->lastUnit; + if (ip->flags & INFTL_LAST) break; + } + lastvunit++; + if ((lastvunit << vshift) < end) { + parts[numparts].name = " DiskOnChip Remainder partition"; + parts[numparts].offset = lastvunit << vshift; + parts[numparts].size = end - parts[numparts].offset; + numparts++; + } + ret = numparts; +out: + kfree(buf); + return ret; +} + +static int __init nftl_scan_bbt(struct mtd_info *mtd) +{ + int ret, numparts; + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + struct mtd_partition parts[2]; + + memset((char *) parts, 0, sizeof(parts)); + /* On NFTL, we have to find the media headers before we can read the + BBTs, since they're stored in the media header eraseblocks. */ + numparts = nftl_partscan(mtd, parts); + if (!numparts) return -EIO; + this->bbt_td->options = NAND_BBT_ABSPAGE | NAND_BBT_8BIT | + NAND_BBT_SAVECONTENT | NAND_BBT_WRITE | + NAND_BBT_VERSION; + this->bbt_td->veroffs = 7; + this->bbt_td->pages[0] = doc->mh0_page + 1; + if (doc->mh1_page != -1) { + this->bbt_md->options = NAND_BBT_ABSPAGE | NAND_BBT_8BIT | + NAND_BBT_SAVECONTENT | NAND_BBT_WRITE | + NAND_BBT_VERSION; + this->bbt_md->veroffs = 7; + this->bbt_md->pages[0] = doc->mh1_page + 1; + } else { + this->bbt_md = NULL; + } + + /* It's safe to set bd=NULL below because NAND_BBT_CREATE is not set. + At least as nand_bbt.c is currently written. */ + if ((ret = nand_scan_bbt(mtd, NULL))) + return ret; + add_mtd_device(mtd); +#ifdef CONFIG_MTD_PARTITIONS + if (!no_autopart) + add_mtd_partitions(mtd, parts, numparts); +#endif + return 0; +} + +static int __init inftl_scan_bbt(struct mtd_info *mtd) +{ + int ret, numparts; + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + struct mtd_partition parts[5]; + + if (this->numchips > doc->chips_per_floor) { + printk(KERN_ERR "Multi-floor INFTL devices not yet supported.\n"); + return -EIO; + } + + if (DoC_is_MillenniumPlus(doc)) { + this->bbt_td->options = NAND_BBT_2BIT | NAND_BBT_ABSPAGE; + if (inftl_bbt_write) + this->bbt_td->options |= NAND_BBT_WRITE; + this->bbt_td->pages[0] = 2; + this->bbt_md = NULL; + } else { + this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | + NAND_BBT_VERSION; + if (inftl_bbt_write) + this->bbt_td->options |= NAND_BBT_WRITE; + this->bbt_td->offs = 8; + this->bbt_td->len = 8; + this->bbt_td->veroffs = 7; + this->bbt_td->maxblocks = INFTL_BBT_RESERVED_BLOCKS; + this->bbt_td->reserved_block_code = 0x01; + this->bbt_td->pattern = "MSYS_BBT"; + + this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | + NAND_BBT_VERSION; + if (inftl_bbt_write) + this->bbt_md->options |= NAND_BBT_WRITE; + this->bbt_md->offs = 8; + this->bbt_md->len = 8; + this->bbt_md->veroffs = 7; + this->bbt_md->maxblocks = INFTL_BBT_RESERVED_BLOCKS; + this->bbt_md->reserved_block_code = 0x01; + this->bbt_md->pattern = "TBB_SYSM"; + } + + /* It's safe to set bd=NULL below because NAND_BBT_CREATE is not set. + At least as nand_bbt.c is currently written. */ + if ((ret = nand_scan_bbt(mtd, NULL))) + return ret; + memset((char *) parts, 0, sizeof(parts)); + numparts = inftl_partscan(mtd, parts); + /* At least for now, require the INFTL Media Header. We could probably + do without it for non-INFTL use, since all it gives us is + autopartitioning, but I want to give it more thought. */ + if (!numparts) return -EIO; + add_mtd_device(mtd); +#ifdef CONFIG_MTD_PARTITIONS + if (!no_autopart) + add_mtd_partitions(mtd, parts, numparts); +#endif + return 0; +} + +static inline int __init doc2000_init(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + + this->write_byte = doc2000_write_byte; + this->read_byte = doc2000_read_byte; + this->write_buf = doc2000_writebuf; + this->read_buf = doc2000_readbuf; + this->verify_buf = doc2000_verifybuf; + this->scan_bbt = nftl_scan_bbt; + + doc->CDSNControl = CDSN_CTRL_FLASH_IO | CDSN_CTRL_ECC_IO; + doc2000_count_chips(mtd); + mtd->name = "DiskOnChip 2000 (NFTL Model)"; + return (4 * doc->chips_per_floor); +} + +static inline int __init doc2001_init(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + + this->write_byte = doc2001_write_byte; + this->read_byte = doc2001_read_byte; + this->write_buf = doc2001_writebuf; + this->read_buf = doc2001_readbuf; + this->verify_buf = doc2001_verifybuf; + + ReadDOC(doc->virtadr, ChipID); + ReadDOC(doc->virtadr, ChipID); + ReadDOC(doc->virtadr, ChipID); + if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) { + /* It's not a Millennium; it's one of the newer + DiskOnChip 2000 units with a similar ASIC. + Treat it like a Millennium, except that it + can have multiple chips. */ + doc2000_count_chips(mtd); + mtd->name = "DiskOnChip 2000 (INFTL Model)"; + this->scan_bbt = inftl_scan_bbt; + return (4 * doc->chips_per_floor); + } else { + /* Bog-standard Millennium */ + doc->chips_per_floor = 1; + mtd->name = "DiskOnChip Millennium"; + this->scan_bbt = nftl_scan_bbt; + return 1; + } +} + +static inline int __init doc2001plus_init(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + struct doc_priv *doc = this->priv; + + this->write_byte = NULL; + this->read_byte = doc2001plus_read_byte; + this->write_buf = doc2001plus_writebuf; + this->read_buf = doc2001plus_readbuf; + this->verify_buf = doc2001plus_verifybuf; + this->scan_bbt = inftl_scan_bbt; + this->hwcontrol = NULL; + this->select_chip = doc2001plus_select_chip; + this->cmdfunc = doc2001plus_command; + this->enable_hwecc = doc2001plus_enable_hwecc; + + doc->chips_per_floor = 1; + mtd->name = "DiskOnChip Millennium Plus"; + + return 1; +} + +static inline int __init doc_probe(unsigned long physadr) +{ + unsigned char ChipID; + struct mtd_info *mtd; + struct nand_chip *nand; + struct doc_priv *doc; + void __iomem *virtadr; + unsigned char save_control; + unsigned char tmp, tmpb, tmpc; + int reg, len, numchips; + int ret = 0; + + virtadr = ioremap(physadr, DOC_IOREMAP_LEN); + if (!virtadr) { + printk(KERN_ERR "Diskonchip ioremap failed: 0x%x bytes at 0x%lx\n", DOC_IOREMAP_LEN, physadr); + return -EIO; + } + + /* It's not possible to cleanly detect the DiskOnChip - the + * bootup procedure will put the device into reset mode, and + * it's not possible to talk to it without actually writing + * to the DOCControl register. So we store the current contents + * of the DOCControl register's location, in case we later decide + * that it's not a DiskOnChip, and want to put it back how we + * found it. + */ + save_control = ReadDOC(virtadr, DOCControl); + + /* Reset the DiskOnChip ASIC */ + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, + virtadr, DOCControl); + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, + virtadr, DOCControl); + + /* Enable the DiskOnChip ASIC */ + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, + virtadr, DOCControl); + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, + virtadr, DOCControl); + + ChipID = ReadDOC(virtadr, ChipID); + + switch(ChipID) { + case DOC_ChipID_Doc2k: + reg = DoC_2k_ECCStatus; + break; + case DOC_ChipID_DocMil: + reg = DoC_ECCConf; + break; + case DOC_ChipID_DocMilPlus16: + case DOC_ChipID_DocMilPlus32: + case 0: + /* Possible Millennium Plus, need to do more checks */ + /* Possibly release from power down mode */ + for (tmp = 0; (tmp < 4); tmp++) + ReadDOC(virtadr, Mplus_Power); + + /* Reset the Millennium Plus ASIC */ + tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | + DOC_MODE_BDECT; + WriteDOC(tmp, virtadr, Mplus_DOCControl); + WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm); + + mdelay(1); + /* Enable the Millennium Plus ASIC */ + tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | + DOC_MODE_BDECT; + WriteDOC(tmp, virtadr, Mplus_DOCControl); + WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm); + mdelay(1); + + ChipID = ReadDOC(virtadr, ChipID); + + switch (ChipID) { + case DOC_ChipID_DocMilPlus16: + reg = DoC_Mplus_Toggle; + break; + case DOC_ChipID_DocMilPlus32: + printk(KERN_ERR "DiskOnChip Millennium Plus 32MB is not supported, ignoring.\n"); + default: + ret = -ENODEV; + goto notfound; + } + break; + + default: + ret = -ENODEV; + goto notfound; + } + /* Check the TOGGLE bit in the ECC register */ + tmp = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT; + tmpb = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT; + tmpc = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT; + if ((tmp == tmpb) || (tmp != tmpc)) { + printk(KERN_WARNING "Possible DiskOnChip at 0x%lx failed TOGGLE test, dropping.\n", physadr); + ret = -ENODEV; + goto notfound; + } + + for (mtd = doclist; mtd; mtd = doc->nextdoc) { + unsigned char oldval; + unsigned char newval; + nand = mtd->priv; + doc = nand->priv; + /* Use the alias resolution register to determine if this is + in fact the same DOC aliased to a new address. If writes + to one chip's alias resolution register change the value on + the other chip, they're the same chip. */ + if (ChipID == DOC_ChipID_DocMilPlus16) { + oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution); + newval = ReadDOC(virtadr, Mplus_AliasResolution); + } else { + oldval = ReadDOC(doc->virtadr, AliasResolution); + newval = ReadDOC(virtadr, AliasResolution); + } + if (oldval != newval) + continue; + if (ChipID == DOC_ChipID_DocMilPlus16) { + WriteDOC(~newval, virtadr, Mplus_AliasResolution); + oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution); + WriteDOC(newval, virtadr, Mplus_AliasResolution); // restore it + } else { + WriteDOC(~newval, virtadr, AliasResolution); + oldval = ReadDOC(doc->virtadr, AliasResolution); + WriteDOC(newval, virtadr, AliasResolution); // restore it + } + newval = ~newval; + if (oldval == newval) { + printk(KERN_DEBUG "Found alias of DOC at 0x%lx to 0x%lx\n", doc->physadr, physadr); + goto notfound; + } + } + + printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr); + + len = sizeof(struct mtd_info) + + sizeof(struct nand_chip) + + sizeof(struct doc_priv) + + (2 * sizeof(struct nand_bbt_descr)); + mtd = kmalloc(len, GFP_KERNEL); + if (!mtd) { + printk(KERN_ERR "DiskOnChip kmalloc (%d bytes) failed!\n", len); + ret = -ENOMEM; + goto fail; + } + memset(mtd, 0, len); + + nand = (struct nand_chip *) (mtd + 1); + doc = (struct doc_priv *) (nand + 1); + nand->bbt_td = (struct nand_bbt_descr *) (doc + 1); + nand->bbt_md = nand->bbt_td + 1; + + mtd->priv = nand; + mtd->owner = THIS_MODULE; + + nand->priv = doc; + nand->select_chip = doc200x_select_chip; + nand->hwcontrol = doc200x_hwcontrol; + nand->dev_ready = doc200x_dev_ready; + nand->waitfunc = doc200x_wait; + nand->block_bad = doc200x_block_bad; + nand->enable_hwecc = doc200x_enable_hwecc; + nand->calculate_ecc = doc200x_calculate_ecc; + nand->correct_data = doc200x_correct_data; + + nand->autooob = &doc200x_oobinfo; + nand->eccmode = NAND_ECC_HW6_512; + nand->options = NAND_USE_FLASH_BBT | NAND_HWECC_SYNDROME; + + doc->physadr = physadr; + doc->virtadr = virtadr; + doc->ChipID = ChipID; + doc->curfloor = -1; + doc->curchip = -1; + doc->mh0_page = -1; + doc->mh1_page = -1; + doc->nextdoc = doclist; + + if (ChipID == DOC_ChipID_Doc2k) + numchips = doc2000_init(mtd); + else if (ChipID == DOC_ChipID_DocMilPlus16) + numchips = doc2001plus_init(mtd); + else + numchips = doc2001_init(mtd); + + if ((ret = nand_scan(mtd, numchips))) { + /* DBB note: i believe nand_release is necessary here, as + buffers may have been allocated in nand_base. Check with + Thomas. FIX ME! */ + /* nand_release will call del_mtd_device, but we haven't yet + added it. This is handled without incident by + del_mtd_device, as far as I can tell. */ + nand_release(mtd); + kfree(mtd); + goto fail; + } + + /* Success! */ + doclist = mtd; + return 0; + +notfound: + /* Put back the contents of the DOCControl register, in case it's not + actually a DiskOnChip. */ + WriteDOC(save_control, virtadr, DOCControl); +fail: + iounmap(virtadr); + return ret; +} + +static void release_nanddoc(void) +{ + struct mtd_info *mtd, *nextmtd; + struct nand_chip *nand; + struct doc_priv *doc; + + for (mtd = doclist; mtd; mtd = nextmtd) { + nand = mtd->priv; + doc = nand->priv; + + nextmtd = doc->nextdoc; + nand_release(mtd); + iounmap(doc->virtadr); + kfree(mtd); + } +} + +static int __init init_nanddoc(void) +{ + int i, ret = 0; + + /* We could create the decoder on demand, if memory is a concern. + * This way we have it handy, if an error happens + * + * Symbolsize is 10 (bits) + * Primitve polynomial is x^10+x^3+1 + * first consecutive root is 510 + * primitve element to generate roots = 1 + * generator polinomial degree = 4 + */ + rs_decoder = init_rs(10, 0x409, FCR, 1, NROOTS); + if (!rs_decoder) { + printk (KERN_ERR "DiskOnChip: Could not create a RS decoder\n"); + return -ENOMEM; + } + + if (doc_config_location) { + printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location); + ret = doc_probe(doc_config_location); + if (ret < 0) + goto outerr; + } else { + for (i=0; (doc_locations[i] != 0xffffffff); i++) { + doc_probe(doc_locations[i]); + } + } + /* No banner message any more. Print a message if no DiskOnChip + found, so the user knows we at least tried. */ + if (!doclist) { + printk(KERN_INFO "No valid DiskOnChip devices found\n"); + ret = -ENODEV; + goto outerr; + } + return 0; +outerr: + free_rs(rs_decoder); + return ret; +} + +static void __exit cleanup_nanddoc(void) +{ + /* Cleanup the nand/DoC resources */ + release_nanddoc(); + + /* Free the reed solomon resources */ + if (rs_decoder) { + free_rs(rs_decoder); + } +} + +module_init(init_nanddoc); +module_exit(cleanup_nanddoc); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("David Woodhouse "); +MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n"); diff --git a/drivers/nand/nand.c b/drivers/nand/nand.c new file mode 100644 index 0000000000..d187c89ea1 --- /dev/null +++ b/drivers/nand/nand.c @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2005 + * 2N Telekomunikace, a.s. + * Ladislav Michl + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) + +#include + +#ifndef CFG_NAND_BASE_LIST +#define CFG_NAND_BASE_LIST { CFG_NAND_BASE } +#endif + +int nand_curr_device = -1; +nand_info_t nand_info[CFG_MAX_NAND_DEVICE]; + +static struct nand_chip nand_chip[CFG_MAX_NAND_DEVICE]; +static ulong base_address[CFG_MAX_NAND_DEVICE] = CFG_NAND_BASE_LIST; + +static const char default_nand_name[] = "nand"; + +extern void board_nand_init(struct nand_chip *nand); + +static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand, + ulong base_addr) +{ + mtd->priv = nand; + + nand->IO_ADDR_R = nand->IO_ADDR_W = base_addr; + board_nand_init(nand); + + if (nand_scan(mtd, 1) == 0) { + if (!mtd->name) + mtd->name = default_nand_name; + } else + mtd->name = NULL; + +} + +void nand_init(void) +{ + int i; + + for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { + nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]); + if (nand_curr_device == -1) + nand_curr_device = i; + } +} + +#endif diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c new file mode 100644 index 0000000000..c423512f18 --- /dev/null +++ b/drivers/nand/nand_base.c @@ -0,0 +1,2630 @@ +/* + * drivers/mtd/nand.c + * + * Overview: + * This is the generic MTD driver for NAND flash devices. It should be + * capable of working with almost all NAND chips currently available. + * Basic support for AG-AND chips is provided. + * + * Additional technical information is available on + * http://www.linux-mtd.infradead.org/tech/nand.html + * + * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) + * 2002 Thomas Gleixner (tglx@linutronix.de) + * + * 02-08-2004 tglx: support for strange chips, which cannot auto increment + * pages on read / read_oob + * + * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes + * pointed this out, as he marked an auto increment capable chip + * as NOAUTOINCR in the board driver. + * Make reads over block boundaries work too + * + * 04-14-2004 tglx: first working version for 2k page size chips + * + * 05-19-2004 tglx: Basic support for Renesas AG-AND chips + * + * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared + * among multiple independend devices. Suggestions and initial patch + * from Ben Dooks + * + * Credits: + * David Woodhouse for adding multichip support + * + * Aleph One Ltd. and Toby Churchill Ltd. for supporting the + * rework for 2K page size chips + * + * TODO: + * Enable cached programming for 2k page size chips + * Check, if mtd->ecctype should be set to MTD_ECC_HW + * if we have HW ecc support. + * The AG-AND chips have nice features for speed improvement, + * which are not supported yet. Read / program 4 pages in one go. + * + * $Id: nand_base.c,v 1.126 2004/12/13 11:22:25 lavinen Exp $ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +/* XXX U-BOOT XXX */ +#if 0 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_MTD_PARTITIONS +#include +#endif + +#else + +#include + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) + +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_JFFS2_NAND +#include +#endif + +#endif + +/* Define default oob placement schemes for large and small page devices */ +static struct nand_oobinfo nand_oob_8 = { + .useecc = MTD_NANDECC_AUTOPLACE, + .eccbytes = 3, + .eccpos = {0, 1, 2}, + .oobfree = { {3, 2}, {6, 2} } +}; + +static struct nand_oobinfo nand_oob_16 = { + .useecc = MTD_NANDECC_AUTOPLACE, + .eccbytes = 6, + .eccpos = {0, 1, 2, 3, 6, 7}, + .oobfree = { {8, 8} } +}; + +static struct nand_oobinfo nand_oob_64 = { + .useecc = MTD_NANDECC_AUTOPLACE, + .eccbytes = 24, + .eccpos = { + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63}, + .oobfree = { {2, 38} } +}; + +/* This is used for padding purposes in nand_write_oob */ +static u_char ffchars[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; + +/* + * NAND low-level MTD interface functions + */ +static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len); +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len); +static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len); + +static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf); +static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, + size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel); +static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf); +static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf); +static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, + size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel); +static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf); +/* XXX U-BOOT XXX */ +#if 0 +static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, + unsigned long count, loff_t to, size_t * retlen); +static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, + unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); +#endif +static int nand_erase (struct mtd_info *mtd, struct erase_info *instr); +static void nand_sync (struct mtd_info *mtd); + +/* Some internal functions */ +static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, + struct nand_oobinfo *oobsel, int mode); +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE +static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, + u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode); +#else +#define nand_verify_pages(...) (0) +#endif + +static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); + +/** + * nand_release_device - [GENERIC] release chip + * @mtd: MTD device structure + * + * Deselect, release chip lock and wake up anyone waiting on the device + */ +/* XXX U-BOOT XXX */ +#if 0 +static void nand_release_device (struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + + /* De-select the NAND device */ + this->select_chip(mtd, -1); + /* Do we have a hardware controller ? */ + if (this->controller) { + spin_lock(&this->controller->lock); + this->controller->active = NULL; + spin_unlock(&this->controller->lock); + } + /* Release the chip */ + spin_lock (&this->chip_lock); + this->state = FL_READY; + wake_up (&this->wq); + spin_unlock (&this->chip_lock); +} +#else +#define nand_release_device(mtd) do {} while(0) +#endif + +/** + * nand_read_byte - [DEFAULT] read one byte from the chip + * @mtd: MTD device structure + * + * Default read function for 8bit buswith + */ +static u_char nand_read_byte(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + return readb(this->IO_ADDR_R); +} + +/** + * nand_write_byte - [DEFAULT] write one byte to the chip + * @mtd: MTD device structure + * @byte: pointer to data byte to write + * + * Default write function for 8it buswith + */ +static void nand_write_byte(struct mtd_info *mtd, u_char byte) +{ + struct nand_chip *this = mtd->priv; + writeb(byte, this->IO_ADDR_W); +} + +/** + * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip + * @mtd: MTD device structure + * + * Default read function for 16bit buswith with + * endianess conversion + */ +static u_char nand_read_byte16(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + return (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); +} + +/** + * nand_write_byte16 - [DEFAULT] write one byte endianess aware to the chip + * @mtd: MTD device structure + * @byte: pointer to data byte to write + * + * Default write function for 16bit buswith with + * endianess conversion + */ +static void nand_write_byte16(struct mtd_info *mtd, u_char byte) +{ + struct nand_chip *this = mtd->priv; + writew(le16_to_cpu((u16) byte), this->IO_ADDR_W); +} + +/** + * nand_read_word - [DEFAULT] read one word from the chip + * @mtd: MTD device structure + * + * Default read function for 16bit buswith without + * endianess conversion + */ +static u16 nand_read_word(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + return readw(this->IO_ADDR_R); +} + +/** + * nand_write_word - [DEFAULT] write one word to the chip + * @mtd: MTD device structure + * @word: data word to write + * + * Default write function for 16bit buswith without + * endianess conversion + */ +static void nand_write_word(struct mtd_info *mtd, u16 word) +{ + struct nand_chip *this = mtd->priv; + writew(word, this->IO_ADDR_W); +} + +/** + * nand_select_chip - [DEFAULT] control CE line + * @mtd: MTD device structure + * @chip: chipnumber to select, -1 for deselect + * + * Default select function for 1 chip devices. + */ +static void nand_select_chip(struct mtd_info *mtd, int chip) +{ + struct nand_chip *this = mtd->priv; + switch(chip) { + case -1: + this->hwcontrol(mtd, NAND_CTL_CLRNCE); + break; + case 0: + this->hwcontrol(mtd, NAND_CTL_SETNCE); + break; + + default: + BUG(); + } +} + +/** + * nand_write_buf - [DEFAULT] write buffer to chip + * @mtd: MTD device structure + * @buf: data buffer + * @len: number of bytes to write + * + * Default write function for 8bit buswith + */ +static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) +{ + int i; + struct nand_chip *this = mtd->priv; + + for (i=0; iIO_ADDR_W); +} + +/** + * nand_read_buf - [DEFAULT] read chip data into buffer + * @mtd: MTD device structure + * @buf: buffer to store date + * @len: number of bytes to read + * + * Default read function for 8bit buswith + */ +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) +{ + int i; + struct nand_chip *this = mtd->priv; + + for (i=0; iIO_ADDR_R); +} + +/** + * nand_verify_buf - [DEFAULT] Verify chip data against buffer + * @mtd: MTD device structure + * @buf: buffer containing the data to compare + * @len: number of bytes to compare + * + * Default verify function for 8bit buswith + */ +static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) +{ + int i; + struct nand_chip *this = mtd->priv; + + for (i=0; iIO_ADDR_R)) + return -EFAULT; + + return 0; +} + +/** + * nand_write_buf16 - [DEFAULT] write buffer to chip + * @mtd: MTD device structure + * @buf: data buffer + * @len: number of bytes to write + * + * Default write function for 16bit buswith + */ +static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) +{ + int i; + struct nand_chip *this = mtd->priv; + u16 *p = (u16 *) buf; + len >>= 1; + + for (i=0; iIO_ADDR_W); + +} + +/** + * nand_read_buf16 - [DEFAULT] read chip data into buffer + * @mtd: MTD device structure + * @buf: buffer to store date + * @len: number of bytes to read + * + * Default read function for 16bit buswith + */ +static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len) +{ + int i; + struct nand_chip *this = mtd->priv; + u16 *p = (u16 *) buf; + len >>= 1; + + for (i=0; iIO_ADDR_R); +} + +/** + * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer + * @mtd: MTD device structure + * @buf: buffer containing the data to compare + * @len: number of bytes to compare + * + * Default verify function for 16bit buswith + */ +static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) +{ + int i; + struct nand_chip *this = mtd->priv; + u16 *p = (u16 *) buf; + len >>= 1; + + for (i=0; iIO_ADDR_R)) + return -EFAULT; + + return 0; +} + +/** + * nand_block_bad - [DEFAULT] Read bad block marker from the chip + * @mtd: MTD device structure + * @ofs: offset from device start + * @getchip: 0, if the chip is already selected + * + * Check, if the block is bad. + */ +static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) +{ + int page, chipnr, res = 0; + struct nand_chip *this = mtd->priv; + u16 bad; + + if (getchip) { + page = (int)(ofs >> this->page_shift); + chipnr = (int)(ofs >> this->chip_shift); + + /* Grab the lock and see if the device is available */ + nand_get_device (this, mtd, FL_READING); + + /* Select the NAND device */ + this->select_chip(mtd, chipnr); + } else + page = (int) ofs; + + if (this->options & NAND_BUSWIDTH_16) { + this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask); + bad = cpu_to_le16(this->read_word(mtd)); + if (this->badblockpos & 0x1) + bad >>= 1; + if ((bad & 0xFF) != 0xff) + res = 1; + } else { + this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask); + if (this->read_byte(mtd) != 0xff) + res = 1; + } + + if (getchip) { + /* Deselect and wake up anyone waiting on the device */ + nand_release_device(mtd); + } + + return res; +} + +/** + * nand_default_block_markbad - [DEFAULT] mark a block bad + * @mtd: MTD device structure + * @ofs: offset from device start + * + * This is the default implementation, which can be overridden by + * a hardware specific driver. +*/ +static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) +{ + struct nand_chip *this = mtd->priv; + u_char buf[2] = {0, 0}; + size_t retlen; + int block; + + /* Get block number */ + block = ((int) ofs) >> this->bbt_erase_shift; + this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); + + /* Do we have a flash based bad block table ? */ + if (this->options & NAND_USE_FLASH_BBT) + return nand_update_bbt (mtd, ofs); + + /* We write two bytes, so we dont have to mess with 16 bit access */ + ofs += mtd->oobsize + (this->badblockpos & ~0x01); + return nand_write_oob (mtd, ofs , 2, &retlen, buf); +} + +/** + * nand_check_wp - [GENERIC] check if the chip is write protected + * @mtd: MTD device structure + * Check, if the device is write protected + * + * The function expects, that the device is already selected + */ +static int nand_check_wp (struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + /* Check the WP bit */ + this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); + return (this->read_byte(mtd) & 0x80) ? 0 : 1; +} + +/** + * nand_block_checkbad - [GENERIC] Check if a block is marked bad + * @mtd: MTD device structure + * @ofs: offset from device start + * @getchip: 0, if the chip is already selected + * @allowbbt: 1, if its allowed to access the bbt area + * + * Check, if the block is bad. Either by reading the bad block table or + * calling of the scan function. + */ +static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) +{ + struct nand_chip *this = mtd->priv; + + if (!this->bbt) + return this->block_bad(mtd, ofs, getchip); + + /* Return info from the table */ + return nand_isbad_bbt (mtd, ofs, allowbbt); +} + +/** + * nand_command - [DEFAULT] Send command to NAND device + * @mtd: MTD device structure + * @command: the command to be sent + * @column: the column address for this command, -1 if none + * @page_addr: the page address for this command, -1 if none + * + * Send command to NAND device. This function is used for small page + * devices (256/512 Bytes per page) + */ +static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) +{ + register struct nand_chip *this = mtd->priv; + + /* Begin command latch cycle */ + this->hwcontrol(mtd, NAND_CTL_SETCLE); + /* + * Write out the command to the device. + */ + if (command == NAND_CMD_SEQIN) { + int readcmd; + + if (column >= mtd->oobblock) { + /* OOB area */ + column -= mtd->oobblock; + readcmd = NAND_CMD_READOOB; + } else if (column < 256) { + /* First 256 bytes --> READ0 */ + readcmd = NAND_CMD_READ0; + } else { + column -= 256; + readcmd = NAND_CMD_READ1; + } + this->write_byte(mtd, readcmd); + } + this->write_byte(mtd, command); + + /* Set ALE and clear CLE to start address cycle */ + this->hwcontrol(mtd, NAND_CTL_CLRCLE); + + if (column != -1 || page_addr != -1) { + this->hwcontrol(mtd, NAND_CTL_SETALE); + + /* Serially input address */ + if (column != -1) { + /* Adjust columns for 16 bit buswidth */ + if (this->options & NAND_BUSWIDTH_16) + column >>= 1; + this->write_byte(mtd, column); + } + if (page_addr != -1) { + this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); + this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); + /* One more address cycle for devices > 32MiB */ + if (this->chipsize > (32 << 20)) + this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f)); + } + /* Latch in address */ + this->hwcontrol(mtd, NAND_CTL_CLRALE); + } + + /* + * program and erase have their own busy handlers + * status and sequential in needs no delay + */ + switch (command) { + + case NAND_CMD_PAGEPROG: + case NAND_CMD_ERASE1: + case NAND_CMD_ERASE2: + case NAND_CMD_SEQIN: + case NAND_CMD_STATUS: + return; + + case NAND_CMD_RESET: + if (this->dev_ready) + break; + udelay(this->chip_delay); + this->hwcontrol(mtd, NAND_CTL_SETCLE); + this->write_byte(mtd, NAND_CMD_STATUS); + this->hwcontrol(mtd, NAND_CTL_CLRCLE); + while ( !(this->read_byte(mtd) & 0x40)); + return; + + /* This applies to read commands */ + default: + /* + * If we don't have access to the busy pin, we apply the given + * command delay + */ + if (!this->dev_ready) { + udelay (this->chip_delay); + return; + } + } + + /* Apply this short delay always to ensure that we do wait tWB in + * any case on any machine. */ + ndelay (100); + /* wait until command is processed */ + while (!this->dev_ready(mtd)); +} + +/** + * nand_command_lp - [DEFAULT] Send command to NAND large page device + * @mtd: MTD device structure + * @command: the command to be sent + * @column: the column address for this command, -1 if none + * @page_addr: the page address for this command, -1 if none + * + * Send command to NAND device. This is the version for the new large page devices + * We dont have the seperate regions as we have in the small page devices. + * We must emulate NAND_CMD_READOOB to keep the code compatible. + * + */ +static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr) +{ + register struct nand_chip *this = mtd->priv; + + /* Emulate NAND_CMD_READOOB */ + if (command == NAND_CMD_READOOB) { + column += mtd->oobblock; + command = NAND_CMD_READ0; + } + + + /* Begin command latch cycle */ + this->hwcontrol(mtd, NAND_CTL_SETCLE); + /* Write out the command to the device. */ + this->write_byte(mtd, command); + /* End command latch cycle */ + this->hwcontrol(mtd, NAND_CTL_CLRCLE); + + if (column != -1 || page_addr != -1) { + this->hwcontrol(mtd, NAND_CTL_SETALE); + + /* Serially input address */ + if (column != -1) { + /* Adjust columns for 16 bit buswidth */ + if (this->options & NAND_BUSWIDTH_16) + column >>= 1; + this->write_byte(mtd, column & 0xff); + this->write_byte(mtd, column >> 8); + } + if (page_addr != -1) { + this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); + this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); + /* One more address cycle for devices > 128MiB */ + if (this->chipsize > (128 << 20)) + this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff)); + } + /* Latch in address */ + this->hwcontrol(mtd, NAND_CTL_CLRALE); + } + + /* + * program and erase have their own busy handlers + * status and sequential in needs no delay + */ + switch (command) { + + case NAND_CMD_CACHEDPROG: + case NAND_CMD_PAGEPROG: + case NAND_CMD_ERASE1: + case NAND_CMD_ERASE2: + case NAND_CMD_SEQIN: + case NAND_CMD_STATUS: + return; + + + case NAND_CMD_RESET: + if (this->dev_ready) + break; + udelay(this->chip_delay); + this->hwcontrol(mtd, NAND_CTL_SETCLE); + this->write_byte(mtd, NAND_CMD_STATUS); + this->hwcontrol(mtd, NAND_CTL_CLRCLE); + while ( !(this->read_byte(mtd) & 0x40)); + return; + + case NAND_CMD_READ0: + /* Begin command latch cycle */ + this->hwcontrol(mtd, NAND_CTL_SETCLE); + /* Write out the start read command */ + this->write_byte(mtd, NAND_CMD_READSTART); + /* End command latch cycle */ + this->hwcontrol(mtd, NAND_CTL_CLRCLE); + /* Fall through into ready check */ + + /* This applies to read commands */ + default: + /* + * If we don't have access to the busy pin, we apply the given + * command delay + */ + if (!this->dev_ready) { + udelay (this->chip_delay); + return; + } + } + + /* Apply this short delay always to ensure that we do wait tWB in + * any case on any machine. */ + ndelay (100); + /* wait until command is processed */ + while (!this->dev_ready(mtd)); +} + +/** + * nand_get_device - [GENERIC] Get chip for selected access + * @this: the nand chip descriptor + * @mtd: MTD device structure + * @new_state: the state which is requested + * + * Get the device and lock it for exclusive access + */ +/* XXX U-BOOT XXX */ +#if 0 +static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) +{ + struct nand_chip *active = this; + + DECLARE_WAITQUEUE (wait, current); + + /* + * Grab the lock and see if the device is available + */ +retry: + /* Hardware controller shared among independend devices */ + if (this->controller) { + spin_lock (&this->controller->lock); + if (this->controller->active) + active = this->controller->active; + else + this->controller->active = this; + spin_unlock (&this->controller->lock); + } + + if (active == this) { + spin_lock (&this->chip_lock); + if (this->state == FL_READY) { + this->state = new_state; + spin_unlock (&this->chip_lock); + return; + } + } + set_current_state (TASK_UNINTERRUPTIBLE); + add_wait_queue (&active->wq, &wait); + spin_unlock (&active->chip_lock); + schedule (); + remove_wait_queue (&active->wq, &wait); + goto retry; +} +#else +static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) {} +#endif + +/** + * nand_wait - [DEFAULT] wait until the command is done + * @mtd: MTD device structure + * @this: NAND chip structure + * @state: state to select the max. timeout value + * + * Wait for command done. This applies to erase and program only + * Erase can take up to 400ms and program up to 20ms according to + * general NAND and SmartMedia specs + * +*/ +/* XXX U-BOOT XXX */ +#if 0 +static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) +{ + unsigned long timeo = jiffies; + int status; + + if (state == FL_ERASING) + timeo += (HZ * 400) / 1000; + else + timeo += (HZ * 20) / 1000; + + /* Apply this short delay always to ensure that we do wait tWB in + * any case on any machine. */ + ndelay (100); + + if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) + this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1); + else + this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); + + while (time_before(jiffies, timeo)) { + /* Check, if we were interrupted */ + if (this->state != state) + return 0; + + if (this->dev_ready) { + if (this->dev_ready(mtd)) + break; + } else { + if (this->read_byte(mtd) & NAND_STATUS_READY) + break; + } + yield (); + } + status = (int) this->read_byte(mtd); + return status; + + return 0; +} +#else +static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) +{ + /* TODO */ + return 0; +} +#endif + +/** + * nand_write_page - [GENERIC] write one page + * @mtd: MTD device structure + * @this: NAND chip structure + * @page: startpage inside the chip, must be called with (page & this->pagemask) + * @oob_buf: out of band data buffer + * @oobsel: out of band selecttion structre + * @cached: 1 = enable cached programming if supported by chip + * + * Nand_page_program function is used for write and writev ! + * This function will always program a full page of data + * If you call it with a non page aligned buffer, you're lost :) + * + * Cached programming is not supported yet. + */ +static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, + u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) +{ + int i, status; + u_char ecc_code[32]; + int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; + int *oob_config = oobsel->eccpos; + int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; + int eccbytes = 0; + + /* FIXME: Enable cached programming */ + cached = 0; + + /* Send command to begin auto page programming */ + this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); + + /* Write out complete page of data, take care of eccmode */ + switch (eccmode) { + /* No ecc, write all */ + case NAND_ECC_NONE: + printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); + this->write_buf(mtd, this->data_poi, mtd->oobblock); + break; + + /* Software ecc 3/256, write all */ + case NAND_ECC_SOFT: + for (; eccsteps; eccsteps--) { + this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code); + for (i = 0; i < 3; i++, eccidx++) + oob_buf[oob_config[eccidx]] = ecc_code[i]; + datidx += this->eccsize; + } + this->write_buf(mtd, this->data_poi, mtd->oobblock); + break; + default: + eccbytes = this->eccbytes; + for (; eccsteps; eccsteps--) { + /* enable hardware ecc logic for write */ + this->enable_hwecc(mtd, NAND_ECC_WRITE); + this->write_buf(mtd, &this->data_poi[datidx], this->eccsize); + this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code); + for (i = 0; i < eccbytes; i++, eccidx++) + oob_buf[oob_config[eccidx]] = ecc_code[i]; + /* If the hardware ecc provides syndromes then + * the ecc code must be written immidiately after + * the data bytes (words) */ + if (this->options & NAND_HWECC_SYNDROME) + this->write_buf(mtd, ecc_code, eccbytes); + datidx += this->eccsize; + } + break; + } + + /* Write out OOB data */ + if (this->options & NAND_HWECC_SYNDROME) + this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes); + else + this->write_buf(mtd, oob_buf, mtd->oobsize); + + /* Send command to actually program the data */ + this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1); + + if (!cached) { + /* call wait ready function */ + status = this->waitfunc (mtd, this, FL_WRITING); + /* See if device thinks it succeeded */ + if (status & 0x01) { + DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page); + return -EIO; + } + } else { + /* FIXME: Implement cached programming ! */ + /* wait until cache is ready*/ + // status = this->waitfunc (mtd, this, FL_CACHEDRPG); + } + return 0; +} + +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE +/** + * nand_verify_pages - [GENERIC] verify the chip contents after a write + * @mtd: MTD device structure + * @this: NAND chip structure + * @page: startpage inside the chip, must be called with (page & this->pagemask) + * @numpages: number of pages to verify + * @oob_buf: out of band data buffer + * @oobsel: out of band selecttion structre + * @chipnr: number of the current chip + * @oobmode: 1 = full buffer verify, 0 = ecc only + * + * The NAND device assumes that it is always writing to a cleanly erased page. + * Hence, it performs its internal write verification only on bits that + * transitioned from 1 to 0. The device does NOT verify the whole page on a + * byte by byte basis. It is possible that the page was not completely erased + * or the page is becoming unusable due to wear. The read with ECC would catch + * the error later when the ECC page check fails, but we would rather catch + * it early in the page write stage. Better to write no data than invalid data. + */ +static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, + u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode) +{ + int i, j, datidx = 0, oobofs = 0, res = -EIO; + int eccsteps = this->eccsteps; + int hweccbytes; + u_char oobdata[64]; + + hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0; + + /* Send command to read back the first page */ + this->cmdfunc (mtd, NAND_CMD_READ0, 0, page); + + for(;;) { + for (j = 0; j < eccsteps; j++) { + /* Loop through and verify the data */ + if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) { + DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page); + goto out; + } + datidx += mtd->eccsize; + /* Have we a hw generator layout ? */ + if (!hweccbytes) + continue; + if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) { + DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page); + goto out; + } + oobofs += hweccbytes; + } + + /* check, if we must compare all data or if we just have to + * compare the ecc bytes + */ + if (oobmode) { + if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) { + DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page); + goto out; + } + } else { + /* Read always, else autoincrement fails */ + this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps); + + if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) { + int ecccnt = oobsel->eccbytes; + + for (i = 0; i < ecccnt; i++) { + int idx = oobsel->eccpos[i]; + if (oobdata[idx] != oob_buf[oobofs + idx] ) { + DEBUG (MTD_DEBUG_LEVEL0, + "%s: Failed ECC write " + "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i); + goto out; + } + } + } + } + oobofs += mtd->oobsize - hweccbytes * eccsteps; + page++; + numpages--; + + /* Apply delay or wait for ready/busy pin + * Do this before the AUTOINCR check, so no problems + * arise if a chip which does auto increment + * is marked as NOAUTOINCR by the board driver. + * Do this also before returning, so the chip is + * ready for the next command. + */ + if (!this->dev_ready) + udelay (this->chip_delay); + else + while (!this->dev_ready(mtd)); + + /* All done, return happy */ + if (!numpages) + return 0; + + + /* Check, if the chip supports auto page increment */ + if (!NAND_CANAUTOINCR(this)) + this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); + } + /* + * Terminate the read command. We come here in case of an error + * So we must issue a reset command. + */ +out: + this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1); + return res; +} +#endif + +/** + * nand_read - [MTD Interface] MTD compability function for nand_read_ecc + * @mtd: MTD device structure + * @from: offset to read from + * @len: number of bytes to read + * @retlen: pointer to variable to store the number of read bytes + * @buf: the databuffer to put data + * + * This function simply calls nand_read_ecc with oob buffer and oobsel = NULL +*/ +static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) +{ + return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL); +} + + +/** + * nand_read_ecc - [MTD Interface] Read data with ECC + * @mtd: MTD device structure + * @from: offset to read from + * @len: number of bytes to read + * @retlen: pointer to variable to store the number of read bytes + * @buf: the databuffer to put data + * @oob_buf: filesystem supplied oob data buffer + * @oobsel: oob selection structure + * + * NAND read with ECC + */ +static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, + size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel) +{ + int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1; + int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0; + struct nand_chip *this = mtd->priv; + u_char *data_poi, *oob_data = oob_buf; + u_char ecc_calc[32]; + u_char ecc_code[32]; + int eccmode, eccsteps; + int *oob_config, datidx; + int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; + int eccbytes; + int compareecc = 1; + int oobreadlen; + + + DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); + + /* Do not allow reads past end of device */ + if ((from + len) > mtd->size) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n"); + *retlen = 0; + return -EINVAL; + } + + /* Grab the lock and see if the device is available */ + nand_get_device (this, mtd ,FL_READING); + + /* use userspace supplied oobinfo, if zero */ + if (oobsel == NULL) + oobsel = &mtd->oobinfo; + + /* Autoplace of oob data ? Use the default placement scheme */ + if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) + oobsel = this->autooob; + + eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; + oob_config = oobsel->eccpos; + + /* Select the NAND device */ + chipnr = (int)(from >> this->chip_shift); + this->select_chip(mtd, chipnr); + + /* First we calculate the starting page */ + realpage = (int) (from >> this->page_shift); + page = realpage & this->pagemask; + + /* Get raw starting column */ + col = from & (mtd->oobblock - 1); + + end = mtd->oobblock; + ecc = this->eccsize; + eccbytes = this->eccbytes; + + if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME)) + compareecc = 0; + + oobreadlen = mtd->oobsize; + if (this->options & NAND_HWECC_SYNDROME) + oobreadlen -= oobsel->eccbytes; + + /* Loop until all data read */ + while (read < len) { + + int aligned = (!col && (len - read) >= end); + /* + * If the read is not page aligned, we have to read into data buffer + * due to ecc, else we read into return buffer direct + */ + if (aligned) + data_poi = &buf[read]; + else + data_poi = this->data_buf; + + /* Check, if we have this page in the buffer + * + * FIXME: Make it work when we must provide oob data too, + * check the usage of data_buf oob field + */ + if (realpage == this->pagebuf && !oob_buf) { + /* aligned read ? */ + if (aligned) + memcpy (data_poi, this->data_buf, end); + goto readdata; + } + + /* Check, if we must send the read command */ + if (sndcmd) { + this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); + sndcmd = 0; + } + + /* get oob area, if we have no oob buffer from fs-driver */ + if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE || + oobsel->useecc == MTD_NANDECC_AUTOPL_USR) + oob_data = &this->data_buf[end]; + + eccsteps = this->eccsteps; + + switch (eccmode) { + case NAND_ECC_NONE: { /* No ECC, Read in a page */ +/* XXX U-BOOT XXX */ +#if 0 + static unsigned long lastwhinge = 0; + if ((lastwhinge / HZ) != (jiffies / HZ)) { + printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n"); + lastwhinge = jiffies; + } +#else + puts("Reading data from NAND FLASH without ECC is not recommended\n"); +#endif + this->read_buf(mtd, data_poi, end); + break; + } + + case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ + this->read_buf(mtd, data_poi, end); + for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) + this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); + break; + + default: + for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) { + this->enable_hwecc(mtd, NAND_ECC_READ); + this->read_buf(mtd, &data_poi[datidx], ecc); + + /* HW ecc with syndrome calculation must read the + * syndrome from flash immidiately after the data */ + if (!compareecc) { + /* Some hw ecc generators need to know when the + * syndrome is read from flash */ + this->enable_hwecc(mtd, NAND_ECC_READSYN); + this->read_buf(mtd, &oob_data[i], eccbytes); + /* We calc error correction directly, it checks the hw + * generator for an error, reads back the syndrome and + * does the error correction on the fly */ + if (this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]) == -1) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " + "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr); + ecc_failed++; + } + } else { + this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); + } + } + break; + } + + /* read oobdata */ + this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen); + + /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */ + if (!compareecc) + goto readoob; + + /* Pick the ECC bytes out of the oob data */ + for (j = 0; j < oobsel->eccbytes; j++) + ecc_code[j] = oob_data[oob_config[j]]; + + /* correct data, if neccecary */ + for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) { + ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]); + + /* Get next chunk of ecc bytes */ + j += eccbytes; + + /* Check, if we have a fs supplied oob-buffer, + * This is the legacy mode. Used by YAFFS1 + * Should go away some day + */ + if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) { + int *p = (int *)(&oob_data[mtd->oobsize]); + p[i] = ecc_status; + } + + if (ecc_status == -1) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); + ecc_failed++; + } + } + + readoob: + /* check, if we have a fs supplied oob-buffer */ + if (oob_buf) { + /* without autoplace. Legacy mode used by YAFFS1 */ + switch(oobsel->useecc) { + case MTD_NANDECC_AUTOPLACE: + case MTD_NANDECC_AUTOPL_USR: + /* Walk through the autoplace chunks */ + for (i = 0, j = 0; j < mtd->oobavail; i++) { + int from = oobsel->oobfree[i][0]; + int num = oobsel->oobfree[i][1]; + memcpy(&oob_buf[oob], &oob_data[from], num); + j+= num; + } + oob += mtd->oobavail; + break; + case MTD_NANDECC_PLACE: + /* YAFFS1 legacy mode */ + oob_data += this->eccsteps * sizeof (int); + default: + oob_data += mtd->oobsize; + } + } + readdata: + /* Partial page read, transfer data into fs buffer */ + if (!aligned) { + for (j = col; j < end && read < len; j++) + buf[read++] = data_poi[j]; + this->pagebuf = realpage; + } else + read += mtd->oobblock; + + /* Apply delay or wait for ready/busy pin + * Do this before the AUTOINCR check, so no problems + * arise if a chip which does auto increment + * is marked as NOAUTOINCR by the board driver. + */ + if (!this->dev_ready) + udelay (this->chip_delay); + else + while (!this->dev_ready(mtd)); + + if (read == len) + break; + + /* For subsequent reads align to page boundary. */ + col = 0; + /* Increment page address */ + realpage++; + + page = realpage & this->pagemask; + /* Check, if we cross a chip boundary */ + if (!page) { + chipnr++; + this->select_chip(mtd, -1); + this->select_chip(mtd, chipnr); + } + /* Check, if the chip supports auto page increment + * or if we have hit a block boundary. + */ + if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) + sndcmd = 1; + } + + /* Deselect and wake up anyone waiting on the device */ + nand_release_device(mtd); + + /* + * Return success, if no ECC failures, else -EBADMSG + * fs driver will take care of that, because + * retlen == desired len and result == -EBADMSG + */ + *retlen = read; + return ecc_failed ? -EBADMSG : 0; +} + +/** + * nand_read_oob - [MTD Interface] NAND read out-of-band + * @mtd: MTD device structure + * @from: offset to read from + * @len: number of bytes to read + * @retlen: pointer to variable to store the number of read bytes + * @buf: the databuffer to put data + * + * NAND read out-of-band data from the spare area + */ +static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) +{ + int i, col, page, chipnr; + struct nand_chip *this = mtd->priv; + int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; + + DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); + + /* Shift to get page */ + page = (int)(from >> this->page_shift); + chipnr = (int)(from >> this->chip_shift); + + /* Mask to get column */ + col = from & (mtd->oobsize - 1); + + /* Initialize return length value */ + *retlen = 0; + + /* Do not allow reads past end of device */ + if ((from + len) > mtd->size) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n"); + *retlen = 0; + return -EINVAL; + } + + /* Grab the lock and see if the device is available */ + nand_get_device (this, mtd , FL_READING); + + /* Select the NAND device */ + this->select_chip(mtd, chipnr); + + /* Send the read command */ + this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask); + /* + * Read the data, if we read more than one page + * oob data, let the device transfer the data ! + */ + i = 0; + while (i < len) { + int thislen = mtd->oobsize - col; + thislen = min_t(int, thislen, len); + this->read_buf(mtd, &buf[i], thislen); + i += thislen; + + /* Apply delay or wait for ready/busy pin + * Do this before the AUTOINCR check, so no problems + * arise if a chip which does auto increment + * is marked as NOAUTOINCR by the board driver. + */ + if (!this->dev_ready) + udelay (this->chip_delay); + else + while (!this->dev_ready(mtd)); + + /* Read more ? */ + if (i < len) { + page++; + col = 0; + + /* Check, if we cross a chip boundary */ + if (!(page & this->pagemask)) { + chipnr++; + this->select_chip(mtd, -1); + this->select_chip(mtd, chipnr); + } + + /* Check, if the chip supports auto page increment + * or if we have hit a block boundary. + */ + if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) { + /* For subsequent page reads set offset to 0 */ + this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); + } + } + } + + /* Deselect and wake up anyone waiting on the device */ + nand_release_device(mtd); + + /* Return happy */ + *retlen = len; + return 0; +} + +/** + * nand_read_raw - [GENERIC] Read raw data including oob into buffer + * @mtd: MTD device structure + * @buf: temporary buffer + * @from: offset to read from + * @len: number of bytes to read + * @ooblen: number of oob data bytes to read + * + * Read raw data including oob into buffer + */ +int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen) +{ + struct nand_chip *this = mtd->priv; + int page = (int) (from >> this->page_shift); + int chip = (int) (from >> this->chip_shift); + int sndcmd = 1; + int cnt = 0; + int pagesize = mtd->oobblock + mtd->oobsize; + int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; + + /* Do not allow reads past end of device */ + if ((from + len) > mtd->size) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n"); + return -EINVAL; + } + + /* Grab the lock and see if the device is available */ + nand_get_device (this, mtd , FL_READING); + + this->select_chip (mtd, chip); + + /* Add requested oob length */ + len += ooblen; + + while (len) { + if (sndcmd) + this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask); + sndcmd = 0; + + this->read_buf (mtd, &buf[cnt], pagesize); + + len -= pagesize; + cnt += pagesize; + page++; + + if (!this->dev_ready) + udelay (this->chip_delay); + else + while (!this->dev_ready(mtd)); + + /* Check, if the chip supports auto page increment */ + if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) + sndcmd = 1; + } + + /* Deselect and wake up anyone waiting on the device */ + nand_release_device(mtd); + return 0; +} + + +/** + * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer + * @mtd: MTD device structure + * @fsbuf: buffer given by fs driver + * @oobsel: out of band selection structre + * @autoplace: 1 = place given buffer into the oob bytes + * @numpages: number of pages to prepare + * + * Return: + * 1. Filesystem buffer available and autoplacement is off, + * return filesystem buffer + * 2. No filesystem buffer or autoplace is off, return internal + * buffer + * 3. Filesystem buffer is given and autoplace selected + * put data from fs buffer into internal buffer and + * retrun internal buffer + * + * Note: The internal buffer is filled with 0xff. This must + * be done only once, when no autoplacement happens + * Autoplacement sets the buffer dirty flag, which + * forces the 0xff fill before using the buffer again. + * +*/ +static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel, + int autoplace, int numpages) +{ + struct nand_chip *this = mtd->priv; + int i, len, ofs; + + /* Zero copy fs supplied buffer */ + if (fsbuf && !autoplace) + return fsbuf; + + /* Check, if the buffer must be filled with ff again */ + if (this->oobdirty) { + memset (this->oob_buf, 0xff, + mtd->oobsize << (this->phys_erase_shift - this->page_shift)); + this->oobdirty = 0; + } + + /* If we have no autoplacement or no fs buffer use the internal one */ + if (!autoplace || !fsbuf) + return this->oob_buf; + + /* Walk through the pages and place the data */ + this->oobdirty = 1; + ofs = 0; + while (numpages--) { + for (i = 0, len = 0; len < mtd->oobavail; i++) { + int to = ofs + oobsel->oobfree[i][0]; + int num = oobsel->oobfree[i][1]; + memcpy (&this->oob_buf[to], fsbuf, num); + len += num; + fsbuf += num; + } + ofs += mtd->oobavail; + } + return this->oob_buf; +} + +#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0 + +/** + * nand_write - [MTD Interface] compability function for nand_write_ecc + * @mtd: MTD device structure + * @to: offset to write to + * @len: number of bytes to write + * @retlen: pointer to variable to store the number of written bytes + * @buf: the data to write + * + * This function simply calls nand_write_ecc with oob buffer and oobsel = NULL + * +*/ +static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf) +{ + return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); +} + +/** + * nand_write_ecc - [MTD Interface] NAND write with ECC + * @mtd: MTD device structure + * @to: offset to write to + * @len: number of bytes to write + * @retlen: pointer to variable to store the number of written bytes + * @buf: the data to write + * @eccbuf: filesystem supplied oob data buffer + * @oobsel: oob selection structure + * + * NAND write with ECC + */ +static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, + size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel) +{ + int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr; + int autoplace = 0, numpages, totalpages; + struct nand_chip *this = mtd->priv; + u_char *oobbuf, *bufstart; + int ppblock = (1 << (this->phys_erase_shift - this->page_shift)); + + DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); + + /* Initialize retlen, in case of early exit */ + *retlen = 0; + + /* Do not allow write past end of device */ + if ((to + len) > mtd->size) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n"); + return -EINVAL; + } + + /* reject writes, which are not page aligned */ + if (NOTALIGNED (to) || NOTALIGNED(len)) { + printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); + return -EINVAL; + } + + /* Grab the lock and see if the device is available */ + nand_get_device (this, mtd, FL_WRITING); + + /* Calculate chipnr */ + chipnr = (int)(to >> this->chip_shift); + /* Select the NAND device */ + this->select_chip(mtd, chipnr); + + /* Check, if it is write protected */ + if (nand_check_wp(mtd)) + goto out; + + /* if oobsel is NULL, use chip defaults */ + if (oobsel == NULL) + oobsel = &mtd->oobinfo; + + /* Autoplace of oob data ? Use the default placement scheme */ + if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { + oobsel = this->autooob; + autoplace = 1; + } + if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) + autoplace = 1; + + /* Setup variables and oob buffer */ + totalpages = len >> this->page_shift; + page = (int) (to >> this->page_shift); + /* Invalidate the page cache, if we write to the cached page */ + if (page <= this->pagebuf && this->pagebuf < (page + totalpages)) + this->pagebuf = -1; + + /* Set it relative to chip */ + page &= this->pagemask; + startpage = page; + /* Calc number of pages we can write in one go */ + numpages = min (ppblock - (startpage & (ppblock - 1)), totalpages); + oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages); + bufstart = (u_char *)buf; + + /* Loop until all data is written */ + while (written < len) { + + this->data_poi = (u_char*) &buf[written]; + /* Write one page. If this is the last page to write + * or the last page in this block, then use the + * real pageprogram command, else select cached programming + * if supported by the chip. + */ + ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0)); + if (ret) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret); + goto out; + } + /* Next oob page */ + oob += mtd->oobsize; + /* Update written bytes count */ + written += mtd->oobblock; + if (written == len) + goto cmp; + + /* Increment page address */ + page++; + + /* Have we hit a block boundary ? Then we have to verify and + * if verify is ok, we have to setup the oob buffer for + * the next pages. + */ + if (!(page & (ppblock - 1))){ + int ofs; + this->data_poi = bufstart; + ret = nand_verify_pages (mtd, this, startpage, + page - startpage, + oobbuf, oobsel, chipnr, (eccbuf != NULL)); + if (ret) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); + goto out; + } + *retlen = written; + + ofs = autoplace ? mtd->oobavail : mtd->oobsize; + if (eccbuf) + eccbuf += (page - startpage) * ofs; + totalpages -= page - startpage; + numpages = min (totalpages, ppblock); + page &= this->pagemask; + startpage = page; + oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, + autoplace, numpages); + /* Check, if we cross a chip boundary */ + if (!page) { + chipnr++; + this->select_chip(mtd, -1); + this->select_chip(mtd, chipnr); + } + } + } + /* Verify the remaining pages */ +cmp: + this->data_poi = bufstart; + ret = nand_verify_pages (mtd, this, startpage, totalpages, + oobbuf, oobsel, chipnr, (eccbuf != NULL)); + if (!ret) + *retlen = written; + else + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); + +out: + /* Deselect and wake up anyone waiting on the device */ + nand_release_device(mtd); + + return ret; +} + + +/** + * nand_write_oob - [MTD Interface] NAND write out-of-band + * @mtd: MTD device structure + * @to: offset to write to + * @len: number of bytes to write + * @retlen: pointer to variable to store the number of written bytes + * @buf: the data to write + * + * NAND write out-of-band + */ +static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf) +{ + int column, page, status, ret = -EIO, chipnr; + struct nand_chip *this = mtd->priv; + + DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); + + /* Shift to get page */ + page = (int) (to >> this->page_shift); + chipnr = (int) (to >> this->chip_shift); + + /* Mask to get column */ + column = to & (mtd->oobsize - 1); + + /* Initialize return length value */ + *retlen = 0; + + /* Do not allow write past end of page */ + if ((column + len) > mtd->oobsize) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n"); + return -EINVAL; + } + + /* Grab the lock and see if the device is available */ + nand_get_device (this, mtd, FL_WRITING); + + /* Select the NAND device */ + this->select_chip(mtd, chipnr); + + /* Reset the chip. Some chips (like the Toshiba TC5832DC found + in one of my DiskOnChip 2000 test units) will clear the whole + data page too if we don't do this. I have no clue why, but + I seem to have 'fixed' it in the doc2000 driver in + August 1999. dwmw2. */ + this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + + /* Check, if it is write protected */ + if (nand_check_wp(mtd)) + goto out; + + /* Invalidate the page cache, if we write to the cached page */ + if (page == this->pagebuf) + this->pagebuf = -1; + + if (NAND_MUST_PAD(this)) { + /* Write out desired data */ + this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask); + /* prepad 0xff for partial programming */ + this->write_buf(mtd, ffchars, column); + /* write data */ + this->write_buf(mtd, buf, len); + /* postpad 0xff for partial programming */ + this->write_buf(mtd, ffchars, mtd->oobsize - (len+column)); + } else { + /* Write out desired data */ + this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask); + /* write data */ + this->write_buf(mtd, buf, len); + } + /* Send command to program the OOB data */ + this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1); + + status = this->waitfunc (mtd, this, FL_WRITING); + + /* See if device thinks it succeeded */ + if (status & 0x01) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page); + ret = -EIO; + goto out; + } + /* Return happy */ + *retlen = len; + +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE + /* Send command to read back the data */ + this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask); + + if (this->verify_buf(mtd, buf, len)) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page); + ret = -EIO; + goto out; + } +#endif + ret = 0; +out: + /* Deselect and wake up anyone waiting on the device */ + nand_release_device(mtd); + + return ret; +} + +/* XXX U-BOOT XXX */ +#if 0 +/** + * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc + * @mtd: MTD device structure + * @vecs: the iovectors to write + * @count: number of vectors + * @to: offset to write to + * @retlen: pointer to variable to store the number of written bytes + * + * NAND write with kvec. This just calls the ecc function + */ +static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, + loff_t to, size_t * retlen) +{ + return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL)); +} + +/** + * nand_writev_ecc - [MTD Interface] write with iovec with ecc + * @mtd: MTD device structure + * @vecs: the iovectors to write + * @count: number of vectors + * @to: offset to write to + * @retlen: pointer to variable to store the number of written bytes + * @eccbuf: filesystem supplied oob data buffer + * @oobsel: oob selection structure + * + * NAND write with iovec with ecc + */ +static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, + loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) +{ + int i, page, len, total_len, ret = -EIO, written = 0, chipnr; + int oob, numpages, autoplace = 0, startpage; + struct nand_chip *this = mtd->priv; + int ppblock = (1 << (this->phys_erase_shift - this->page_shift)); + u_char *oobbuf, *bufstart; + + /* Preset written len for early exit */ + *retlen = 0; + + /* Calculate total length of data */ + total_len = 0; + for (i = 0; i < count; i++) + total_len += (int) vecs[i].iov_len; + + DEBUG (MTD_DEBUG_LEVEL3, + "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count); + + /* Do not allow write past end of page */ + if ((to + total_len) > mtd->size) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n"); + return -EINVAL; + } + + /* reject writes, which are not page aligned */ + if (NOTALIGNED (to) || NOTALIGNED(total_len)) { + printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); + return -EINVAL; + } + + /* Grab the lock and see if the device is available */ + nand_get_device (this, mtd, FL_WRITING); + + /* Get the current chip-nr */ + chipnr = (int) (to >> this->chip_shift); + /* Select the NAND device */ + this->select_chip(mtd, chipnr); + + /* Check, if it is write protected */ + if (nand_check_wp(mtd)) + goto out; + + /* if oobsel is NULL, use chip defaults */ + if (oobsel == NULL) + oobsel = &mtd->oobinfo; + + /* Autoplace of oob data ? Use the default placement scheme */ + if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { + oobsel = this->autooob; + autoplace = 1; + } + if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) + autoplace = 1; + + /* Setup start page */ + page = (int) (to >> this->page_shift); + /* Invalidate the page cache, if we write to the cached page */ + if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) + this->pagebuf = -1; + + startpage = page & this->pagemask; + + /* Loop until all kvec' data has been written */ + len = 0; + while (count) { + /* If the given tuple is >= pagesize then + * write it out from the iov + */ + if ((vecs->iov_len - len) >= mtd->oobblock) { + /* Calc number of pages we can write + * out of this iov in one go */ + numpages = (vecs->iov_len - len) >> this->page_shift; + /* Do not cross block boundaries */ + numpages = min (ppblock - (startpage & (ppblock - 1)), numpages); + oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); + bufstart = (u_char *)vecs->iov_base; + bufstart += len; + this->data_poi = bufstart; + oob = 0; + for (i = 1; i <= numpages; i++) { + /* Write one page. If this is the last page to write + * then use the real pageprogram command, else select + * cached programming if supported by the chip. + */ + ret = nand_write_page (mtd, this, page & this->pagemask, + &oobbuf[oob], oobsel, i != numpages); + if (ret) + goto out; + this->data_poi += mtd->oobblock; + len += mtd->oobblock; + oob += mtd->oobsize; + page++; + } + /* Check, if we have to switch to the next tuple */ + if (len >= (int) vecs->iov_len) { + vecs++; + len = 0; + count--; + } + } else { + /* We must use the internal buffer, read data out of each + * tuple until we have a full page to write + */ + int cnt = 0; + while (cnt < mtd->oobblock) { + if (vecs->iov_base != NULL && vecs->iov_len) + this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++]; + /* Check, if we have to switch to the next tuple */ + if (len >= (int) vecs->iov_len) { + vecs++; + len = 0; + count--; + } + } + this->pagebuf = page; + this->data_poi = this->data_buf; + bufstart = this->data_poi; + numpages = 1; + oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); + ret = nand_write_page (mtd, this, page & this->pagemask, + oobbuf, oobsel, 0); + if (ret) + goto out; + page++; + } + + this->data_poi = bufstart; + ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); + if (ret) + goto out; + + written += mtd->oobblock * numpages; + /* All done ? */ + if (!count) + break; + + startpage = page & this->pagemask; + /* Check, if we cross a chip boundary */ + if (!startpage) { + chipnr++; + this->select_chip(mtd, -1); + this->select_chip(mtd, chipnr); + } + } + ret = 0; +out: + /* Deselect and wake up anyone waiting on the device */ + nand_release_device(mtd); + + *retlen = written; + return ret; +} +#endif + +/** + * single_erease_cmd - [GENERIC] NAND standard block erase command function + * @mtd: MTD device structure + * @page: the page address of the block which will be erased + * + * Standard erase command for NAND chips + */ +static void single_erase_cmd (struct mtd_info *mtd, int page) +{ + struct nand_chip *this = mtd->priv; + /* Send commands to erase a block */ + this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page); + this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1); +} + +/** + * multi_erease_cmd - [GENERIC] AND specific block erase command function + * @mtd: MTD device structure + * @page: the page address of the block which will be erased + * + * AND multi block erase command function + * Erase 4 consecutive blocks + */ +static void multi_erase_cmd (struct mtd_info *mtd, int page) +{ + struct nand_chip *this = mtd->priv; + /* Send commands to erase a block */ + this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); + this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); + this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); + this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page); + this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1); +} + +/** + * nand_erase - [MTD Interface] erase block(s) + * @mtd: MTD device structure + * @instr: erase instruction + * + * Erase one ore more blocks + */ +static int nand_erase (struct mtd_info *mtd, struct erase_info *instr) +{ + return nand_erase_nand (mtd, instr, 0); +} + +/** + * nand_erase_intern - [NAND Interface] erase block(s) + * @mtd: MTD device structure + * @instr: erase instruction + * @allowbbt: allow erasing the bbt area + * + * Erase one ore more blocks + */ +int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt) +{ + int page, len, status, pages_per_block, ret, chipnr; + struct nand_chip *this = mtd->priv; + + DEBUG (MTD_DEBUG_LEVEL3, + "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len); + + /* Start address must align on block boundary */ + if (instr->addr & ((1 << this->phys_erase_shift) - 1)) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n"); + return -EINVAL; + } + + /* Length must align on block boundary */ + if (instr->len & ((1 << this->phys_erase_shift) - 1)) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n"); + return -EINVAL; + } + + /* Do not allow erase past end of device */ + if ((instr->len + instr->addr) > mtd->size) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n"); + return -EINVAL; + } + + instr->fail_addr = 0xffffffff; + + /* Grab the lock and see if the device is available */ + nand_get_device (this, mtd, FL_ERASING); + + /* Shift to get first page */ + page = (int) (instr->addr >> this->page_shift); + chipnr = (int) (instr->addr >> this->chip_shift); + + /* Calculate pages in each block */ + pages_per_block = 1 << (this->phys_erase_shift - this->page_shift); + + /* Select the NAND device */ + this->select_chip(mtd, chipnr); + + /* Check the WP bit */ + /* Check, if it is write protected */ + if (nand_check_wp(mtd)) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n"); + instr->state = MTD_ERASE_FAILED; + goto erase_exit; + } + + /* Loop through the pages */ + len = instr->len; + + instr->state = MTD_ERASING; + + while (len) { + /* Check if we have a bad block, we do not erase bad blocks ! */ + if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) { + printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page); + instr->state = MTD_ERASE_FAILED; + goto erase_exit; + } + + /* Invalidate the page cache, if we erase the block which contains + the current cached page */ + if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) + this->pagebuf = -1; + + this->erase_cmd (mtd, page & this->pagemask); + + status = this->waitfunc (mtd, this, FL_ERASING); + + /* See if block erase succeeded */ + if (status & 0x01) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page); + instr->state = MTD_ERASE_FAILED; + instr->fail_addr = (page << this->page_shift); + goto erase_exit; + } + + /* Increment page address and decrement length */ + len -= (1 << this->phys_erase_shift); + page += pages_per_block; + + /* Check, if we cross a chip boundary */ + if (len && !(page & this->pagemask)) { + chipnr++; + this->select_chip(mtd, -1); + this->select_chip(mtd, chipnr); + } + } + instr->state = MTD_ERASE_DONE; + +erase_exit: + + ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; + /* Do call back function */ + if (!ret) + mtd_erase_callback(instr); + + /* Deselect and wake up anyone waiting on the device */ + nand_release_device(mtd); + + /* Return more or less happy */ + return ret; +} + +/** + * nand_sync - [MTD Interface] sync + * @mtd: MTD device structure + * + * Sync is actually a wait for chip ready function + */ +static void nand_sync (struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + + DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n"); + + /* Grab the lock and see if the device is available */ + nand_get_device (this, mtd, FL_SYNCING); + /* Release it and go back */ + nand_release_device (mtd); +} + + +/** + * nand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad + * @mtd: MTD device structure + * @ofs: offset relative to mtd start + */ +static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs) +{ + /* Check for invalid offset */ + if (ofs > mtd->size) + return -EINVAL; + + return nand_block_checkbad (mtd, ofs, 1, 0); +} + +/** + * nand_block_markbad - [MTD Interface] Mark the block at the given offset as bad + * @mtd: MTD device structure + * @ofs: offset relative to mtd start + */ +static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs) +{ + struct nand_chip *this = mtd->priv; + int ret; + + if ((ret = nand_block_isbad(mtd, ofs))) { + /* If it was bad already, return success and do nothing. */ + if (ret > 0) + return 0; + return ret; + } + + return this->block_markbad(mtd, ofs); +} + +/** + * nand_scan - [NAND Interface] Scan for the NAND device + * @mtd: MTD device structure + * @maxchips: Number of chips to scan for + * + * This fills out all the not initialized function pointers + * with the defaults. + * The flash ID is read and the mtd/chip structures are + * filled with the appropriate values. Buffers are allocated if + * they are not provided by the board driver + * + */ +int nand_scan (struct mtd_info *mtd, int maxchips) +{ + int i, j, nand_maf_id, nand_dev_id, busw; + struct nand_chip *this = mtd->priv; + + /* Get buswidth to select the correct functions*/ + busw = this->options & NAND_BUSWIDTH_16; + + /* check for proper chip_delay setup, set 20us if not */ + if (!this->chip_delay) + this->chip_delay = 20; + + /* check, if a user supplied command function given */ + if (this->cmdfunc == NULL) + this->cmdfunc = nand_command; + + /* check, if a user supplied wait function given */ + if (this->waitfunc == NULL) + this->waitfunc = nand_wait; + + if (!this->select_chip) + this->select_chip = nand_select_chip; + if (!this->write_byte) + this->write_byte = busw ? nand_write_byte16 : nand_write_byte; + if (!this->read_byte) + this->read_byte = busw ? nand_read_byte16 : nand_read_byte; + if (!this->write_word) + this->write_word = nand_write_word; + if (!this->read_word) + this->read_word = nand_read_word; + if (!this->block_bad) + this->block_bad = nand_block_bad; + if (!this->block_markbad) + this->block_markbad = nand_default_block_markbad; + if (!this->write_buf) + this->write_buf = busw ? nand_write_buf16 : nand_write_buf; + if (!this->read_buf) + this->read_buf = busw ? nand_read_buf16 : nand_read_buf; + if (!this->verify_buf) + this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf; + if (!this->scan_bbt) + this->scan_bbt = nand_default_bbt; + + /* Select the device */ + this->select_chip(mtd, 0); + + /* Send the command for reading device ID */ + this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); + + /* Read manufacturer and device IDs */ + nand_maf_id = this->read_byte(mtd); + nand_dev_id = this->read_byte(mtd); + + /* Print and store flash device information */ + for (i = 0; nand_flash_ids[i].name != NULL; i++) { + + if (nand_dev_id != nand_flash_ids[i].id) + continue; + + if (!mtd->name) mtd->name = nand_flash_ids[i].name; + this->chipsize = nand_flash_ids[i].chipsize << 20; + + /* New devices have all the information in additional id bytes */ + if (!nand_flash_ids[i].pagesize) { + int extid; + /* The 3rd id byte contains non relevant data ATM */ + extid = this->read_byte(mtd); + /* The 4th id byte is the important one */ + extid = this->read_byte(mtd); + /* Calc pagesize */ + mtd->oobblock = 1024 << (extid & 0x3); + extid >>= 2; + /* Calc oobsize */ + mtd->oobsize = (8 << (extid & 0x03)) * (mtd->oobblock / 512); + extid >>= 2; + /* Calc blocksize. Blocksize is multiples of 64KiB */ + mtd->erasesize = (64 * 1024) << (extid & 0x03); + extid >>= 2; + /* Get buswidth information */ + busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; + + } else { + /* Old devices have this data hardcoded in the + * device id table */ + mtd->erasesize = nand_flash_ids[i].erasesize; + mtd->oobblock = nand_flash_ids[i].pagesize; + mtd->oobsize = mtd->oobblock / 32; + busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16; + } + + /* Check, if buswidth is correct. Hardware drivers should set + * this correct ! */ + if (busw != (this->options & NAND_BUSWIDTH_16)) { + printk (KERN_INFO "NAND device: Manufacturer ID:" + " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, + nand_manuf_ids[i].name , mtd->name); + printk (KERN_WARNING + "NAND bus width %d instead %d bit\n", + (this->options & NAND_BUSWIDTH_16) ? 16 : 8, + busw ? 16 : 8); + this->select_chip(mtd, -1); + return 1; + } + + /* Calculate the address shift from the page size */ + this->page_shift = ffs(mtd->oobblock) - 1; + this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1; + this->chip_shift = ffs(this->chipsize) - 1; + + /* Set the bad block position */ + this->badblockpos = mtd->oobblock > 512 ? + NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; + + /* Get chip options, preserve non chip based options */ + this->options &= ~NAND_CHIPOPTIONS_MSK; + this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK; + /* Set this as a default. Board drivers can override it, if neccecary */ + this->options |= NAND_NO_AUTOINCR; + /* Check if this is a not a samsung device. Do not clear the options + * for chips which are not having an extended id. + */ + if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize) + this->options &= ~NAND_SAMSUNG_LP_OPTIONS; + + /* Check for AND chips with 4 page planes */ + if (this->options & NAND_4PAGE_ARRAY) + this->erase_cmd = multi_erase_cmd; + else + this->erase_cmd = single_erase_cmd; + + /* Do not replace user supplied command function ! */ + if (mtd->oobblock > 512 && this->cmdfunc == nand_command) + this->cmdfunc = nand_command_lp; + + /* Try to identify manufacturer */ + for (j = 0; nand_manuf_ids[j].id != 0x0; j++) { + if (nand_manuf_ids[j].id == nand_maf_id) + break; + } + printk (KERN_INFO "NAND device: Manufacturer ID:" + " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, + nand_manuf_ids[j].name , nand_flash_ids[i].name); + break; + } + + if (!nand_flash_ids[i].name) { + printk (KERN_WARNING "No NAND device found!!!\n"); + this->select_chip(mtd, -1); + return 1; + } + + for (i=1; i < maxchips; i++) { + this->select_chip(mtd, i); + + /* Send the command for reading device ID */ + this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); + + /* Read manufacturer and device IDs */ + if (nand_maf_id != this->read_byte(mtd) || + nand_dev_id != this->read_byte(mtd)) + break; + } + if (i > 1) + printk(KERN_INFO "%d NAND chips detected\n", i); + + /* Allocate buffers, if neccecary */ + if (!this->oob_buf) { + size_t len; + len = mtd->oobsize << (this->phys_erase_shift - this->page_shift); + this->oob_buf = kmalloc (len, GFP_KERNEL); + if (!this->oob_buf) { + printk (KERN_ERR "nand_scan(): Cannot allocate oob_buf\n"); + return -ENOMEM; + } + this->options |= NAND_OOBBUF_ALLOC; + } + + if (!this->data_buf) { + size_t len; + len = mtd->oobblock + mtd->oobsize; + this->data_buf = kmalloc (len, GFP_KERNEL); + if (!this->data_buf) { + if (this->options & NAND_OOBBUF_ALLOC) + kfree (this->oob_buf); + printk (KERN_ERR "nand_scan(): Cannot allocate data_buf\n"); + return -ENOMEM; + } + this->options |= NAND_DATABUF_ALLOC; + } + + /* Store the number of chips and calc total size for mtd */ + this->numchips = i; + mtd->size = i * this->chipsize; + /* Convert chipsize to number of pages per chip -1. */ + this->pagemask = (this->chipsize >> this->page_shift) - 1; + /* Preset the internal oob buffer */ + memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift)); + + /* If no default placement scheme is given, select an + * appropriate one */ + if (!this->autooob) { + /* Select the appropriate default oob placement scheme for + * placement agnostic filesystems */ + switch (mtd->oobsize) { + case 8: + this->autooob = &nand_oob_8; + break; + case 16: + this->autooob = &nand_oob_16; + break; + case 64: + this->autooob = &nand_oob_64; + break; + default: + printk (KERN_WARNING "No oob scheme defined for oobsize %d\n", + mtd->oobsize); +/* BUG(); */ + } + } + + /* The number of bytes available for the filesystem to place fs dependend + * oob data */ + if (this->options & NAND_BUSWIDTH_16) { + mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 2); + if (this->autooob->eccbytes & 0x01) + mtd->oobavail--; + } else + mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 1); + + /* + * check ECC mode, default to software + * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize + * fallback to software ECC + */ + this->eccsize = 256; /* set default eccsize */ + this->eccbytes = 3; + + switch (this->eccmode) { + case NAND_ECC_HW12_2048: + if (mtd->oobblock < 2048) { + printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n", + mtd->oobblock); + this->eccmode = NAND_ECC_SOFT; + this->calculate_ecc = nand_calculate_ecc; + this->correct_data = nand_correct_data; + } else + this->eccsize = 2048; + break; + + case NAND_ECC_HW3_512: + case NAND_ECC_HW6_512: + case NAND_ECC_HW8_512: + if (mtd->oobblock == 256) { + printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); + this->eccmode = NAND_ECC_SOFT; + this->calculate_ecc = nand_calculate_ecc; + this->correct_data = nand_correct_data; + } else + this->eccsize = 512; /* set eccsize to 512 */ + break; + + case NAND_ECC_HW3_256: + break; + + case NAND_ECC_NONE: + printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); + this->eccmode = NAND_ECC_NONE; + break; + + case NAND_ECC_SOFT: + this->calculate_ecc = nand_calculate_ecc; + this->correct_data = nand_correct_data; + break; + + default: + printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); +/* BUG(); */ + } + + /* Check hardware ecc function availability and adjust number of ecc bytes per + * calculation step + */ + switch (this->eccmode) { + case NAND_ECC_HW12_2048: + this->eccbytes += 4; + case NAND_ECC_HW8_512: + this->eccbytes += 2; + case NAND_ECC_HW6_512: + this->eccbytes += 3; + case NAND_ECC_HW3_512: + case NAND_ECC_HW3_256: + if (this->calculate_ecc && this->correct_data && this->enable_hwecc) + break; + printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n"); +/* BUG(); */ + } + + mtd->eccsize = this->eccsize; + + /* Set the number of read / write steps for one page to ensure ECC generation */ + switch (this->eccmode) { + case NAND_ECC_HW12_2048: + this->eccsteps = mtd->oobblock / 2048; + break; + case NAND_ECC_HW3_512: + case NAND_ECC_HW6_512: + case NAND_ECC_HW8_512: + this->eccsteps = mtd->oobblock / 512; + break; + case NAND_ECC_HW3_256: + case NAND_ECC_SOFT: + this->eccsteps = mtd->oobblock / 256; + break; + + case NAND_ECC_NONE: + this->eccsteps = 1; + break; + } + +/* XXX U-BOOT XXX */ +#if 0 + /* Initialize state, waitqueue and spinlock */ + this->state = FL_READY; + init_waitqueue_head (&this->wq); + spin_lock_init (&this->chip_lock); +#endif + + /* De-select the device */ + this->select_chip(mtd, -1); + + /* Invalidate the pagebuffer reference */ + this->pagebuf = -1; + + /* Fill in remaining MTD driver data */ + mtd->type = MTD_NANDFLASH; + mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC; + mtd->ecctype = MTD_ECC_SW; + mtd->erase = nand_erase; + mtd->point = NULL; + mtd->unpoint = NULL; + mtd->read = nand_read; + mtd->write = nand_write; + mtd->read_ecc = nand_read_ecc; + mtd->write_ecc = nand_write_ecc; + mtd->read_oob = nand_read_oob; + mtd->write_oob = nand_write_oob; +/* XXX U-BOOT XXX */ +#if 0 + mtd->readv = NULL; + mtd->writev = nand_writev; + mtd->writev_ecc = nand_writev_ecc; +#endif + mtd->sync = nand_sync; +/* XXX U-BOOT XXX */ +#if 0 + mtd->lock = NULL; + mtd->unlock = NULL; + mtd->suspend = NULL; + mtd->resume = NULL; +#endif + mtd->block_isbad = nand_block_isbad; + mtd->block_markbad = nand_block_markbad; + + /* and make the autooob the default one */ + memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); +/* XXX U-BOOT XXX */ +#if 0 + mtd->owner = THIS_MODULE; +#endif + /* Build bad block table */ + return this->scan_bbt (mtd); +} + +/** + * nand_release - [NAND Interface] Free resources held by the NAND device + * @mtd: MTD device structure +*/ +void nand_release (struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + +#ifdef CONFIG_MTD_PARTITIONS + /* Deregister partitions */ + del_mtd_partitions (mtd); +#endif + /* Deregister the device */ +/* XXX U-BOOT XXX */ +#if 0 + del_mtd_device (mtd); +#endif + /* Free bad block table memory, if allocated */ + if (this->bbt) + kfree (this->bbt); + /* Buffer allocated by nand_scan ? */ + if (this->options & NAND_OOBBUF_ALLOC) + kfree (this->oob_buf); + /* Buffer allocated by nand_scan ? */ + if (this->options & NAND_DATABUF_ALLOC) + kfree (this->data_buf); +} + +#endif diff --git a/drivers/nand/nand_bbt.c b/drivers/nand/nand_bbt.c new file mode 100644 index 0000000000..6f7e05b7eb --- /dev/null +++ b/drivers/nand/nand_bbt.c @@ -0,0 +1,1056 @@ +/* + * drivers/mtd/nand_bbt.c + * + * Overview: + * Bad block table support for the NAND driver + * + * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) + * + * $Id: nand_bbt.c,v 1.28 2004/11/13 10:19:09 gleixner Exp $ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Description: + * + * When nand_scan_bbt is called, then it tries to find the bad block table + * depending on the options in the bbt descriptor(s). If a bbt is found + * then the contents are read and the memory based bbt is created. If a + * mirrored bbt is selected then the mirror is searched too and the + * versions are compared. If the mirror has a greater version number + * than the mirror bbt is used to build the memory based bbt. + * If the tables are not versioned, then we "or" the bad block information. + * If one of the bbt's is out of date or does not exist it is (re)created. + * If no bbt exists at all then the device is scanned for factory marked + * good / bad blocks and the bad block tables are created. + * + * For manufacturer created bbts like the one found on M-SYS DOC devices + * the bbt is searched and read but never created + * + * The autogenerated bad block table is located in the last good blocks + * of the device. The table is mirrored, so it can be updated eventually. + * The table is marked in the oob area with an ident pattern and a version + * number which indicates which of both tables is more up to date. + * + * The table uses 2 bits per block + * 11b: block is good + * 00b: block is factory marked bad + * 01b, 10b: block is marked bad due to wear + * + * The memory bad block table uses the following scheme: + * 00b: block is good + * 01b: block is marked bad due to wear + * 10b: block is reserved (to protect the bbt area) + * 11b: block is factory marked bad + * + * Multichip devices like DOC store the bad block info per floor. + * + * Following assumptions are made: + * - bbts start at a page boundary, if autolocated on a block boundary + * - the space neccecary for a bbt in FLASH does not exceed a block boundary + * + */ + +#include + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) + +#include +#include +#include +#include + +#include + +/** + * check_pattern - [GENERIC] check if a pattern is in the buffer + * @buf: the buffer to search + * @len: the length of buffer to search + * @paglen: the pagelength + * @td: search pattern descriptor + * + * Check for a pattern at the given place. Used to search bad block + * tables and good / bad block identifiers. + * If the SCAN_EMPTY option is set then check, if all bytes except the + * pattern area contain 0xff + * +*/ +static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) +{ + int i, end; + uint8_t *p = buf; + + end = paglen + td->offs; + if (td->options & NAND_BBT_SCANEMPTY) { + for (i = 0; i < end; i++) { + if (p[i] != 0xff) + return -1; + } + } + p += end; + + /* Compare the pattern */ + for (i = 0; i < td->len; i++) { + if (p[i] != td->pattern[i]) + return -1; + } + + p += td->len; + end += td->len; + if (td->options & NAND_BBT_SCANEMPTY) { + for (i = end; i < len; i++) { + if (*p++ != 0xff) + return -1; + } + } + return 0; +} + +/** + * read_bbt - [GENERIC] Read the bad block table starting from page + * @mtd: MTD device structure + * @buf: temporary buffer + * @page: the starting page + * @num: the number of bbt descriptors to read + * @bits: number of bits per block + * @offs: offset in the memory table + * @reserved_block_code: Pattern to identify reserved blocks + * + * Read the bad block table starting from page. + * + */ +static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, + int bits, int offs, int reserved_block_code) +{ + int res, i, j, act = 0; + struct nand_chip *this = mtd->priv; + size_t retlen, len, totlen; + loff_t from; + uint8_t msk = (uint8_t) ((1 << bits) - 1); + + totlen = (num * bits) >> 3; + from = ((loff_t)page) << this->page_shift; + + while (totlen) { + len = min (totlen, (size_t) (1 << this->bbt_erase_shift)); + res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob); + if (res < 0) { + if (retlen != len) { + printk (KERN_INFO "nand_bbt: Error reading bad block table\n"); + return res; + } + printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); + } + + /* Analyse data */ + for (i = 0; i < len; i++) { + uint8_t dat = buf[i]; + for (j = 0; j < 8; j += bits, act += 2) { + uint8_t tmp = (dat >> j) & msk; + if (tmp == msk) + continue; + if (reserved_block_code && + (tmp == reserved_block_code)) { + printk (KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n", + ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); + this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06); + continue; + } + /* Leave it for now, if its matured we can move this + * message to MTD_DEBUG_LEVEL0 */ + printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", + ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); + /* Factory marked bad or worn out ? */ + if (tmp == 0) + this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); + else + this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06); + } + } + totlen -= len; + from += len; + } + return 0; +} + +/** + * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page + * @mtd: MTD device structure + * @buf: temporary buffer + * @td: descriptor for the bad block table + * @chip: read the table for a specific chip, -1 read all chips. + * Applies only if NAND_BBT_PERCHIP option is set + * + * Read the bad block table for all chips starting at a given page + * We assume that the bbt bits are in consecutive order. +*/ +static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip) +{ + struct nand_chip *this = mtd->priv; + int res = 0, i; + int bits; + + bits = td->options & NAND_BBT_NRBITS_MSK; + if (td->options & NAND_BBT_PERCHIP) { + int offs = 0; + for (i = 0; i < this->numchips; i++) { + if (chip == -1 || chip == i) + res = read_bbt (mtd, buf, td->pages[i], this->chipsize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code); + if (res) + return res; + offs += this->chipsize >> (this->bbt_erase_shift + 2); + } + } else { + res = read_bbt (mtd, buf, td->pages[0], mtd->size >> this->bbt_erase_shift, bits, 0, td->reserved_block_code); + if (res) + return res; + } + return 0; +} + +/** + * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page + * @mtd: MTD device structure + * @buf: temporary buffer + * @td: descriptor for the bad block table + * @md: descriptor for the bad block table mirror + * + * Read the bad block table(s) for all chips starting at a given page + * We assume that the bbt bits are in consecutive order. + * +*/ +static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, + struct nand_bbt_descr *md) +{ + struct nand_chip *this = mtd->priv; + + /* Read the primary version, if available */ + if (td->options & NAND_BBT_VERSION) { + nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); + td->version[0] = buf[mtd->oobblock + td->veroffs]; + printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); + } + + /* Read the mirror version, if available */ + if (md && (md->options & NAND_BBT_VERSION)) { + nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); + md->version[0] = buf[mtd->oobblock + md->veroffs]; + printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); + } + + return 1; +} + +/** + * create_bbt - [GENERIC] Create a bad block table by scanning the device + * @mtd: MTD device structure + * @buf: temporary buffer + * @bd: descriptor for the good/bad block search pattern + * @chip: create the table for a specific chip, -1 read all chips. + * Applies only if NAND_BBT_PERCHIP option is set + * + * Create a bad block table by scanning the device + * for the given good/bad block identify pattern + */ +static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip) +{ + struct nand_chip *this = mtd->priv; + int i, j, numblocks, len, scanlen; + int startblock; + loff_t from; + size_t readlen, ooblen; + + printk (KERN_INFO "Scanning device for bad blocks\n"); + + if (bd->options & NAND_BBT_SCANALLPAGES) + len = 1 << (this->bbt_erase_shift - this->page_shift); + else { + if (bd->options & NAND_BBT_SCAN2NDPAGE) + len = 2; + else + len = 1; + } + scanlen = mtd->oobblock + mtd->oobsize; + readlen = len * mtd->oobblock; + ooblen = len * mtd->oobsize; + + if (chip == -1) { + /* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it + * makes shifting and masking less painful */ + numblocks = mtd->size >> (this->bbt_erase_shift - 1); + startblock = 0; + from = 0; + } else { + if (chip >= this->numchips) { + printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n", + chip + 1, this->numchips); + return; + } + numblocks = this->chipsize >> (this->bbt_erase_shift - 1); + startblock = chip * numblocks; + numblocks += startblock; + from = startblock << (this->bbt_erase_shift - 1); + } + + for (i = startblock; i < numblocks;) { + nand_read_raw (mtd, buf, from, readlen, ooblen); + for (j = 0; j < len; j++) { + if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { + this->bbt[i >> 3] |= 0x03 << (i & 0x6); + printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", + i >> 1, (unsigned int) from); + break; + } + } + i += 2; + from += (1 << this->bbt_erase_shift); + } +} + +/** + * search_bbt - [GENERIC] scan the device for a specific bad block table + * @mtd: MTD device structure + * @buf: temporary buffer + * @td: descriptor for the bad block table + * + * Read the bad block table by searching for a given ident pattern. + * Search is preformed either from the beginning up or from the end of + * the device downwards. The search starts always at the start of a + * block. + * If the option NAND_BBT_PERCHIP is given, each chip is searched + * for a bbt, which contains the bad block information of this chip. + * This is neccecary to provide support for certain DOC devices. + * + * The bbt ident pattern resides in the oob area of the first page + * in a block. + */ +static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) +{ + struct nand_chip *this = mtd->priv; + int i, chips; + int bits, startblock, block, dir; + int scanlen = mtd->oobblock + mtd->oobsize; + int bbtblocks; + + /* Search direction top -> down ? */ + if (td->options & NAND_BBT_LASTBLOCK) { + startblock = (mtd->size >> this->bbt_erase_shift) -1; + dir = -1; + } else { + startblock = 0; + dir = 1; + } + + /* Do we have a bbt per chip ? */ + if (td->options & NAND_BBT_PERCHIP) { + chips = this->numchips; + bbtblocks = this->chipsize >> this->bbt_erase_shift; + startblock &= bbtblocks - 1; + } else { + chips = 1; + bbtblocks = mtd->size >> this->bbt_erase_shift; + } + + /* Number of bits for each erase block in the bbt */ + bits = td->options & NAND_BBT_NRBITS_MSK; + + for (i = 0; i < chips; i++) { + /* Reset version information */ + td->version[i] = 0; + td->pages[i] = -1; + /* Scan the maximum number of blocks */ + for (block = 0; block < td->maxblocks; block++) { + int actblock = startblock + dir * block; + /* Read first page */ + nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize); + if (!check_pattern(buf, scanlen, mtd->oobblock, td)) { + td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift); + if (td->options & NAND_BBT_VERSION) { + td->version[i] = buf[mtd->oobblock + td->veroffs]; + } + break; + } + } + startblock += this->chipsize >> this->bbt_erase_shift; + } + /* Check, if we found a bbt for each requested chip */ + for (i = 0; i < chips; i++) { + if (td->pages[i] == -1) + printk (KERN_WARNING "Bad block table not found for chip %d\n", i); + else + printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); + } + return 0; +} + +/** + * search_read_bbts - [GENERIC] scan the device for bad block table(s) + * @mtd: MTD device structure + * @buf: temporary buffer + * @td: descriptor for the bad block table + * @md: descriptor for the bad block table mirror + * + * Search and read the bad block table(s) +*/ +static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, + struct nand_bbt_descr *td, struct nand_bbt_descr *md) +{ + /* Search the primary table */ + search_bbt (mtd, buf, td); + + /* Search the mirror table */ + if (md) + search_bbt (mtd, buf, md); + + /* Force result check */ + return 1; +} + + +/** + * write_bbt - [GENERIC] (Re)write the bad block table + * + * @mtd: MTD device structure + * @buf: temporary buffer + * @td: descriptor for the bad block table + * @md: descriptor for the bad block table mirror + * @chipsel: selector for a specific chip, -1 for all + * + * (Re)write the bad block table + * +*/ +static int write_bbt (struct mtd_info *mtd, uint8_t *buf, + struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) +{ + struct nand_chip *this = mtd->priv; + struct nand_oobinfo oobinfo; + struct erase_info einfo; + int i, j, res, chip = 0; + int bits, startblock, dir, page, offs, numblocks, sft, sftmsk; + int nrchips, bbtoffs, pageoffs; + uint8_t msk[4]; + uint8_t rcode = td->reserved_block_code; + size_t retlen, len = 0; + loff_t to; + + if (!rcode) + rcode = 0xff; + /* Write bad block table per chip rather than per device ? */ + if (td->options & NAND_BBT_PERCHIP) { + numblocks = (int) (this->chipsize >> this->bbt_erase_shift); + /* Full device write or specific chip ? */ + if (chipsel == -1) { + nrchips = this->numchips; + } else { + nrchips = chipsel + 1; + chip = chipsel; + } + } else { + numblocks = (int) (mtd->size >> this->bbt_erase_shift); + nrchips = 1; + } + + /* Loop through the chips */ + for (; chip < nrchips; chip++) { + + /* There was already a version of the table, reuse the page + * This applies for absolute placement too, as we have the + * page nr. in td->pages. + */ + if (td->pages[chip] != -1) { + page = td->pages[chip]; + goto write; + } + + /* Automatic placement of the bad block table */ + /* Search direction top -> down ? */ + if (td->options & NAND_BBT_LASTBLOCK) { + startblock = numblocks * (chip + 1) - 1; + dir = -1; + } else { + startblock = chip * numblocks; + dir = 1; + } + + for (i = 0; i < td->maxblocks; i++) { + int block = startblock + dir * i; + /* Check, if the block is bad */ + switch ((this->bbt[block >> 2] >> (2 * (block & 0x03))) & 0x03) { + case 0x01: + case 0x03: + continue; + } + page = block << (this->bbt_erase_shift - this->page_shift); + /* Check, if the block is used by the mirror table */ + if (!md || md->pages[chip] != page) + goto write; + } + printk (KERN_ERR "No space left to write bad block table\n"); + return -ENOSPC; +write: + + /* Set up shift count and masks for the flash table */ + bits = td->options & NAND_BBT_NRBITS_MSK; + switch (bits) { + case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x01; break; + case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x03; break; + case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C; msk[2] = ~rcode; msk[3] = 0x0f; break; + case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break; + default: return -EINVAL; + } + + bbtoffs = chip * (numblocks >> 2); + + to = ((loff_t) page) << this->page_shift; + + memcpy (&oobinfo, this->autooob, sizeof(oobinfo)); + oobinfo.useecc = MTD_NANDECC_PLACEONLY; + + /* Must we save the block contents ? */ + if (td->options & NAND_BBT_SAVECONTENT) { + /* Make it block aligned */ + to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1)); + len = 1 << this->bbt_erase_shift; + res = mtd->read_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); + if (res < 0) { + if (retlen != len) { + printk (KERN_INFO "nand_bbt: Error reading block for writing the bad block table\n"); + return res; + } + printk (KERN_WARNING "nand_bbt: ECC error while reading block for writing bad block table\n"); + } + /* Calc the byte offset in the buffer */ + pageoffs = page - (int)(to >> this->page_shift); + offs = pageoffs << this->page_shift; + /* Preset the bbt area with 0xff */ + memset (&buf[offs], 0xff, (size_t)(numblocks >> sft)); + /* Preset the bbt's oob area with 0xff */ + memset (&buf[len + pageoffs * mtd->oobsize], 0xff, + ((len >> this->page_shift) - pageoffs) * mtd->oobsize); + if (td->options & NAND_BBT_VERSION) { + buf[len + (pageoffs * mtd->oobsize) + td->veroffs] = td->version[chip]; + } + } else { + /* Calc length */ + len = (size_t) (numblocks >> sft); + /* Make it page aligned ! */ + len = (len + (mtd->oobblock-1)) & ~(mtd->oobblock-1); + /* Preset the buffer with 0xff */ + memset (buf, 0xff, len + (len >> this->page_shift) * mtd->oobsize); + offs = 0; + /* Pattern is located in oob area of first page */ + memcpy (&buf[len + td->offs], td->pattern, td->len); + if (td->options & NAND_BBT_VERSION) { + buf[len + td->veroffs] = td->version[chip]; + } + } + + /* walk through the memory table */ + for (i = 0; i < numblocks; ) { + uint8_t dat; + dat = this->bbt[bbtoffs + (i >> 2)]; + for (j = 0; j < 4; j++ , i++) { + int sftcnt = (i << (3 - sft)) & sftmsk; + /* Do not store the reserved bbt blocks ! */ + buf[offs + (i >> sft)] &= ~(msk[dat & 0x03] << sftcnt); + dat >>= 2; + } + } + + memset (&einfo, 0, sizeof (einfo)); + einfo.mtd = mtd; + einfo.addr = (unsigned long) to; + einfo.len = 1 << this->bbt_erase_shift; + res = nand_erase_nand (mtd, &einfo, 1); + if (res < 0) { + printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res); + return res; + } + + res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); + if (res < 0) { + printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res); + return res; + } + printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", + (unsigned int) to, td->version[chip]); + + /* Mark it as used */ + td->pages[chip] = page; + } + return 0; +} + +/** + * nand_memory_bbt - [GENERIC] create a memory based bad block table + * @mtd: MTD device structure + * @bd: descriptor for the good/bad block search pattern + * + * The function creates a memory based bbt by scanning the device + * for manufacturer / software marked good / bad blocks +*/ +static int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) +{ + struct nand_chip *this = mtd->priv; + + /* Ensure that we only scan for the pattern and nothing else */ + bd->options = 0; + create_bbt (mtd, this->data_buf, bd, -1); + return 0; +} + +/** + * check_create - [GENERIC] create and write bbt(s) if neccecary + * @mtd: MTD device structure + * @buf: temporary buffer + * @bd: descriptor for the good/bad block search pattern + * + * The function checks the results of the previous call to read_bbt + * and creates / updates the bbt(s) if neccecary + * Creation is neccecary if no bbt was found for the chip/device + * Update is neccecary if one of the tables is missing or the + * version nr. of one table is less than the other +*/ +static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) +{ + int i, chips, writeops, chipsel, res; + struct nand_chip *this = mtd->priv; + struct nand_bbt_descr *td = this->bbt_td; + struct nand_bbt_descr *md = this->bbt_md; + struct nand_bbt_descr *rd, *rd2; + + /* Do we have a bbt per chip ? */ + if (td->options & NAND_BBT_PERCHIP) + chips = this->numchips; + else + chips = 1; + + for (i = 0; i < chips; i++) { + writeops = 0; + rd = NULL; + rd2 = NULL; + /* Per chip or per device ? */ + chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1; + /* Mirrored table avilable ? */ + if (md) { + if (td->pages[i] == -1 && md->pages[i] == -1) { + writeops = 0x03; + goto create; + } + + if (td->pages[i] == -1) { + rd = md; + td->version[i] = md->version[i]; + writeops = 1; + goto writecheck; + } + + if (md->pages[i] == -1) { + rd = td; + md->version[i] = td->version[i]; + writeops = 2; + goto writecheck; + } + + if (td->version[i] == md->version[i]) { + rd = td; + if (!(td->options & NAND_BBT_VERSION)) + rd2 = md; + goto writecheck; + } + + if (((int8_t) (td->version[i] - md->version[i])) > 0) { + rd = td; + md->version[i] = td->version[i]; + writeops = 2; + } else { + rd = md; + td->version[i] = md->version[i]; + writeops = 1; + } + + goto writecheck; + + } else { + if (td->pages[i] == -1) { + writeops = 0x01; + goto create; + } + rd = td; + goto writecheck; + } +create: + /* Create the bad block table by scanning the device ? */ + if (!(td->options & NAND_BBT_CREATE)) + continue; + + /* Create the table in memory by scanning the chip(s) */ + create_bbt (mtd, buf, bd, chipsel); + + td->version[i] = 1; + if (md) + md->version[i] = 1; +writecheck: + /* read back first ? */ + if (rd) + read_abs_bbt (mtd, buf, rd, chipsel); + /* If they weren't versioned, read both. */ + if (rd2) + read_abs_bbt (mtd, buf, rd2, chipsel); + + /* Write the bad block table to the device ? */ + if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { + res = write_bbt (mtd, buf, td, md, chipsel); + if (res < 0) + return res; + } + + /* Write the mirror bad block table to the device ? */ + if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { + res = write_bbt (mtd, buf, md, td, chipsel); + if (res < 0) + return res; + } + } + return 0; +} + +/** + * mark_bbt_regions - [GENERIC] mark the bad block table regions + * @mtd: MTD device structure + * @td: bad block table descriptor + * + * The bad block table regions are marked as "bad" to prevent + * accidental erasures / writes. The regions are identified by + * the mark 0x02. +*/ +static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) +{ + struct nand_chip *this = mtd->priv; + int i, j, chips, block, nrblocks, update; + uint8_t oldval, newval; + + /* Do we have a bbt per chip ? */ + if (td->options & NAND_BBT_PERCHIP) { + chips = this->numchips; + nrblocks = (int)(this->chipsize >> this->bbt_erase_shift); + } else { + chips = 1; + nrblocks = (int)(mtd->size >> this->bbt_erase_shift); + } + + for (i = 0; i < chips; i++) { + if ((td->options & NAND_BBT_ABSPAGE) || + !(td->options & NAND_BBT_WRITE)) { + if (td->pages[i] == -1) continue; + block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); + block <<= 1; + oldval = this->bbt[(block >> 3)]; + newval = oldval | (0x2 << (block & 0x06)); + this->bbt[(block >> 3)] = newval; + if ((oldval != newval) && td->reserved_block_code) + nand_update_bbt(mtd, block << (this->bbt_erase_shift - 1)); + continue; + } + update = 0; + if (td->options & NAND_BBT_LASTBLOCK) + block = ((i + 1) * nrblocks) - td->maxblocks; + else + block = i * nrblocks; + block <<= 1; + for (j = 0; j < td->maxblocks; j++) { + oldval = this->bbt[(block >> 3)]; + newval = oldval | (0x2 << (block & 0x06)); + this->bbt[(block >> 3)] = newval; + if (oldval != newval) update = 1; + block += 2; + } + /* If we want reserved blocks to be recorded to flash, and some + new ones have been marked, then we need to update the stored + bbts. This should only happen once. */ + if (update && td->reserved_block_code) + nand_update_bbt(mtd, (block - 2) << (this->bbt_erase_shift - 1)); + } +} + +/** + * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s) + * @mtd: MTD device structure + * @bd: descriptor for the good/bad block search pattern + * + * The function checks, if a bad block table(s) is/are already + * available. If not it scans the device for manufacturer + * marked good / bad blocks and writes the bad block table(s) to + * the selected place. + * + * The bad block table memory is allocated here. It must be freed + * by calling the nand_free_bbt function. + * +*/ +int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) +{ + struct nand_chip *this = mtd->priv; + int len, res = 0; + uint8_t *buf; + struct nand_bbt_descr *td = this->bbt_td; + struct nand_bbt_descr *md = this->bbt_md; + + len = mtd->size >> (this->bbt_erase_shift + 2); + /* Allocate memory (2bit per block) */ + this->bbt = kmalloc (len, GFP_KERNEL); + if (!this->bbt) { + printk (KERN_ERR "nand_scan_bbt: Out of memory\n"); + return -ENOMEM; + } + /* Clear the memory bad block table */ + memset (this->bbt, 0x00, len); + + /* If no primary table decriptor is given, scan the device + * to build a memory based bad block table + */ + if (!td) + return nand_memory_bbt(mtd, bd); + + /* Allocate a temporary buffer for one eraseblock incl. oob */ + len = (1 << this->bbt_erase_shift); + len += (len >> this->page_shift) * mtd->oobsize; + buf = kmalloc (len, GFP_KERNEL); + if (!buf) { + printk (KERN_ERR "nand_bbt: Out of memory\n"); + kfree (this->bbt); + this->bbt = NULL; + return -ENOMEM; + } + + /* Is the bbt at a given page ? */ + if (td->options & NAND_BBT_ABSPAGE) { + res = read_abs_bbts (mtd, buf, td, md); + } else { + /* Search the bad block table using a pattern in oob */ + res = search_read_bbts (mtd, buf, td, md); + } + + if (res) + res = check_create (mtd, buf, bd); + + /* Prevent the bbt regions from erasing / writing */ + mark_bbt_region (mtd, td); + if (md) + mark_bbt_region (mtd, md); + + kfree (buf); + return res; +} + + +/** + * nand_update_bbt - [NAND Interface] update bad block table(s) + * @mtd: MTD device structure + * @offs: the offset of the newly marked block + * + * The function updates the bad block table(s) +*/ +int nand_update_bbt (struct mtd_info *mtd, loff_t offs) +{ + struct nand_chip *this = mtd->priv; + int len, res = 0, writeops = 0; + int chip, chipsel; + uint8_t *buf; + struct nand_bbt_descr *td = this->bbt_td; + struct nand_bbt_descr *md = this->bbt_md; + + if (!this->bbt || !td) + return -EINVAL; + + len = mtd->size >> (this->bbt_erase_shift + 2); + /* Allocate a temporary buffer for one eraseblock incl. oob */ + len = (1 << this->bbt_erase_shift); + len += (len >> this->page_shift) * mtd->oobsize; + buf = kmalloc (len, GFP_KERNEL); + if (!buf) { + printk (KERN_ERR "nand_update_bbt: Out of memory\n"); + return -ENOMEM; + } + + writeops = md != NULL ? 0x03 : 0x01; + + /* Do we have a bbt per chip ? */ + if (td->options & NAND_BBT_PERCHIP) { + chip = (int) (offs >> this->chip_shift); + chipsel = chip; + } else { + chip = 0; + chipsel = -1; + } + + td->version[chip]++; + if (md) + md->version[chip]++; + + /* Write the bad block table to the device ? */ + if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { + res = write_bbt (mtd, buf, td, md, chipsel); + if (res < 0) + goto out; + } + /* Write the mirror bad block table to the device ? */ + if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { + res = write_bbt (mtd, buf, md, td, chipsel); + } + +out: + kfree (buf); + return res; +} + +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + * + * The memory based patterns just + */ +static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; + +static struct nand_bbt_descr smallpage_memorybased = { + .options = 0, + .offs = 5, + .len = 1, + .pattern = scan_ff_pattern +}; + +static struct nand_bbt_descr largepage_memorybased = { + .options = 0, + .offs = 0, + .len = 2, + .pattern = scan_ff_pattern +}; + +static struct nand_bbt_descr smallpage_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 5, + .len = 1, + .pattern = scan_ff_pattern +}; + +static struct nand_bbt_descr largepage_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 2, + .pattern = scan_ff_pattern +}; + +static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 }; + +static struct nand_bbt_descr agand_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0x20, + .len = 6, + .pattern = scan_agand_pattern +}; + +/* Generic flash bbt decriptors +*/ +static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; +static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; + +static struct nand_bbt_descr bbt_main_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 8, + .len = 4, + .veroffs = 12, + .maxblocks = 4, + .pattern = bbt_pattern +}; + +static struct nand_bbt_descr bbt_mirror_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 8, + .len = 4, + .veroffs = 12, + .maxblocks = 4, + .pattern = mirror_pattern +}; + +/** + * nand_default_bbt - [NAND Interface] Select a default bad block table for the device + * @mtd: MTD device structure + * + * This function selects the default bad block table + * support for the device and calls the nand_scan_bbt function + * +*/ +int nand_default_bbt (struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + + /* Default for AG-AND. We must use a flash based + * bad block table as the devices have factory marked + * _good_ blocks. Erasing those blocks leads to loss + * of the good / bad information, so we _must_ store + * this information in a good / bad table during + * startup + */ + if (this->options & NAND_IS_AND) { + /* Use the default pattern descriptors */ + if (!this->bbt_td) { + this->bbt_td = &bbt_main_descr; + this->bbt_md = &bbt_mirror_descr; + } + this->options |= NAND_USE_FLASH_BBT; + return nand_scan_bbt (mtd, &agand_flashbased); + } + + + /* Is a flash based bad block table requested ? */ + if (this->options & NAND_USE_FLASH_BBT) { + /* Use the default pattern descriptors */ + if (!this->bbt_td) { + this->bbt_td = &bbt_main_descr; + this->bbt_md = &bbt_mirror_descr; + } + if (!this->badblock_pattern) { + this->badblock_pattern = (mtd->oobblock > 512) ? + &largepage_flashbased : &smallpage_flashbased; + } + } else { + this->bbt_td = NULL; + this->bbt_md = NULL; + if (!this->badblock_pattern) { + this->badblock_pattern = (mtd->oobblock > 512) ? + &largepage_memorybased : &smallpage_memorybased; + } + } + return nand_scan_bbt (mtd, this->badblock_pattern); +} + +/** + * nand_isbad_bbt - [NAND Interface] Check if a block is bad + * @mtd: MTD device structure + * @offs: offset in the device + * @allowbbt: allow access to bad block table region + * +*/ +int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt) +{ + struct nand_chip *this = mtd->priv; + int block; + uint8_t res; + + /* Get block number * 2 */ + block = (int) (offs >> (this->bbt_erase_shift - 1)); + res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; + + DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", + (unsigned int)offs, res, block >> 1); + + switch ((int)res) { + case 0x00: return 0; + case 0x01: return 1; + case 0x02: return allowbbt ? 0 : 1; + } + return 1; +} + +#endif diff --git a/drivers/nand/nand_ecc.c b/drivers/nand/nand_ecc.c new file mode 100644 index 0000000000..dc9db4b480 --- /dev/null +++ b/drivers/nand/nand_ecc.c @@ -0,0 +1,244 @@ +/* + * This file contains an ECC algorithm from Toshiba that detects and + * corrects 1 bit errors in a 256 byte block of data. + * + * drivers/mtd/nand/nand_ecc.c + * + * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) + * Toshiba America Electronics Components, Inc. + * + * $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $ + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 or (at your option) any + * later version. + * + * This file is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this file; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * As a special exception, if other files instantiate templates or use + * macros or inline functions from these files, or you compile these + * files and link them with other works to produce a work based on these + * files, these files do not by themselves cause the resulting work to be + * covered by the GNU General Public License. However the source code for + * these files must still be made available in accordance with section (3) + * of the GNU General Public License. + * + * This exception does not invalidate any other reasons why a work based on + * this file might be covered by the GNU General Public License. + */ + +#include + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) + +/* + * Pre-calculated 256-way 1 byte column parity + */ +static const u_char nand_ecc_precalc_table[] = { + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 +}; + + +/** + * nand_trans_result - [GENERIC] create non-inverted ECC + * @reg2: line parity reg 2 + * @reg3: line parity reg 3 + * @ecc_code: ecc + * + * Creates non-inverted ECC code from line parity + */ +static void nand_trans_result(u_char reg2, u_char reg3, + u_char *ecc_code) +{ + u_char a, b, i, tmp1, tmp2; + + /* Initialize variables */ + a = b = 0x80; + tmp1 = tmp2 = 0; + + /* Calculate first ECC byte */ + for (i = 0; i < 4; i++) { + if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ + tmp1 |= b; + b >>= 1; + if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */ + tmp1 |= b; + b >>= 1; + a >>= 1; + } + + /* Calculate second ECC byte */ + b = 0x80; + for (i = 0; i < 4; i++) { + if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */ + tmp2 |= b; + b >>= 1; + if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */ + tmp2 |= b; + b >>= 1; + a >>= 1; + } + + /* Store two of the ECC bytes */ + ecc_code[0] = tmp1; + ecc_code[1] = tmp2; +} + +/** + * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for 256 byte block + * @mtd: MTD block structure + * @dat: raw data + * @ecc_code: buffer for ECC + */ +int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) +{ + u_char idx, reg1, reg2, reg3; + int j; + + /* Initialize variables */ + reg1 = reg2 = reg3 = 0; + ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; + + /* Build up column parity */ + for(j = 0; j < 256; j++) { + + /* Get CP0 - CP5 from table */ + idx = nand_ecc_precalc_table[dat[j]]; + reg1 ^= (idx & 0x3f); + + /* All bit XOR = 1 ? */ + if (idx & 0x40) { + reg3 ^= (u_char) j; + reg2 ^= ~((u_char) j); + } + } + + /* Create non-inverted ECC code from line parity */ + nand_trans_result(reg2, reg3, ecc_code); + + /* Calculate final ECC code */ + ecc_code[0] = ~ecc_code[0]; + ecc_code[1] = ~ecc_code[1]; + ecc_code[2] = ((~reg1) << 2) | 0x03; + return 0; +} + +/** + * nand_correct_data - [NAND Interface] Detect and correct bit error(s) + * @mtd: MTD block structure + * @dat: raw data read from the chip + * @read_ecc: ECC from the chip + * @calc_ecc: the ECC calculated from raw data + * + * Detect and correct a 1 bit error for 256 byte block + */ +int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) +{ + u_char a, b, c, d1, d2, d3, add, bit, i; + + /* Do error detection */ + d1 = calc_ecc[0] ^ read_ecc[0]; + d2 = calc_ecc[1] ^ read_ecc[1]; + d3 = calc_ecc[2] ^ read_ecc[2]; + + if ((d1 | d2 | d3) == 0) { + /* No errors */ + return 0; + } + else { + a = (d1 ^ (d1 >> 1)) & 0x55; + b = (d2 ^ (d2 >> 1)) & 0x55; + c = (d3 ^ (d3 >> 1)) & 0x54; + + /* Found and will correct single bit error in the data */ + if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { + c = 0x80; + add = 0; + a = 0x80; + for (i=0; i<4; i++) { + if (d1 & c) + add |= a; + c >>= 2; + a >>= 1; + } + c = 0x80; + for (i=0; i<4; i++) { + if (d2 & c) + add |= a; + c >>= 2; + a >>= 1; + } + bit = 0; + b = 0x04; + c = 0x80; + for (i=0; i<3; i++) { + if (d3 & c) + bit |= b; + c >>= 2; + b >>= 1; + } + b = 0x01; + a = dat[add]; + a ^= (b << bit); + dat[add] = a; + return 1; + } + else { + i = 0; + while (d1) { + if (d1 & 0x01) + ++i; + d1 >>= 1; + } + while (d2) { + if (d2 & 0x01) + ++i; + d2 >>= 1; + } + while (d3) { + if (d3 & 0x01) + ++i; + d3 >>= 1; + } + if (i == 1) { + /* ECC Code Error Correction */ + read_ecc[0] = calc_ecc[0]; + read_ecc[1] = calc_ecc[1]; + read_ecc[2] = calc_ecc[2]; + return 2; + } + else { + /* Uncorrectable Error */ + return -1; + } + } + } + + /* Should never happen */ + return -1; +} + +#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */ diff --git a/drivers/nand/nand_ids.c b/drivers/nand/nand_ids.c new file mode 100644 index 0000000000..5df1e8971d --- /dev/null +++ b/drivers/nand/nand_ids.c @@ -0,0 +1,127 @@ +/* + * drivers/mtd/nandids.c + * + * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) + * + * $Id: nand_ids.c,v 1.10 2004/05/26 13:40:12 gleixner Exp $ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) + +#include + +/* +* Chip ID list +* +* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, +* options +* +* Pagesize; 0, 256, 512 +* 0 get this information from the extended chip ID ++ 256 256 Byte page size +* 512 512 Byte page size +*/ +struct nand_flash_dev nand_flash_ids[] = { + {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, + {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0}, + {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0}, + {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0}, + {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0}, + {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0}, + {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0}, + {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, + {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, + {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, + + {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, + {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, + {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, + {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, + + {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, + {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, + {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, + {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, + {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, + {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, + {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, + {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, + {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, + + {"NAND 512MiB 3,3V 8-bit", 0xDC, 512, 512, 0x4000, 0}, + + /* These are the new chips with large page size. The pagesize + * and the erasesize is determined from the extended id bytes + */ + /* 1 Gigabit */ + {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + + /* 2 Gigabit */ + {"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + + /* 4 Gigabit */ + {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + + /* 8 Gigabit */ + {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + + /* 16 Gigabit */ + {"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + + /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! + * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes + * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 + * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go + * There are more speed improvements for reads and writes possible, but not implemented now + */ + {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY}, + + {NULL,} +}; + +/* +* Manufacturer ID list +*/ +struct nand_manufacturers nand_manuf_ids[] = { + {NAND_MFR_TOSHIBA, "Toshiba"}, + {NAND_MFR_SAMSUNG, "Samsung"}, + {NAND_MFR_FUJITSU, "Fujitsu"}, + {NAND_MFR_NATIONAL, "National"}, + {NAND_MFR_RENESAS, "Renesas"}, + {NAND_MFR_STMICRO, "ST Micro"}, + {0x0, "Unknown"} +}; +#endif diff --git a/fs/jffs2/jffs2_nand_1pass.c b/fs/jffs2/jffs2_nand_1pass.c new file mode 100644 index 0000000000..ce80a43fa1 --- /dev/null +++ b/fs/jffs2/jffs2_nand_1pass.c @@ -0,0 +1,1045 @@ +#include + +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) + +#include +#include +#include + +#include +#include +#include + +#include "jffs2_nand_private.h" + +#define NODE_CHUNK 1024 /* size of memory allocation chunk in b_nodes */ + +/* Debugging switches */ +#undef DEBUG_DIRENTS /* print directory entry list after scan */ +#undef DEBUG_FRAGMENTS /* print fragment list after scan */ +#undef DEBUG /* enable debugging messages */ + +#ifdef DEBUG +# define DEBUGF(fmt,args...) printf(fmt ,##args) +#else +# define DEBUGF(fmt,args...) +#endif + +static int nanddev = -1; /* nand device of current partition */ +static nand_info_t *nand; + +/* Compression names */ +static char *compr_names[] = { + "NONE", + "ZERO", + "RTIME", + "RUBINMIPS", + "COPY", + "DYNRUBIN", + "ZLIB", +#if defined(CONFIG_JFFS2_LZO_LZARI) + "LZO", + "LZARI", +#endif +}; + +/* Spinning wheel */ +static char spinner[] = { '|', '/', '-', '\\' }; + +/* Memory management */ +struct mem_block { + unsigned index; + struct mem_block *next; + char nodes[0]; +}; + +static void +free_nodes(struct b_list *list) +{ + while (list->listMemBase != NULL) { + struct mem_block *next = list->listMemBase->next; + free(list->listMemBase); + list->listMemBase = next; + } +} + +static struct b_node * +add_node(struct b_list *list, int size) +{ + u32 index = 0; + struct mem_block *memBase; + struct b_node *b; + + memBase = list->listMemBase; + if (memBase != NULL) + index = memBase->index; + + if (memBase == NULL || index >= NODE_CHUNK) { + /* we need more space before we continue */ + memBase = mmalloc(sizeof(struct mem_block) + NODE_CHUNK * size); + if (memBase == NULL) { + putstr("add_node: malloc failed\n"); + return NULL; + } + memBase->next = list->listMemBase; + index = 0; + } + /* now we have room to add it. */ + b = (struct b_node *)&memBase->nodes[size * index]; + index ++; + + memBase->index = index; + list->listMemBase = memBase; + list->listCount++; + return b; +} + +static struct b_node * +insert_node(struct b_list *list, struct b_node *new) +{ +#ifdef CFG_JFFS2_SORT_FRAGMENTS + struct b_node *b, *prev; + + if (list->listTail != NULL && list->listCompare(new, list->listTail)) + prev = list->listTail; + else if (list->listLast != NULL && list->listCompare(new, list->listLast)) + prev = list->listLast; + else + prev = NULL; + + for (b = (prev ? prev->next : list->listHead); + b != NULL && list->listCompare(new, b); + prev = b, b = b->next) { + list->listLoops++; + } + if (b != NULL) + list->listLast = prev; + + if (b != NULL) { + new->next = b; + if (prev != NULL) + prev->next = new; + else + list->listHead = new; + } else +#endif + { + new->next = (struct b_node *) NULL; + if (list->listTail != NULL) { + list->listTail->next = new; + list->listTail = new; + } else { + list->listTail = list->listHead = new; + } + } + + return new; +} + +static struct b_node * +insert_inode(struct b_list *list, struct jffs2_raw_inode *node, u32 offset) +{ + struct b_inode *new; + + if (!(new = (struct b_inode *)add_node(list, sizeof(struct b_inode)))) { + putstr("add_node failed!\r\n"); + return NULL; + } + new->offset = offset; + new->version = node->version; + new->ino = node->ino; + new->isize = node->isize; + new->csize = node->csize; + + return insert_node(list, (struct b_node *)new); +} + +static struct b_node * +insert_dirent(struct b_list *list, struct jffs2_raw_dirent *node, u32 offset) +{ + struct b_dirent *new; + + if (!(new = (struct b_dirent *)add_node(list, sizeof(struct b_dirent)))) { + putstr("add_node failed!\r\n"); + return NULL; + } + new->offset = offset; + new->version = node->version; + new->pino = node->pino; + new->ino = node->ino; + new->nhash = full_name_hash(node->name, node->nsize); + new->nsize = node->nsize; + new->type = node->type; + + return insert_node(list, (struct b_node *)new); +} + +#ifdef CFG_JFFS2_SORT_FRAGMENTS +/* Sort data entries with the latest version last, so that if there + * is overlapping data the latest version will be used. + */ +static int compare_inodes(struct b_node *new, struct b_node *old) +{ + struct jffs2_raw_inode ojNew; + struct jffs2_raw_inode ojOld; + struct jffs2_raw_inode *jNew = + (struct jffs2_raw_inode *)get_fl_mem(new->offset, sizeof(ojNew), &ojNew); + struct jffs2_raw_inode *jOld = + (struct jffs2_raw_inode *)get_fl_mem(old->offset, sizeof(ojOld), &ojOld); + + return jNew->version > jOld->version; +} + +/* Sort directory entries so all entries in the same directory + * with the same name are grouped together, with the latest version + * last. This makes it easy to eliminate all but the latest version + * by marking the previous version dead by setting the inode to 0. + */ +static int compare_dirents(struct b_node *new, struct b_node *old) +{ + struct jffs2_raw_dirent ojNew; + struct jffs2_raw_dirent ojOld; + struct jffs2_raw_dirent *jNew = + (struct jffs2_raw_dirent *)get_fl_mem(new->offset, sizeof(ojNew), &ojNew); + struct jffs2_raw_dirent *jOld = + (struct jffs2_raw_dirent *)get_fl_mem(old->offset, sizeof(ojOld), &ojOld); + int cmp; + + /* ascending sort by pino */ + if (jNew->pino != jOld->pino) + return jNew->pino > jOld->pino; + + /* pino is the same, so use ascending sort by nsize, so + * we don't do strncmp unless we really must. + */ + if (jNew->nsize != jOld->nsize) + return jNew->nsize > jOld->nsize; + + /* length is also the same, so use ascending sort by name + */ + cmp = strncmp(jNew->name, jOld->name, jNew->nsize); + if (cmp != 0) + return cmp > 0; + + /* we have duplicate names in this directory, so use ascending + * sort by version + */ + if (jNew->version > jOld->version) { + /* since jNew is newer, we know jOld is not valid, so + * mark it with inode 0 and it will not be used + */ + jOld->ino = 0; + return 1; + } + + return 0; +} +#endif + +static u32 +jffs_init_1pass_list(struct part_info *part) +{ + struct b_lists *pL; + + if (part->jffs2_priv != NULL) { + pL = (struct b_lists *)part->jffs2_priv; + free_nodes(&pL->frag); + free_nodes(&pL->dir); + free(pL); + } + if (NULL != (part->jffs2_priv = malloc(sizeof(struct b_lists)))) { + pL = (struct b_lists *)part->jffs2_priv; + + memset(pL, 0, sizeof(*pL)); +#ifdef CFG_JFFS2_SORT_FRAGMENTS + pL->dir.listCompare = compare_dirents; + pL->frag.listCompare = compare_inodes; +#endif + } + return 0; +} + +/* find the inode from the slashless name given a parent */ +static long +jffs2_1pass_read_inode(struct b_lists *pL, u32 ino, char *dest, + struct stat *stat) +{ + struct b_inode *jNode; + u32 totalSize = 0; + u32 latestVersion = 0; + long ret; + +#ifdef CFG_JFFS2_SORT_FRAGMENTS + /* Find file size before loading any data, so fragments that + * start past the end of file can be ignored. A fragment + * that is partially in the file is loaded, so extra data may + * be loaded up to the next 4K boundary above the file size. + * This shouldn't cause trouble when loading kernel images, so + * we will live with it. + */ + for (jNode = (struct b_inode *)pL->frag.listHead; jNode; jNode = jNode->next) { + if ((ino == jNode->ino)) { + /* get actual file length from the newest node */ + if (jNode->version >= latestVersion) { + totalSize = jNode->isize; + latestVersion = jNode->version; + } + } + } +#endif + + for (jNode = (struct b_inode *)pL->frag.listHead; jNode; jNode = jNode->next) { + if ((ino != jNode->ino)) + continue; +#ifndef CFG_JFFS2_SORT_FRAGMENTS + /* get actual file length from the newest node */ + if (jNode->version >= latestVersion) { + totalSize = jNode->isize; + latestVersion = jNode->version; + } +#endif + if (dest || stat) { + char *src, *dst; + char data[4096 + sizeof(struct jffs2_raw_inode)]; + struct jffs2_raw_inode *inode; + size_t len; + + inode = (struct jffs2_raw_inode *)&data; + len = sizeof(struct jffs2_raw_inode); + if (dest) + len += jNode->csize; + nand_read(nand, jNode->offset, &len, inode); + /* ignore data behind latest known EOF */ + if (inode->offset > totalSize) + continue; + + if (stat) { + stat->st_mtime = inode->mtime; + stat->st_mode = inode->mode; + stat->st_ino = inode->ino; + stat->st_size = totalSize; + } + + if (!dest) + continue; + + src = ((char *) inode) + sizeof(struct jffs2_raw_inode); + dst = (char *) (dest + inode->offset); + + switch (inode->compr) { + case JFFS2_COMPR_NONE: + ret = 0; + memcpy(dst, src, inode->dsize); + break; + case JFFS2_COMPR_ZERO: + ret = 0; + memset(dst, 0, inode->dsize); + break; + case JFFS2_COMPR_RTIME: + ret = 0; + rtime_decompress(src, dst, inode->csize, inode->dsize); + break; + case JFFS2_COMPR_DYNRUBIN: + /* this is slow but it works */ + ret = 0; + dynrubin_decompress(src, dst, inode->csize, inode->dsize); + break; + case JFFS2_COMPR_ZLIB: + ret = zlib_decompress(src, dst, inode->csize, inode->dsize); + break; +#if defined(CONFIG_JFFS2_LZO_LZARI) + case JFFS2_COMPR_LZO: + ret = lzo_decompress(src, dst, inode->csize, inode->dsize); + break; + case JFFS2_COMPR_LZARI: + ret = lzari_decompress(src, dst, inode->csize, inode->dsize); + break; +#endif + default: + /* unknown */ + putLabeledWord("UNKOWN COMPRESSION METHOD = ", inode->compr); + return -1; + } + } + } + + return totalSize; +} + +/* find the inode from the slashless name given a parent */ +static u32 +jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino) +{ + struct b_dirent *jDir; + int len = strlen(name); /* name is assumed slash free */ + unsigned int nhash = full_name_hash(name, len); + u32 version = 0; + u32 inode = 0; + + /* we need to search all and return the inode with the highest version */ + for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) { + if ((pino == jDir->pino) && (jDir->ino) && /* 0 for unlink */ + (len == jDir->nsize) && (nhash == jDir->nhash)) { + /* TODO: compare name */ + if (jDir->version < version) + continue; + + if (jDir->version == version && inode != 0) { + /* I'm pretty sure this isn't legal */ + putstr(" ** ERROR ** "); +// putnstr(jDir->name, jDir->nsize); +// putLabeledWord(" has dup version =", version); + } + inode = jDir->ino; + version = jDir->version; + } + } + return inode; +} + +char *mkmodestr(unsigned long mode, char *str) +{ + static const char *l = "xwr"; + int mask = 1, i; + char c; + + switch (mode & S_IFMT) { + case S_IFDIR: str[0] = 'd'; break; + case S_IFBLK: str[0] = 'b'; break; + case S_IFCHR: str[0] = 'c'; break; + case S_IFIFO: str[0] = 'f'; break; + case S_IFLNK: str[0] = 'l'; break; + case S_IFSOCK: str[0] = 's'; break; + case S_IFREG: str[0] = '-'; break; + default: str[0] = '?'; + } + + for(i = 0; i < 9; i++) { + c = l[i%3]; + str[9-i] = (mode & mask)?c:'-'; + mask = mask<<1; + } + + if(mode & S_ISUID) str[3] = (mode & S_IXUSR)?'s':'S'; + if(mode & S_ISGID) str[6] = (mode & S_IXGRP)?'s':'S'; + if(mode & S_ISVTX) str[9] = (mode & S_IXOTH)?'t':'T'; + str[10] = '\0'; + return str; +} + +static inline void dump_stat(struct stat *st, const char *name) +{ + char str[20]; + char s[64], *p; + + if (st->st_mtime == (time_t)(-1)) /* some ctimes really hate -1 */ + st->st_mtime = 1; + + ctime_r(&st->st_mtime, s/*,64*/); /* newlib ctime doesn't have buflen */ + + if ((p = strchr(s,'\n')) != NULL) *p = '\0'; + if ((p = strchr(s,'\r')) != NULL) *p = '\0'; + +/* + printf("%6lo %s %8ld %s %s\n", st->st_mode, mkmodestr(st->st_mode, str), + st->st_size, s, name); +*/ + + printf(" %s %8ld %s %s", mkmodestr(st->st_mode,str), st->st_size, s, name); +} + +static inline int +dump_inode(struct b_lists *pL, struct b_dirent *d, struct b_inode *i) +{ + char fname[JFFS2_MAX_NAME_LEN + 1]; + struct stat st; + size_t len; + + if(!d || !i) return -1; + len = d->nsize; + nand_read(nand, d->offset + sizeof(struct jffs2_raw_dirent), + &len, &fname); + fname[d->nsize] = '\0'; + + memset(&st, 0, sizeof(st)); + + jffs2_1pass_read_inode(pL, i->ino, NULL, &st); + + dump_stat(&st, fname); +/* FIXME + if (d->type == DT_LNK) { + unsigned char *src = (unsigned char *) (&i[1]); + putstr(" -> "); + putnstr(src, (int)i->dsize); + } +*/ + putstr("\r\n"); + + return 0; +} + +/* list inodes with the given pino */ +static u32 +jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino) +{ + struct b_dirent *jDir; + u32 i_version = 0; + + for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) { + if ((pino == jDir->pino) && (jDir->ino)) { /* ino=0 -> unlink */ + struct b_inode *jNode = (struct b_inode *)pL->frag.listHead; + struct b_inode *i = NULL; + + while (jNode) { + if (jNode->ino == jDir->ino && jNode->version >= i_version) { + i_version = jNode->version; + i = jNode; + } + jNode = jNode->next; + } + dump_inode(pL, jDir, i); + } + } + return pino; +} + +static u32 +jffs2_1pass_search_inode(struct b_lists * pL, const char *fname, u32 pino) +{ + int i; + char tmp[256]; + char working_tmp[256]; + char *c; + + /* discard any leading slash */ + i = 0; + while (fname[i] == '/') + i++; + strcpy(tmp, &fname[i]); + + while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */ + { + strncpy(working_tmp, tmp, c - tmp); + working_tmp[c - tmp] = '\0'; +#if 0 + putstr("search_inode: tmp = "); + putstr(tmp); + putstr("\r\n"); + putstr("search_inode: wtmp = "); + putstr(working_tmp); + putstr("\r\n"); + putstr("search_inode: c = "); + putstr(c); + putstr("\r\n"); +#endif + for (i = 0; i < strlen(c) - 1; i++) + tmp[i] = c[i + 1]; + tmp[i] = '\0'; +#if 0 + putstr("search_inode: post tmp = "); + putstr(tmp); + putstr("\r\n"); +#endif + + if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino))) { + putstr("find_inode failed for name="); + putstr(working_tmp); + putstr("\r\n"); + return 0; + } + } + /* this is for the bare filename, directories have already been mapped */ + if (!(pino = jffs2_1pass_find_inode(pL, tmp, pino))) { + putstr("find_inode failed for name="); + putstr(tmp); + putstr("\r\n"); + return 0; + } + return pino; + +} + +static u32 +jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) +{ + struct b_dirent *jDir; + struct b_inode *jNode; + u8 jDirFoundType = 0; + u32 jDirFoundIno = 0; + u32 jDirFoundPino = 0; + char tmp[JFFS2_MAX_NAME_LEN + 1]; + u32 version = 0; + u32 pino; + + /* we need to search all and return the inode with the highest version */ + for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) { + if (ino == jDir->ino) { + if (jDir->version < version) + continue; + + if (jDir->version == version && jDirFoundType) { + /* I'm pretty sure this isn't legal */ + putstr(" ** ERROR ** "); +// putnstr(jDir->name, jDir->nsize); +// putLabeledWord(" has dup version (resolve) = ", +// version); + } + + jDirFoundType = jDir->type; + jDirFoundIno = jDir->ino; + jDirFoundPino = jDir->pino; + version = jDir->version; + } + } + /* now we found the right entry again. (shoulda returned inode*) */ + if (jDirFoundType != DT_LNK) + return jDirFoundIno; + + /* it's a soft link so we follow it again. */ + for (jNode = (struct b_inode *)pL->frag.listHead; jNode; jNode = jNode->next) { + if (jNode->ino == jDirFoundIno) { + size_t len = jNode->csize; + nand_read(nand, jNode->offset + sizeof(struct jffs2_raw_inode), &len, &tmp); + tmp[jNode->csize] = '\0'; + break; + } + } + /* ok so the name of the new file to find is in tmp */ + /* if it starts with a slash it is root based else shared dirs */ + if (tmp[0] == '/') + pino = 1; + else + pino = jDirFoundPino; + + return jffs2_1pass_search_inode(pL, tmp, pino); +} + +static u32 +jffs2_1pass_search_list_inodes(struct b_lists * pL, const char *fname, u32 pino) +{ + int i; + char tmp[256]; + char working_tmp[256]; + char *c; + + /* discard any leading slash */ + i = 0; + while (fname[i] == '/') + i++; + strcpy(tmp, &fname[i]); + working_tmp[0] = '\0'; + while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */ + { + strncpy(working_tmp, tmp, c - tmp); + working_tmp[c - tmp] = '\0'; + for (i = 0; i < strlen(c) - 1; i++) + tmp[i] = c[i + 1]; + tmp[i] = '\0'; + /* only a failure if we arent looking at top level */ + if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) && + (working_tmp[0])) { + putstr("find_inode failed for name="); + putstr(working_tmp); + putstr("\r\n"); + return 0; + } + } + + if (tmp[0] && !(pino = jffs2_1pass_find_inode(pL, tmp, pino))) { + putstr("find_inode failed for name="); + putstr(tmp); + putstr("\r\n"); + return 0; + } + /* this is for the bare filename, directories have already been mapped */ + if (!(pino = jffs2_1pass_list_inodes(pL, pino))) { + putstr("find_inode failed for name="); + putstr(tmp); + putstr("\r\n"); + return 0; + } + return pino; + +} + +unsigned char +jffs2_1pass_rescan_needed(struct part_info *part) +{ + struct b_node *b; + struct jffs2_unknown_node onode; + struct jffs2_unknown_node *node; + struct b_lists *pL = (struct b_lists *)part->jffs2_priv; + + if (part->jffs2_priv == 0){ + DEBUGF ("rescan: First time in use\n"); + return 1; + } + /* if we have no list, we need to rescan */ + if (pL->frag.listCount == 0) { + DEBUGF ("rescan: fraglist zero\n"); + return 1; + } + + /* or if we are scanning a new partition */ + if (pL->partOffset != part->offset) { + DEBUGF ("rescan: different partition\n"); + return 1; + } + +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) + if (nanddev != (int)part->usr_priv - 1) { + DEBUGF ("rescan: nand device changed\n"); + return -1; + } +#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ + /* FIXME */ +#if 0 + /* but suppose someone reflashed a partition at the same offset... */ + b = pL->dir.listHead; + while (b) { + node = (struct jffs2_unknown_node *) get_fl_mem(b->offset, + sizeof(onode), &onode); + if (node->nodetype != JFFS2_NODETYPE_DIRENT) { + DEBUGF ("rescan: fs changed beneath me? (%lx)\n", + (unsigned long) b->offset); + return 1; + } + b = b->next; + } +#endif + return 0; +} + +#ifdef DEBUG_FRAGMENTS +static void +dump_fragments(struct b_lists *pL) +{ + struct b_node *b; + struct jffs2_raw_inode ojNode; + struct jffs2_raw_inode *jNode; + + putstr("\r\n\r\n******The fragment Entries******\r\n"); + b = pL->frag.listHead; + while (b) { + jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, + sizeof(ojNode), &ojNode); + putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset); + putLabeledWord("\tbuild_list: totlen = ", jNode->totlen); + putLabeledWord("\tbuild_list: inode = ", jNode->ino); + putLabeledWord("\tbuild_list: version = ", jNode->version); + putLabeledWord("\tbuild_list: isize = ", jNode->isize); + putLabeledWord("\tbuild_list: atime = ", jNode->atime); + putLabeledWord("\tbuild_list: offset = ", jNode->offset); + putLabeledWord("\tbuild_list: csize = ", jNode->csize); + putLabeledWord("\tbuild_list: dsize = ", jNode->dsize); + putLabeledWord("\tbuild_list: compr = ", jNode->compr); + putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr); + putLabeledWord("\tbuild_list: flags = ", jNode->flags); + putLabeledWord("\tbuild_list: offset = ", b->offset); /* FIXME: ? [RS] */ + b = b->next; + } +} +#endif + +#ifdef DEBUG_DIRENTS +static void +dump_dirents(struct b_lists *pL) +{ + struct b_node *b; + struct jffs2_raw_dirent *jDir; + + putstr("\r\n\r\n******The directory Entries******\r\n"); + b = pL->dir.listHead; + while (b) { + jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); + putstr("\r\n"); + putnstr(jDir->name, jDir->nsize); + putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic); + putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype); + putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc); + putLabeledWord("\tbuild_list: pino = ", jDir->pino); + putLabeledWord("\tbuild_list: version = ", jDir->version); + putLabeledWord("\tbuild_list: ino = ", jDir->ino); + putLabeledWord("\tbuild_list: mctime = ", jDir->mctime); + putLabeledWord("\tbuild_list: nsize = ", jDir->nsize); + putLabeledWord("\tbuild_list: type = ", jDir->type); + putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc); + putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc); + putLabeledWord("\tbuild_list: offset = ", b->offset); /* FIXME: ? [RS] */ + b = b->next; + put_fl_mem(jDir); + } +} +#endif + +static int +jffs2_fill_scan_buf(nand_info_t *nand, unsigned char *buf, + unsigned ofs, unsigned len) +{ + int ret; + unsigned olen; + + olen = len; + ret = nand_read(nand, ofs, &olen, buf); + if (ret) { + printf("nand_read(0x%x bytes from 0x%x) returned %d\n", len, ofs, ret); + return ret; + } + if (olen < len) { + printf("Read at 0x%x gave only 0x%x bytes\n", ofs, olen); + return -1; + } + return 0; +} + +#define EMPTY_SCAN_SIZE 1024 +static u32 +jffs2_1pass_build_lists(struct part_info * part) +{ + struct b_lists *pL; + struct jffs2_unknown_node *node; + unsigned nr_blocks, sectorsize, ofs, offset; + char *buf; + int i; + u32 counter = 0; + u32 counter4 = 0; + u32 counterF = 0; + u32 counterN = 0; + +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) + nanddev = (int)part->usr_priv - 1; + nand = &nand_info[nanddev]; +#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ + + /* if we are building a list we need to refresh the cache. */ + jffs_init_1pass_list(part); + pL = (struct b_lists *)part->jffs2_priv; + pL->partOffset = part->offset; + puts ("Scanning JFFS2 FS: "); + + sectorsize = nand->erasesize; + nr_blocks = part->size / sectorsize; + buf = malloc(sectorsize); + if (!buf) + return 0; + + for (i = 0; i < nr_blocks; i++) { + printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]); + + offset = part->offset + i * sectorsize; + + if (nand_block_isbad(nand, offset)) + continue; + + if (jffs2_fill_scan_buf(nand, buf, offset, EMPTY_SCAN_SIZE)) + return 0; + + ofs = 0; + /* Scan only 4KiB of 0xFF before declaring it's empty */ + while (ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) + ofs += 4; + if (ofs == EMPTY_SCAN_SIZE) + continue; + + if (jffs2_fill_scan_buf(nand, buf + EMPTY_SCAN_SIZE, offset + EMPTY_SCAN_SIZE, sectorsize - EMPTY_SCAN_SIZE)) + return 0; + offset += ofs; + + while (ofs < sectorsize - sizeof(struct jffs2_unknown_node)) { + node = (struct jffs2_unknown_node *)&buf[ofs]; + if (node->magic != JFFS2_MAGIC_BITMASK || !hdr_crc(node)) { + offset += 4; + ofs += 4; + counter4++; + continue; + } + /* if its a fragment add it */ + if (node->nodetype == JFFS2_NODETYPE_INODE && + inode_crc((struct jffs2_raw_inode *) node)) { + if (insert_inode(&pL->frag, (struct jffs2_raw_inode *) node, + offset) == NULL) { + return 0; + } + } else if (node->nodetype == JFFS2_NODETYPE_DIRENT && + dirent_crc((struct jffs2_raw_dirent *) node) && + dirent_name_crc((struct jffs2_raw_dirent *) node)) { + if (! (counterN%100)) + puts ("\b\b. "); + if (insert_dirent(&pL->dir, (struct jffs2_raw_dirent *) node, + offset) == NULL) { + return 0; + } + counterN++; + } else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) { + if (node->totlen != sizeof(struct jffs2_unknown_node)) + printf("OOPS Cleanmarker has bad size " + "%d != %d\n", node->totlen, + sizeof(struct jffs2_unknown_node)); + } else if (node->nodetype == JFFS2_NODETYPE_PADDING) { + if (node->totlen < sizeof(struct jffs2_unknown_node)) + printf("OOPS Padding has bad size " + "%d < %d\n", node->totlen, + sizeof(struct jffs2_unknown_node)); + } else { + printf("Unknown node type: %x len %d " + "offset 0x%x\n", node->nodetype, + node->totlen, offset); + } + offset += ((node->totlen + 3) & ~3); + ofs += ((node->totlen + 3) & ~3); + counterF++; + } + } + + putstr("\b\b done.\r\n"); /* close off the dots */ + +#if 0 + putLabeledWord("dir entries = ", pL->dir.listCount); + putLabeledWord("frag entries = ", pL->frag.listCount); + putLabeledWord("+4 increments = ", counter4); + putLabeledWord("+file_offset increments = ", counterF); +#endif + +#ifdef DEBUG_DIRENTS + dump_dirents(pL); +#endif + +#ifdef DEBUG_FRAGMENTS + dump_fragments(pL); +#endif + + /* give visual feedback that we are done scanning the flash */ + led_blink(0x0, 0x0, 0x1, 0x1); /* off, forever, on 100ms, off 100ms */ + free(buf); + + return 1; +} + + +static u32 +jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL) +{ + struct b_node *b; + struct jffs2_raw_inode ojNode; + struct jffs2_raw_inode *jNode; + int i; + + for (i = 0; i < JFFS2_NUM_COMPR; i++) { + piL->compr_info[i].num_frags = 0; + piL->compr_info[i].compr_sum = 0; + piL->compr_info[i].decompr_sum = 0; + } +/* FIXME + b = pL->frag.listHead; + while (b) { + jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, + sizeof(ojNode), &ojNode); + if (jNode->compr < JFFS2_NUM_COMPR) { + piL->compr_info[jNode->compr].num_frags++; + piL->compr_info[jNode->compr].compr_sum += jNode->csize; + piL->compr_info[jNode->compr].decompr_sum += jNode->dsize; + } + b = b->next; + } +*/ + return 0; +} + + +static struct b_lists * +jffs2_get_list(struct part_info * part, const char *who) +{ + if (jffs2_1pass_rescan_needed(part)) { + if (!jffs2_1pass_build_lists(part)) { + printf("%s: Failed to scan JFFSv2 file structure\n", who); + return NULL; + } + } + return (struct b_lists *)part->jffs2_priv; +} + + +/* Print directory / file contents */ +u32 +jffs2_1pass_ls(struct part_info * part, const char *fname) +{ + struct b_lists *pl; + long ret = 0; + u32 inode; + + if (! (pl = jffs2_get_list(part, "ls"))) + return 0; + + if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) { + putstr("ls: Failed to scan jffs2 file structure\r\n"); + return 0; + } + +#if 0 + putLabeledWord("found file at inode = ", inode); + putLabeledWord("read_inode returns = ", ret); +#endif + + return ret; +} + + +/* Load a file from flash into memory. fname can be a full path */ +u32 +jffs2_1pass_load(char *dest, struct part_info * part, const char *fname) +{ + + struct b_lists *pl; + long ret = 0; + u32 inode; + + if (! (pl = jffs2_get_list(part, "load"))) + return 0; + + if (! (inode = jffs2_1pass_search_inode(pl, fname, 1))) { + putstr("load: Failed to find inode\r\n"); + return 0; + } + + /* Resolve symlinks */ + if (! (inode = jffs2_1pass_resolve_inode(pl, inode))) { + putstr("load: Failed to resolve inode structure\r\n"); + return 0; + } + + if ((ret = jffs2_1pass_read_inode(pl, inode, dest, NULL)) < 0) { + putstr("load: Failed to read inode\r\n"); + return 0; + } + + DEBUGF ("load: loaded '%s' to 0x%lx (%ld bytes)\n", fname, + (unsigned long) dest, ret); + return ret; +} + +/* Return information about the fs on this partition */ +u32 +jffs2_1pass_info(struct part_info * part) +{ + struct b_jffs2_info info; + struct b_lists *pl; + int i; + + if (! (pl = jffs2_get_list(part, "info"))) + return 0; + + jffs2_1pass_fill_info(pl, &info); + for (i = 0; i < JFFS2_NUM_COMPR; i++) { + printf ("Compression: %s\n" + "\tfrag count: %d\n" + "\tcompressed sum: %d\n" + "\tuncompressed sum: %d\n", + compr_names[i], + info.compr_info[i].num_frags, + info.compr_info[i].compr_sum, + info.compr_info[i].decompr_sum); + } + return 1; +} + +#endif /* CFG_CMD_JFFS2 */ diff --git a/fs/jffs2/jffs2_nand_private.h b/fs/jffs2/jffs2_nand_private.h new file mode 100644 index 0000000000..18cca8d076 --- /dev/null +++ b/fs/jffs2/jffs2_nand_private.h @@ -0,0 +1,133 @@ +#ifndef jffs2_private_h +#define jffs2_private_h + +#include + +struct b_node { + struct b_node *next; +}; + +struct b_inode { + struct b_inode *next; + u32 offset; /* physical offset to beginning of real inode */ + u32 version; + u32 ino; + u32 isize; + u32 csize; +}; + +struct b_dirent { + struct b_dirent *next; + u32 offset; /* physical offset to beginning of real dirent */ + u32 version; + u32 pino; + u32 ino; + unsigned int nhash; + unsigned char nsize; + unsigned char type; +}; + +struct b_list { + struct b_node *listTail; + struct b_node *listHead; + unsigned int listCount; + struct mem_block *listMemBase; +}; + +struct b_lists { + char *partOffset; + struct b_list dir; + struct b_list frag; +}; + +struct b_compr_info { + u32 num_frags; + u32 compr_sum; + u32 decompr_sum; +}; + +struct b_jffs2_info { + struct b_compr_info compr_info[JFFS2_NUM_COMPR]; +}; + +static inline int +hdr_crc(struct jffs2_unknown_node *node) +{ +#if 1 + u32 crc = crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); +#else + /* what's the semantics of this? why is this here? */ + u32 crc = crc32_no_comp(~0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); + + crc ^= ~0; +#endif + if (node->hdr_crc != crc) { + return 0; + } else { + return 1; + } +} + +static inline int +dirent_crc(struct jffs2_raw_dirent *node) +{ + if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_dirent) - 8)) { + return 0; + } else { + return 1; + } +} + +static inline int +dirent_name_crc(struct jffs2_raw_dirent *node) +{ + if (node->name_crc != crc32_no_comp(0, (unsigned char *)&(node->name), node->nsize)) { + return 0; + } else { + return 1; + } +} + +static inline int +inode_crc(struct jffs2_raw_inode *node) +{ + if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_inode) - 8)) { + return 0; + } else { + return 1; + } +} + +/* Borrowed from include/linux/dcache.h */ + +/* Name hashing routines. Initial hash value */ +/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */ +#define init_name_hash() 0 + +/* partial hash update function. Assume roughly 4 bits per character */ +static inline unsigned long +partial_name_hash(unsigned long c, unsigned long prevhash) +{ + return (prevhash + (c << 4) + (c >> 4)) * 11; +} + +/* + * Finally: cut down the number of bits to a int value (and try to avoid + * losing bits) + */ +static inline unsigned long end_name_hash(unsigned long hash) +{ + return (unsigned int) hash; +} + +/* Compute the hash for a name string. */ +static inline unsigned int +full_name_hash(const unsigned char *name, unsigned int len) +{ + unsigned long hash = init_name_hash(); + while (len--) + hash = partial_name_hash(*name++, hash); + return end_name_hash(hash); +} + +#endif /* jffs2_private.h */ diff --git a/include/linux/mtd/compat.h b/include/linux/mtd/compat.h new file mode 100644 index 0000000000..460cd45c80 --- /dev/null +++ b/include/linux/mtd/compat.h @@ -0,0 +1,44 @@ +#ifndef _LINUX_COMPAT_H_ +#define _LINUX_COMPAT_H_ + +#define __user +#define __iomem + +#define ndelay(x) udelay(1) + +#define printk printf + +#define KERN_EMERG +#define KERN_ALERT +#define KERN_CRIT +#define KERN_ERR +#define KERN_WARNING +#define KERN_NOTICE +#define KERN_INFO +#define KERN_DEBUG + +#define kmalloc(size, flags) malloc(size) +#define kfree(ptr) free(ptr) + +/* + * ..and if you can't take the strict + * types, you can specify one yourself. + * + * Or not use min/max at all, of course. + */ +#define min_t(type,x,y) \ + ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) +#define max_t(type,x,y) \ + ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) + +#define BUG() do { \ + printf("U-Boot BUG at %s:%d!\n", __FILE__, __LINE__); \ +} while (0) + +#define BUG_ON(condition) do { if (condition) BUG(); } while(0) + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + +#define PAGE_SIZE 4096 +#endif diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h new file mode 100644 index 0000000000..afe96b59cb --- /dev/null +++ b/include/linux/mtd/mtd-abi.h @@ -0,0 +1,99 @@ +/* + * $Id: mtd-abi.h,v 1.7 2004/11/23 15:37:32 gleixner Exp $ + * + * Portions of MTD ABI definition which are shared by kernel and user space + */ + +#ifndef __MTD_ABI_H__ +#define __MTD_ABI_H__ + +struct erase_info_user { + uint32_t start; + uint32_t length; +}; + +struct mtd_oob_buf { + uint32_t start; + uint32_t length; + unsigned char *ptr; +}; + +#define MTD_ABSENT 0 +#define MTD_RAM 1 +#define MTD_ROM 2 +#define MTD_NORFLASH 3 +#define MTD_NANDFLASH 4 +#define MTD_PEROM 5 +#define MTD_OTHER 14 +#define MTD_UNKNOWN 15 + +#define MTD_CLEAR_BITS 1 // Bits can be cleared (flash) +#define MTD_SET_BITS 2 // Bits can be set +#define MTD_ERASEABLE 4 // Has an erase function +#define MTD_WRITEB_WRITEABLE 8 // Direct IO is possible +#define MTD_VOLATILE 16 // Set for RAMs +#define MTD_XIP 32 // eXecute-In-Place possible +#define MTD_OOB 64 // Out-of-band data (NAND flash) +#define MTD_ECC 128 // Device capable of automatic ECC +#define MTD_NO_VIRTBLOCKS 256 // Virtual blocks not allowed + +// Some common devices / combinations of capabilities +#define MTD_CAP_ROM 0 +#define MTD_CAP_RAM (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE) +#define MTD_CAP_NORFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE) +#define MTD_CAP_NANDFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB) +#define MTD_WRITEABLE (MTD_CLEAR_BITS|MTD_SET_BITS) + + +// Types of automatic ECC/Checksum available +#define MTD_ECC_NONE 0 // No automatic ECC available +#define MTD_ECC_RS_DiskOnChip 1 // Automatic ECC on DiskOnChip +#define MTD_ECC_SW 2 // SW ECC for Toshiba & Samsung devices + +/* ECC byte placement */ +#define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended) +#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode) +#define MTD_NANDECC_AUTOPLACE 2 // Use the default placement scheme +#define MTD_NANDECC_PLACEONLY 3 // Use the given placement in the structure (Do not store ecc result on read) +#define MTD_NANDECC_AUTOPL_USR 4 // Use the given autoplacement scheme rather than using the default + +struct mtd_info_user { + uint8_t type; + uint32_t flags; + uint32_t size; // Total size of the MTD + uint32_t erasesize; + uint32_t oobblock; // Size of OOB blocks (e.g. 512) + uint32_t oobsize; // Amount of OOB data per block (e.g. 16) + uint32_t ecctype; + uint32_t eccsize; +}; + +struct region_info_user { + uint32_t offset; /* At which this region starts, + * from the beginning of the MTD */ + uint32_t erasesize; /* For this region */ + uint32_t numblocks; /* Number of blocks in this region */ + uint32_t regionindex; +}; + +#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) +#define MEMERASE _IOW('M', 2, struct erase_info_user) +#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) +#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) +#define MEMLOCK _IOW('M', 5, struct erase_info_user) +#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) +#define MEMGETREGIONCOUNT _IOR('M', 7, int) +#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) +#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) +#define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo) +#define MEMGETBADBLOCK _IOW('M', 11, loff_t) +#define MEMSETBADBLOCK _IOW('M', 12, loff_t) + +struct nand_oobinfo { + uint32_t useecc; + uint32_t eccbytes; + uint32_t oobfree[8][2]; + uint32_t eccpos[32]; +}; + +#endif /* __MTD_ABI_H__ */ diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h new file mode 100644 index 0000000000..9ef4cced5e --- /dev/null +++ b/include/linux/mtd/mtd.h @@ -0,0 +1,214 @@ +/* + * $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $ + * + * Copyright (C) 1999-2003 David Woodhouse et al. + * + * Released under GPL + */ + +#ifndef __MTD_MTD_H__ +#define __MTD_MTD_H__ +#include +#include + +#define MAX_MTD_DEVICES 16 + +#define MTD_ERASE_PENDING 0x01 +#define MTD_ERASING 0x02 +#define MTD_ERASE_SUSPEND 0x04 +#define MTD_ERASE_DONE 0x08 +#define MTD_ERASE_FAILED 0x10 + +/* If the erase fails, fail_addr might indicate exactly which block failed. If + fail_addr = 0xffffffff, the failure was not at the device level or was not + specific to any particular block. */ +struct erase_info { + struct mtd_info *mtd; + u_int32_t addr; + u_int32_t len; + u_int32_t fail_addr; + u_long time; + u_long retries; + u_int dev; + u_int cell; + void (*callback) (struct erase_info *self); + u_long priv; + u_char state; + struct erase_info *next; +}; + +struct mtd_erase_region_info { + u_int32_t offset; /* At which this region starts, from the beginning of the MTD */ + u_int32_t erasesize; /* For this region */ + u_int32_t numblocks; /* Number of blocks of erasesize in this region */ +}; + +struct mtd_info { + u_char type; + u_int32_t flags; + u_int32_t size; // Total size of the MTD + + /* "Major" erase size for the device. Naïve users may take this + * to be the only erase size available, or may use the more detailed + * information below if they desire + */ + u_int32_t erasesize; + + u_int32_t oobblock; // Size of OOB blocks (e.g. 512) + u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) + u_int32_t oobavail; // Number of bytes in OOB area available for fs + u_int32_t ecctype; + u_int32_t eccsize; + + + // Kernel-only stuff starts here. + char *name; + int index; + + // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) + struct nand_oobinfo oobinfo; + + /* Data for variable erase regions. If numeraseregions is zero, + * it means that the whole device has erasesize as given above. + */ + int numeraseregions; + struct mtd_erase_region_info *eraseregions; + + /* This really shouldn't be here. It can go away in 2.5 */ + u_int32_t bank_size; + + int (*erase) (struct mtd_info *mtd, struct erase_info *instr); + + /* This stuff for eXecute-In-Place */ + int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); + + /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ + void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len); + + + int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); + + int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); + int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); + + int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); + + /* + * Methods to access the protection register area, present in some + * flash devices. The user data is one time programmable but the + * factory data is read only. + */ + int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + + int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + + /* This function is not yet implemented */ + int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); +#if 0 + /* kvec-based read/write methods. We need these especially for NAND flash, + with its limited number of write cycles per erase. + NB: The 'count' parameter is the number of _vectors_, each of + which contains an (ofs, len) tuple. + */ + int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); + int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, + size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); + int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); + int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, + size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); +#endif + /* Sync */ + void (*sync) (struct mtd_info *mtd); +#if 0 + /* Chip-supported device locking */ + int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); + int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); + + /* Power Management functions */ + int (*suspend) (struct mtd_info *mtd); + void (*resume) (struct mtd_info *mtd); +#endif + /* Bad block management functions */ + int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); + int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); + + void *priv; + + struct module *owner; + int usecount; +}; + + + /* Kernel-side ioctl definitions */ + +extern int add_mtd_device(struct mtd_info *mtd); +extern int del_mtd_device (struct mtd_info *mtd); + +extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); + +extern void put_mtd_device(struct mtd_info *mtd); + +#if 0 +struct mtd_notifier { + void (*add)(struct mtd_info *mtd); + void (*remove)(struct mtd_info *mtd); + struct list_head list; +}; + + +extern void register_mtd_user (struct mtd_notifier *new); +extern int unregister_mtd_user (struct mtd_notifier *old); + +int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, + unsigned long count, loff_t to, size_t *retlen); + +int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, + unsigned long count, loff_t from, size_t *retlen); +#endif + +#define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args) +#define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d)) +#define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg) +#define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args) +#define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args) +#define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args) +#define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args) +#define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args) +#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) +#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) +#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) +#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) + + +#ifdef CONFIG_MTD_PARTITIONS +void mtd_erase_callback(struct erase_info *instr); +#else +static inline void mtd_erase_callback(struct erase_info *instr) +{ + if (instr->callback) + instr->callback(instr); +} +#endif + +/* + * Debugging macro and defines + */ +#define MTD_DEBUG_LEVEL0 (0) /* Quiet */ +#define MTD_DEBUG_LEVEL1 (1) /* Audible */ +#define MTD_DEBUG_LEVEL2 (2) /* Loud */ +#define MTD_DEBUG_LEVEL3 (3) /* Noisy */ + +#ifdef CONFIG_MTD_DEBUG +#define DEBUG(n, args...) \ + do { \ + if (n <= CONFIG_MTD_DEBUG_VERBOSE) \ + printk(KERN_INFO args); \ + } while(0) +#else /* CONFIG_MTD_DEBUG */ +#define DEBUG(n, args...) do { } while(0) + +#endif /* CONFIG_MTD_DEBUG */ + +#endif /* __MTD_MTD_H__ */ diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 5236904959..9a0108f78c 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -2,10 +2,10 @@ * linux/include/linux/mtd/nand.h * * Copyright (c) 2000 David Woodhouse - * Steven J. Hill - * Thomas Gleixner + * Steven J. Hill + * Thomas Gleixner * - * $Id: nand.h,v 1.7 2003/07/24 23:30:46 a0384864 Exp $ + * $Id: nand.h,v 1.68 2004/11/12 10:40:37 gleixner Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -24,7 +24,7 @@ * bat later if I did something naughty. * 10-11-2000 SJH Added private NAND flash structure for driver * 10-24-2000 SJH Added prototype for 'nand_scan' function - * 10-29-2001 TG changed nand_chip structure to support + * 10-29-2001 TG changed nand_chip structure to support * hardwarespecific function for accessing control lines * 02-21-2002 TG added support for different read/write adress and * ready/busy line access function @@ -32,10 +32,68 @@ * command delay times for different chips * 04-28-2002 TG OOB config defines moved from nand.c to avoid duplicate * defines in jffs2/wbuf.c + * 08-07-2002 TG forced bad block location to byte 5 of OOB, even if + * CONFIG_MTD_NAND_ECC_JFFS2 is not set + * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC + * + * 08-29-2002 tglx nand_chip structure: data_poi for selecting + * internal / fs-driver buffer + * support for 6byte/512byte hardware ECC + * read_ecc, write_ecc extended for different oob-layout + * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB, + * NAND_YAFFS_OOB + * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL + * Split manufacturer and device ID structures + * + * 02-08-2004 tglx added option field to nand structure for chip anomalities + * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id + * update of nand_chip structure description */ #ifndef __LINUX_MTD_NAND_H #define __LINUX_MTD_NAND_H +#include +#include + +struct mtd_info; +/* Scan and identify a NAND device */ +extern int nand_scan (struct mtd_info *mtd, int max_chips); +/* Free resources held by the NAND device */ +extern void nand_release (struct mtd_info *mtd); + +/* Read raw data from the device without ECC */ +extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen); + + +/* The maximum number of NAND chips in an array */ +#define NAND_MAX_CHIPS 8 + +/* This constant declares the max. oobsize / page, which + * is supported now. If you add a chip with bigger oobsize/page + * adjust this accordingly. + */ +#define NAND_MAX_OOBSIZE 64 + +/* + * Constants for hardware specific CLE/ALE/NCE function +*/ +/* Select the chip by setting nCE to low */ +#define NAND_CTL_SETNCE 1 +/* Deselect the chip by setting nCE to high */ +#define NAND_CTL_CLRNCE 2 +/* Select the command latch by setting CLE to high */ +#define NAND_CTL_SETCLE 3 +/* Deselect the command latch by setting CLE to low */ +#define NAND_CTL_CLRCLE 4 +/* Select the address latch by setting ALE to high */ +#define NAND_CTL_SETALE 5 +/* Deselect the address latch by setting ALE to low */ +#define NAND_CTL_CLRALE 6 +/* Set write protection by setting WP to high. Not used! */ +#define NAND_CTL_SETWP 7 +/* Clear write protection by setting WP to low. Not used! */ +#define NAND_CTL_CLRWP 8 + /* * Standard NAND flash commands */ @@ -45,12 +103,104 @@ #define NAND_CMD_READOOB 0x50 #define NAND_CMD_ERASE1 0x60 #define NAND_CMD_STATUS 0x70 +#define NAND_CMD_STATUS_MULTI 0x71 #define NAND_CMD_SEQIN 0x80 #define NAND_CMD_READID 0x90 #define NAND_CMD_ERASE2 0xd0 #define NAND_CMD_RESET 0xff +/* Extended commands for large page devices */ +#define NAND_CMD_READSTART 0x30 +#define NAND_CMD_CACHEDPROG 0x15 + +/* Status bits */ +#define NAND_STATUS_FAIL 0x01 +#define NAND_STATUS_FAIL_N1 0x02 +#define NAND_STATUS_TRUE_READY 0x20 +#define NAND_STATUS_READY 0x40 +#define NAND_STATUS_WP 0x80 + +/* + * Constants for ECC_MODES + */ + +/* No ECC. Usage is not recommended ! */ +#define NAND_ECC_NONE 0 +/* Software ECC 3 byte ECC per 256 Byte data */ +#define NAND_ECC_SOFT 1 +/* Hardware ECC 3 byte ECC per 256 Byte data */ +#define NAND_ECC_HW3_256 2 +/* Hardware ECC 3 byte ECC per 512 Byte data */ +#define NAND_ECC_HW3_512 3 +/* Hardware ECC 3 byte ECC per 512 Byte data */ +#define NAND_ECC_HW6_512 4 +/* Hardware ECC 8 byte ECC per 512 Byte data */ +#define NAND_ECC_HW8_512 6 +/* Hardware ECC 12 byte ECC per 2048 Byte data */ +#define NAND_ECC_HW12_2048 7 + /* + * Constants for Hardware ECC +*/ +/* Reset Hardware ECC for read */ +#define NAND_ECC_READ 0 +/* Reset Hardware ECC for write */ +#define NAND_ECC_WRITE 1 +/* Enable Hardware ECC before syndrom is read back from flash */ +#define NAND_ECC_READSYN 2 + +/* Option constants for bizarre disfunctionality and real +* features +*/ +/* Chip can not auto increment pages */ +#define NAND_NO_AUTOINCR 0x00000001 +/* Buswitdh is 16 bit */ +#define NAND_BUSWIDTH_16 0x00000002 +/* Device supports partial programming without padding */ +#define NAND_NO_PADDING 0x00000004 +/* Chip has cache program function */ +#define NAND_CACHEPRG 0x00000008 +/* Chip has copy back function */ +#define NAND_COPYBACK 0x00000010 +/* AND Chip which has 4 banks and a confusing page / block + * assignment. See Renesas datasheet for further information */ +#define NAND_IS_AND 0x00000020 +/* Chip has a array of 4 pages which can be read without + * additional ready /busy waits */ +#define NAND_4PAGE_ARRAY 0x00000040 + +/* Options valid for Samsung large page devices */ +#define NAND_SAMSUNG_LP_OPTIONS \ + (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK) + +/* Macros to identify the above */ +#define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR)) +#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING)) +#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) +#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK)) + +/* Mask to zero out the chip options, which come from the id table */ +#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR) + +/* Non chip related options */ +/* Use a flash based bad block table. This option is passed to the + * default bad block table function. */ +#define NAND_USE_FLASH_BBT 0x00010000 +/* The hw ecc generator provides a syndrome instead a ecc value on read + * This can only work if we have the ecc bytes directly behind the + * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ +#define NAND_HWECC_SYNDROME 0x00020000 + + +/* Options set by nand scan */ +/* Nand scan has allocated oob_buf */ +#define NAND_OOBBUF_ALLOC 0x40000000 +/* Nand scan has allocated data_buf */ +#define NAND_DATABUF_ALLOC 0x80000000 + + +/* + * nand_state_t - chip states * Enumeration for NAND flash chip state */ typedef enum { @@ -58,71 +208,138 @@ typedef enum { FL_READING, FL_WRITING, FL_ERASING, - FL_SYNCING + FL_SYNCING, + FL_CACHEDPRG, } nand_state_t; +/* Keep gcc happy */ +struct nand_chip; -/* - * NAND Private Flash Chip Data - * - * Structure overview: - * - * IO_ADDR - address to access the 8 I/O lines of the flash device - * - * hwcontrol - hardwarespecific function for accesing control-lines - * - * dev_ready - hardwarespecific function for accesing device ready/busy line - * - * chip_lock - spinlock used to protect access to this structure - * - * wq - wait queue to sleep on if a NAND operation is in progress - * - * state - give the current state of the NAND device - * - * page_shift - number of address bits in a page (column address bits) - * - * data_buf - data buffer passed to/from MTD user modules - * - * data_cache - data cache for redundant page access and shadow for - * ECC failure - * - * ecc_code_buf - used only for holding calculated or read ECCs for - * a page read or written when ECC is in use - * - * reserved - padding to make structure fall on word boundary if - * when ECC is in use +#if 0 +/** + * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices + * @lock: protection lock + * @active: the mtd device which holds the controller currently */ -struct Nand { - char floor, chip; - unsigned long curadr; - unsigned char curmode; - /* Also some erase/write/pipeline info when we get that far */ +struct nand_hw_control { + spinlock_t lock; + struct nand_chip *active; }; +#endif +/** + * struct nand_chip - NAND Private Flash Chip Data + * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device + * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device + * @read_byte: [REPLACEABLE] read one byte from the chip + * @write_byte: [REPLACEABLE] write one byte to the chip + * @read_word: [REPLACEABLE] read one word from the chip + * @write_word: [REPLACEABLE] write one word to the chip + * @write_buf: [REPLACEABLE] write data from the buffer to the chip + * @read_buf: [REPLACEABLE] read data from the chip into the buffer + * @verify_buf: [REPLACEABLE] verify buffer contents against the chip data + * @select_chip: [REPLACEABLE] select chip nr + * @block_bad: [REPLACEABLE] check, if the block is bad + * @block_markbad: [REPLACEABLE] mark the block bad + * @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines + * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line + * If set to NULL no access to ready/busy is available and the ready/busy information + * is read from the chip status register + * @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip + * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready + * @calculate_ecc: [REPLACEABLE] function for ecc calculation or readback from ecc hardware + * @correct_data: [REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw) + * @enable_hwecc: [BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only + * be provided if a hardware ECC is available + * @erase_cmd: [INTERN] erase command write function, selectable due to AND support + * @scan_bbt: [REPLACEABLE] function to scan bad block table + * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines + * @eccsize: [INTERN] databytes used per ecc-calculation + * @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step + * @eccsteps: [INTERN] number of ecc calculation steps per page + * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR) + * @chip_lock: [INTERN] spinlock used to protect access to this structure and the chip + * @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress + * @state: [INTERN] the current state of the NAND device + * @page_shift: [INTERN] number of address bits in a page (column address bits) + * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock + * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry + * @chip_shift: [INTERN] number of address bits in one chip + * @data_buf: [INTERN] internal buffer for one page + oob + * @oob_buf: [INTERN] oob buffer for one eraseblock + * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized + * @data_poi: [INTERN] pointer to a data buffer + * @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about + * special functionality. See the defines for further explanation + * @badblockpos: [INTERN] position of the bad block marker in the oob area + * @numchips: [INTERN] number of physical chips + * @chipsize: [INTERN] the size of one chip for multichip arrays + * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 + * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf + * @autooob: [REPLACEABLE] the default (auto)placement scheme + * @bbt: [INTERN] bad block table pointer + * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup + * @bbt_md: [REPLACEABLE] bad block table mirror descriptor + * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan + * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices + * @priv: [OPTIONAL] pointer to private chip date + */ + struct nand_chip { + void __iomem *IO_ADDR_R; + void __iomem *IO_ADDR_W; + + u_char (*read_byte)(struct mtd_info *mtd); + void (*write_byte)(struct mtd_info *mtd, u_char byte); + u16 (*read_word)(struct mtd_info *mtd); + void (*write_word)(struct mtd_info *mtd, u16 word); + + void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); + void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len); + int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len); + void (*select_chip)(struct mtd_info *mtd, int chip); + int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); + int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); + void (*hwcontrol)(struct mtd_info *mtd, int cmd); + int (*dev_ready)(struct mtd_info *mtd); + void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); + int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); + int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); + int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); + void (*enable_hwecc)(struct mtd_info *mtd, int mode); + void (*erase_cmd)(struct mtd_info *mtd, int page); + int (*scan_bbt)(struct mtd_info *mtd); + int eccmode; + int eccsize; + int eccbytes; + int eccsteps; + int chip_delay; +#if 0 + spinlock_t chip_lock; + wait_queue_head_t wq; + nand_state_t state; +#endif int page_shift; + int phys_erase_shift; + int bbt_erase_shift; + int chip_shift; u_char *data_buf; - u_char *data_cache; - int cache_page; - u_char ecc_code_buf[6]; - u_char reserved[2]; - char ChipID; /* Type of DiskOnChip */ - struct Nand *chips; - int chipshift; - char* chips_name; - unsigned long erasesize; - unsigned long mfr; /* Flash IDs - only one type of flash per device */ - unsigned long id; - char* name; - int numchips; - char page256; - char pageadrlen; - unsigned long IO_ADDR; /* address to access the 8 I/O lines to the flash device */ - unsigned long totlen; - uint oobblock; /* Size of OOB blocks (e.g. 512) */ - uint oobsize; /* Amount of OOB data per block (e.g. 16) */ - uint eccsize; - int bus16; + u_char *oob_buf; + int oobdirty; + u_char *data_poi; + unsigned int options; + int badblockpos; + int numchips; + unsigned long chipsize; + int pagemask; + int pagebuf; + struct nand_oobinfo *autooob; + uint8_t *bbt; + struct nand_bbt_descr *bbt_td; + struct nand_bbt_descr *bbt_md; + struct nand_bbt_descr *badblock_pattern; + struct nand_hw_control *controller; + void *priv; }; /* @@ -130,71 +347,125 @@ struct nand_chip { */ #define NAND_MFR_TOSHIBA 0x98 #define NAND_MFR_SAMSUNG 0xec +#define NAND_MFR_FUJITSU 0x04 +#define NAND_MFR_NATIONAL 0x8f +#define NAND_MFR_RENESAS 0x07 +#define NAND_MFR_STMICRO 0x20 -/* - * NAND Flash Device ID Structure +/** + * struct nand_flash_dev - NAND Flash Device ID Structure * - * Structure overview: - * - * name - Complete name of device - * - * manufacture_id - manufacturer ID code of device. - * - * model_id - model ID code of device. - * - * chipshift - total number of address bits for the device which - * is used to calculate address offsets and the total - * number of bytes the device is capable of. - * - * page256 - denotes if flash device has 256 byte pages or not. - * - * pageadrlen - number of bytes minus one needed to hold the - * complete address into the flash array. Keep in - * mind that when a read or write is done to a - * specific address, the address is input serially - * 8 bits at a time. This structure member is used - * by the read/write routines as a loop index for - * shifting the address out 8 bits at a time. - * - * erasesize - size of an erase block in the flash device. + * @name: Identify the device type + * @id: device ID code + * @pagesize: Pagesize in bytes. Either 256 or 512 or 0 + * If the pagesize is 0, then the real pagesize + * and the eraseize are determined from the + * extended id bytes in the chip + * @erasesize: Size of an erase block in the flash device. + * @chipsize: Total chipsize in Mega Bytes + * @options: Bitfield to store chip relevant options */ struct nand_flash_dev { - char * name; - int manufacture_id; - int model_id; - int chipshift; - char page256; - char pageadrlen; + char *name; + int id; + unsigned long pagesize; + unsigned long chipsize; unsigned long erasesize; - int bus16; + unsigned long options; }; +/** + * struct nand_manufacturers - NAND Flash Manufacturer ID Structure + * @name: Manufacturer name + * @id: manufacturer ID code of device. +*/ +struct nand_manufacturers { + int id; + char * name; +}; + +extern struct nand_flash_dev nand_flash_ids[]; +extern struct nand_manufacturers nand_manuf_ids[]; + +/** + * struct nand_bbt_descr - bad block table descriptor + * @options: options for this descriptor + * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE + * when bbt is searched, then we store the found bbts pages here. + * Its an array and supports up to 8 chips now + * @offs: offset of the pattern in the oob area of the page + * @veroffs: offset of the bbt version counter in the oob are of the page + * @version: version read from the bbt page during scan + * @len: length of the pattern, if 0 no pattern check is performed + * @maxblocks: maximum number of blocks to search for a bbt. This number of + * blocks is reserved at the end of the device where the tables are + * written. + * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than + * bad) block in the stored bbt + * @pattern: pattern to identify bad block table or factory marked good / + * bad blocks, can be NULL, if len = 0 + * + * Descriptor for the bad block table marker and the descriptor for the + * pattern which identifies good and bad blocks. The assumption is made + * that the pattern and the version count are always located in the oob area + * of the first block. + */ +struct nand_bbt_descr { + int options; + int pages[NAND_MAX_CHIPS]; + int offs; + int veroffs; + uint8_t version[NAND_MAX_CHIPS]; + int len; + int maxblocks; + int reserved_block_code; + uint8_t *pattern; +}; + +/* Options for the bad block table descriptors */ + +/* The number of bits used per block in the bbt on the device */ +#define NAND_BBT_NRBITS_MSK 0x0000000F +#define NAND_BBT_1BIT 0x00000001 +#define NAND_BBT_2BIT 0x00000002 +#define NAND_BBT_4BIT 0x00000004 +#define NAND_BBT_8BIT 0x00000008 +/* The bad block table is in the last good block of the device */ +#define NAND_BBT_LASTBLOCK 0x00000010 +/* The bbt is at the given page, else we must scan for the bbt */ +#define NAND_BBT_ABSPAGE 0x00000020 +/* The bbt is at the given page, else we must scan for the bbt */ +#define NAND_BBT_SEARCH 0x00000040 +/* bbt is stored per chip on multichip devices */ +#define NAND_BBT_PERCHIP 0x00000080 +/* bbt has a version counter at offset veroffs */ +#define NAND_BBT_VERSION 0x00000100 +/* Create a bbt if none axists */ +#define NAND_BBT_CREATE 0x00000200 +/* Search good / bad pattern through all pages of a block */ +#define NAND_BBT_SCANALLPAGES 0x00000400 +/* Scan block empty during good / bad block scan */ +#define NAND_BBT_SCANEMPTY 0x00000800 +/* Write bbt if neccecary */ +#define NAND_BBT_WRITE 0x00001000 +/* Read and write back block contents when writing bbt */ +#define NAND_BBT_SAVECONTENT 0x00002000 +/* Search good / bad pattern on the first and the second page */ +#define NAND_BBT_SCAN2NDPAGE 0x00004000 + +/* The maximum number of blocks to scan for a bbt */ +#define NAND_BBT_SCAN_MAXBLOCKS 4 + +extern int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd); +extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs); +extern int nand_default_bbt (struct mtd_info *mtd); +extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt); +extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt); + /* * Constants for oob configuration */ -#define NAND_NOOB_ECCPOS0 0 -#define NAND_NOOB_ECCPOS1 1 -#define NAND_NOOB_ECCPOS2 2 -#define NAND_NOOB_ECCPOS3 3 -#define NAND_NOOB_ECCPOS4 6 -#define NAND_NOOB_ECCPOS5 7 -#define NAND_NOOB_BADBPOS -1 -#define NAND_NOOB_ECCVPOS -1 - -#define NAND_JFFS2_OOB_ECCPOS0 0 -#define NAND_JFFS2_OOB_ECCPOS1 1 -#define NAND_JFFS2_OOB_ECCPOS2 2 -#define NAND_JFFS2_OOB_ECCPOS3 3 -#define NAND_JFFS2_OOB_ECCPOS4 6 -#define NAND_JFFS2_OOB_ECCPOS5 7 -#define NAND_JFFS2_OOB_BADBPOS 5 -#define NAND_JFFS2_OOB_ECCVPOS 4 - -#define NAND_JFFS2_OOB8_FSDAPOS 6 -#define NAND_JFFS2_OOB16_FSDAPOS 8 -#define NAND_JFFS2_OOB8_FSDALEN 2 -#define NAND_JFFS2_OOB16_FSDALEN 8 - -unsigned long nand_probe(unsigned long physadr); +#define NAND_SMALL_BADBLOCK_POS 5 +#define NAND_LARGE_BADBLOCK_POS 0 #endif /* __LINUX_MTD_NAND_H */ diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h new file mode 100644 index 0000000000..12c5bc342e --- /dev/null +++ b/include/linux/mtd/nand_ecc.h @@ -0,0 +1,30 @@ +/* + * drivers/mtd/nand_ecc.h + * + * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) + * + * $Id: nand_ecc.h,v 1.4 2004/06/17 02:35:02 dbrown Exp $ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file is the header for the ECC algorithm. + */ + +#ifndef __MTD_NAND_ECC_H__ +#define __MTD_NAND_ECC_H__ + +struct mtd_info; + +/* + * Calculate 3 byte ECC code for 256 byte block + */ +int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); + +/* + * Detect and correct a 1 bit error for 256 byte block + */ +int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); + +#endif /* __MTD_NAND_ECC_H__ */ diff --git a/include/linux/mtd/nand_ids.h b/include/linux/mtd/nand_ids.h index a3d0363a2a..75c305b569 100644 --- a/include/linux/mtd/nand_ids.h +++ b/include/linux/mtd/nand_ids.h @@ -49,6 +49,7 @@ static struct nand_flash_dev nand_flash_ids[] = { {"Samsung KM29W16000", NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000, 0}, {"Samsung K9F5616Q0C", NAND_MFR_SAMSUNG, 0x45, 25, 0, 2, 0x4000, 1}, {"Samsung K9K1216Q0C", NAND_MFR_SAMSUNG, 0x46, 26, 0, 3, 0x4000, 1}, + {"Samsung K9F1G08U0M", NAND_MFR_SAMSUNG, 0xf1, 27, 0, 2, 0, 0}, {NULL,} }; diff --git a/include/nand.h b/include/nand.h new file mode 100644 index 0000000000..29580da4fe --- /dev/null +++ b/include/nand.h @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2005 + * 2N Telekomunikace, a.s. + * Ladislav Michl + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _NAND_H_ +#define _NAND_H_ + +#include +#include +#include + +typedef struct mtd_info nand_info_t; + +extern int nand_curr_device; +extern nand_info_t nand_info[]; + +static inline int nand_read(nand_info_t *info, ulong ofs, ulong *len, u_char *buf) +{ + return info->read(info, ofs, *len, len, buf); +} + +static inline int nand_write(nand_info_t *info, ulong ofs, ulong *len, u_char *buf) +{ + return info->write(info, ofs, *len, len, buf); +} + +static inline int nand_block_isbad(nand_info_t *info, ulong ofs) +{ + return info->block_isbad(info, ofs); +} + +static inline int nand_erase(nand_info_t *info, ulong off, ulong size) +{ + return 0; /* FIXME */ +} + +#endif From ac7eb8a315e25863637a8d2c02af18815458b63f Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 14 Sep 2005 23:53:32 +0200 Subject: [PATCH 002/102] Update of new NAND code Patch by Ladislav Michl, 13 Sep 2005 --- Makefile | 12 + board/netstar/Makefile | 85 ++ board/netstar/config.mk | 11 + board/netstar/crcek.S | 177 +++ board/netstar/crcek.h | 3 + board/netstar/crcit.c | 86 ++ board/netstar/eeprom.c | 215 ++++ board/netstar/eeprom.lds | 51 + board/netstar/eeprom_start.S | 177 +++ board/netstar/flash.c | 343 ++++++ board/netstar/nand.c | 64 ++ board/netstar/netstar.c | 68 ++ board/netstar/setup.S | 287 +++++ board/netstar/u-boot.lds | 55 + common/cmd_jffs2.c | 19 +- common/cmd_nand.c | 2082 +++++++++++++++++++++++++++++----- common/cmd_nand_new.c | 364 ++++++ cpu/arm925t/config.mk | 2 +- drivers/nand/Makefile | 1 - drivers/nand/diskonchip.c | 198 ++-- drivers/nand/nand_base.c | 494 ++++---- drivers/nand/nand_bbt.c | 246 ++-- drivers/nand/nand_ecc.c | 45 +- drivers/nand/nand_ids.c | 28 +- fs/jffs2/jffs2_1pass.c | 8 +- fs/jffs2/jffs2_nand_1pass.c | 39 +- include/asm-arm/io.h | 8 + include/configs/netstar.h | 265 +++++ include/linux/mtd/mtd-abi.h | 48 +- include/linux/mtd/mtd.h | 34 +- include/linux/mtd/nand.h | 44 +- include/nand.h | 2 +- 32 files changed, 4658 insertions(+), 903 deletions(-) create mode 100644 board/netstar/Makefile create mode 100644 board/netstar/config.mk create mode 100644 board/netstar/crcek.S create mode 100644 board/netstar/crcek.h create mode 100644 board/netstar/crcit.c create mode 100644 board/netstar/eeprom.c create mode 100644 board/netstar/eeprom.lds create mode 100644 board/netstar/eeprom_start.S create mode 100644 board/netstar/flash.c create mode 100644 board/netstar/nand.c create mode 100644 board/netstar/netstar.c create mode 100644 board/netstar/setup.S create mode 100644 board/netstar/u-boot.lds create mode 100644 common/cmd_nand_new.c create mode 100644 include/configs/netstar.h diff --git a/Makefile b/Makefile index ab302768cf..c15efd9c8a 100644 --- a/Makefile +++ b/Makefile @@ -118,6 +118,7 @@ LIBS += disk/libdisk.a LIBS += rtc/librtc.a LIBS += dtt/libdtt.a LIBS += drivers/libdrivers.a +LIBS += drivers/nand/libnand.a LIBS += drivers/sk98lin/libsk98lin.a LIBS += post/libpost.a post/cpu/libcpu.a LIBS += common/libcommon.a @@ -1391,6 +1392,17 @@ mx1ads_config : unconfig mx1fs2_config : unconfig @./mkconfig $(@:_config=) arm arm920t mx1fs2 NULL imx +netstar_32_config \ +netstar_config: unconfig + @if [ "$(findstring _32_,$@)" ] ; then \ + echo "... 32MB SDRAM" ; \ + echo "#define PHYS_SDRAM_1_SIZE SZ_32M" >>include/config.h ; \ + else \ + echo "... 64MB SDRAM" ; \ + echo "#define PHYS_SDRAM_1_SIZE SZ_64M" >>include/config.h ; \ + fi + @./mkconfig -a netstar arm arm925t netstar + omap1510inn_config : unconfig @./mkconfig $(@:_config=) arm arm925t omap1510inn diff --git a/board/netstar/Makefile b/board/netstar/Makefile new file mode 100644 index 0000000000..8ef21893ee --- /dev/null +++ b/board/netstar/Makefile @@ -0,0 +1,85 @@ +# +# (C) Copyright 2005 +# Ladislav Michl, 2N Telekomunikace, michl@2n.cz +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := netstar.o flash.o nand.o +SOBJS := setup.o crcek.o + +gcclibdir := $(shell dirname `$(CC) -print-libgcc-file-name`) + +LOAD_ADDR = 0x10400000 +LDSCRIPT = $(TOPDIR)/board/$(BOARDDIR)/eeprom.lds + +HOST_CFLAGS = -Wall -pedantic -I$(TOPDIR)/include + +all: $(LIB) eeprom.srec eeprom.bin crcek.srec crcek.bin crcit + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $^ + +eeprom.srec: eeprom.o eeprom_start.o + $(LD) -T $(LDSCRIPT) -g -Ttext $(LOAD_ADDR) \ + -o $(<:.o=) -e $(<:.o=) $^ \ + -L../../examples -lstubs \ + -L../../lib_generic -lgeneric \ + -L$(gcclibdir) -lgcc + $(OBJCOPY) -O srec $(<:.o=) $@ + +eeprom.bin: eeprom.srec + $(OBJCOPY) -I srec -O binary $< $@ 2>/dev/null + +crcek.srec: crcek.o + $(LD) -g -Ttext 0x00000000 \ + -o $(<:.o=) -e $(<:.o=) $^ + $(OBJCOPY) -O srec $(<:.o=) $@ + +crcek.bin: crcek.srec + $(OBJCOPY) -I srec -O binary $< $@ 2>/dev/null + +crcit: crcit.o crc32.o + $(HOSTCC) $(HOST_CFLAGS) -o $@ $^ + +crcit.o: crcit.c + $(HOSTCC) $(HOST_CFLAGS) -c $< + +crc32.o: $(TOPDIR)/tools/crc32.c + $(HOSTCC) $(HOST_CFLAGS) -DUSE_HOSTCC -c $< + +clean: + rm -f $(SOBJS) $(OBJS) eeprom eeprom.srec eeprom.bin \ + crcek crcek.srec crcek.bin + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/netstar/config.mk b/board/netstar/config.mk new file mode 100644 index 0000000000..8b73e97598 --- /dev/null +++ b/board/netstar/config.mk @@ -0,0 +1,11 @@ +# +# Linux-Kernel is expected to be at 1000'8000, +# entry 1000'8000 (mem base + reserved) +# +# We load ourself to internal RAM at 2001'2000 +# Check map file when changing TEXT_BASE. +# Everything has fit into 192kB internal SRAM! +# + +# XXX TEXT_BASE = 0x20012000 +TEXT_BASE = 0x13FC0000 diff --git a/board/netstar/crcek.S b/board/netstar/crcek.S new file mode 100644 index 0000000000..6ca4d11df8 --- /dev/null +++ b/board/netstar/crcek.S @@ -0,0 +1,177 @@ +/** + * (C) Copyright 2005 + * 2N Telekomunikace, Ladislav Michl + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2. + * + * Image layout looks like following: + * u32 - size + * u32 - version + * ... - data + * u32 - crc32 + */ + +#include "crcek.h" + +/** + * do_crc32 - calculate CRC32 of given buffer + * r0 - crc + * r1 - pointer to buffer + * r2 - buffer len + */ + .macro do_crc32 + ldr r5, FFFFFFFF + eor r0, r0, r5 + adr r3, CRC32_TABLE +1: + ldrb r4, [r1], #1 + eor r4, r4, r0 + and r4, r4, #0xff + ldr r4, [r3, r4, lsl#2] + eor r0, r4, r0, lsr#8 + subs r2, r2, #0x1 + bne 1b + eor r0, r0, r5 + .endm + + .macro crcuj, offset, size + mov r0, #0 + ldr r1, \offset + ldr r2, [r1] + cmp r2, r0 @ no data, no problem + beq 2f + tst r2, #3 @ unaligned size + bne 2f + ldr r3, \size + cmp r2, r3 @ bogus size + bhi 2f + add r1, r1, #4 + do_crc32 + ldr r1, [r1] +2: + cmp r0, r1 + .endm + + .macro wait, reg + mov \reg, #0x1000 +3: + subs \reg, \reg, #0x1 + bne 3b + + .endm +.text +.globl crcek +crcek: + b crc2_bad + mov r6, #0 + crcuj _LOADER1_OFFSET, _LOADER_SIZE + bne crc1_bad + orr r6, r6, #1 +crc1_bad: + crcuj _LOADER2_OFFSET, _LOADER_SIZE + bne crc2_bad + orr r6, r6, #2 +crc2_bad: + ldr r3, _LOADER1_OFFSET + ldr r4, _LOADER2_OFFSET + b boot_2nd + tst r6, #3 + beq one_is_bad @ one of them (or both) has bad crc + ldr r1, [r3, #4] + ldr r2, [r4, #4] + cmp r1, r2 @ boot 2nd loader if versions differ + beq boot_1st + b boot_2nd +one_is_bad: + tst r6, #1 + bne boot_1st + tst r6, #2 + bne boot_2nd +@ We are doomed, so let user know. + ldr r0, GPIO_BASE @ configure GPIO pins + ldr r1, GPIO_DIRECTION + strh r1, [r0, #0x08] +blink_loop: + mov r1, #0x08 + strh r1, [r0, #0x04] + wait r3 + mov r1, #0x10 + strh r1, [r0, #0x04] + wait r3 + b blink_loop +boot_1st: + add pc, r3, #8 +boot_2nd: + add pc, r4, #8 + +_LOADER_SIZE: + .word LOADER_SIZE - 8 @ minus size and crc32 +_LOADER1_OFFSET: + .word LOADER1_OFFSET +_LOADER2_OFFSET: + .word LOADER2_OFFSET + +FFFFFFFF: + .word 0xffffffff +CRC32_TABLE: + .word 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419 + .word 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4 + .word 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07 + .word 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de + .word 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856 + .word 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9 + .word 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4 + .word 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b + .word 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3 + .word 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a + .word 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599 + .word 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924 + .word 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190 + .word 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f + .word 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e + .word 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01 + .word 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed + .word 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950 + .word 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3 + .word 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2 + .word 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a + .word 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5 + .word 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010 + .word 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f + .word 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17 + .word 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6 + .word 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615 + .word 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8 + .word 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344 + .word 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb + .word 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a + .word 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5 + .word 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1 + .word 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c + .word 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef + .word 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236 + .word 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe + .word 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31 + .word 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c + .word 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713 + .word 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b + .word 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242 + .word 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1 + .word 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c + .word 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278 + .word 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7 + .word 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66 + .word 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9 + .word 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605 + .word 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8 + .word 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b + .word 0x2d02ef8d + +GPIO_BASE: + .word 0xfffce000 +GPIO_DIRECTION: + .word 0x0000ffe7 + +.end diff --git a/board/netstar/crcek.h b/board/netstar/crcek.h new file mode 100644 index 0000000000..30c08602f5 --- /dev/null +++ b/board/netstar/crcek.h @@ -0,0 +1,3 @@ +#define LOADER_SIZE (448 * 1024) +#define LOADER1_OFFSET (128 * 1024) +#define LOADER2_OFFSET (LOADER1_OFFSET + LOADER_SIZE) diff --git a/board/netstar/crcit.c b/board/netstar/crcit.c new file mode 100644 index 0000000000..f6d3066c15 --- /dev/null +++ b/board/netstar/crcit.c @@ -0,0 +1,86 @@ +/* + * (C) Copyright 2005 + * 2N Telekomunikace, Ladislav Michl + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "crcek.h" + +extern unsigned long crc32(unsigned long, const unsigned char *, unsigned int); + +uint32_t data[LOADER_SIZE/4 + 3]; + +int doit(char *path, unsigned version) +{ + uint32_t *p; + ssize_t size; + int fd; + + fd = open(path, O_RDONLY); + if (fd == -1) { + perror("Error opening file"); + return EXIT_FAILURE; + } + p = data + 2; + size = read(fd, p, LOADER_SIZE + 4); + if (size == -1) { + perror("Error reading file"); + return EXIT_FAILURE; + } + if (size > LOADER_SIZE) { + fprintf(stderr, "File too large\n"); + return EXIT_FAILURE; + } + size = (((size - 1) >> 2) + 1) << 2; + data[0] = size + 4; /* add size of version field */ + data[1] = version; + data[(size >> 2) + 2] = crc32(0, (unsigned char *)(data + 1), data[0]); + close(fd); + + if (write(STDOUT_FILENO, data, size + 3*4) == -1) { + perror("Error writing file"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +int main(int argc, char **argv) +{ + if (argc == 2) { + return doit(argv[1], 0); + } else if ((argc == 4) && (strcmp(argv[1], "-v") == 0)) { + char *endptr, *nptr = argv[2]; + unsigned ver = strtoul(nptr, &endptr, 0); + if (nptr != '\0' && endptr == '\0') + return doit(argv[3], ver); + } + fprintf(stderr, "Usage: crcit [-v version] \n"); + + return EXIT_FAILURE; +} diff --git a/board/netstar/eeprom.c b/board/netstar/eeprom.c new file mode 100644 index 0000000000..fef3822aae --- /dev/null +++ b/board/netstar/eeprom.c @@ -0,0 +1,215 @@ +/* + * (C) Copyright 2005 + * Ladislav Michl, 2N Telekomunikace, michl@2n.cz + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Some code shamelessly stolen back from Robin Getz. + */ + +#define DEBUG + +#include +#include +#include "../drivers/smc91111.h" + +#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE + +static u16 read_eeprom_reg(u16 reg) +{ + int timeout; + + SMC_SELECT_BANK(2); + SMC_outw(reg, PTR_REG); + + SMC_SELECT_BANK(1); + SMC_outw(SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_RELOAD, + CTL_REG); + timeout = 100; + while((SMC_inw (CTL_REG) & CTL_RELOAD) && --timeout) + udelay(100); + if (timeout == 0) { + printf("Timeout Reading EEPROM register %02x\n", reg); + return 0; + } + + return SMC_inw (GP_REG); +} + +static int write_eeprom_reg(u16 value, u16 reg) +{ + int timeout; + + SMC_SELECT_BANK(2); + SMC_outw(reg, PTR_REG); + + SMC_SELECT_BANK(1); + SMC_outw(value, GP_REG); + SMC_outw(SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_STORE, CTL_REG); + timeout = 100; + while ((SMC_inw(CTL_REG) & CTL_STORE) && --timeout) + udelay (100); + if (timeout == 0) { + printf("Timeout Writing EEPROM register %02x\n", reg); + return 0; + } + + return 1; +} + +static int write_data(u16 *buf, int len) +{ + u16 reg = 0x23; + + while (len--) + write_eeprom_reg(*buf++, reg++); + + return 0; +} + +static int verify_macaddr(char *s) +{ + u16 reg; + int i, err = 0; + + printf("MAC Address: "); + err = i = 0; + for (i = 0; i < 3; i++) { + reg = read_eeprom_reg(0x20 + i); + printf("%02x:%02x%c", reg & 0xff, reg >> 8, i != 2 ? ':' : '\n'); + if (s) + err |= reg != ((u16 *)s)[i]; + } + + return err ? 0 : 1; +} + +static int set_mac(char *s) +{ + int i; + char *e, eaddr[6]; + + /* turn string into mac value */ + for (i = 0; i < 6; i++) { + eaddr[i] = simple_strtoul(s, &e, 16); + s = (*e) ? e+1 : e; + } + + for (i = 0; i < 3; i++) + write_eeprom_reg(*(((u16 *)eaddr) + i), 0x20 + i); + + return 0; +} + +static int parse_element(char *s, unsigned char *buf, int len) +{ + int cnt; + char *p, num[3]; + unsigned char id; + + id = simple_strtoul(s, &p, 16); + if (*p++ != ':') + return -1; + cnt = 2; + num[2] = 0; + for (; *p; p += 2) { + if (p[1] == 0) + return -2; + if (cnt + 3 > len) + return -3; + num[0] = p[0]; + num[1] = p[1]; + buf[cnt++] = simple_strtoul(num, NULL, 16); + } + buf[0] = id; + buf[1] = cnt - 2; + + return cnt; +} + +extern int crcek(void); + +int eeprom(int argc, char *argv[]) +{ + int i, len, ret; + unsigned char buf[58], *p; + + app_startup(argv); + if (get_version() != XF_VERSION) { + printf("Wrong XF_VERSION.\n"); + printf("Application expects ABI version %d\n", XF_VERSION); + printf("Actual U-Boot ABI version %d\n", (int)get_version()); + return 1; + } + + return crcek(); + + if ((SMC_inw (BANK_SELECT) & 0xFF00) != 0x3300) { + printf("SMSC91111 not found.\n"); + return 2; + } + + /* Called without parameters - print MAC address */ + if (argc < 2) { + verify_macaddr(NULL); + return 0; + } + + /* Print help message */ + if (argv[1][1] == 'h') { + printf("VoiceBlue EEPROM writer\n"); + printf("Built: %s at %s\n", __DATE__ , __TIME__ ); + printf("Usage:\n\t [] [<...>]\n"); + return 0; + } + + /* Try to parse information elements */ + len = sizeof(buf); + p = buf; + for (i = 2; i < argc; i++) { + ret = parse_element(argv[i], p, len); + switch (ret) { + case -1: + printf("Element %d: malformed\n", i - 1); + return 3; + case -2: + printf("Element %d: odd character count\n", i - 1); + return 3; + case -3: + printf("Out of EEPROM memory\n"); + return 3; + default: + p += ret; + len -= ret; + } + } + + /* First argument (MAC) is mandatory */ + set_mac(argv[1]); + if (verify_macaddr(argv[1])) { + printf("*** MAC address does not match! ***\n"); + return 4; + } + + while (len--) + *p++ = 0; + + write_data((u16 *)buf, sizeof(buf) >> 1); + + return 0; +} diff --git a/board/netstar/eeprom.lds b/board/netstar/eeprom.lds new file mode 100644 index 0000000000..317550dbad --- /dev/null +++ b/board/netstar/eeprom.lds @@ -0,0 +1,51 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * (C) Copyright 2005 + * Ladislav Michl, 2N Telekomunikace, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = ALIGN(4); + .text : + { + eeprom_start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} diff --git a/board/netstar/eeprom_start.S b/board/netstar/eeprom_start.S new file mode 100644 index 0000000000..75d9f0558f --- /dev/null +++ b/board/netstar/eeprom_start.S @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2005 2N Telekomunikace + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + */ + +.globl _start +_start: b eeprom + +#include "crcek.h" + +/** + * do_crc32 - calculate CRC32 of given buffer + * r0 - crc + * r1 - pointer to buffer + * r2 - buffer len + */ + .macro do_crc32 + ldr r5, FFFFFFFF + eor r0, r0, r5 + adr r3, CRC32_TABLE +1: + ldrb r4, [r1], #1 + eor r4, r4, r0 + and r4, r4, #0xff + ldr r4, [r3, r4, lsl#2] + eor r0, r4, r0, lsr#8 + subs r2, r2, #0x1 + bne 1b + eor r0, r0, r5 + .endm + + .macro crcuj, offset, size + ldr r1, \offset + ldr r2, [r1] + cmp r2, #0 @ no data, no problem + beq 2f + mov r7, #1 + tst r2, #3 @ unaligned size + bne 2f + mov r7, #2 + ldr r0, \size + cmp r2, r0 @ bogus size + bhi 2f + mov r7, #3 + add r1, r1, #4 + mov r0, #0 + do_crc32 + ldr r1, [r1] +2: + cmp r0, r1 + .endm + + .macro wait, reg + mov \reg, #0x1000 +3: + subs \reg, \reg, #0x1 + bne 3b + + .endm +.text +.globl crcek +crcek: + mov r6, #0 +@ crcuj _LOADER1_OFFSET, _LOADER_SIZE +@ bne crc1_bad +@ orr r6, r6, #1 +crc1_bad: + crcuj _LOADER2_OFFSET, _LOADER_SIZE + bne crc2_bad + orr r6, r6, #2 +crc2_bad: +@ mov r0, r6 + mov pc, lr + ldr r3, _LOADER1_OFFSET + ldr r4, _LOADER2_OFFSET + tst r6, #3 + beq one_is_bad @ one of them (or both) has bad crc + ldr r1, [r3, #4] + ldr r2, [r4, #4] + cmp r1, r2 @ boot 2nd loader if versions differ + beq boot_1st + b boot_2nd +one_is_bad: + tst r6, #1 + bne boot_1st + tst r6, #2 + bne boot_2nd +@ We are doomed, so let user know. + ldr r0, GPIO_BASE @ configure GPIO pins + ldr r1, GPIO_DIRECTION + strh r1, [r0, #0x08] +blink_loop: + mov r1, #0x08 + strh r1, [r0, #0x04] + wait r3 + mov r1, #0x10 + strh r1, [r0, #0x04] + wait r3 + b blink_loop +boot_1st: + add pc, r3, #8 +boot_2nd: + add pc, r4, #8 + +_LOADER_SIZE: + .word LOADER_SIZE - 8 @ minus size and crc32 +_LOADER1_OFFSET: + .word LOADER1_OFFSET +_LOADER2_OFFSET: + .word LOADER2_OFFSET + +FFFFFFFF: + .word 0xffffffff +CRC32_TABLE: + .word 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419 + .word 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4 + .word 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07 + .word 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de + .word 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856 + .word 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9 + .word 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4 + .word 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b + .word 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3 + .word 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a + .word 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599 + .word 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924 + .word 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190 + .word 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f + .word 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e + .word 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01 + .word 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed + .word 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950 + .word 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3 + .word 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2 + .word 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a + .word 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5 + .word 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010 + .word 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f + .word 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17 + .word 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6 + .word 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615 + .word 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8 + .word 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344 + .word 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb + .word 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a + .word 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5 + .word 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1 + .word 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c + .word 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef + .word 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236 + .word 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe + .word 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31 + .word 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c + .word 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713 + .word 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b + .word 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242 + .word 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1 + .word 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c + .word 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278 + .word 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7 + .word 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66 + .word 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9 + .word 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605 + .word 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8 + .word 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b + .word 0x2d02ef8d + +GPIO_BASE: + .word 0xfffce000 +GPIO_DIRECTION: + .word 0x0000ffe7 + +.end diff --git a/board/netstar/flash.c b/board/netstar/flash.c new file mode 100644 index 0000000000..f555c0c006 --- /dev/null +++ b/board/netstar/flash.c @@ -0,0 +1,343 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2005 + * 2N Telekomunikace, a.s. + * Ladislav Michl + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +/*#if 0 */ +#if (PHYS_SDRAM_1_SIZE != SZ_32M) + +#include "crcek.h" + +#if (CFG_MAX_FLASH_BANKS > 1) +#error There is always only _one_ flash chip +#endif + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +#define CMD_READ_ARRAY 0x000000f0 +#define CMD_UNLOCK1 0x000000aa +#define CMD_UNLOCK2 0x00000055 +#define CMD_ERASE_SETUP 0x00000080 +#define CMD_ERASE_CONFIRM 0x00000030 +#define CMD_PROGRAM 0x000000a0 +#define CMD_UNLOCK_BYPASS 0x00000020 + +#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555 << 1))) +#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002aa << 1))) + +#define BIT_ERASE_DONE 0x00000080 +#define BIT_RDY_MASK 0x00000080 +#define BIT_PROGRAM_ERROR 0x00000020 +#define BIT_TIMEOUT 0x80000000 /* our flag */ + +/*----------------------------------------------------------------------- + */ + +ulong flash_init(void) +{ + int i; + + flash_info[0].flash_id = (AMD_MANUFACT & FLASH_VENDMASK) | + (AMD_ID_LV800B & FLASH_TYPEMASK); + flash_info[0].size = PHYS_FLASH_1_SIZE; + flash_info[0].sector_count = CFG_MAX_FLASH_SECT; + memset(flash_info[0].protect, 0, CFG_MAX_FLASH_SECT); + + for (i = 0; i < flash_info[0].sector_count; i++) { + switch (i) { + case 0: /* 16kB */ + flash_info[0].start[0] = CFG_FLASH_BASE; + break; + case 1: /* 8kB */ + flash_info[0].start[1] = CFG_FLASH_BASE + 0x4000; + break; + case 2: /* 8kB */ + flash_info[0].start[2] = CFG_FLASH_BASE + 0x4000 + + 0x2000; + break; + case 3: /* 32 KB */ + flash_info[0].start[3] = CFG_FLASH_BASE + 0x4000 + + 2 * 0x2000; + break; + case 4: + flash_info[0].start[4] = CFG_FLASH_BASE + 0x4000 + + 2 * 0x2000 + 0x8000; + break; + default: /* 64kB */ + flash_info[0].start[i] = flash_info[0].start[i-1] + + 0x10000; + break; + } + } + + /* U-Boot */ + flash_protect(FLAG_PROTECT_SET, + LOADER1_OFFSET, + LOADER1_OFFSET + LOADER_SIZE - 1, flash_info); + /* Protect crcek, env and r_env as well */ + flash_protect(FLAG_PROTECT_SET, 0, 0x8000 - 1, flash_info); + + return flash_info[0].size; +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info(flash_info_t *info) +{ + int i; + + switch (info->flash_id & FLASH_VENDMASK) { + case (AMD_MANUFACT & FLASH_VENDMASK): + puts("AMD: "); + break; + default: + puts("Unknown vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case (AMD_ID_LV800B & FLASH_TYPEMASK): + puts("AM29LV800BB (8Mb)\n"); + break; + default: + puts("Unknown chip type\n"); + return; + } + + printf(" Size: %ld MB in %d sectors\n", + info->size >> 20, info->sector_count); + + puts(" Sector start addresses:"); + for (i = 0; i < info->sector_count; i++) { + if ((i % 5) == 0) + puts("\n "); + + printf(" %08lX%s", info->start[i], + info->protect[i] ? " (RO)" : " "); + } + puts("\n"); +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase(flash_info_t *info, int s_first, int s_last) +{ + ushort result; + int prot, sect; + int rc = ERR_OK; + + /* first look for protection bits */ + + if (info->flash_id == FLASH_UNKNOWN) + return ERR_UNKNOWN_FLASH_TYPE; + + if ((s_first < 0) || (s_first > s_last)) + return ERR_INVAL; + + if ((info->flash_id & FLASH_VENDMASK) != + (AMD_MANUFACT & FLASH_VENDMASK)) + return ERR_UNKNOWN_FLASH_VENDOR; + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) + if (info->protect[sect]) + prot++; + + if (prot) + printf("- Warning: %d protected sectors will not be erased!\n", + prot); + else + putc('\n'); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last && !ctrlc (); sect++) { + if (info->protect[sect] == 0) { /* not protected */ + vu_short *addr = (vu_short *) (info->start[sect]); + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked(); + + MEM_FLASH_ADDR1 = CMD_UNLOCK1; + MEM_FLASH_ADDR2 = CMD_UNLOCK2; + MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; + + MEM_FLASH_ADDR1 = CMD_UNLOCK1; + MEM_FLASH_ADDR2 = CMD_UNLOCK2; + *addr = CMD_ERASE_CONFIRM; + + /* wait until flash is ready */ + while (1) { + result = *addr; + + /* check timeout */ + if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) { + MEM_FLASH_ADDR1 = CMD_READ_ARRAY; + rc = ERR_TIMOUT; + break; + } + + if ((result & 0xfff) & BIT_ERASE_DONE) + break; + + if ((result & 0xffff) & BIT_PROGRAM_ERROR) { + rc = ERR_PROG_ERROR; + break; + } + } + + MEM_FLASH_ADDR1 = CMD_READ_ARRAY; + + if (rc != ERR_OK) + goto out; + + putc('.'); + } + } +out: + /* allow flash to settle - wait 10 ms */ + udelay_masked(10000); + + return rc; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash + */ + +volatile static int write_hword(flash_info_t *info, ulong dest, ushort data) +{ + vu_short *addr = (vu_short *) dest; + ushort result; + int rc = ERR_OK; + + /* check if flash is (sufficiently) erased */ + result = *addr; + if ((result & data) != data) + return ERR_NOT_ERASED; + + MEM_FLASH_ADDR1 = CMD_UNLOCK1; + MEM_FLASH_ADDR2 = CMD_UNLOCK2; + MEM_FLASH_ADDR1 = CMD_PROGRAM; + *addr = data; + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked(); + + /* wait until flash is ready */ + while (1) { + result = *addr; + + /* check timeout */ + if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { + rc = ERR_TIMOUT; + break; + } + + if ((result & 0x80) == (data & 0x80)) + break; + + if ((result & 0xffff) & BIT_PROGRAM_ERROR) { + result = *addr; + + if ((result & 0x80) != (data & 0x80)) + rc = ERR_PROG_ERROR; + } + } + + *addr = CMD_READ_ARRAY; + + if (*addr != data) + rc = ERR_PROG_ERROR; + + return rc; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash. + */ + +int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp; + int l; + int i, rc; + ushort data; + + wp = (addr & ~1); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) + data = (data >> 8) | (*(uchar *) cp << 8); + for (; i < 2 && cnt > 0; ++i) { + data = (data >> 8) | (*src++ << 8); + --cnt; + ++cp; + } + for (; cnt == 0 && i < 2; ++i, ++cp) + data = (data >> 8) | (*(uchar *) cp << 8); + + if ((rc = write_hword(info, wp, data)) != 0) + return (rc); + wp += 2; + } + + /* + * handle word aligned part + */ + while (cnt >= 2) { + data = *((vu_short *) src); + if ((rc = write_hword(info, wp, data)) != 0) + return (rc); + src += 2; + wp += 2; + cnt -= 2; + } + + if (cnt == 0) + return ERR_OK; + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) { + data = (data >> 8) | (*src++ << 8); + --cnt; + } + for (; i < 2; ++i, ++cp) + data = (data >> 8) | (*(uchar *) cp << 8); + + return write_hword(info, wp, data); +} + +#endif diff --git a/board/netstar/nand.c b/board/netstar/nand.c new file mode 100644 index 0000000000..e5b7f3346e --- /dev/null +++ b/board/netstar/nand.c @@ -0,0 +1,64 @@ +/* + * (C) Copyright 2005 2N TELEKOMUNIKACE, Ladislav Michl + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) + +#include + +/* + * hardware specific access to control-lines + */ +#define MASK_CLE 0x02 +#define MASK_ALE 0x04 + +static void netstar_nand_hwcontrol(struct mtd_info *mtd, int cmd) +{ + struct nand_chip *this = mtd->priv; + ulong IO_ADDR_W = (ulong) this->IO_ADDR_W; + + IO_ADDR_W &= ~(MASK_ALE|MASK_CLE); + switch (cmd) { + case NAND_CTL_SETCLE: IO_ADDR_W |= MASK_CLE; break; + case NAND_CTL_SETALE: IO_ADDR_W |= MASK_ALE; break; + } + this->IO_ADDR_W = (void *) IO_ADDR_W; +} + +/* + * chip R/B detection + */ +static int netstar_nand_ready(struct mtd_info *mtd) +{ + return (*(volatile ushort *)GPIO_DATA_INPUT_REG) & 0x02; +} + +void board_nand_init(struct nand_chip *nand) +{ + nand->options = NAND_SAMSUNG_LP_OPTIONS; + nand->eccmode = NAND_ECC_SOFT; + nand->hwcontrol = netstar_nand_hwcontrol; +/* nand->dev_ready = netstar_nand_ready; */ + nand->chip_delay = 18; +} +#endif diff --git a/board/netstar/netstar.c b/board/netstar/netstar.c new file mode 100644 index 0000000000..62615e5c56 --- /dev/null +++ b/board/netstar/netstar.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2005 2N TELEKOMUNIKACE, Ladislav Michl + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +int board_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + /* arch number of NetStar board */ + /* TODO: use define from asm/mach-types.h */ + gd->bd->bi_arch_number = 692; + + /* adress of boot parameters */ + gd->bd->bi_boot_params = 0x10000100; + + return 0; +} + +int dram_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + + /* Take the Ethernet controller out of reset and wait + * for the EEPROM load to complete. */ + *((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) |= 0x80; + udelay(10); /* doesn't work before interrupt_init call */ + *((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) &= ~0x80; + udelay(500); + + return 0; +} + +extern void partition_flash(void); + +int misc_init_r(void) +{ + return 0; +} + +extern void nand_init(void); + +int board_late_init(void) +{ + return 0; +} diff --git a/board/netstar/setup.S b/board/netstar/setup.S new file mode 100644 index 0000000000..82c0342357 --- /dev/null +++ b/board/netstar/setup.S @@ -0,0 +1,287 @@ +/* + * Board specific setup info + * + * (C) Copyright 2004 Ales Jindra + * (C) Copyright 2005 Ladislav Michl + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +_TEXT_BASE: + .word TEXT_BASE /* SDRAM load addr from config.mk */ + +OMAP5910_LPG1_BASE: .word 0xfffbd000 +OMAP5910_TIPB_SWITCHES_BASE: .word 0xfffbc800 +OMAP5910_MPU_TC_BASE: .word 0xfffecc00 +OMAP5910_MPU_CLKM_BASE: .word 0xfffece00 +OMAP5910_ULPD_PWR_MNG_BASE: .word 0xfffe0800 +OMAP5910_DPLL1_BASE: .word 0xfffecf00 +OMAP5910_GPIO_BASE: .word 0xfffce000 +OMAP5910_MPU_WD_TIMER_BASE: .word 0xfffec800 +OMAP5910_MPUI_BASE: .word 0xfffec900 + +_OMAP5910_ARM_CKCTL: .word OMAP5910_ARM_CKCTL +_OMAP5910_ARM_EN_CLK: .word OMAP5910_ARM_EN_CLK + +OMAP5910_MPUI_CTRL: .word 0x0000ff1b + +VAL_EMIFS_CS0_CONFIG: .word 0x00009090 +VAL_EMIFS_CS1_CONFIG: .word 0x00003031 +VAL_EMIFS_CS2_CONFIG: .word 0x0000a0a1 +VAL_EMIFS_CS3_CONFIG: .word 0x0000c0c0 +VAL_EMIFS_DYN_WAIT: .word 0x00000000 +/* autorefresh counter 0x246 ((64000000/13.4)-400)/8192) */ + /* SLRF SD_RET ARE SDRAM_TYPE ARCV SDRAM_FREQUENCY PWD CLK */ + +#if (PHYS_SDRAM_1_SIZE == SZ_32M) +VAL_EMIFF_SDRAM_CONFIG: .word ((0 << 0) | (0 << 1) | (3 << 2) | (0xf << 4) | (0x246 << 8) | (0 << 24) | (0 << 26) | (0 << 27)) +#else +VAL_EMIFF_SDRAM_CONFIG: .word ((0 << 0) | (0 << 1) | (3 << 2) | (0xd << 4) | (0x246 << 8) | (0 << 24) | (0 << 26) | (0 << 27)) +#endif + +VAL_EMIFF_SDRAM_CONFIG2: .word 0x00000003 +VAL_EMIFF_MRS: .word 0x00000037 + +/* + * GPIO04 - Green LED (Red LED is connected to LED Pulse Generator) + * GPIO07 - LAN91C111 reset + */ +GPIO_DIRECTION: + .word 0x0000ff6f +/* + * Disable everything (green LED is connected via invertor) + */ +GPIO_OUTPUT: + .word 0x00000010 + +MUX_CONFIG_BASE: + .word 0xfffe1000 + +MUX_CONFIG_VALUES: + .align 4 + .word 0x00000000 @ FUNC_MUX_CTRL_0 + .word 0x00000000 @ FUNC_MUX_CTRL_1 + .word 0x00000000 @ FUNC_MUX_CTRL_2 + .word 0x00000000 @ FUNC_MUX_CTRL_3 + .word 0x00000000 @ FUNC_MUX_CTRL_4 + .word 0x02080480 @ FUNC_MUX_CTRL_5 + .word 0x0100001c @ FUNC_MUX_CTRL_6 + .word 0x0004800b @ FUNC_MUX_CTRL_7 + .word 0x10001200 @ FUNC_MUX_CTRL_8 + .word 0x01201012 @ FUNC_MUX_CTRL_9 + .word 0x02082248 @ FUNC_MUX_CTRL_A + .word 0x00000248 @ FUNC_MUX_CTRL_B + .word 0x12240000 @ FUNC_MUX_CTRL_C + .word 0x00002000 @ FUNC_MUX_CTRL_D + .word 0x00000000 @ PULL_DWN_CTRL_0 + .word 0x00000800 @ PULL_DWN_CTRL_1 + .word 0x01801000 @ PULL_DWN_CTRL_2 + .word 0x00000000 @ PULL_DWN_CTRL_3 + .word 0x00000000 @ GATE_INH_CTRL_0 + .word 0x00000000 @ VOLTAGE_CTRL_0 + .word 0x00000000 @ TEST_DBG_CTRL_0 + .word 0x00000006 @ MOD_CONF_CTRL_0 + .word 0x0000eaef @ COMP_MODE_CTRL_0 + +MUX_CONFIG_OFFSETS: + .align 1 + .byte 0x00 @ FUNC_MUX_CTRL_0 + .byte 0x04 @ FUNC_MUX_CTRL_1 + .byte 0x08 @ FUNC_MUX_CTRL_2 + .byte 0x10 @ FUNC_MUX_CTRL_3 + .byte 0x14 @ FUNC_MUX_CTRL_4 + .byte 0x18 @ FUNC_MUX_CTRL_5 + .byte 0x1c @ FUNC_MUX_CTRL_6 + .byte 0x20 @ FUNC_MUX_CTRL_7 + .byte 0x24 @ FUNC_MUX_CTRL_8 + .byte 0x28 @ FUNC_MUX_CTRL_9 + .byte 0x2c @ FUNC_MUX_CTRL_A + .byte 0x30 @ FUNC_MUX_CTRL_B + .byte 0x34 @ FUNC_MUX_CTRL_C + .byte 0x38 @ FUNC_MUX_CTRL_D + .byte 0x40 @ PULL_DWN_CTRL_0 + .byte 0x44 @ PULL_DWN_CTRL_1 + .byte 0x48 @ PULL_DWN_CTRL_2 + .byte 0x4c @ PULL_DWN_CTRL_3 + .byte 0x50 @ GATE_INH_CTRL_0 + .byte 0x60 @ VOLTAGE_CTRL_0 + .byte 0x70 @ TEST_DBG_CTRL_0 + .byte 0x80 @ MOD_CONF_CTRL_0 + .byte 0x0c @ COMP_MODE_CTRL_0 + .byte 0xff + +.globl platformsetup +platformsetup: + /* Improve performance a bit... */ + mrc p15, 0, r1, c0, c0, 0 @ read C15 ID register + mrc p15, 0, r1, c0, c0, 1 @ read C15 Cache information register + mrc p15, 0, r1, c1, c0, 0 @ read C15 Control register + orr r1, r1, #0x1000 @ enable I-cache, map interrupt vector 0xffff0000 + mcr p15, 0, r1, c1, c0, 0 @ write C15 Control register + mov r1, #0x00 + mcr p15, 0, r1, c7, c5, 0 @ Flush I-cache + nop + nop + nop + nop + + /* Setup clocking mode */ + ldr r0, OMAP5910_MPU_CLKM_BASE @ prepare base of CLOCK unit + ldrh r1, [r0, #0x18] @ get reset status + bic r1, r1, #(7 << 11) @ clear clock select + orr r1, r1, #(2 << 11) @ set synchronous scalable + mov r2, #0 @ set wait counter to 100 clock cycles + +icache_loop: + cmp r2, #0x01 + streqh r1, [r0, #0x18] + add r2, r2, #0x01 + cmp r2, #0x10 + bne icache_loop + nop + + /* Setup clock divisors */ + ldr r0, OMAP5910_MPU_CLKM_BASE @ base of CLOCK unit + ldr r1, _OMAP5910_ARM_CKCTL + orr r1, r1, #0x2000 @ enable DSP clock + strh r1, [r0, #0x00] @ setup clock divisors + + /* Setup DPLL to generate requested freq */ + ldr r0, OMAP5910_DPLL1_BASE @ base of DPLL1 register + mov r1, #0x0010 @ set PLL_ENABLE + orr r1, r1, #0x2000 @ set IOB to new locking + orr r1, r1, #(OMAP5910_DPLL_MUL << 7) @ setup multiplier CLKREF + orr r1, r1, #(OMAP5910_DPLL_DIV << 5) @ setup divider CLKREF + strh r1, [r0] @ write + +locking: + ldrh r1, [r0] @ get DPLL value + tst r1, #0x01 + beq locking @ while LOCK not set + + /* Enable clock */ + ldr r0, OMAP5910_MPU_CLKM_BASE @ base of CLOCK unit + mov r1, #(1 << 10) @ disable idle mode do not check + @ nWAKEUP pin, other remain active + strh r1, [r0, #0x04] + ldr r1, _OMAP5910_ARM_EN_CLK + strh r1, [r0, #0x08] + mov r1, #0x003f @ FLASH.RP not enabled in idle and + @ max delayed ( 32 x CLKIN ) + strh r1, [r0, #0x0c] + + /* Configure 5910 pins functions to match our board. */ + ldr r0, MUX_CONFIG_BASE + adr r1, MUX_CONFIG_VALUES + adr r2, MUX_CONFIG_OFFSETS +next_mux_cfg: + ldrb r3, [r2], #1 + ldr r4, [r1], #4 + cmp r3, #0xff + strne r4, [r0, r3] + bne next_mux_cfg + + /* Configure GPIO pins (also disables Green LED) */ + ldr r0, OMAP5910_GPIO_BASE + ldr r1, GPIO_OUTPUT + strh r1, [r0, #0x04] + ldr r1, GPIO_DIRECTION + strh r1, [r0, #0x08] + + /* EnablePeripherals */ + ldr r0, OMAP5910_MPU_CLKM_BASE @ CLOCK unit + mov r1, #0x0001 @ Peripheral enable + strh r1, [r0, #0x14] + + /* Program LED Pulse Generator */ + ldr r0, OMAP5910_LPG1_BASE @ 1st LED Pulse Generator + mov r1, #0x7F @ Set obscure frequency in + strb r1, [r0, #0x00] @ LCR + mov r1, #0x01 @ Enable clock (CLK_EN) in + strb r1, [r0, #0x04] @ PMR + + /* TIPB Lock UART1 */ + ldr r0, OMAP5910_TIPB_SWITCHES_BASE @ prepare base of TIPB switches + mov r1, #1 @ ARM allocated + strh r1, [r0,#0x04] @ clear IRQ line and status bits + strh r1, [r0,#0x00] + ldrh r1, [r0,#0x04] + + /* Disable watchdog */ + ldr r0, OMAP5910_MPU_WD_TIMER_BASE + mov r1, #0xf5 + strh r1, [r0, #0x8] + mov r1, #0xa0 + strh r1, [r0, #0x8] + + /* Enable MCLK */ + ldr r0, OMAP5910_ULPD_PWR_MNG_BASE + mov r1, #0x6 + strh r1, [r0, #0x34] + strh r1, [r0, #0x34] + + /* Setup clock divisors */ + ldr r0, OMAP5910_ULPD_PWR_MNG_BASE @ base of ULDPL DPLL1 register + + mov r1, #0x0010 @ set PLL_ENABLE + orr r1, r1, #0x2000 @ set IOB to new locking + strh r1, [r0] @ write + +ulocking: + ldrh r1, [r0] @ get DPLL value + tst r1, #1 + beq ulocking @ while LOCK not set + + /* EMIF init */ + ldr r0, OMAP5910_MPU_TC_BASE + ldrh r1, [r0, #0x0c] @ EMIFS_CONFIG_REG + bic r1, r1, #0x0c @ pwr down disabled, flash WP + orr r1, r1, #0x01 + str r1, [r0, #0x0c] + + ldr r1, VAL_EMIFS_CS0_CONFIG + str r1, [r0, #0x10] @ EMIFS_CS0_CONFIG + ldr r1, VAL_EMIFS_CS1_CONFIG + str r1, [r0, #0x14] @ EMIFS_CS1_CONFIG + ldr r1, VAL_EMIFS_CS2_CONFIG + str r1, [r0, #0x18] @ EMIFS_CS2_CONFIG + ldr r1, VAL_EMIFS_CS3_CONFIG + str r1, [r0, #0x1c] @ EMIFS_CS3_CONFIG + ldr r1, VAL_EMIFS_DYN_WAIT + str r1, [r0, #0x40] @ EMIFS_CFG_DYN_WAIT + + /* Setup SDRAM */ + ldr r1, VAL_EMIFF_SDRAM_CONFIG + str r1, [r0, #0x20] @ EMIFF_SDRAM_CONFIG + ldr r1, VAL_EMIFF_SDRAM_CONFIG2 + str r1, [r0, #0x3c] @ EMIFF_SDRAM_CONFIG2 + ldr r1, VAL_EMIFF_MRS + str r1, [r0, #0x24] @ EMIFF_MRS + /* SDRAM needs 100us to stabilize */ + mov r0, #0x4000 +sdelay: + subs r0, r0, #0x1 + bne sdelay + + /* back to arch calling code */ + mov pc, lr +.end diff --git a/board/netstar/u-boot.lds b/board/netstar/u-boot.lds new file mode 100644 index 0000000000..8317f72d06 --- /dev/null +++ b/board/netstar/u-boot.lds @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/arm925t/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index 7ab6e9ca7a..bc63f0c492 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -99,6 +99,10 @@ #include +#ifdef CONFIG_NEW_NAND_CODE +#include +#endif + /* enable/disable debugging messages */ #define DEBUG #undef DEBUG @@ -324,10 +328,9 @@ static int part_validate_nand(struct mtdids *id, struct part_info *part) { #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) /* info for NAND chips */ - extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; - struct nand_chip *nand; + nand_info_t *nand; - nand = &nand_dev_desc[id->num]; + nand = &nand_info[id->num]; if ((unsigned long)(part->offset) % nand->erasesize) { printf("%s%d: partition (%s) start offset alignment incorrect\n", @@ -422,8 +425,9 @@ static int part_del(struct mtd_device *dev, struct part_info *part) } } - +#ifndef CONFIG_NEW_NAND_CODE jffs2_free_cache(part); +#endif list_del(&part->link); free(part); dev->num_parts--; @@ -445,7 +449,9 @@ static void part_delall(struct list_head *head) list_for_each_safe(entry, n, head) { part_tmp = list_entry(entry, struct part_info, link); +#ifndef CONFIG_NEW_NAND_CODE jffs2_free_cache(part_tmp); +#endif list_del(entry); free(part_tmp); } @@ -661,6 +667,7 @@ static int device_validate(u8 type, u8 num, u32 *size) if (num < CFG_MAX_FLASH_BANKS) { extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; *size = flash_info[num].size; + return 0; } @@ -672,8 +679,12 @@ static int device_validate(u8 type, u8 num, u32 *size) } else if (type == MTD_DEV_TYPE_NAND) { #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) if (num < CFG_MAX_NAND_DEVICE) { +#ifdef CONFIG_NEW_NAND_CODE + *size = nand_info[num].size; +#else extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; *size = nand_dev_desc[num].totlen; +#endif return 0; } diff --git a/common/cmd_nand.c b/common/cmd_nand.c index ae4c68ac1f..0c05255855 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -1,15 +1,18 @@ /* - * Rick Bronson and Pantelis Antoniou + * Driver for NAND support, Rick Bronson + * borrowed heavily from: + * (c) 1999 Machine Vision Holdings, Inc. + * (c) 1999, 2000 David Woodhouse + * + * Added 16-bit nand support + * (C) 2004 Texas Instruments */ #include - -#if (CONFIG_COMMANDS & CFG_CMD_NAND) - #include -#include #include -#include +#include +#include #ifdef CONFIG_SHOW_BOOT_PROGRESS # include @@ -18,311 +21,290 @@ # define SHOW_BOOT_PROGRESS(arg) #endif +#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined CONFIG_NEW_NAND_CODE + +#include +#include #include -#include -extern nand_info_t nand_info[]; /* info for NAND chips */ +#ifdef CONFIG_OMAP1510 +void archflashwp(void *archdata, int wp); +#endif -static int nand_dump_oob(nand_info_t *nand, ulong off) -{ - return 0; -} +#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) -static int nand_dump(nand_info_t *nand, ulong off) -{ - int i; - u_char *buf, *p; +/* + * Definition of the out of band configuration structure + */ +struct nand_oob_config { + int ecc_pos[6]; /* position of ECC bytes inside oob */ + int badblock_pos; /* position of bad block flag inside oob -1 = inactive */ + int eccvalid_pos; /* position of ECC valid flag inside oob -1 = inactive */ +} oob_config = { {0}, 0, 0}; - buf = malloc(nand->oobblock + nand->oobsize); - if (!buf) { - puts("No memory for page buffer\n"); - return 1; - } - off &= ~(nand->oobblock - 1); - i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize); - if (i < 0) { - printf("Error (%d) reading page %08x\n", i, off); - free(buf); - return 1; - } - printf("Page %08x dump:\n", off); - i = nand->oobblock >> 4; p = buf; - while (i--) { - printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x" - " %02x %02x %02x %02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], - p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); - p += 16; - } - puts("OOB:\n"); - i = nand->oobsize >> 3; - while (i--) { - printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - p += 8; - } - free(buf); +#undef NAND_DEBUG +#undef PSYCHO_DEBUG - return 0; -} +/* ****************** WARNING ********************* + * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will + * erase (or at least attempt to erase) blocks that are marked + * bad. This can be very handy if you are _sure_ that the block + * is OK, say because you marked a good block bad to test bad + * block handling and you are done testing, or if you have + * accidentally marked blocks bad. + * + * Erasing factory marked bad blocks is a _bad_ idea. If the + * erase succeeds there is no reliable way to find them again, + * and attempting to program or erase bad blocks can affect + * the data in _other_ (good) blocks. + */ +#define ALLOW_ERASE_BAD_DEBUG 0 + +#define CONFIG_MTD_NAND_ECC /* enable ECC */ +#define CONFIG_MTD_NAND_ECC_JFFS2 + +/* bits for nand_rw() `cmd'; or together as needed */ +#define NANDRW_READ 0x01 +#define NANDRW_WRITE 0x00 +#define NANDRW_JFFS2 0x02 +#define NANDRW_JFFS2_SKIP 0x04 + +/* + * Function Prototypes + */ +static void nand_print(struct nand_chip *nand); +int nand_rw (struct nand_chip* nand, int cmd, + size_t start, size_t len, + size_t * retlen, u_char * buf); +int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean); +static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len, + size_t * retlen, u_char *buf, u_char *ecc_code); +static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len, + size_t * retlen, const u_char * buf, u_char * ecc_code); +static void nand_print_bad(struct nand_chip *nand); +static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, u_char * buf); +static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, const u_char * buf); +static int NanD_WaitReady(struct nand_chip *nand, int ale_wait); +#ifdef CONFIG_MTD_NAND_ECC +static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); +static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); +#endif + +struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}}; + +/* Current NAND Device */ +static int curr_device = -1; /* ------------------------------------------------------------------------- */ -static void -arg_off_size(int argc, char *argv[], ulong *off, ulong *size, ulong totsize) +int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - *off = 0; - *size = 0; + int rcode = 0; -#if defined(CONFIG_JFFS2_NAND) && defined(CFG_JFFS_CUSTOM_PART) - if (argc >= 1 && strcmp(argv[0], "partition") == 0) { - int part_num; - struct part_info *part; - const char *partstr; + switch (argc) { + case 0: + case 1: + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + case 2: + if (strcmp(argv[1],"info") == 0) { + int i; - if (argc >= 2) - partstr = argv[1]; - else - partstr = getenv("partition"); + putc ('\n'); - if (partstr) - part_num = (int)simple_strtoul(partstr, NULL, 10); - else - part_num = 0; - - part = jffs2_part_info(part_num); - if (part == NULL) { - printf("\nInvalid partition %d\n", part_num); - return; - } - *size = part->size; - *off = (ulong)part->offset; - } else -#endif - { - if (argc >= 1) - *off = (ulong)simple_strtoul(argv[0], NULL, 16); - else - *off = 0; - - if (argc >= 2) - *size = (ulong)simple_strtoul(argv[1], NULL, 16); - else - *size = totsize - *off; - - } - -} - -int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - int i, dev, ret; - ulong addr, off, size; - char *cmd, *s; - nand_info_t *nand; - - /* at least two arguments please */ - if (argc < 2) - goto usage; - - cmd = argv[1]; - - if (strcmp(cmd, "info") == 0) { - - putc('\n'); - for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { - if (nand_info[i].name) - printf("Device %d: %s\n", i, nand_info[i].name); + for (i=0; i= CFG_MAX_NAND_DEVICE)) - puts("\nno devices available\n"); - else - printf("\nDevice %d: %s\n", nand_curr_device, - nand_info[nand_curr_device].name); - return 0; - } - dev = (int)simple_strtoul(argv[2], NULL, 10); - if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { - puts("No such device\n"); + } else if (strcmp(argv[1],"device") == 0) { + if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) { + puts ("\nno devices available\n"); return 1; } - printf("Device %d: %s", dev, nand_info[dev].name); - puts("... is now current device\n"); - nand_curr_device = dev; + printf ("\nDevice %d: ", curr_device); + nand_print(&nand_dev_desc[curr_device]); return 0; - } - if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && - strncmp(cmd, "dump", 4) != 0 && - strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 -#ifdef CONFIG_MTD_NAND_UNSAFE - && strcmp(cmd, "scrub") != 0 && strcmp(cmd, "biterr") != 0 - && strcmp(cmd, "markbad") != 0 -#endif - ) - goto usage; - - /* the following commands operate on the current device */ - if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE || - !nand_info[nand_curr_device].name) { - puts("\nno devices available\n"); - return 1; - } - nand = &nand_info[nand_curr_device]; - - if (strcmp(cmd, "bad") == 0) { - printf("\nDevice %d bad blocks:\n", nand_curr_device); - for (off = 0; off < nand->size; off += nand->erasesize) - if (nand_block_isbad(nand, off)) - printf(" %08x\n", off); - return 0; - } - - if (strcmp(cmd, "erase") == 0 -#ifdef CONFIG_MTD_NAND_UNSAFE - || strcmp(cmd, "scrub") == 0 -#endif - ) { - -#ifdef CONFIG_MTD_NAND_UNSAFE - i = strcmp(cmd, "scrub") == 0; /* 1 scrub, 0 = erase */ -#endif - - arg_off_size(argc - 2, argv + 2, &off, &size, nand->size); - if (off == 0 && size == 0) + } else if (strcmp(argv[1],"bad") == 0) { + if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) { + puts ("\nno devices available\n"); return 1; + } + printf ("\nDevice %d bad blocks:\n", curr_device); + nand_print_bad(&nand_dev_desc[curr_device]); + return 0; - printf("\nNAND %s: device %d offset 0x%x, size 0x%x ", -#ifdef CONFIG_MTD_NAND_UNSAFE - i ? "scrub" : -#endif - "erase", - nand_curr_device, off, size); + } + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + case 3: + if (strcmp(argv[1],"device") == 0) { + int dev = (int)simple_strtoul(argv[2], NULL, 10); -#ifdef CONFIG_MTD_NAND_UNSAFE - if (i) - ret = nand_scrub(nand, off, size); - else -#endif - ret = nand_erase(nand, off, size); + printf ("\nDevice %d: ", dev); + if (dev >= CFG_MAX_NAND_DEVICE) { + puts ("unknown device\n"); + return 1; + } + nand_print(&nand_dev_desc[dev]); + /*nand_print (dev);*/ + + if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) { + return 1; + } + + curr_device = dev; + + puts ("... is now current device\n"); + + return 0; + } + else if (strcmp(argv[1],"erase") == 0 && strcmp(argv[2], "clean") == 0) { + struct nand_chip* nand = &nand_dev_desc[curr_device]; + ulong off = 0; + ulong size = nand->totlen; + int ret; + + printf ("\nNAND erase: device %d offset %ld, size %ld ... ", + curr_device, off, size); + + ret = nand_erase (nand, off, size, 1); printf("%s\n", ret ? "ERROR" : "OK"); - return ret == 0 ? 0 : 1; + return ret; } - if (strncmp(cmd, "dump", 4) == 0) { - if (argc < 3) - goto usage; - - s = strchr(cmd, '.'); - off = (int)simple_strtoul(argv[2], NULL, 16); - - if (s != NULL && strcmp(s, ".oob") == 0) - ret = nand_dump_oob(nand, off); - else - ret = nand_dump(nand, off); - - return ret == 0 ? 1 : 0; - - } - - /* read write */ - if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { - if (argc < 4) - goto usage; -/* - s = strchr(cmd, '.'); - clean = CLEAN_NONE; - if (s != NULL) { - if (strcmp(s, ".jffs2") == 0 || strcmp(s, ".e") == 0 - || strcmp(s, ".i")) - clean = CLEAN_JFFS2; - } -*/ - addr = (ulong)simple_strtoul(argv[2], NULL, 16); - - arg_off_size(argc - 3, argv + 3, &off, &size, nand->size); - if (off == 0 && size == 0) - return 1; - - i = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ - printf("\nNAND %s: device %d offset %u, size %u ... ", - i ? "read" : "write", nand_curr_device, off, size); - - if (i) - ret = nand_read(nand, off, &size, (u_char *)addr); - else - ret = nand_write(nand, off, &size, (u_char *)addr); - - printf(" %d bytes %s: %s\n", size, - i ? "read" : "written", ret ? "ERROR" : "OK"); - - return ret == 0 ? 0 : 1; - } -#ifdef CONFIG_MTD_NAND_UNSAFE - if (strcmp(cmd, "markbad") == 0 || strcmp(cmd, "biterr") == 0) { - if (argc < 3) - goto usage; - - i = strcmp(cmd, "biterr") == 0; - - off = (int)simple_strtoul(argv[2], NULL, 16); - - if (i) - ret = nand_make_bit_error(nand, off); - else - ret = nand_mark_bad(nand, off); - - return ret == 0 ? 0 : 1; - } -#endif - -usage: - printf("Usage:\n%s\n", cmdtp->usage); + printf ("Usage:\n%s\n", cmdtp->usage); return 1; + default: + /* at least 4 args */ + + if (strncmp(argv[1], "read", 4) == 0 || + strncmp(argv[1], "write", 5) == 0) { + ulong addr = simple_strtoul(argv[2], NULL, 16); + ulong off = simple_strtoul(argv[3], NULL, 16); + ulong size = simple_strtoul(argv[4], NULL, 16); + int cmd = (strncmp(argv[1], "read", 4) == 0) ? + NANDRW_READ : NANDRW_WRITE; + int ret, total; + char* cmdtail = strchr(argv[1], '.'); + + if (cmdtail && !strncmp(cmdtail, ".oob", 2)) { + /* read out-of-band data */ + if (cmd & NANDRW_READ) { + ret = nand_read_oob(nand_dev_desc + curr_device, + off, size, &total, + (u_char*)addr); + } + else { + ret = nand_write_oob(nand_dev_desc + curr_device, + off, size, &total, + (u_char*)addr); + } + return ret; + } + else if (cmdtail && !strncmp(cmdtail, ".jffs2", 2)) + cmd |= NANDRW_JFFS2; /* skip bad blocks */ + else if (cmdtail && !strncmp(cmdtail, ".jffs2s", 2)) { + cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ + if (cmd & NANDRW_READ) + cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ + } +#ifdef SXNI855T + /* need ".e" same as ".j" for compatibility with older units */ + else if (cmdtail && !strcmp(cmdtail, ".e")) + cmd |= NANDRW_JFFS2; /* skip bad blocks */ +#endif +#ifdef CFG_NAND_SKIP_BAD_DOT_I + /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */ + /* ".i" for image -> read skips bad block (no 0xff) */ + else if (cmdtail && !strcmp(cmdtail, ".i")) { + cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ + if (cmd & NANDRW_READ) + cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ + } +#endif /* CFG_NAND_SKIP_BAD_DOT_I */ + else if (cmdtail) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + printf ("\nNAND %s: device %d offset %ld, size %ld ... ", + (cmd & NANDRW_READ) ? "read" : "write", + curr_device, off, size); + + ret = nand_rw(nand_dev_desc + curr_device, cmd, off, size, + &total, (u_char*)addr); + + printf (" %d bytes %s: %s\n", total, + (cmd & NANDRW_READ) ? "read" : "written", + ret ? "ERROR" : "OK"); + + return ret; + } else if (strcmp(argv[1],"erase") == 0 && + (argc == 4 || strcmp("clean", argv[2]) == 0)) { + int clean = argc == 5; + ulong off = simple_strtoul(argv[2 + clean], NULL, 16); + ulong size = simple_strtoul(argv[3 + clean], NULL, 16); + int ret; + + printf ("\nNAND erase: device %d offset %ld, size %ld ... ", + curr_device, off, size); + + ret = nand_erase (nand_dev_desc + curr_device, off, size, clean); + + printf("%s\n", ret ? "ERROR" : "OK"); + + return ret; + } else { + printf ("Usage:\n%s\n", cmdtp->usage); + rcode = 1; + } + + return rcode; + } } -U_BOOT_CMD(nand, 5, 1, do_nand, +U_BOOT_CMD( + nand, 5, 1, do_nand, "nand - NAND sub-system\n", - "info - show available NAND devices\n" - "nand device [dev] - show or set current device\n" - "nand read[.jffs2] - addr off size\n" - "nand write[.jffs2] - addr off size - read/write `size' bytes starting\n" + "info - show available NAND devices\n" + "nand device [dev] - show or set current device\n" + "nand read[.jffs2[s]] addr off size\n" + "nand write[.jffs2] addr off size - read/write `size' bytes starting\n" " at offset `off' to/from memory address `addr'\n" "nand erase [clean] [off size] - erase `size' bytes from\n" " offset `off' (entire device if not specified)\n" "nand bad - show bad blocks\n" - "nand dump[.oob] off - dump page\n" - "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n" - "nand markbad off - mark bad block at offset (UNSAFE)\n" - "nand biterr off - make a bit error at offset (UNSAFE)\n"); + "nand read.oob addr off size - read out-of-band data\n" + "nand write.oob addr off size - read out-of-band data\n" +); -int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *boot_device = NULL; char *ep; int dev; - int r; - ulong addr, cnt, offset = 0; + ulong cnt; + ulong addr; + ulong offset = 0; image_header_t *hdr; - nand_info_t *nand; - + int rcode = 0; switch (argc) { case 1: addr = CFG_LOAD_ADDR; - boot_device = getenv("bootdevice"); + boot_device = getenv ("bootdevice"); break; case 2: addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv("bootdevice"); + boot_device = getenv ("bootdevice"); break; case 3: addr = simple_strtoul(argv[1], NULL, 16); @@ -334,53 +316,55 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) offset = simple_strtoul(argv[3], NULL, 16); break; default: - printf("Usage:\n%s\n", cmdtp->usage); - SHOW_BOOT_PROGRESS(-1); + printf ("Usage:\n%s\n", cmdtp->usage); + SHOW_BOOT_PROGRESS (-1); return 1; } if (!boot_device) { - puts("\n** No boot device **\n"); - SHOW_BOOT_PROGRESS(-1); + puts ("\n** No boot device **\n"); + SHOW_BOOT_PROGRESS (-1); return 1; } dev = simple_strtoul(boot_device, &ep, 16); - if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { - printf("\n** Device %d not available\n", dev); - SHOW_BOOT_PROGRESS(-1); + if ((dev >= CFG_MAX_NAND_DEVICE) || + (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) { + printf ("\n** Device %d not available\n", dev); + SHOW_BOOT_PROGRESS (-1); return 1; } - nand = &nand_info[dev]; - printf("\nLoading from device %d: %s (offset 0x%lx)\n", - dev, nand->name, offset); + printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n", + dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR, + offset); - cnt = nand->oobblock; - r = nand_read(nand, offset, &cnt, (u_char *) addr); - if (r) { - printf("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS(-1); + if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset, + SECTORSIZE, NULL, (u_char *)addr)) { + printf ("** Read error on %d\n", dev); + SHOW_BOOT_PROGRESS (-1); return 1; } - hdr = (image_header_t *) addr; + hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); - SHOW_BOOT_PROGRESS(-1); + if (ntohl(hdr->ih_magic) == IH_MAGIC) { + + print_image_hdr (hdr); + + cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); + cnt -= SECTORSIZE; + } else { + printf ("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); + SHOW_BOOT_PROGRESS (-1); return 1; } - print_image_hdr(hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t)); - - r = nand_read(nand, offset, &cnt, (u_char *) addr); - if (r) { - printf("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS(-1); + if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset + SECTORSIZE, cnt, + NULL, (u_char *)(addr+SECTORSIZE))) { + printf ("** Read error on %d\n", dev); + SHOW_BOOT_PROGRESS (-1); return 1; } @@ -389,24 +373,1526 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) load_addr = addr; /* Check if we should attempt an auto-start */ - if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) { + if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { char *local_args[2]; - extern int do_bootm(cmd_tbl_t *, int, int, char *[]); + extern int do_bootm (cmd_tbl_t *, int, int, char *[]); local_args[0] = argv[0]; local_args[1] = NULL; - printf("Automatic boot of image at addr 0x%08lx ...\n", addr); + printf ("Automatic boot of image at addr 0x%08lx ...\n", addr); - do_bootm(cmdtp, 0, 1, local_args); - return 1; + do_bootm (cmdtp, 0, 1, local_args); + rcode = 1; } + return rcode; +} + +U_BOOT_CMD( + nboot, 4, 1, do_nandboot, + "nboot - boot from NAND device\n", + "loadAddr dev\n" +); + +/* returns 0 if block containing pos is OK: + * valid erase block and + * not marked bad, or no bad mark position is specified + * returns 1 if marked bad or otherwise invalid + */ +int check_block (struct nand_chip *nand, unsigned long pos) +{ + int retlen; + uint8_t oob_data; + uint16_t oob_data16[6]; + int page0 = pos & (-nand->erasesize); + int page1 = page0 + nand->oobblock; + int badpos = oob_config.badblock_pos; + + if (pos >= nand->totlen) + return 1; + + if (badpos < 0) + return 0; /* no way to check, assume OK */ + + if (nand->bus16) { + if (nand_read_oob(nand, (page0 + 0), 12, &retlen, (uint8_t *)oob_data16) + || (oob_data16[2] & 0xff00) != 0xff00) + return 1; + if (nand_read_oob(nand, (page1 + 0), 12, &retlen, (uint8_t *)oob_data16) + || (oob_data16[2] & 0xff00) != 0xff00) + return 1; + } else { + /* Note - bad block marker can be on first or second page */ + if (nand_read_oob(nand, page0 + badpos, 1, &retlen, &oob_data) + || oob_data != 0xff + || nand_read_oob (nand, page1 + badpos, 1, &retlen, &oob_data) + || oob_data != 0xff) + return 1; + } + return 0; } -U_BOOT_CMD(nboot, 4, 1, do_nandboot, - "nboot - boot from NAND device\n", "loadAddr dev\n"); +/* print bad blocks in NAND flash */ +static void nand_print_bad(struct nand_chip* nand) +{ + unsigned long pos; + + for (pos = 0; pos < nand->totlen; pos += nand->erasesize) { + if (check_block(nand, pos)) + printf(" 0x%8.8lx\n", pos); + } + puts("\n"); +} + +/* cmd: 0: NANDRW_WRITE write, fail on bad block + * 1: NANDRW_READ read, fail on bad block + * 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks + * 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks + * 7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks + */ +int nand_rw (struct nand_chip* nand, int cmd, + size_t start, size_t len, + size_t * retlen, u_char * buf) +{ + int ret = 0, n, total = 0; + char eccbuf[6]; + /* eblk (once set) is the start of the erase block containing the + * data being processed. + */ + unsigned long eblk = ~0; /* force mismatch on first pass */ + unsigned long erasesize = nand->erasesize; + + while (len) { + if ((start & (-erasesize)) != eblk) { + /* have crossed into new erase block, deal with + * it if it is sure marked bad. + */ + eblk = start & (-erasesize); /* start of block */ + if (check_block(nand, eblk)) { + if (cmd == (NANDRW_READ | NANDRW_JFFS2)) { + while (len > 0 && + start - eblk < erasesize) { + *(buf++) = 0xff; + ++start; + ++total; + --len; + } + continue; + } else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) { + start += erasesize; + continue; + } else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) { + /* skip bad block */ + start += erasesize; + continue; + } else { + ret = 1; + break; + } + } + } + /* The ECC will not be calculated correctly if + less than 512 is written or read */ + /* Is request at least 512 bytes AND it starts on a proper boundry */ + if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200)) + printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n"); + + if (cmd & NANDRW_READ) { + ret = nand_read_ecc(nand, start, + min(len, eblk + erasesize - start), + &n, (u_char*)buf, eccbuf); + } else { + ret = nand_write_ecc(nand, start, + min(len, eblk + erasesize - start), + &n, (u_char*)buf, eccbuf); + } + + if (ret) + break; + + start += n; + buf += n; + total += n; + len -= n; + } + if (retlen) + *retlen = total; + + return ret; +} + +static void nand_print(struct nand_chip *nand) +{ + if (nand->numchips > 1) { + printf("%s at 0x%lx,\n" + "\t %d chips %s, size %d MB, \n" + "\t total size %ld MB, sector size %ld kB\n", + nand->name, nand->IO_ADDR, nand->numchips, + nand->chips_name, 1 << (nand->chipshift - 20), + nand->totlen >> 20, nand->erasesize >> 10); + } + else { + printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR); + print_size(nand->totlen, ", "); + print_size(nand->erasesize, " sector)\n"); + } +} + +/* ------------------------------------------------------------------------- */ + +static int NanD_WaitReady(struct nand_chip *nand, int ale_wait) +{ + /* This is inline, to optimise the common case, where it's ready instantly */ + int ret = 0; + +#ifdef NAND_NO_RB /* in config file, shorter delays currently wrap accesses */ + if(ale_wait) + NAND_WAIT_READY(nand); /* do the worst case 25us wait */ + else + udelay(10); +#else /* has functional r/b signal */ + NAND_WAIT_READY(nand); +#endif + return ret; +} + +/* NanD_Command: Send a flash command to the flash chip */ + +static inline int NanD_Command(struct nand_chip *nand, unsigned char command) +{ + unsigned long nandptr = nand->IO_ADDR; + + /* Assert the CLE (Command Latch Enable) line to the flash chip */ + NAND_CTL_SETCLE(nandptr); + + /* Send the command */ + WRITE_NAND_COMMAND(command, nandptr); + + /* Lower the CLE line */ + NAND_CTL_CLRCLE(nandptr); + +#ifdef NAND_NO_RB + if(command == NAND_CMD_RESET){ + u_char ret_val; + NanD_Command(nand, NAND_CMD_STATUS); + do { + ret_val = READ_NAND(nandptr);/* wait till ready */ + } while((ret_val & 0x40) != 0x40); + } +#endif + return NanD_WaitReady(nand, 0); +} + +/* NanD_Address: Set the current address for the flash chip */ + +static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs) +{ + unsigned long nandptr; + int i; + + nandptr = nand->IO_ADDR; + + /* Assert the ALE (Address Latch Enable) line to the flash chip */ + NAND_CTL_SETALE(nandptr); + + /* Send the address */ + /* Devices with 256-byte page are addressed as: + * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31) + * there is no device on the market with page256 + * and more than 24 bits. + * Devices with 512-byte page are addressed as: + * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31) + * 25-31 is sent only if the chip support it. + * bit 8 changes the read command to be sent + * (NAND_CMD_READ0 or NAND_CMD_READ1). + */ + + if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) + WRITE_NAND_ADDRESS(ofs, nandptr); + + ofs = ofs >> nand->page_shift; + + if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) { + for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) { + WRITE_NAND_ADDRESS(ofs, nandptr); + } + } + + /* Lower the ALE line */ + NAND_CTL_CLRALE(nandptr); + + /* Wait for the chip to respond */ + return NanD_WaitReady(nand, 1); +} + +/* NanD_SelectChip: Select a given flash chip within the current floor */ + +static inline int NanD_SelectChip(struct nand_chip *nand, int chip) +{ + /* Wait for it to be ready */ + return NanD_WaitReady(nand, 0); +} + +/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */ + +static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip) +{ + int mfr, id, i; + + NAND_ENABLE_CE(nand); /* set pin low */ + /* Reset the chip */ + if (NanD_Command(nand, NAND_CMD_RESET)) { +#ifdef NAND_DEBUG + printf("NanD_Command (reset) for %d,%d returned true\n", + floor, chip); +#endif + NAND_DISABLE_CE(nand); /* set pin high */ + return 0; + } + + /* Read the NAND chip ID: 1. Send ReadID command */ + if (NanD_Command(nand, NAND_CMD_READID)) { +#ifdef NAND_DEBUG + printf("NanD_Command (ReadID) for %d,%d returned true\n", + floor, chip); +#endif + NAND_DISABLE_CE(nand); /* set pin high */ + return 0; + } + + /* Read the NAND chip ID: 2. Send address byte zero */ + NanD_Address(nand, ADDR_COLUMN, 0); + + /* Read the manufacturer and device id codes from the device */ + + mfr = READ_NAND(nand->IO_ADDR); + + id = READ_NAND(nand->IO_ADDR); + + NAND_DISABLE_CE(nand); /* set pin high */ + +#ifdef NAND_DEBUG + printf("NanD_Command (ReadID) got %x %x\n", mfr, id); +#endif + if (mfr == 0xff || mfr == 0) { + /* No response - return failure */ + return 0; + } + + /* Check it's the same as the first chip we identified. + * M-Systems say that any given nand_chip device should only + * contain _one_ type of flash part, although that's not a + * hardware restriction. */ + if (nand->mfr) { + if (nand->mfr == mfr && nand->id == id) { + return 1; /* This is another the same the first */ + } else { + printf("Flash chip at floor %d, chip %d is different:\n", + floor, chip); + } + } + + /* Print and store the manufacturer and ID codes. */ + for (i = 0; nand_flash_ids[i].name != NULL; i++) { + if (mfr == nand_flash_ids[i].manufacture_id && + id == nand_flash_ids[i].model_id) { +#ifdef NAND_DEBUG + printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, " + "Chip ID: 0x%2.2X (%s)\n", mfr, id, + nand_flash_ids[i].name); +#endif + if (!nand->mfr) { + nand->mfr = mfr; + nand->id = id; + nand->chipshift = + nand_flash_ids[i].chipshift; + nand->page256 = nand_flash_ids[i].page256; + nand->eccsize = 256; + if (nand->page256) { + nand->oobblock = 256; + nand->oobsize = 8; + nand->page_shift = 8; + } else { + nand->oobblock = 512; + nand->oobsize = 16; + nand->page_shift = 9; + } + nand->pageadrlen = nand_flash_ids[i].pageadrlen; + nand->erasesize = nand_flash_ids[i].erasesize; + nand->chips_name = nand_flash_ids[i].name; + nand->bus16 = nand_flash_ids[i].bus16; + return 1; + } + return 0; + } + } -#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ +#ifdef NAND_DEBUG + /* We haven't fully identified the chip. Print as much as we know. */ + printf("Unknown flash chip found: %2.2X %2.2X\n", + id, mfr); +#endif + return 0; +} + +/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */ + +static void NanD_ScanChips(struct nand_chip *nand) +{ + int floor, chip; + int numchips[NAND_MAX_FLOORS]; + int maxchips = NAND_MAX_CHIPS; + int ret = 1; + + nand->numchips = 0; + nand->mfr = 0; + nand->id = 0; + + + /* For each floor, find the number of valid chips it contains */ + for (floor = 0; floor < NAND_MAX_FLOORS; floor++) { + ret = 1; + numchips[floor] = 0; + for (chip = 0; chip < maxchips && ret != 0; chip++) { + + ret = NanD_IdentChip(nand, floor, chip); + if (ret) { + numchips[floor]++; + nand->numchips++; + } + } + } + + /* If there are none at all that we recognise, bail */ + if (!nand->numchips) { +#ifdef NAND_DEBUG + puts ("No NAND flash chips recognised.\n"); +#endif + return; + } + + /* Allocate an array to hold the information for each chip */ + nand->chips = malloc(sizeof(struct Nand) * nand->numchips); + if (!nand->chips) { + puts ("No memory for allocating chip info structures\n"); + return; + } + + ret = 0; + + /* Fill out the chip array with {floor, chipno} for each + * detected chip in the device. */ + for (floor = 0; floor < NAND_MAX_FLOORS; floor++) { + for (chip = 0; chip < numchips[floor]; chip++) { + nand->chips[ret].floor = floor; + nand->chips[ret].chip = chip; + nand->chips[ret].curadr = 0; + nand->chips[ret].curmode = 0x50; + ret++; + } + } + + /* Calculate and print the total size of the device */ + nand->totlen = nand->numchips * (1 << nand->chipshift); + +#ifdef NAND_DEBUG + printf("%d flash chips found. Total nand_chip size: %ld MB\n", + nand->numchips, nand->totlen >> 20); +#endif +} + +/* we need to be fast here, 1 us per read translates to 1 second per meg */ +static void NanD_ReadBuf (struct nand_chip *nand, u_char * data_buf, int cntr) +{ + unsigned long nandptr = nand->IO_ADDR; + + NanD_Command (nand, NAND_CMD_READ0); + + if (nand->bus16) { + u16 val; + + while (cntr >= 16) { + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + cntr -= 16; + } + + while (cntr > 0) { + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + cntr -= 2; + } + } else { + while (cntr >= 16) { + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + cntr -= 16; + } + + while (cntr > 0) { + *data_buf++ = READ_NAND (nandptr); + cntr--; + } + } +} + +/* + * NAND read with ECC + */ +static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len, + size_t * retlen, u_char *buf, u_char *ecc_code) +{ + int col, page; + int ecc_status = 0; +#ifdef CONFIG_MTD_NAND_ECC + int j; + int ecc_failed = 0; + u_char *data_poi; + u_char ecc_calc[6]; +#endif + + /* Do not allow reads past end of device */ + if ((start + len) > nand->totlen) { + printf ("%s: Attempt read beyond end of device %x %x %x\n", + __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen); + *retlen = 0; + return -1; + } + + /* First we calculate the starting page */ + /*page = shr(start, nand->page_shift);*/ + page = start >> nand->page_shift; + + /* Get raw starting column */ + col = start & (nand->oobblock - 1); + + /* Initialize return value */ + *retlen = 0; + + /* Select the NAND device */ + NAND_ENABLE_CE(nand); /* set pin low */ + + /* Loop until all data read */ + while (*retlen < len) { + +#ifdef CONFIG_MTD_NAND_ECC + /* Do we have this page in cache ? */ + if (nand->cache_page == page) + goto readdata; + /* Send the read command */ + NanD_Command(nand, NAND_CMD_READ0); + if (nand->bus16) { + NanD_Address(nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address(nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + + /* Read in a page + oob data */ + NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize); + + /* copy data into cache, for read out of cache and if ecc fails */ + if (nand->data_cache) { + memcpy (nand->data_cache, nand->data_buf, + nand->oobblock + nand->oobsize); + } + + /* Pick the ECC bytes out of the oob data */ + for (j = 0; j < 6; j++) { + ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])]; + } + + /* Calculate the ECC and verify it */ + /* If block was not written with ECC, skip ECC */ + if (oob_config.eccvalid_pos != -1 && + (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) { + + nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]); + switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) { + case -1: + printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page); + ecc_failed++; + break; + case 1: + case 2: /* transfer ECC corrected data to cache */ + if (nand->data_cache) + memcpy (nand->data_cache, nand->data_buf, 256); + break; + } + } + + if (oob_config.eccvalid_pos != -1 && + nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) { + + nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]); + switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) { + case -1: + printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page); + ecc_failed++; + break; + case 1: + case 2: /* transfer ECC corrected data to cache */ + if (nand->data_cache) + memcpy (&nand->data_cache[256], &nand->data_buf[256], 256); + break; + } + } +readdata: + /* Read the data from ECC data buffer into return buffer */ + data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf; + data_poi += col; + if ((*retlen + (nand->oobblock - col)) >= len) { + memcpy (buf + *retlen, data_poi, len - *retlen); + *retlen = len; + } else { + memcpy (buf + *retlen, data_poi, nand->oobblock - col); + *retlen += nand->oobblock - col; + } + /* Set cache page address, invalidate, if ecc_failed */ + nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1; + + ecc_status += ecc_failed; + ecc_failed = 0; + +#else + /* Send the read command */ + NanD_Command(nand, NAND_CMD_READ0); + if (nand->bus16) { + NanD_Address(nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address(nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + + /* Read the data directly into the return buffer */ + if ((*retlen + (nand->oobblock - col)) >= len) { + NanD_ReadBuf(nand, buf + *retlen, len - *retlen); + *retlen = len; + /* We're done */ + continue; + } else { + NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col); + *retlen += nand->oobblock - col; + } +#endif + /* For subsequent reads align to page boundary. */ + col = 0; + /* Increment page address */ + page++; + } + + /* De-select the NAND device */ + NAND_DISABLE_CE(nand); /* set pin high */ + + /* + * Return success, if no ECC failures, else -EIO + * fs driver will take care of that, because + * retlen == desired len and result == -EIO + */ + return ecc_status ? -1 : 0; +} + +/* + * Nand_page_program function is used for write and writev ! + */ +static int nand_write_page (struct nand_chip *nand, + int page, int col, int last, u_char * ecc_code) +{ + + int i; + unsigned long nandptr = nand->IO_ADDR; + +#ifdef CONFIG_MTD_NAND_ECC +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE + int ecc_bytes = (nand->oobblock == 512) ? 6 : 3; +#endif +#endif + /* pad oob area */ + for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++) + nand->data_buf[i] = 0xff; + +#ifdef CONFIG_MTD_NAND_ECC + /* Zero out the ECC array */ + for (i = 0; i < 6; i++) + ecc_code[i] = 0x00; + + /* Read back previous written data, if col > 0 */ + if (col) { + NanD_Command (nand, NAND_CMD_READ0); + if (nand->bus16) { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + + if (nand->bus16) { + u16 val; + + for (i = 0; i < col; i += 2) { + val = READ_NAND (nandptr); + nand->data_buf[i] = val & 0xff; + nand->data_buf[i + 1] = val >> 8; + } + } else { + for (i = 0; i < col; i++) + nand->data_buf[i] = READ_NAND (nandptr); + } + } + + /* Calculate and write the ECC if we have enough data */ + if ((col < nand->eccsize) && (last >= nand->eccsize)) { + nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0])); + for (i = 0; i < 3; i++) { + nand->data_buf[(nand->oobblock + + oob_config.ecc_pos[i])] = ecc_code[i]; + } + if (oob_config.eccvalid_pos != -1) { + nand->data_buf[nand->oobblock + + oob_config.eccvalid_pos] = 0xf0; + } + } + + /* Calculate and write the second ECC if we have enough data */ + if ((nand->oobblock == 512) && (last == nand->oobblock)) { + nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3])); + for (i = 3; i < 6; i++) { + nand->data_buf[(nand->oobblock + + oob_config.ecc_pos[i])] = ecc_code[i]; + } + if (oob_config.eccvalid_pos != -1) { + nand->data_buf[nand->oobblock + + oob_config.eccvalid_pos] &= 0x0f; + } + } +#endif + /* Prepad for partial page programming !!! */ + for (i = 0; i < col; i++) + nand->data_buf[i] = 0xff; + + /* Postpad for partial page programming !!! oob is already padded */ + for (i = last; i < nand->oobblock; i++) + nand->data_buf[i] = 0xff; + + /* Send command to begin auto page programming */ + NanD_Command (nand, NAND_CMD_READ0); + NanD_Command (nand, NAND_CMD_SEQIN); + if (nand->bus16) { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + + /* Write out complete page of data */ + if (nand->bus16) { + for (i = 0; i < (nand->oobblock + nand->oobsize); i += 2) { + WRITE_NAND (nand->data_buf[i] + + (nand->data_buf[i + 1] << 8), + nand->IO_ADDR); + } + } else { + for (i = 0; i < (nand->oobblock + nand->oobsize); i++) + WRITE_NAND (nand->data_buf[i], nand->IO_ADDR); + } + + /* Send command to actually program the data */ + NanD_Command (nand, NAND_CMD_PAGEPROG); + NanD_Command (nand, NAND_CMD_STATUS); +#ifdef NAND_NO_RB + { + u_char ret_val; + + do { + ret_val = READ_NAND (nandptr); /* wait till ready */ + } while ((ret_val & 0x40) != 0x40); + } +#endif + /* See if device thinks it succeeded */ + if (READ_NAND (nand->IO_ADDR) & 0x01) { + printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, + page); + return -1; + } +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE + /* + * The NAND device assumes that it is always writing to + * a cleanly erased page. Hence, it performs its internal + * write verification only on bits that transitioned from + * 1 to 0. The device does NOT verify the whole page on a + * byte by byte basis. It is possible that the page was + * not completely erased or the page is becoming unusable + * due to wear. The read with ECC would catch the error + * later when the ECC page check fails, but we would rather + * catch it early in the page write stage. Better to write + * no data than invalid data. + */ + + /* Send command to read back the page */ + if (col < nand->eccsize) + NanD_Command (nand, NAND_CMD_READ0); + else + NanD_Command (nand, NAND_CMD_READ1); + if (nand->bus16) { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + + /* Loop through and verify the data */ + if (nand->bus16) { + for (i = col; i < last; i = +2) { + if ((nand->data_buf[i] + + (nand->data_buf[i + 1] << 8)) != READ_NAND (nand->IO_ADDR)) { + printf ("%s: Failed write verify, page 0x%08x ", + __FUNCTION__, page); + return -1; + } + } + } else { + for (i = col; i < last; i++) { + if (nand->data_buf[i] != READ_NAND (nand->IO_ADDR)) { + printf ("%s: Failed write verify, page 0x%08x ", + __FUNCTION__, page); + return -1; + } + } + } + +#ifdef CONFIG_MTD_NAND_ECC + /* + * We also want to check that the ECC bytes wrote + * correctly for the same reasons stated above. + */ + NanD_Command (nand, NAND_CMD_READOOB); + if (nand->bus16) { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + if (nand->bus16) { + for (i = 0; i < nand->oobsize; i += 2) { + u16 val; + + val = READ_NAND (nand->IO_ADDR); + nand->data_buf[i] = val & 0xff; + nand->data_buf[i + 1] = val >> 8; + } + } else { + for (i = 0; i < nand->oobsize; i++) { + nand->data_buf[i] = READ_NAND (nand->IO_ADDR); + } + } + for (i = 0; i < ecc_bytes; i++) { + if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) { + printf ("%s: Failed ECC write " + "verify, page 0x%08x, " + "%6i bytes were succesful\n", + __FUNCTION__, page, i); + return -1; + } + } +#endif /* CONFIG_MTD_NAND_ECC */ +#endif /* CONFIG_MTD_NAND_VERIFY_WRITE */ + return 0; +} + +static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len, + size_t * retlen, const u_char * buf, u_char * ecc_code) +{ + int i, page, col, cnt, ret = 0; + + /* Do not allow write past end of device */ + if ((to + len) > nand->totlen) { + printf ("%s: Attempt to write past end of page\n", __FUNCTION__); + return -1; + } + + /* Shift to get page */ + page = ((int) to) >> nand->page_shift; + + /* Get the starting column */ + col = to & (nand->oobblock - 1); + + /* Initialize return length value */ + *retlen = 0; + + /* Select the NAND device */ +#ifdef CONFIG_OMAP1510 + archflashwp(0,0); +#endif +#ifdef CFG_NAND_WP + NAND_WP_OFF(); +#endif + + NAND_ENABLE_CE(nand); /* set pin low */ + + /* Check the WP bit */ + NanD_Command(nand, NAND_CMD_STATUS); + if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { + printf ("%s: Device is write protected!!!\n", __FUNCTION__); + ret = -1; + goto out; + } + + /* Loop until all data is written */ + while (*retlen < len) { + /* Invalidate cache, if we write to this page */ + if (nand->cache_page == page) + nand->cache_page = -1; + + /* Write data into buffer */ + if ((col + len) >= nand->oobblock) { + for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++) { + nand->data_buf[i] = buf[(*retlen + cnt)]; + } + } else { + for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++) { + nand->data_buf[i] = buf[(*retlen + cnt)]; + } + } + /* We use the same function for write and writev !) */ + ret = nand_write_page (nand, page, col, i, ecc_code); + if (ret) + goto out; + + /* Next data start at page boundary */ + col = 0; + + /* Update written bytes count */ + *retlen += cnt; + + /* Increment page address */ + page++; + } + + /* Return happy */ + *retlen = len; + +out: + /* De-select the NAND device */ + NAND_DISABLE_CE(nand); /* set pin high */ +#ifdef CONFIG_OMAP1510 + archflashwp(0,1); +#endif +#ifdef CFG_NAND_WP + NAND_WP_ON(); +#endif + + return ret; +} + +/* read from the 16 bytes of oob data that correspond to a 512 byte + * page or 2 256-byte pages. + */ +static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, u_char * buf) +{ + int len256 = 0; + struct Nand *mychip; + int ret = 0; + + mychip = &nand->chips[ofs >> nand->chipshift]; + + /* update address for 2M x 8bit devices. OOB starts on the second */ + /* page to maintain compatibility with nand_read_ecc. */ + if (nand->page256) { + if (!(ofs & 0x8)) + ofs += 0x100; + else + ofs -= 0x8; + } + + NAND_ENABLE_CE(nand); /* set pin low */ + NanD_Command(nand, NAND_CMD_READOOB); + if (nand->bus16) { + NanD_Address(nand, ADDR_COLUMN_PAGE, + ((ofs >> nand->page_shift) << nand->page_shift) + + ((ofs & (nand->oobblock - 1)) >> 1)); + } else { + NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); + } + + /* treat crossing 8-byte OOB data for 2M x 8bit devices */ + /* Note: datasheet says it should automaticaly wrap to the */ + /* next OOB block, but it didn't work here. mf. */ + if (nand->page256 && ofs + len > (ofs | 0x7) + 1) { + len256 = (ofs | 0x7) + 1 - ofs; + NanD_ReadBuf(nand, buf, len256); + + NanD_Command(nand, NAND_CMD_READOOB); + NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff)); + } + + NanD_ReadBuf(nand, &buf[len256], len - len256); + + *retlen = len; + /* Reading the full OOB data drops us off of the end of the page, + * causing the flash device to go into busy mode, so we need + * to wait until ready 11.4.1 and Toshiba TC58256FT nands */ + + ret = NanD_WaitReady(nand, 1); + NAND_DISABLE_CE(nand); /* set pin high */ + + return ret; + +} + +/* write to the 16 bytes of oob data that correspond to a 512 byte + * page or 2 256-byte pages. + */ +static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, const u_char * buf) +{ + int len256 = 0; + int i; + unsigned long nandptr = nand->IO_ADDR; + +#ifdef PSYCHO_DEBUG + printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n", + (long)ofs, len, buf[0], buf[1], buf[2], buf[3], + buf[8], buf[9], buf[14],buf[15]); +#endif + + NAND_ENABLE_CE(nand); /* set pin low to enable chip */ + + /* Reset the chip */ + NanD_Command(nand, NAND_CMD_RESET); + + /* issue the Read2 command to set the pointer to the Spare Data Area. */ + NanD_Command(nand, NAND_CMD_READOOB); + if (nand->bus16) { + NanD_Address(nand, ADDR_COLUMN_PAGE, + ((ofs >> nand->page_shift) << nand->page_shift) + + ((ofs & (nand->oobblock - 1)) >> 1)); + } else { + NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); + } + + /* update address for 2M x 8bit devices. OOB starts on the second */ + /* page to maintain compatibility with nand_read_ecc. */ + if (nand->page256) { + if (!(ofs & 0x8)) + ofs += 0x100; + else + ofs -= 0x8; + } + + /* issue the Serial Data In command to initial the Page Program process */ + NanD_Command(nand, NAND_CMD_SEQIN); + if (nand->bus16) { + NanD_Address(nand, ADDR_COLUMN_PAGE, + ((ofs >> nand->page_shift) << nand->page_shift) + + ((ofs & (nand->oobblock - 1)) >> 1)); + } else { + NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); + } + + /* treat crossing 8-byte OOB data for 2M x 8bit devices */ + /* Note: datasheet says it should automaticaly wrap to the */ + /* next OOB block, but it didn't work here. mf. */ + if (nand->page256 && ofs + len > (ofs | 0x7) + 1) { + len256 = (ofs | 0x7) + 1 - ofs; + for (i = 0; i < len256; i++) + WRITE_NAND(buf[i], nandptr); + + NanD_Command(nand, NAND_CMD_PAGEPROG); + NanD_Command(nand, NAND_CMD_STATUS); +#ifdef NAND_NO_RB + { u_char ret_val; + do { + ret_val = READ_NAND(nandptr); /* wait till ready */ + } while ((ret_val & 0x40) != 0x40); + } +#endif + if (READ_NAND(nandptr) & 1) { + puts ("Error programming oob data\n"); + /* There was an error */ + NAND_DISABLE_CE(nand); /* set pin high */ + *retlen = 0; + return -1; + } + NanD_Command(nand, NAND_CMD_SEQIN); + NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff)); + } + + if (nand->bus16) { + for (i = len256; i < len; i += 2) { + WRITE_NAND(buf[i] + (buf[i+1] << 8), nandptr); + } + } else { + for (i = len256; i < len; i++) + WRITE_NAND(buf[i], nandptr); + } + + NanD_Command(nand, NAND_CMD_PAGEPROG); + NanD_Command(nand, NAND_CMD_STATUS); +#ifdef NAND_NO_RB + { u_char ret_val; + do { + ret_val = READ_NAND(nandptr); /* wait till ready */ + } while ((ret_val & 0x40) != 0x40); + } +#endif + if (READ_NAND(nandptr) & 1) { + puts ("Error programming oob data\n"); + /* There was an error */ + NAND_DISABLE_CE(nand); /* set pin high */ + *retlen = 0; + return -1; + } + + NAND_DISABLE_CE(nand); /* set pin high */ + *retlen = len; + return 0; + +} + +int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean) +{ + /* This is defined as a structure so it will work on any system + * using native endian jffs2 (the default). + */ + static struct jffs2_unknown_node clean_marker = { + JFFS2_MAGIC_BITMASK, + JFFS2_NODETYPE_CLEANMARKER, + 8 /* 8 bytes in this node */ + }; + unsigned long nandptr; + struct Nand *mychip; + int ret = 0; + + if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) { + printf ("Offset and size must be sector aligned, erasesize = %d\n", + (int) nand->erasesize); + return -1; + } + + nandptr = nand->IO_ADDR; + + /* Select the NAND device */ +#ifdef CONFIG_OMAP1510 + archflashwp(0,0); +#endif +#ifdef CFG_NAND_WP + NAND_WP_OFF(); +#endif + NAND_ENABLE_CE(nand); /* set pin low */ + + /* Check the WP bit */ + NanD_Command(nand, NAND_CMD_STATUS); + if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { + printf ("nand_write_ecc: Device is write protected!!!\n"); + ret = -1; + goto out; + } + + /* Check the WP bit */ + NanD_Command(nand, NAND_CMD_STATUS); + if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { + printf ("%s: Device is write protected!!!\n", __FUNCTION__); + ret = -1; + goto out; + } + + /* FIXME: Do nand in the background. Use timers or schedule_task() */ + while(len) { + /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/ + mychip = &nand->chips[ofs >> nand->chipshift]; + + /* always check for bad block first, genuine bad blocks + * should _never_ be erased. + */ + if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) { + /* Select the NAND device */ + NAND_ENABLE_CE(nand); /* set pin low */ + + NanD_Command(nand, NAND_CMD_ERASE1); + NanD_Address(nand, ADDR_PAGE, ofs); + NanD_Command(nand, NAND_CMD_ERASE2); + + NanD_Command(nand, NAND_CMD_STATUS); + +#ifdef NAND_NO_RB + { u_char ret_val; + do { + ret_val = READ_NAND(nandptr); /* wait till ready */ + } while ((ret_val & 0x40) != 0x40); + } +#endif + if (READ_NAND(nandptr) & 1) { + printf ("%s: Error erasing at 0x%lx\n", + __FUNCTION__, (long)ofs); + /* There was an error */ + ret = -1; + goto out; + } + if (clean) { + int n; /* return value not used */ + int p, l; + + /* clean marker position and size depend + * on the page size, since 256 byte pages + * only have 8 bytes of oob data + */ + if (nand->page256) { + p = NAND_JFFS2_OOB8_FSDAPOS; + l = NAND_JFFS2_OOB8_FSDALEN; + } else { + p = NAND_JFFS2_OOB16_FSDAPOS; + l = NAND_JFFS2_OOB16_FSDALEN; + } + + ret = nand_write_oob(nand, ofs + p, l, &n, + (u_char *)&clean_marker); + /* quit here if write failed */ + if (ret) + goto out; + } + } + ofs += nand->erasesize; + len -= nand->erasesize; + } + +out: + /* De-select the NAND device */ + NAND_DISABLE_CE(nand); /* set pin high */ +#ifdef CONFIG_OMAP1510 + archflashwp(0,1); +#endif +#ifdef CFG_NAND_WP + NAND_WP_ON(); +#endif + + return ret; +} + +static inline int nandcheck(unsigned long potential, unsigned long physadr) +{ + return 0; +} + +unsigned long nand_probe(unsigned long physadr) +{ + struct nand_chip *nand = NULL; + int i = 0, ChipID = 1; + +#ifdef CONFIG_MTD_NAND_ECC_JFFS2 + oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0; + oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1; + oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2; + oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3; + oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4; + oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5; + oob_config.eccvalid_pos = 4; +#else + oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0; + oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1; + oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2; + oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3; + oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4; + oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5; + oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS; +#endif + oob_config.badblock_pos = 5; + + for (i=0; iIO_ADDR = physadr; + nand->cache_page = -1; /* init the cache page */ + NanD_ScanChips(nand); + + if (nand->totlen == 0) { + /* no chips found, clean up and quit */ + memset((char *)nand, 0, sizeof(struct nand_chip)); + nand->ChipID = NAND_ChipID_UNKNOWN; + return (0); + } + + nand->ChipID = ChipID; + if (curr_device == -1) + curr_device = i; + + nand->data_buf = malloc (nand->oobblock + nand->oobsize); + if (!nand->data_buf) { + puts ("Cannot allocate memory for data structures.\n"); + return (0); + } + + return (nand->totlen); +} + +#ifdef CONFIG_MTD_NAND_ECC +/* + * Pre-calculated 256-way 1 byte column parity + */ +static const u_char nand_ecc_precalc_table[] = { + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, + 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, + 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, + 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, + 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, + 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, + 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, + 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, + 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, + 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, + 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, + 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, + 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, + 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, + 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, + 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, + 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 +}; + + +/* + * Creates non-inverted ECC code from line parity + */ +static void nand_trans_result(u_char reg2, u_char reg3, + u_char *ecc_code) +{ + u_char a, b, i, tmp1, tmp2; + + /* Initialize variables */ + a = b = 0x80; + tmp1 = tmp2 = 0; + + /* Calculate first ECC byte */ + for (i = 0; i < 4; i++) { + if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ + tmp1 |= b; + b >>= 1; + if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */ + tmp1 |= b; + b >>= 1; + a >>= 1; + } + + /* Calculate second ECC byte */ + b = 0x80; + for (i = 0; i < 4; i++) { + if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */ + tmp2 |= b; + b >>= 1; + if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */ + tmp2 |= b; + b >>= 1; + a >>= 1; + } + + /* Store two of the ECC bytes */ + ecc_code[0] = tmp1; + ecc_code[1] = tmp2; +} + +/* + * Calculate 3 byte ECC code for 256 byte block + */ +static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code) +{ + u_char idx, reg1, reg3; + int j; + + /* Initialize variables */ + reg1 = reg3 = 0; + ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; + + /* Build up column parity */ + for(j = 0; j < 256; j++) { + + /* Get CP0 - CP5 from table */ + idx = nand_ecc_precalc_table[dat[j]]; + reg1 ^= idx; + + /* All bit XOR = 1 ? */ + if (idx & 0x40) { + reg3 ^= (u_char) j; + } + } + + /* Create non-inverted ECC code from line parity */ + nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code); + + /* Calculate final ECC code */ + ecc_code[0] = ~ecc_code[0]; + ecc_code[1] = ~ecc_code[1]; + ecc_code[2] = ((~reg1) << 2) | 0x03; +} + +/* + * Detect and correct a 1 bit error for 256 byte block + */ +static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc) +{ + u_char a, b, c, d1, d2, d3, add, bit, i; + + /* Do error detection */ + d1 = calc_ecc[0] ^ read_ecc[0]; + d2 = calc_ecc[1] ^ read_ecc[1]; + d3 = calc_ecc[2] ^ read_ecc[2]; + + if ((d1 | d2 | d3) == 0) { + /* No errors */ + return 0; + } else { + a = (d1 ^ (d1 >> 1)) & 0x55; + b = (d2 ^ (d2 >> 1)) & 0x55; + c = (d3 ^ (d3 >> 1)) & 0x54; + + /* Found and will correct single bit error in the data */ + if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { + c = 0x80; + add = 0; + a = 0x80; + for (i=0; i<4; i++) { + if (d1 & c) + add |= a; + c >>= 2; + a >>= 1; + } + c = 0x80; + for (i=0; i<4; i++) { + if (d2 & c) + add |= a; + c >>= 2; + a >>= 1; + } + bit = 0; + b = 0x04; + c = 0x80; + for (i=0; i<3; i++) { + if (d3 & c) + bit |= b; + c >>= 2; + b >>= 1; + } + b = 0x01; + a = dat[add]; + a ^= (b << bit); + dat[add] = a; + return 1; + } + else { + i = 0; + while (d1) { + if (d1 & 0x01) + ++i; + d1 >>= 1; + } + while (d2) { + if (d2 & 0x01) + ++i; + d2 >>= 1; + } + while (d3) { + if (d3 & 0x01) + ++i; + d3 >>= 1; + } + if (i == 1) { + /* ECC Code Error Correction */ + read_ecc[0] = calc_ecc[0]; + read_ecc[1] = calc_ecc[1]; + read_ecc[2] = calc_ecc[2]; + return 2; + } + else { + /* Uncorrectable Error */ + return -1; + } + } + } + + /* Should never happen */ + return -1; +} + +#endif + +#ifdef CONFIG_JFFS2_NAND + +int read_jffs2_nand(size_t start, size_t len, + size_t * retlen, u_char * buf, int nanddev) +{ + return nand_rw(nand_dev_desc + nanddev, NANDRW_READ | NANDRW_JFFS2, + start, len, retlen, buf); +} + +#endif /* CONFIG_JFFS2_NAND */ + + +#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ diff --git a/common/cmd_nand_new.c b/common/cmd_nand_new.c new file mode 100644 index 0000000000..3ff2ebaf60 --- /dev/null +++ b/common/cmd_nand_new.c @@ -0,0 +1,364 @@ +#include + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) && defined CONFIG_NEW_NAND_CODE + +#include +#include +#include +#include + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# include +# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) +#else +# define SHOW_BOOT_PROGRESS(arg) +#endif + +#include +#include + +extern nand_info_t nand_info[]; /* info for NAND chips */ + +static int nand_dump_oob(nand_info_t *nand, ulong off) +{ + return 0; +} + +static int nand_dump(nand_info_t *nand, ulong off) +{ + int i; + u_char *buf, *p; + + buf = malloc(nand->oobblock + nand->oobsize); + if (!buf) { + puts("No memory for page buffer\n"); + return 1; + } + off &= ~(nand->oobblock - 1); + i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize); + if (i < 0) { + printf("Error (%d) reading page %08x\n", i, off); + free(buf); + return 1; + } + printf("Page %08x dump:\n", off); + i = nand->oobblock >> 4; p = buf; + while (i--) { + printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x" + " %02x %02x %02x %02x %02x %02x %02x %02x\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); + p += 16; + } + puts("OOB:\n"); + i = nand->oobsize >> 3; + while (i--) { + printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + p += 8; + } + free(buf); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static void +arg_off_size(int argc, char *argv[], ulong *off, ulong *size, ulong totsize) +{ + *off = 0; + *size = 0; + +#if defined(CONFIG_JFFS2_NAND) && defined(CFG_JFFS_CUSTOM_PART) + if (argc >= 1 && strcmp(argv[0], "partition") == 0) { + int part_num; + struct part_info *part; + const char *partstr; + + if (argc >= 2) + partstr = argv[1]; + else + partstr = getenv("partition"); + + if (partstr) + part_num = (int)simple_strtoul(partstr, NULL, 10); + else + part_num = 0; + + part = jffs2_part_info(part_num); + if (part == NULL) { + printf("\nInvalid partition %d\n", part_num); + return; + } + *size = part->size; + *off = (ulong)part->offset; + } else +#endif + { + if (argc >= 1) + *off = (ulong)simple_strtoul(argv[0], NULL, 16); + else + *off = 0; + + if (argc >= 2) + *size = (ulong)simple_strtoul(argv[1], NULL, 16); + else + *size = totsize - *off; + + } + +} + +int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + int i, dev, ret; + ulong addr, off, size; + char *cmd, *s; + nand_info_t *nand; + + /* at least two arguments please */ + if (argc < 2) + goto usage; + + cmd = argv[1]; + + if (strcmp(cmd, "info") == 0) { + + putc('\n'); + for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { + if (nand_info[i].name) + printf("Device %d: %s\n", i, nand_info[i].name); + } + return 0; + } + + if (strcmp(cmd, "device") == 0) { + + if (argc < 3) { + if ((nand_curr_device < 0) || + (nand_curr_device >= CFG_MAX_NAND_DEVICE)) + puts("\nno devices available\n"); + else + printf("\nDevice %d: %s\n", nand_curr_device, + nand_info[nand_curr_device].name); + return 0; + } + dev = (int)simple_strtoul(argv[2], NULL, 10); + if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { + puts("No such device\n"); + return 1; + } + printf("Device %d: %s", dev, nand_info[dev].name); + puts("... is now current device\n"); + nand_curr_device = dev; + return 0; + } + + if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && + strncmp(cmd, "dump", 4) != 0 && + strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0) + goto usage; + + /* the following commands operate on the current device */ + if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE || + !nand_info[nand_curr_device].name) { + puts("\nno devices available\n"); + return 1; + } + nand = &nand_info[nand_curr_device]; + + if (strcmp(cmd, "bad") == 0) { + printf("\nDevice %d bad blocks:\n", nand_curr_device); + for (off = 0; off < nand->size; off += nand->erasesize) + if (nand_block_isbad(nand, off)) + printf(" %08x\n", off); + return 0; + } + + if (strcmp(cmd, "erase") == 0) { + arg_off_size(argc - 2, argv + 2, &off, &size, nand->size); + if (off == 0 && size == 0) + return 1; + + printf("\nNAND erase: device %d offset 0x%x, size 0x%x ", + nand_curr_device, off, size); + ret = nand_erase(nand, off, size); + printf("%s\n", ret ? "ERROR" : "OK"); + + return ret == 0 ? 0 : 1; + } + + if (strncmp(cmd, "dump", 4) == 0) { + if (argc < 3) + goto usage; + + s = strchr(cmd, '.'); + off = (int)simple_strtoul(argv[2], NULL, 16); + + if (s != NULL && strcmp(s, ".oob") == 0) + ret = nand_dump_oob(nand, off); + else + ret = nand_dump(nand, off); + + return ret == 0 ? 1 : 0; + + } + + /* read write */ + if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { + if (argc < 4) + goto usage; +/* + s = strchr(cmd, '.'); + clean = CLEAN_NONE; + if (s != NULL) { + if (strcmp(s, ".jffs2") == 0 || strcmp(s, ".e") == 0 + || strcmp(s, ".i")) + clean = CLEAN_JFFS2; + } +*/ + addr = (ulong)simple_strtoul(argv[2], NULL, 16); + + arg_off_size(argc - 3, argv + 3, &off, &size, nand->size); + if (off == 0 && size == 0) + return 1; + + i = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ + printf("\nNAND %s: device %d offset %u, size %u ... ", + i ? "read" : "write", nand_curr_device, off, size); + + if (i) + ret = nand_read(nand, off, &size, (u_char *)addr); + else + ret = nand_write(nand, off, &size, (u_char *)addr); + + printf(" %d bytes %s: %s\n", size, + i ? "read" : "written", ret ? "ERROR" : "OK"); + + return ret == 0 ? 0 : 1; + } +usage: + printf("Usage:\n%s\n", cmdtp->usage); + return 1; +} + +U_BOOT_CMD(nand, 5, 1, do_nand, + "nand - NAND sub-system\n", + "info - show available NAND devices\n" + "nand device [dev] - show or set current device\n" + "nand read[.jffs2] - addr off size\n" + "nand write[.jffs2] - addr off size - read/write `size' bytes starting\n" + " at offset `off' to/from memory address `addr'\n" + "nand erase [clean] [off size] - erase `size' bytes from\n" + " offset `off' (entire device if not specified)\n" + "nand bad - show bad blocks\n" + "nand dump[.oob] off - dump page\n" + "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n" + "nand markbad off - mark bad block at offset (UNSAFE)\n" + "nand biterr off - make a bit error at offset (UNSAFE)\n"); + +int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + char *boot_device = NULL; + char *ep; + int dev; + int r; + ulong addr, cnt, offset = 0; + image_header_t *hdr; + nand_info_t *nand; + + switch (argc) { + case 1: + addr = CFG_LOAD_ADDR; + boot_device = getenv("bootdevice"); + break; + case 2: + addr = simple_strtoul(argv[1], NULL, 16); + boot_device = getenv("bootdevice"); + break; + case 3: + addr = simple_strtoul(argv[1], NULL, 16); + boot_device = argv[2]; + break; + case 4: + addr = simple_strtoul(argv[1], NULL, 16); + boot_device = argv[2]; + offset = simple_strtoul(argv[3], NULL, 16); + break; + default: + printf("Usage:\n%s\n", cmdtp->usage); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + if (!boot_device) { + puts("\n** No boot device **\n"); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + dev = simple_strtoul(boot_device, &ep, 16); + + if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { + printf("\n** Device %d not available\n", dev); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + nand = &nand_info[dev]; + printf("\nLoading from device %d: %s (offset 0x%lx)\n", + dev, nand->name, offset); + + cnt = nand->oobblock; + r = nand_read(nand, offset, &cnt, (u_char *) addr); + if (r) { + printf("** Read error on %d\n", dev); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + hdr = (image_header_t *) addr; + + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + print_image_hdr(hdr); + + cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t)); + + r = nand_read(nand, offset, &cnt, (u_char *) addr); + if (r) { + printf("** Read error on %d\n", dev); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + /* Loading ok, update default load address */ + + load_addr = addr; + + /* Check if we should attempt an auto-start */ + if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) { + char *local_args[2]; + extern int do_bootm(cmd_tbl_t *, int, int, char *[]); + + local_args[0] = argv[0]; + local_args[1] = NULL; + + printf("Automatic boot of image at addr 0x%08lx ...\n", addr); + + do_bootm(cmdtp, 0, 1, local_args); + return 1; + } + return 0; +} + +U_BOOT_CMD(nboot, 4, 1, do_nandboot, + "nboot - boot from NAND device\n", "loadAddr dev\n"); + + +#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ diff --git a/cpu/arm925t/config.mk b/cpu/arm925t/config.mk index cef7d26f1c..960df4c989 100644 --- a/cpu/arm925t/config.mk +++ b/cpu/arm925t/config.mk @@ -22,6 +22,6 @@ # PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ - -mshort-load-bytes -msoft-float + -msoft-float PLATFORM_CPPFLAGS += -mapcs-32 -march=armv4 diff --git a/drivers/nand/Makefile b/drivers/nand/Makefile index 3906bf951d..96f67dfca8 100644 --- a/drivers/nand/Makefile +++ b/drivers/nand/Makefile @@ -14,4 +14,3 @@ $(LIB): $(OBJS) $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ sinclude .depend - diff --git a/drivers/nand/diskonchip.c b/drivers/nand/diskonchip.c index 02135c3ac2..b421d4c1c3 100644 --- a/drivers/nand/diskonchip.c +++ b/drivers/nand/diskonchip.c @@ -1,4 +1,4 @@ -/* +/* * drivers/mtd/nand/diskonchip.c * * (C) 2003 Red Hat, Inc. @@ -8,12 +8,12 @@ * Author: David Woodhouse * Additional Diskonchip 2000 and Millennium support by Dan Brown * Diskonchip Millennium Plus support by Kalev Lember - * + * * Error correction code lifted from the old docecc code - * Author: Fabrice Bellard (fabrice.bellard@netgem.com) + * Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Copyright (C) 2000 Netgem S.A. * converted to the generic Reed-Solomon library by Thomas Gleixner - * + * * Interface to generic NAND code for M-Systems DiskOnChip devices * * $Id: diskonchip.c,v 1.45 2005/01/05 18:05:14 dwmw2 Exp $ @@ -42,25 +42,25 @@ static unsigned long __initdata doc_locations[] = { #if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) #ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH - 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, + 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, - 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, - 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, + 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, + 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000, #else /* CONFIG_MTD_DOCPROBE_HIGH */ - 0xc8000, 0xca000, 0xcc000, 0xce000, + 0xc8000, 0xca000, 0xcc000, 0xce000, 0xd0000, 0xd2000, 0xd4000, 0xd6000, - 0xd8000, 0xda000, 0xdc000, 0xde000, - 0xe0000, 0xe2000, 0xe4000, 0xe6000, + 0xd8000, 0xda000, 0xdc000, 0xde000, + 0xe0000, 0xe2000, 0xe4000, 0xe6000, 0xe8000, 0xea000, 0xec000, 0xee000, #endif /* CONFIG_MTD_DOCPROBE_HIGH */ #elif defined(__PPC__) 0xe4000000, #elif defined(CONFIG_MOMENCO_OCELOT) 0x2f000000, - 0xff000000, + 0xff000000, #elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C) - 0xff000000, + 0xff000000, ##else #warning Unknown architecture for DiskOnChip. No default probe locations defined #endif @@ -142,7 +142,7 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe /* the Reed Solomon control structure */ static struct rs_control *rs_decoder; -/* +/* * The HW decoder in the DoC ASIC's provides us a error syndrome, * which we must convert to a standard syndrom usable by the generic * Reed-Solomon library code. @@ -167,8 +167,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) /* Initialize the syndrom buffer */ for (i = 0; i < NROOTS; i++) s[i] = ds[0]; - /* - * Evaluate + /* + * Evaluate * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0] * where x = alpha^(FCR + i) */ @@ -192,7 +192,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) if (nerr < 0) return nerr; - /* + /* * Correct the errors. The bitpositions are a bit of magic, * but they are given by the design of the de/encoder circuit * in the DoC ASIC's. @@ -209,7 +209,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) can be modified since pos is even */ index = (pos >> 3) ^ 1; bitpos = pos & 7; - if ((index >= 0 && index < SECTOR_SIZE) || + if ((index >= 0 && index < SECTOR_SIZE) || index == (SECTOR_SIZE + 1)) { val = (uint8_t) (errval[i] >> (2 + bitpos)); parity ^= val; @@ -220,7 +220,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) bitpos = (bitpos + 10) & 7; if (bitpos == 0) bitpos = 8; - if ((index >= 0 && index < SECTOR_SIZE) || + if ((index >= 0 && index < SECTOR_SIZE) || index == (SECTOR_SIZE + 1)) { val = (uint8_t)(errval[i] << (8 - bitpos)); parity ^= val; @@ -237,7 +237,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles) { volatile char dummy; int i; - + for (i = 0; i < cycles; i++) { if (DoC_is_Millennium(doc)) dummy = ReadDOC(doc->virtadr, NOP); @@ -246,7 +246,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles) else dummy = ReadDOC(doc->virtadr, DOCStatus); } - + } #define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1) @@ -254,7 +254,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles) /* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ static int _DoC_WaitReady(struct doc_priv *doc) { - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; unsigned long timeo = jiffies + (HZ * 10); if(debug) printk("_DoC_WaitReady...\n"); @@ -284,7 +284,7 @@ static int _DoC_WaitReady(struct doc_priv *doc) static inline int DoC_WaitReady(struct doc_priv *doc) { - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int ret = 0; if (DoC_is_MillenniumPlus(doc)) { @@ -310,7 +310,7 @@ static void doc2000_write_byte(struct mtd_info *mtd, u_char datum) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; if(debug)printk("write_byte %02x\n", datum); WriteDOC(datum, docptr, CDSNSlowIO); @@ -321,7 +321,7 @@ static u_char doc2000_read_byte(struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; u_char ret; ReadDOC(docptr, CDSNSlowIO); @@ -331,12 +331,12 @@ static u_char doc2000_read_byte(struct mtd_info *mtd) return ret; } -static void doc2000_writebuf(struct mtd_info *mtd, +static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int i; if (debug)printk("writebuf of %d bytes: ", len); for (i=0; i < len; i++) { @@ -347,12 +347,12 @@ static void doc2000_writebuf(struct mtd_info *mtd, if (debug) printk("\n"); } -static void doc2000_readbuf(struct mtd_info *mtd, +static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int i; if (debug)printk("readbuf of %d bytes: ", len); @@ -362,12 +362,12 @@ static void doc2000_readbuf(struct mtd_info *mtd, } } -static void doc2000_readbuf_dword(struct mtd_info *mtd, +static void doc2000_readbuf_dword(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int i; if (debug) printk("readbuf_dword of %d bytes: ", len); @@ -383,12 +383,12 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd, } } -static int doc2000_verifybuf(struct mtd_info *mtd, +static int doc2000_verifybuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int i; for (i=0; i < len; i++) @@ -435,7 +435,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) this->read_buf = &doc2000_readbuf_dword; } } - + return ret; } @@ -466,7 +466,7 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state) struct doc_priv *doc = this->priv; int status; - + DoC_WaitReady(doc); this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); DoC_WaitReady(doc); @@ -479,7 +479,7 @@ static void doc2001_write_byte(struct mtd_info *mtd, u_char datum) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; WriteDOC(datum, docptr, CDSNSlowIO); WriteDOC(datum, docptr, Mil_CDSN_IO); @@ -490,22 +490,22 @@ static u_char doc2001_read_byte(struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; - //ReadDOC(docptr, CDSNSlowIO); + /*ReadDOC(docptr, CDSNSlowIO); */ /* 11.4.5 -- delay twice to allow extended length cycle */ DoC_Delay(doc, 2); ReadDOC(docptr, ReadPipeInit); - //return ReadDOC(docptr, Mil_CDSN_IO); + /*return ReadDOC(docptr, Mil_CDSN_IO); */ return ReadDOC(docptr, LastDataRead); } -static void doc2001_writebuf(struct mtd_info *mtd, +static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int i; for (i=0; i < len; i++) @@ -514,12 +514,12 @@ static void doc2001_writebuf(struct mtd_info *mtd, WriteDOC(0x00, docptr, WritePipeTerm); } -static void doc2001_readbuf(struct mtd_info *mtd, +static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int i; /* Start read pipeline */ @@ -532,12 +532,12 @@ static void doc2001_readbuf(struct mtd_info *mtd, buf[i] = ReadDOC(docptr, LastDataRead); } -static int doc2001_verifybuf(struct mtd_info *mtd, +static int doc2001_verifybuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int i; /* Start read pipeline */ @@ -557,22 +557,22 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; u_char ret; - ReadDOC(docptr, Mplus_ReadPipeInit); - ReadDOC(docptr, Mplus_ReadPipeInit); - ret = ReadDOC(docptr, Mplus_LastDataRead); + ReadDOC(docptr, Mplus_ReadPipeInit); + ReadDOC(docptr, Mplus_ReadPipeInit); + ret = ReadDOC(docptr, Mplus_LastDataRead); if (debug) printk("read_byte returns %02x\n", ret); return ret; } -static void doc2001plus_writebuf(struct mtd_info *mtd, +static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int i; if (debug)printk("writebuf of %d bytes: ", len); @@ -584,12 +584,12 @@ static void doc2001plus_writebuf(struct mtd_info *mtd, if (debug) printk("\n"); } -static void doc2001plus_readbuf(struct mtd_info *mtd, +static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int i; if (debug)printk("readbuf of %d bytes: ", len); @@ -614,12 +614,12 @@ static void doc2001plus_readbuf(struct mtd_info *mtd, if (debug) printk("\n"); } -static int doc2001plus_verifybuf(struct mtd_info *mtd, +static int doc2001plus_verifybuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int i; if (debug)printk("verifybuf of %d bytes: ", len); @@ -645,7 +645,7 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int floor = 0; if(debug)printk("select chip (%d)\n", chip); @@ -671,7 +671,7 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int floor = 0; if(debug)printk("select chip (%d)\n", chip); @@ -698,7 +698,7 @@ static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; switch(cmd) { case NAND_CTL_SETNCE: @@ -736,7 +736,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; /* * Must terminate write pipeline before sending any commands @@ -794,7 +794,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col WriteDOC(0, docptr, Mplus_FlashControl); } - /* + /* * program and erase have their own busy handlers * status and sequential in needs no delay */ @@ -819,7 +819,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col /* This applies to read commands */ default: - /* + /* * If we don't have access to the busy pin, we apply the given * command delay */ @@ -840,7 +840,7 @@ static int doc200x_dev_ready(struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; if (DoC_is_MillenniumPlus(doc)) { /* 11.4.2 -- must NOP four times before checking FR/B# */ @@ -878,7 +878,7 @@ static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; /* Prime the ECC engine */ switch(mode) { @@ -897,7 +897,7 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; /* Prime the ECC engine */ switch(mode) { @@ -918,7 +918,7 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; int i; int emptymatch = 1; @@ -942,7 +942,7 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, for (i = 0; i < 6; i++) { if (DoC_is_MillenniumPlus(doc)) ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); - else + else ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); if (ecc_code[i] != empty_write_ecc[i]) emptymatch = 0; @@ -976,10 +976,10 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ int i, ret = 0; struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - void __iomem *docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; volatile u_char dummy; int emptymatch = 1; - + /* flush the pipeline */ if (DoC_is_2000(doc)) { dummy = ReadDOC(docptr, 2k_ECCStatus); @@ -994,7 +994,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ dummy = ReadDOC(docptr, ECCConf); dummy = ReadDOC(docptr, ECCConf); } - + /* Error occured ? */ if (dummy & 0x80) { for (i = 0; i < 6; i++) { @@ -1032,7 +1032,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc); if (ret > 0) printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); - } + } if (DoC_is_MillenniumPlus(doc)) WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); else @@ -1043,16 +1043,16 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ } return ret; } - -//u_char mydatabuf[528]; + +/*u_char mydatabuf[528]; */ static struct nand_oobinfo doc200x_oobinfo = { - .useecc = MTD_NANDECC_AUTOPLACE, - .eccbytes = 6, - .eccpos = {0, 1, 2, 3, 4, 5}, - .oobfree = { {8, 8} } + .useecc = MTD_NANDECC_AUTOPLACE, + .eccbytes = 6, + .eccpos = {0, 1, 2, 3, 4, 5}, + .oobfree = { {8, 8} } }; - + /* Find the (I)NFTL Media Header, and optionally also the mirror media header. On sucessful return, buf will contain a copy of the media header for further processing. id is the string to scan for, and will presumably be @@ -1068,7 +1068,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, int ret; size_t retlen; - end = min(end, mtd->size); // paranoia + end = min(end, mtd->size); /* paranoia */ for (offs = 0; offs < end; offs += mtd->erasesize) { ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf); if (retlen != mtd->oobblock) continue; @@ -1122,8 +1122,8 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out; mh = (struct NFTLMediaHeader *) buf; -//#ifdef CONFIG_MTD_DEBUG_VERBOSE -// if (CONFIG_MTD_DEBUG_VERBOSE >= 2) +/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */ +/* if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */ printk(KERN_INFO " DataOrgID = %s\n" " NumEraseUnits = %d\n" " FirstPhysicalEUN = %d\n" @@ -1132,7 +1132,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, mh->DataOrgID, mh->NumEraseUnits, mh->FirstPhysicalEUN, mh->FormattedSize, mh->UnitSizeFactor); -//#endif +/*#endif */ blocks = mtd->size >> this->phys_erase_shift; maxblocks = min(32768U, mtd->erasesize - psize); @@ -1175,9 +1175,9 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, offs <<= this->page_shift; offs += mtd->erasesize; - //parts[0].name = " DiskOnChip Boot / Media Header partition"; - //parts[0].offset = 0; - //parts[0].size = offs; + /*parts[0].name = " DiskOnChip Boot / Media Header partition"; */ + /*parts[0].offset = 0; */ + /*parts[0].size = offs; */ parts[0].name = " DiskOnChip BDTL partition"; parts[0].offset = offs; @@ -1232,9 +1232,9 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits); mh->FormatFlags = le32_to_cpu(mh->FormatFlags); mh->PercentUsed = le32_to_cpu(mh->PercentUsed); - -//#ifdef CONFIG_MTD_DEBUG_VERBOSE -// if (CONFIG_MTD_DEBUG_VERBOSE >= 2) + +/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */ +/* if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */ printk(KERN_INFO " bootRecordID = %s\n" " NoOfBootImageBlocks = %d\n" " NoOfBinaryPartitions = %d\n" @@ -1252,7 +1252,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, ((unsigned char *) &mh->OsakVersion)[2] & 0xf, ((unsigned char *) &mh->OsakVersion)[3] & 0xf, mh->PercentUsed); -//#endif +/*#endif */ vshift = this->phys_erase_shift + mh->BlockMultiplierBits; @@ -1278,8 +1278,8 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, ip->spareUnits = le32_to_cpu(ip->spareUnits); ip->Reserved0 = le32_to_cpu(ip->Reserved0); -//#ifdef CONFIG_MTD_DEBUG_VERBOSE -// if (CONFIG_MTD_DEBUG_VERBOSE >= 2) +/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */ +/* if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */ printk(KERN_INFO " PARTITION[%d] ->\n" " virtualUnits = %d\n" " firstUnit = %d\n" @@ -1289,7 +1289,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, i, ip->virtualUnits, ip->firstUnit, ip->lastUnit, ip->flags, ip->spareUnits); -//#endif +/*#endif */ /* if ((i == 0) && (ip->firstUnit > 0)) { @@ -1456,7 +1456,7 @@ static inline int __init doc2001_init(struct mtd_info *mtd) ReadDOC(doc->virtadr, ChipID); if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) { /* It's not a Millennium; it's one of the newer - DiskOnChip 2000 units with a similar ASIC. + DiskOnChip 2000 units with a similar ASIC. Treat it like a Millennium, except that it can have multiple chips. */ doc2000_count_chips(mtd); @@ -1518,20 +1518,20 @@ static inline int __init doc_probe(unsigned long physadr) * to the DOCControl register. So we store the current contents * of the DOCControl register's location, in case we later decide * that it's not a DiskOnChip, and want to put it back how we - * found it. + * found it. */ save_control = ReadDOC(virtadr, DOCControl); /* Reset the DiskOnChip ASIC */ - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, virtadr, DOCControl); - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, virtadr, DOCControl); /* Enable the DiskOnChip ASIC */ - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, virtadr, DOCControl); - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, virtadr, DOCControl); ChipID = ReadDOC(virtadr, ChipID); @@ -1614,11 +1614,11 @@ static inline int __init doc_probe(unsigned long physadr) if (ChipID == DOC_ChipID_DocMilPlus16) { WriteDOC(~newval, virtadr, Mplus_AliasResolution); oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution); - WriteDOC(newval, virtadr, Mplus_AliasResolution); // restore it + WriteDOC(newval, virtadr, Mplus_AliasResolution); /* restore it */ } else { WriteDOC(~newval, virtadr, AliasResolution); oldval = ReadDOC(doc->virtadr, AliasResolution); - WriteDOC(newval, virtadr, AliasResolution); // restore it + WriteDOC(newval, virtadr, AliasResolution); /* restore it */ } newval = ~newval; if (oldval == newval) { @@ -1726,7 +1726,7 @@ static int __init init_nanddoc(void) int i, ret = 0; /* We could create the decoder on demand, if memory is a concern. - * This way we have it handy, if an error happens + * This way we have it handy, if an error happens * * Symbolsize is 10 (bits) * Primitve polynomial is x^10+x^3+1 diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c index c423512f18..a7ab8c27ad 100644 --- a/drivers/nand/nand_base.c +++ b/drivers/nand/nand_base.c @@ -5,14 +5,14 @@ * This is the generic MTD driver for NAND flash devices. It should be * capable of working with almost all NAND chips currently available. * Basic support for AG-AND chips is provided. - * + * * Additional technical information is available on * http://www.linux-mtd.infradead.org/tech/nand.html - * + * * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * 2002 Thomas Gleixner (tglx@linutronix.de) * - * 02-08-2004 tglx: support for strange chips, which cannot auto increment + * 02-08-2004 tglx: support for strange chips, which cannot auto increment * pages on read / read_oob * * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes @@ -21,7 +21,7 @@ * Make reads over block boundaries work too * * 04-14-2004 tglx: first working version for 2k page size chips - * + * * 05-19-2004 tglx: Basic support for Renesas AG-AND chips * * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared @@ -29,8 +29,8 @@ * from Ben Dooks * * Credits: - * David Woodhouse for adding multichip support - * + * David Woodhouse for adding multichip support + * * Aleph One Ltd. and Toby Churchill Ltd. for supporting the * rework for 2K page size chips * @@ -68,7 +68,7 @@ #include #endif -#else +#endif #include @@ -88,8 +88,6 @@ #include #endif -#endif - /* Define default oob placement schemes for large and small page devices */ static struct nand_oobinfo nand_oob_8 = { .useecc = MTD_NANDECC_AUTOPLACE, @@ -109,8 +107,8 @@ static struct nand_oobinfo nand_oob_64 = { .useecc = MTD_NANDECC_AUTOPLACE, .eccbytes = 24, .eccpos = { - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}, .oobfree = { {2, 38} } }; @@ -156,19 +154,19 @@ static void nand_sync (struct mtd_info *mtd); static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, struct nand_oobinfo *oobsel, int mode); #ifdef CONFIG_MTD_NAND_VERIFY_WRITE -static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, +static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode); #else #define nand_verify_pages(...) (0) #endif - + static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); /** * nand_release_device - [GENERIC] release chip * @mtd: MTD device structure - * - * Deselect, release chip lock and wake up anyone waiting on the device + * + * Deselect, release chip lock and wake up anyone waiting on the device */ /* XXX U-BOOT XXX */ #if 0 @@ -223,7 +221,7 @@ static void nand_write_byte(struct mtd_info *mtd, u_char byte) * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip * @mtd: MTD device structure * - * Default read function for 16bit buswith with + * Default read function for 16bit buswith with * endianess conversion */ static u_char nand_read_byte16(struct mtd_info *mtd) @@ -250,7 +248,7 @@ static void nand_write_byte16(struct mtd_info *mtd, u_char byte) * nand_read_word - [DEFAULT] read one word from the chip * @mtd: MTD device structure * - * Default read function for 16bit buswith without + * Default read function for 16bit buswith without * endianess conversion */ static u16 nand_read_word(struct mtd_info *mtd) @@ -264,7 +262,7 @@ static u16 nand_read_word(struct mtd_info *mtd) * @mtd: MTD device structure * @word: data word to write * - * Default write function for 16bit buswith without + * Default write function for 16bit buswith without * endianess conversion */ static void nand_write_word(struct mtd_info *mtd, u16 word) @@ -285,7 +283,7 @@ static void nand_select_chip(struct mtd_info *mtd, int chip) struct nand_chip *this = mtd->priv; switch(chip) { case -1: - this->hwcontrol(mtd, NAND_CTL_CLRNCE); + this->hwcontrol(mtd, NAND_CTL_CLRNCE); break; case 0: this->hwcontrol(mtd, NAND_CTL_SETNCE); @@ -314,7 +312,7 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) } /** - * nand_read_buf - [DEFAULT] read chip data into buffer + * nand_read_buf - [DEFAULT] read chip data into buffer * @mtd: MTD device structure * @buf: buffer to store date * @len: number of bytes to read @@ -331,7 +329,7 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) } /** - * nand_verify_buf - [DEFAULT] Verify chip data against buffer + * nand_verify_buf - [DEFAULT] Verify chip data against buffer * @mtd: MTD device structure * @buf: buffer containing the data to compare * @len: number of bytes to compare @@ -364,14 +362,14 @@ static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) struct nand_chip *this = mtd->priv; u16 *p = (u16 *) buf; len >>= 1; - + for (i=0; iIO_ADDR_W); - + } /** - * nand_read_buf16 - [DEFAULT] read chip data into buffer + * nand_read_buf16 - [DEFAULT] read chip data into buffer * @mtd: MTD device structure * @buf: buffer to store date * @len: number of bytes to read @@ -390,7 +388,7 @@ static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len) } /** - * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer + * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer * @mtd: MTD device structure * @buf: buffer containing the data to compare * @len: number of bytes to compare @@ -417,7 +415,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) * @ofs: offset from device start * @getchip: 0, if the chip is already selected * - * Check, if the block is bad. + * Check, if the block is bad. */ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) { @@ -434,8 +432,8 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) /* Select the NAND device */ this->select_chip(mtd, chipnr); - } else - page = (int) ofs; + } else + page = (int) ofs; if (this->options & NAND_BUSWIDTH_16) { this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask); @@ -449,12 +447,12 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) if (this->read_byte(mtd) != 0xff) res = 1; } - + if (getchip) { /* Deselect and wake up anyone waiting on the device */ nand_release_device(mtd); - } - + } + return res; } @@ -472,7 +470,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) u_char buf[2] = {0, 0}; size_t retlen; int block; - + /* Get block number */ block = ((int) ofs) >> this->bbt_erase_shift; this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); @@ -480,25 +478,25 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) /* Do we have a flash based bad block table ? */ if (this->options & NAND_USE_FLASH_BBT) return nand_update_bbt (mtd, ofs); - + /* We write two bytes, so we dont have to mess with 16 bit access */ ofs += mtd->oobsize + (this->badblockpos & ~0x01); return nand_write_oob (mtd, ofs , 2, &retlen, buf); } -/** +/** * nand_check_wp - [GENERIC] check if the chip is write protected * @mtd: MTD device structure - * Check, if the device is write protected + * Check, if the device is write protected * - * The function expects, that the device is already selected + * The function expects, that the device is already selected */ static int nand_check_wp (struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; /* Check the WP bit */ this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); - return (this->read_byte(mtd) & 0x80) ? 0 : 1; + return (this->read_byte(mtd) & 0x80) ? 0 : 1; } /** @@ -514,10 +512,10 @@ static int nand_check_wp (struct mtd_info *mtd) static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) { struct nand_chip *this = mtd->priv; - + if (!this->bbt) return this->block_bad(mtd, ofs, getchip); - + /* Return info from the table */ return nand_isbad_bbt (mtd, ofs, allowbbt); } @@ -582,13 +580,13 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in /* Latch in address */ this->hwcontrol(mtd, NAND_CTL_CLRALE); } - - /* - * program and erase have their own busy handlers + + /* + * program and erase have their own busy handlers * status and sequential in needs no delay */ switch (command) { - + case NAND_CMD_PAGEPROG: case NAND_CMD_ERASE1: case NAND_CMD_ERASE2: @@ -597,7 +595,7 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in return; case NAND_CMD_RESET: - if (this->dev_ready) + if (this->dev_ready) break; udelay(this->chip_delay); this->hwcontrol(mtd, NAND_CTL_SETCLE); @@ -606,18 +604,18 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in while ( !(this->read_byte(mtd) & 0x40)); return; - /* This applies to read commands */ + /* This applies to read commands */ default: - /* + /* * If we don't have access to the busy pin, we apply the given * command delay */ if (!this->dev_ready) { udelay (this->chip_delay); return; - } + } } - + /* Apply this short delay always to ensure that we do wait tWB in * any case on any machine. */ ndelay (100); @@ -646,8 +644,8 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, column += mtd->oobblock; command = NAND_CMD_READ0; } - - + + /* Begin command latch cycle */ this->hwcontrol(mtd, NAND_CTL_SETCLE); /* Write out the command to the device. */ @@ -665,7 +663,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, column >>= 1; this->write_byte(mtd, column & 0xff); this->write_byte(mtd, column >> 8); - } + } if (page_addr != -1) { this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); @@ -676,13 +674,13 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, /* Latch in address */ this->hwcontrol(mtd, NAND_CTL_CLRALE); } - - /* - * program and erase have their own busy handlers + + /* + * program and erase have their own busy handlers * status and sequential in needs no delay */ switch (command) { - + case NAND_CMD_CACHEDPROG: case NAND_CMD_PAGEPROG: case NAND_CMD_ERASE1: @@ -693,7 +691,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, case NAND_CMD_RESET: - if (this->dev_ready) + if (this->dev_ready) break; udelay(this->chip_delay); this->hwcontrol(mtd, NAND_CTL_SETCLE); @@ -710,19 +708,19 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, /* End command latch cycle */ this->hwcontrol(mtd, NAND_CTL_CLRCLE); /* Fall through into ready check */ - - /* This applies to read commands */ + + /* This applies to read commands */ default: - /* + /* * If we don't have access to the busy pin, we apply the given * command delay */ if (!this->dev_ready) { udelay (this->chip_delay); return; - } + } } - + /* Apply this short delay always to ensure that we do wait tWB in * any case on any machine. */ ndelay (100); @@ -734,7 +732,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, * nand_get_device - [GENERIC] Get chip for selected access * @this: the nand chip descriptor * @mtd: MTD device structure - * @new_state: the state which is requested + * @new_state: the state which is requested * * Get the device and lock it for exclusive access */ @@ -746,8 +744,8 @@ static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int n DECLARE_WAITQUEUE (wait, current); - /* - * Grab the lock and see if the device is available + /* + * Grab the lock and see if the device is available */ retry: /* Hardware controller shared among independend devices */ @@ -759,7 +757,7 @@ retry: this->controller->active = this; spin_unlock (&this->controller->lock); } - + if (active == this) { spin_lock (&this->chip_lock); if (this->state == FL_READY) { @@ -767,7 +765,7 @@ retry: spin_unlock (&this->chip_lock); return; } - } + } set_current_state (TASK_UNINTERRUPTIBLE); add_wait_queue (&active->wq, &wait); spin_unlock (&active->chip_lock); @@ -786,7 +784,7 @@ static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int n * @state: state to select the max. timeout value * * Wait for command done. This applies to erase and program only - * Erase can take up to 400ms and program up to 20ms according to + * Erase can take up to 400ms and program up to 20ms according to * general NAND and SmartMedia specs * */ @@ -796,7 +794,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) { unsigned long timeo = jiffies; int status; - + if (state == FL_ERASING) timeo += (HZ * 400) / 1000; else @@ -808,17 +806,17 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1); - else + else this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); - while (time_before(jiffies, timeo)) { + while (time_before(jiffies, timeo)) { /* Check, if we were interrupted */ if (this->state != state) return 0; if (this->dev_ready) { if (this->dev_ready(mtd)) - break; + break; } else { if (this->read_byte(mtd) & NAND_STATUS_READY) break; @@ -853,7 +851,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) * * Cached programming is not supported yet. */ -static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, +static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) { int i, status; @@ -862,10 +860,10 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa int *oob_config = oobsel->eccpos; int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; int eccbytes = 0; - + /* FIXME: Enable cached programming */ cached = 0; - + /* Send command to begin auto page programming */ this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); @@ -876,7 +874,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); this->write_buf(mtd, this->data_poi, mtd->oobblock); break; - + /* Software ecc 3/256, write all */ case NAND_ECC_SOFT: for (; eccsteps; eccsteps--) { @@ -905,11 +903,11 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa } break; } - + /* Write out OOB data */ if (this->options & NAND_HWECC_SYNDROME) this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes); - else + else this->write_buf(mtd, oob_buf, mtd->oobsize); /* Send command to actually program the data */ @@ -926,9 +924,9 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa } else { /* FIXME: Implement cached programming ! */ /* wait until cache is ready*/ - // status = this->waitfunc (mtd, this, FL_CACHEDRPG); + /* status = this->waitfunc (mtd, this, FL_CACHEDRPG); */ } - return 0; + return 0; } #ifdef CONFIG_MTD_NAND_VERIFY_WRITE @@ -944,19 +942,19 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa * @oobmode: 1 = full buffer verify, 0 = ecc only * * The NAND device assumes that it is always writing to a cleanly erased page. - * Hence, it performs its internal write verification only on bits that + * Hence, it performs its internal write verification only on bits that * transitioned from 1 to 0. The device does NOT verify the whole page on a - * byte by byte basis. It is possible that the page was not completely erased - * or the page is becoming unusable due to wear. The read with ECC would catch - * the error later when the ECC page check fails, but we would rather catch + * byte by byte basis. It is possible that the page was not completely erased + * or the page is becoming unusable due to wear. The read with ECC would catch + * the error later when the ECC page check fails, but we would rather catch * it early in the page write stage. Better to write no data than invalid data. */ -static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, +static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode) { int i, j, datidx = 0, oobofs = 0, res = -EIO; int eccsteps = this->eccsteps; - int hweccbytes; + int hweccbytes; u_char oobdata[64]; hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0; @@ -996,7 +994,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) { int ecccnt = oobsel->eccbytes; - + for (i = 0; i < ecccnt; i++) { int idx = oobsel->eccpos[i]; if (oobdata[idx] != oob_buf[oobofs + idx] ) { @@ -1006,38 +1004,38 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int goto out; } } - } + } } oobofs += mtd->oobsize - hweccbytes * eccsteps; page++; numpages--; - /* Apply delay or wait for ready/busy pin + /* Apply delay or wait for ready/busy pin * Do this before the AUTOINCR check, so no problems * arise if a chip which does auto increment * is marked as NOAUTOINCR by the board driver. * Do this also before returning, so the chip is * ready for the next command. */ - if (!this->dev_ready) + if (!this->dev_ready) udelay (this->chip_delay); else - while (!this->dev_ready(mtd)); + while (!this->dev_ready(mtd)); /* All done, return happy */ if (!numpages) return 0; - - - /* Check, if the chip supports auto page increment */ + + + /* Check, if the chip supports auto page increment */ if (!NAND_CANAUTOINCR(this)) this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); } - /* + /* * Terminate the read command. We come here in case of an error * So we must issue a reset command. */ -out: +out: this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1); return res; } @@ -1056,7 +1054,7 @@ out: static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) { return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL); -} +} /** @@ -1080,7 +1078,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, u_char *data_poi, *oob_data = oob_buf; u_char ecc_calc[32]; u_char ecc_code[32]; - int eccmode, eccsteps; + int eccmode, eccsteps; int *oob_config, datidx; int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; int eccbytes; @@ -1103,11 +1101,11 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, /* use userspace supplied oobinfo, if zero */ if (oobsel == NULL) oobsel = &mtd->oobinfo; - + /* Autoplace of oob data ? Use the default placement scheme */ if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) oobsel = this->autooob; - + eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; oob_config = oobsel->eccpos; @@ -1125,28 +1123,28 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, end = mtd->oobblock; ecc = this->eccsize; eccbytes = this->eccbytes; - + if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME)) compareecc = 0; oobreadlen = mtd->oobsize; - if (this->options & NAND_HWECC_SYNDROME) + if (this->options & NAND_HWECC_SYNDROME) oobreadlen -= oobsel->eccbytes; /* Loop until all data read */ while (read < len) { - + int aligned = (!col && (len - read) >= end); - /* + /* * If the read is not page aligned, we have to read into data buffer * due to ecc, else we read into return buffer direct */ if (aligned) data_poi = &buf[read]; - else + else data_poi = this->data_buf; - - /* Check, if we have this page in the buffer + + /* Check, if we have this page in the buffer * * FIXME: Make it work when we must provide oob data too, * check the usage of data_buf oob field @@ -1162,7 +1160,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, if (sndcmd) { this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); sndcmd = 0; - } + } /* get oob area, if we have no oob buffer from fs-driver */ if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE || @@ -1170,7 +1168,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, oob_data = &this->data_buf[end]; eccsteps = this->eccsteps; - + switch (eccmode) { case NAND_ECC_NONE: { /* No ECC, Read in a page */ /* XXX U-BOOT XXX */ @@ -1186,12 +1184,12 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, this->read_buf(mtd, data_poi, end); break; } - + case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ this->read_buf(mtd, data_poi, end); - for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) + for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); - break; + break; default: for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) { @@ -1209,15 +1207,15 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, * generator for an error, reads back the syndrome and * does the error correction on the fly */ if (this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]) == -1) { - DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " + DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr); ecc_failed++; } } else { this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); - } + } } - break; + break; } /* read oobdata */ @@ -1225,8 +1223,8 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */ if (!compareecc) - goto readoob; - + goto readoob; + /* Pick the ECC bytes out of the oob data */ for (j = 0; j < oobsel->eccbytes; j++) ecc_code[j] = oob_data[oob_config[j]]; @@ -1234,24 +1232,24 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, /* correct data, if neccecary */ for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) { ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]); - + /* Get next chunk of ecc bytes */ j += eccbytes; - - /* Check, if we have a fs supplied oob-buffer, + + /* Check, if we have a fs supplied oob-buffer, * This is the legacy mode. Used by YAFFS1 * Should go away some day */ - if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) { + if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) { int *p = (int *)(&oob_data[mtd->oobsize]); p[i] = ecc_status; } - - if (ecc_status == -1) { + + if (ecc_status == -1) { DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); ecc_failed++; } - } + } readoob: /* check, if we have a fs supplied oob-buffer */ @@ -1278,25 +1276,25 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, } readdata: /* Partial page read, transfer data into fs buffer */ - if (!aligned) { + if (!aligned) { for (j = col; j < end && read < len; j++) buf[read++] = data_poi[j]; - this->pagebuf = realpage; - } else + this->pagebuf = realpage; + } else read += mtd->oobblock; - /* Apply delay or wait for ready/busy pin + /* Apply delay or wait for ready/busy pin * Do this before the AUTOINCR check, so no problems * arise if a chip which does auto increment * is marked as NOAUTOINCR by the board driver. */ - if (!this->dev_ready) + if (!this->dev_ready) udelay (this->chip_delay); else - while (!this->dev_ready(mtd)); - + while (!this->dev_ready(mtd)); + if (read == len) - break; + break; /* For subsequent reads align to page boundary. */ col = 0; @@ -1310,11 +1308,11 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, this->select_chip(mtd, -1); this->select_chip(mtd, chipnr); } - /* Check, if the chip supports auto page increment - * or if we have hit a block boundary. - */ + /* Check, if the chip supports auto page increment + * or if we have hit a block boundary. + */ if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) - sndcmd = 1; + sndcmd = 1; } /* Deselect and wake up anyone waiting on the device */ @@ -1350,7 +1348,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t /* Shift to get page */ page = (int)(from >> this->page_shift); chipnr = (int)(from >> this->chip_shift); - + /* Mask to get column */ col = from & (mtd->oobsize - 1); @@ -1372,7 +1370,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t /* Send the read command */ this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask); - /* + /* * Read the data, if we read more than one page * oob data, let the device transfer the data ! */ @@ -1382,16 +1380,16 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t thislen = min_t(int, thislen, len); this->read_buf(mtd, &buf[i], thislen); i += thislen; - - /* Apply delay or wait for ready/busy pin + + /* Apply delay or wait for ready/busy pin * Do this before the AUTOINCR check, so no problems * arise if a chip which does auto increment * is marked as NOAUTOINCR by the board driver. */ - if (!this->dev_ready) + if (!this->dev_ready) udelay (this->chip_delay); else - while (!this->dev_ready(mtd)); + while (!this->dev_ready(mtd)); /* Read more ? */ if (i < len) { @@ -1404,13 +1402,13 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t this->select_chip(mtd, -1); this->select_chip(mtd, chipnr); } - - /* Check, if the chip supports auto page increment - * or if we have hit a block boundary. - */ + + /* Check, if the chip supports auto page increment + * or if we have hit a block boundary. + */ if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) { /* For subsequent page reads set offset to 0 */ - this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); + this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); } } } @@ -1453,27 +1451,27 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, nand_get_device (this, mtd , FL_READING); this->select_chip (mtd, chip); - + /* Add requested oob length */ len += ooblen; - + while (len) { if (sndcmd) this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask); - sndcmd = 0; + sndcmd = 0; this->read_buf (mtd, &buf[cnt], pagesize); len -= pagesize; cnt += pagesize; page++; - - if (!this->dev_ready) + + if (!this->dev_ready) udelay (this->chip_delay); else - while (!this->dev_ready(mtd)); - - /* Check, if the chip supports auto page increment */ + while (!this->dev_ready(mtd)); + + /* Check, if the chip supports auto page increment */ if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) sndcmd = 1; } @@ -1484,8 +1482,8 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, } -/** - * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer +/** + * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer * @mtd: MTD device structure * @fsbuf: buffer given by fs driver * @oobsel: out of band selection structre @@ -1514,20 +1512,20 @@ static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct int i, len, ofs; /* Zero copy fs supplied buffer */ - if (fsbuf && !autoplace) + if (fsbuf && !autoplace) return fsbuf; /* Check, if the buffer must be filled with ff again */ - if (this->oobdirty) { - memset (this->oob_buf, 0xff, + if (this->oobdirty) { + memset (this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift)); this->oobdirty = 0; - } - + } + /* If we have no autoplacement or no fs buffer use the internal one */ if (!autoplace || !fsbuf) return this->oob_buf; - + /* Walk through the pages and place the data */ this->oobdirty = 1; ofs = 0; @@ -1561,7 +1559,7 @@ static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * ret { return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); } - + /** * nand_write_ecc - [MTD Interface] NAND write with ECC * @mtd: MTD device structure @@ -1594,7 +1592,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, return -EINVAL; } - /* reject writes, which are not page aligned */ + /* reject writes, which are not page aligned */ if (NOTALIGNED (to) || NOTALIGNED(len)) { printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); return -EINVAL; @@ -1613,14 +1611,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, goto out; /* if oobsel is NULL, use chip defaults */ - if (oobsel == NULL) - oobsel = &mtd->oobinfo; - + if (oobsel == NULL) + oobsel = &mtd->oobinfo; + /* Autoplace of oob data ? Use the default placement scheme */ if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { oobsel = this->autooob; autoplace = 1; - } + } if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) autoplace = 1; @@ -1628,9 +1626,9 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, totalpages = len >> this->page_shift; page = (int) (to >> this->page_shift); /* Invalidate the page cache, if we write to the cached page */ - if (page <= this->pagebuf && this->pagebuf < (page + totalpages)) + if (page <= this->pagebuf && this->pagebuf < (page + totalpages)) this->pagebuf = -1; - + /* Set it relative to chip */ page &= this->pagemask; startpage = page; @@ -1652,14 +1650,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, if (ret) { DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret); goto out; - } + } /* Next oob page */ oob += mtd->oobsize; /* Update written bytes count */ written += mtd->oobblock; - if (written == len) + if (written == len) goto cmp; - + /* Increment page address */ page++; @@ -1670,13 +1668,13 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, if (!(page & (ppblock - 1))){ int ofs; this->data_poi = bufstart; - ret = nand_verify_pages (mtd, this, startpage, + ret = nand_verify_pages (mtd, this, startpage, page - startpage, oobbuf, oobsel, chipnr, (eccbuf != NULL)); if (ret) { DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); goto out; - } + } *retlen = written; ofs = autoplace ? mtd->oobavail : mtd->oobsize; @@ -1686,7 +1684,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, numpages = min (totalpages, ppblock); page &= this->pagemask; startpage = page; - oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, + oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages); /* Check, if we cross a chip boundary */ if (!page) { @@ -1703,7 +1701,7 @@ cmp: oobbuf, oobsel, chipnr, (eccbuf != NULL)); if (!ret) *retlen = written; - else + else DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); out: @@ -1763,7 +1761,7 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * /* Check, if it is write protected */ if (nand_check_wp(mtd)) goto out; - + /* Invalidate the page cache, if we write to the cached page */ if (page == this->pagebuf) this->pagebuf = -1; @@ -1827,10 +1825,10 @@ out: * * NAND write with kvec. This just calls the ecc function */ -static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, +static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t * retlen) { - return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL)); + return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL)); } /** @@ -1845,7 +1843,7 @@ static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned * * NAND write with iovec with ecc */ -static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, +static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) { int i, page, len, total_len, ret = -EIO, written = 0, chipnr; @@ -1871,7 +1869,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig return -EINVAL; } - /* reject writes, which are not page aligned */ + /* reject writes, which are not page aligned */ if (NOTALIGNED (to) || NOTALIGNED(total_len)) { printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); return -EINVAL; @@ -1890,21 +1888,21 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig goto out; /* if oobsel is NULL, use chip defaults */ - if (oobsel == NULL) - oobsel = &mtd->oobinfo; + if (oobsel == NULL) + oobsel = &mtd->oobinfo; /* Autoplace of oob data ? Use the default placement scheme */ if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { oobsel = this->autooob; autoplace = 1; - } + } if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) autoplace = 1; /* Setup start page */ page = (int) (to >> this->page_shift); /* Invalidate the page cache, if we write to the cached page */ - if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) + if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) this->pagebuf = -1; startpage = page & this->pagemask; @@ -1928,10 +1926,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig oob = 0; for (i = 1; i <= numpages; i++) { /* Write one page. If this is the last page to write - * then use the real pageprogram command, else select + * then use the real pageprogram command, else select * cached programming if supported by the chip. */ - ret = nand_write_page (mtd, this, page & this->pagemask, + ret = nand_write_page (mtd, this, page & this->pagemask, &oobbuf[oob], oobsel, i != numpages); if (ret) goto out; @@ -1947,12 +1945,12 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig count--; } } else { - /* We must use the internal buffer, read data out of each + /* We must use the internal buffer, read data out of each * tuple until we have a full page to write */ int cnt = 0; while (cnt < mtd->oobblock) { - if (vecs->iov_base != NULL && vecs->iov_len) + if (vecs->iov_base != NULL && vecs->iov_len) this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++]; /* Check, if we have to switch to the next tuple */ if (len >= (int) vecs->iov_len) { @@ -1961,10 +1959,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig count--; } } - this->pagebuf = page; - this->data_poi = this->data_buf; + this->pagebuf = page; + this->data_poi = this->data_buf; bufstart = this->data_poi; - numpages = 1; + numpages = 1; oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); ret = nand_write_page (mtd, this, page & this->pagemask, oobbuf, oobsel, 0); @@ -1977,7 +1975,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); if (ret) goto out; - + written += mtd->oobblock * numpages; /* All done ? */ if (!count) @@ -2046,7 +2044,7 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr) { return nand_erase_nand (mtd, instr, 0); } - + /** * nand_erase_intern - [NAND Interface] erase block(s) * @mtd: MTD device structure @@ -2116,14 +2114,14 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb instr->state = MTD_ERASE_FAILED; goto erase_exit; } - - /* Invalidate the page cache, if we erase the block which contains + + /* Invalidate the page cache, if we erase the block which contains the current cached page */ if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) this->pagebuf = -1; this->erase_cmd (mtd, page & this->pagemask); - + status = this->waitfunc (mtd, this, FL_ERASING); /* See if block erase succeeded */ @@ -2133,7 +2131,7 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb instr->fail_addr = (page << this->page_shift); goto erase_exit; } - + /* Increment page address and decrement length */ len -= (1 << this->phys_erase_shift); page += pages_per_block; @@ -2188,9 +2186,9 @@ static void nand_sync (struct mtd_info *mtd) static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs) { /* Check for invalid offset */ - if (ofs > mtd->size) + if (ofs > mtd->size) return -EINVAL; - + return nand_block_checkbad (mtd, ofs, 1, 0); } @@ -2204,12 +2202,12 @@ static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs) struct nand_chip *this = mtd->priv; int ret; - if ((ret = nand_block_isbad(mtd, ofs))) { - /* If it was bad already, return success and do nothing. */ + if ((ret = nand_block_isbad(mtd, ofs))) { + /* If it was bad already, return success and do nothing. */ if (ret > 0) return 0; - return ret; - } + return ret; + } return this->block_markbad(mtd, ofs); } @@ -2281,13 +2279,13 @@ int nand_scan (struct mtd_info *mtd, int maxchips) /* Print and store flash device information */ for (i = 0; nand_flash_ids[i].name != NULL; i++) { - - if (nand_dev_id != nand_flash_ids[i].id) + + if (nand_dev_id != nand_flash_ids[i].id) continue; if (!mtd->name) mtd->name = nand_flash_ids[i].name; this->chipsize = nand_flash_ids[i].chipsize << 20; - + /* New devices have all the information in additional id bytes */ if (!nand_flash_ids[i].pagesize) { int extid; @@ -2306,7 +2304,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips) extid >>= 2; /* Get buswidth information */ busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; - + } else { /* Old devices have this data hardcoded in the * device id table */ @@ -2320,23 +2318,23 @@ int nand_scan (struct mtd_info *mtd, int maxchips) * this correct ! */ if (busw != (this->options & NAND_BUSWIDTH_16)) { printk (KERN_INFO "NAND device: Manufacturer ID:" - " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, + " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, nand_manuf_ids[i].name , mtd->name); - printk (KERN_WARNING - "NAND bus width %d instead %d bit\n", + printk (KERN_WARNING + "NAND bus width %d instead %d bit\n", (this->options & NAND_BUSWIDTH_16) ? 16 : 8, busw ? 16 : 8); this->select_chip(mtd, -1); - return 1; + return 1; } - - /* Calculate the address shift from the page size */ + + /* Calculate the address shift from the page size */ this->page_shift = ffs(mtd->oobblock) - 1; this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1; this->chip_shift = ffs(this->chipsize) - 1; /* Set the bad block position */ - this->badblockpos = mtd->oobblock > 512 ? + this->badblockpos = mtd->oobblock > 512 ? NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; /* Get chip options, preserve non chip based options */ @@ -2346,10 +2344,10 @@ int nand_scan (struct mtd_info *mtd, int maxchips) this->options |= NAND_NO_AUTOINCR; /* Check if this is a not a samsung device. Do not clear the options * for chips which are not having an extended id. - */ + */ if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize) this->options &= ~NAND_SAMSUNG_LP_OPTIONS; - + /* Check for AND chips with 4 page planes */ if (this->options & NAND_4PAGE_ARRAY) this->erase_cmd = multi_erase_cmd; @@ -2359,14 +2357,14 @@ int nand_scan (struct mtd_info *mtd, int maxchips) /* Do not replace user supplied command function ! */ if (mtd->oobblock > 512 && this->cmdfunc == nand_command) this->cmdfunc = nand_command_lp; - + /* Try to identify manufacturer */ for (j = 0; nand_manuf_ids[j].id != 0x0; j++) { if (nand_manuf_ids[j].id == nand_maf_id) break; } printk (KERN_INFO "NAND device: Manufacturer ID:" - " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, + " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, nand_manuf_ids[j].name , nand_flash_ids[i].name); break; } @@ -2390,7 +2388,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips) } if (i > 1) printk(KERN_INFO "%d NAND chips detected\n", i); - + /* Allocate buffers, if neccecary */ if (!this->oob_buf) { size_t len; @@ -2402,7 +2400,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips) } this->options |= NAND_OOBBUF_ALLOC; } - + if (!this->data_buf) { size_t len; len = mtd->oobblock + mtd->oobsize; @@ -2429,7 +2427,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips) if (!this->autooob) { /* Select the appropriate default oob placement scheme for * placement agnostic filesystems */ - switch (mtd->oobsize) { + switch (mtd->oobsize) { case 8: this->autooob = &nand_oob_8; break; @@ -2445,7 +2443,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips) /* BUG(); */ } } - + /* The number of bytes available for the filesystem to place fs dependend * oob data */ if (this->options & NAND_BUSWIDTH_16) { @@ -2455,12 +2453,12 @@ int nand_scan (struct mtd_info *mtd, int maxchips) } else mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 1); - /* + /* * check ECC mode, default to software * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize - * fallback to software ECC + * fallback to software ECC */ - this->eccsize = 256; /* set default eccsize */ + this->eccsize = 256; /* set default eccsize */ this->eccbytes = 3; switch (this->eccmode) { @@ -2475,27 +2473,27 @@ int nand_scan (struct mtd_info *mtd, int maxchips) this->eccsize = 2048; break; - case NAND_ECC_HW3_512: - case NAND_ECC_HW6_512: - case NAND_ECC_HW8_512: + case NAND_ECC_HW3_512: + case NAND_ECC_HW6_512: + case NAND_ECC_HW8_512: if (mtd->oobblock == 256) { printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); this->eccmode = NAND_ECC_SOFT; this->calculate_ecc = nand_calculate_ecc; this->correct_data = nand_correct_data; - } else + } else this->eccsize = 512; /* set eccsize to 512 */ break; - + case NAND_ECC_HW3_256: break; - - case NAND_ECC_NONE: + + case NAND_ECC_NONE: printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); this->eccmode = NAND_ECC_NONE; break; - case NAND_ECC_SOFT: + case NAND_ECC_SOFT: this->calculate_ecc = nand_calculate_ecc; this->correct_data = nand_correct_data; break; @@ -2503,28 +2501,28 @@ int nand_scan (struct mtd_info *mtd, int maxchips) default: printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); /* BUG(); */ - } + } - /* Check hardware ecc function availability and adjust number of ecc bytes per + /* Check hardware ecc function availability and adjust number of ecc bytes per * calculation step */ switch (this->eccmode) { case NAND_ECC_HW12_2048: this->eccbytes += 4; - case NAND_ECC_HW8_512: + case NAND_ECC_HW8_512: this->eccbytes += 2; - case NAND_ECC_HW6_512: + case NAND_ECC_HW6_512: this->eccbytes += 3; - case NAND_ECC_HW3_512: + case NAND_ECC_HW3_512: case NAND_ECC_HW3_256: if (this->calculate_ecc && this->correct_data && this->enable_hwecc) break; printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n"); /* BUG(); */ } - + mtd->eccsize = this->eccsize; - + /* Set the number of read / write steps for one page to ensure ECC generation */ switch (this->eccmode) { case NAND_ECC_HW12_2048: @@ -2536,17 +2534,17 @@ int nand_scan (struct mtd_info *mtd, int maxchips) this->eccsteps = mtd->oobblock / 512; break; case NAND_ECC_HW3_256: - case NAND_ECC_SOFT: + case NAND_ECC_SOFT: this->eccsteps = mtd->oobblock / 256; break; - - case NAND_ECC_NONE: + + case NAND_ECC_NONE: this->eccsteps = 1; break; } /* XXX U-BOOT XXX */ -#if 0 +#if 0 /* Initialize state, waitqueue and spinlock */ this->state = FL_READY; init_waitqueue_head (&this->wq); @@ -2600,9 +2598,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips) } /** - * nand_release - [NAND Interface] Free resources held by the NAND device + * nand_release - [NAND Interface] Free resources held by the NAND device * @mtd: MTD device structure -*/ + */ void nand_release (struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; diff --git a/drivers/nand/nand_bbt.c b/drivers/nand/nand_bbt.c index 6f7e05b7eb..dfa88a3af6 100644 --- a/drivers/nand/nand_bbt.c +++ b/drivers/nand/nand_bbt.c @@ -3,7 +3,7 @@ * * Overview: * Bad block table support for the NAND driver - * + * * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) * * $Id: nand_bbt.c,v 1.28 2004/11/13 10:19:09 gleixner Exp $ @@ -14,23 +14,23 @@ * * Description: * - * When nand_scan_bbt is called, then it tries to find the bad block table - * depending on the options in the bbt descriptor(s). If a bbt is found - * then the contents are read and the memory based bbt is created. If a + * When nand_scan_bbt is called, then it tries to find the bad block table + * depending on the options in the bbt descriptor(s). If a bbt is found + * then the contents are read and the memory based bbt is created. If a * mirrored bbt is selected then the mirror is searched too and the - * versions are compared. If the mirror has a greater version number + * versions are compared. If the mirror has a greater version number * than the mirror bbt is used to build the memory based bbt. * If the tables are not versioned, then we "or" the bad block information. - * If one of the bbt's is out of date or does not exist it is (re)created. - * If no bbt exists at all then the device is scanned for factory marked - * good / bad blocks and the bad block tables are created. + * If one of the bbt's is out of date or does not exist it is (re)created. + * If no bbt exists at all then the device is scanned for factory marked + * good / bad blocks and the bad block tables are created. * - * For manufacturer created bbts like the one found on M-SYS DOC devices + * For manufacturer created bbts like the one found on M-SYS DOC devices * the bbt is searched and read but never created * - * The autogenerated bad block table is located in the last good blocks - * of the device. The table is mirrored, so it can be updated eventually. - * The table is marked in the oob area with an ident pattern and a version + * The autogenerated bad block table is located in the last good blocks + * of the device. The table is mirrored, so it can be updated eventually. + * The table is marked in the oob area with an ident pattern and a version * number which indicates which of both tables is more up to date. * * The table uses 2 bits per block @@ -43,13 +43,13 @@ * 01b: block is marked bad due to wear * 10b: block is reserved (to protect the bbt area) * 11b: block is factory marked bad - * + * * Multichip devices like DOC store the bad block info per floor. * * Following assumptions are made: * - bbts start at a page boundary, if autolocated on a block boundary * - the space neccecary for a bbt in FLASH does not exceed a block boundary - * + * */ #include @@ -63,7 +63,7 @@ #include -/** +/** * check_pattern - [GENERIC] check if a pattern is in the buffer * @buf: the buffer to search * @len: the length of buffer to search @@ -87,9 +87,9 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des if (p[i] != 0xff) return -1; } - } + } p += end; - + /* Compare the pattern */ for (i = 0; i < td->len; i++) { if (p[i] != td->pattern[i]) @@ -120,7 +120,7 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des * Read the bad block table starting from page. * */ -static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, +static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, int bits, int offs, int reserved_block_code) { int res, i, j, act = 0; @@ -131,7 +131,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, totlen = (num * bits) >> 3; from = ((loff_t)page) << this->page_shift; - + while (totlen) { len = min (totlen, (size_t) (1 << this->bbt_erase_shift)); res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob); @@ -141,7 +141,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, return res; } printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); - } + } /* Analyse data */ for (i = 0; i < len; i++) { @@ -161,12 +161,12 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, * message to MTD_DEBUG_LEVEL0 */ printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); - /* Factory marked bad or worn out ? */ + /* Factory marked bad or worn out ? */ if (tmp == 0) this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); else this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06); - } + } } totlen -= len; from += len; @@ -178,7 +178,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page * @mtd: MTD device structure * @buf: temporary buffer - * @td: descriptor for the bad block table + * @td: descriptor for the bad block table * @chip: read the table for a specific chip, -1 read all chips. * Applies only if NAND_BBT_PERCHIP option is set * @@ -213,7 +213,7 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page * @mtd: MTD device structure * @buf: temporary buffer - * @td: descriptor for the bad block table + * @td: descriptor for the bad block table * @md: descriptor for the bad block table mirror * * Read the bad block table(s) for all chips starting at a given page @@ -225,16 +225,16 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de { struct nand_chip *this = mtd->priv; - /* Read the primary version, if available */ + /* Read the primary version, if available */ if (td->options & NAND_BBT_VERSION) { - nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); + nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); td->version[0] = buf[mtd->oobblock + td->veroffs]; printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); } - /* Read the mirror version, if available */ + /* Read the mirror version, if available */ if (md && (md->options & NAND_BBT_VERSION)) { - nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); + nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); md->version[0] = buf[mtd->oobblock + md->veroffs]; printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); } @@ -268,7 +268,7 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc else { if (bd->options & NAND_BBT_SCAN2NDPAGE) len = 2; - else + else len = 1; } scanlen = mtd->oobblock + mtd->oobsize; @@ -285,20 +285,20 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc if (chip >= this->numchips) { printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n", chip + 1, this->numchips); - return; + return; } numblocks = this->chipsize >> (this->bbt_erase_shift - 1); startblock = chip * numblocks; numblocks += startblock; from = startblock << (this->bbt_erase_shift - 1); } - + for (i = startblock; i < numblocks;) { nand_read_raw (mtd, buf, from, readlen, ooblen); for (j = 0; j < len; j++) { if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { this->bbt[i >> 3] |= 0x03 << (i & 0x6); - printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", + printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", i >> 1, (unsigned int) from); break; } @@ -315,15 +315,15 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc * @td: descriptor for the bad block table * * Read the bad block table by searching for a given ident pattern. - * Search is preformed either from the beginning up or from the end of + * Search is preformed either from the beginning up or from the end of * the device downwards. The search starts always at the start of a * block. - * If the option NAND_BBT_PERCHIP is given, each chip is searched + * If the option NAND_BBT_PERCHIP is given, each chip is searched * for a bbt, which contains the bad block information of this chip. * This is neccecary to provide support for certain DOC devices. * - * The bbt ident pattern resides in the oob area of the first page - * in a block. + * The bbt ident pattern resides in the oob area of the first page + * in a block. */ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) { @@ -338,10 +338,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr startblock = (mtd->size >> this->bbt_erase_shift) -1; dir = -1; } else { - startblock = 0; + startblock = 0; dir = 1; - } - + } + /* Do we have a bbt per chip ? */ if (td->options & NAND_BBT_PERCHIP) { chips = this->numchips; @@ -351,19 +351,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr chips = 1; bbtblocks = mtd->size >> this->bbt_erase_shift; } - + /* Number of bits for each erase block in the bbt */ bits = td->options & NAND_BBT_NRBITS_MSK; - + for (i = 0; i < chips; i++) { /* Reset version information */ - td->version[i] = 0; + td->version[i] = 0; td->pages[i] = -1; /* Scan the maximum number of blocks */ for (block = 0; block < td->maxblocks; block++) { int actblock = startblock + dir * block; /* Read first page */ - nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize); + nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize); if (!check_pattern(buf, scanlen, mtd->oobblock, td)) { td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift); if (td->options & NAND_BBT_VERSION) { @@ -381,46 +381,46 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr else printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); } - return 0; + return 0; } /** * search_read_bbts - [GENERIC] scan the device for bad block table(s) * @mtd: MTD device structure * @buf: temporary buffer - * @td: descriptor for the bad block table + * @td: descriptor for the bad block table * @md: descriptor for the bad block table mirror * * Search and read the bad block table(s) */ -static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, +static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md) { /* Search the primary table */ search_bbt (mtd, buf, td); - + /* Search the mirror table */ if (md) search_bbt (mtd, buf, md); - - /* Force result check */ - return 1; -} - -/** + /* Force result check */ + return 1; +} + + +/** * write_bbt - [GENERIC] (Re)write the bad block table * * @mtd: MTD device structure * @buf: temporary buffer - * @td: descriptor for the bad block table + * @td: descriptor for the bad block table * @md: descriptor for the bad block table mirror * @chipsel: selector for a specific chip, -1 for all * * (Re)write the bad block table * */ -static int write_bbt (struct mtd_info *mtd, uint8_t *buf, +static int write_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) { struct nand_chip *this = mtd->priv; @@ -439,7 +439,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf, /* Write bad block table per chip rather than per device ? */ if (td->options & NAND_BBT_PERCHIP) { numblocks = (int) (this->chipsize >> this->bbt_erase_shift); - /* Full device write or specific chip ? */ + /* Full device write or specific chip ? */ if (chipsel == -1) { nrchips = this->numchips; } else { @@ -449,19 +449,19 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf, } else { numblocks = (int) (mtd->size >> this->bbt_erase_shift); nrchips = 1; - } - + } + /* Loop through the chips */ for (; chip < nrchips; chip++) { - - /* There was already a version of the table, reuse the page - * This applies for absolute placement too, as we have the + + /* There was already a version of the table, reuse the page + * This applies for absolute placement too, as we have the * page nr. in td->pages. */ if (td->pages[chip] != -1) { page = td->pages[chip]; goto write; - } + } /* Automatic placement of the bad block table */ /* Search direction top -> down ? */ @@ -471,7 +471,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf, } else { startblock = chip * numblocks; dir = 1; - } + } for (i = 0; i < td->maxblocks; i++) { int block = startblock + dir * i; @@ -488,7 +488,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf, } printk (KERN_ERR "No space left to write bad block table\n"); return -ENOSPC; -write: +write: /* Set up shift count and masks for the flash table */ bits = td->options & NAND_BBT_NRBITS_MSK; @@ -499,14 +499,14 @@ write: case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break; default: return -EINVAL; } - + bbtoffs = chip * (numblocks >> 2); - + to = ((loff_t) page) << this->page_shift; memcpy (&oobinfo, this->autooob, sizeof(oobinfo)); oobinfo.useecc = MTD_NANDECC_PLACEONLY; - + /* Must we save the block contents ? */ if (td->options & NAND_BBT_SAVECONTENT) { /* Make it block aligned */ @@ -545,7 +545,7 @@ write: buf[len + td->veroffs] = td->version[chip]; } } - + /* walk through the memory table */ for (i = 0; i < numblocks; ) { uint8_t dat; @@ -557,7 +557,7 @@ write: dat >>= 2; } } - + memset (&einfo, 0, sizeof (einfo)); einfo.mtd = mtd; einfo.addr = (unsigned long) to; @@ -567,18 +567,18 @@ write: printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res); return res; } - + res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); if (res < 0) { printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res); return res; } - printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", + printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", (unsigned int) to, td->version[chip]); - + /* Mark it as used */ td->pages[chip] = page; - } + } return 0; } @@ -587,7 +587,7 @@ write: * @mtd: MTD device structure * @bd: descriptor for the good/bad block search pattern * - * The function creates a memory based bbt by scanning the device + * The function creates a memory based bbt by scanning the device * for manufacturer / software marked good / bad blocks */ static int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) @@ -621,11 +621,11 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des struct nand_bbt_descr *rd, *rd2; /* Do we have a bbt per chip ? */ - if (td->options & NAND_BBT_PERCHIP) + if (td->options & NAND_BBT_PERCHIP) chips = this->numchips; - else + else chips = 1; - + for (i = 0; i < chips; i++) { writeops = 0; rd = NULL; @@ -640,7 +640,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des } if (td->pages[i] == -1) { - rd = md; + rd = md; td->version[i] = md->version[i]; writeops = 1; goto writecheck; @@ -658,7 +658,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des if (!(td->options & NAND_BBT_VERSION)) rd2 = md; goto writecheck; - } + } if (((int8_t) (td->version[i] - md->version[i])) > 0) { rd = td; @@ -683,15 +683,15 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des create: /* Create the bad block table by scanning the device ? */ if (!(td->options & NAND_BBT_CREATE)) - continue; - + continue; + /* Create the table in memory by scanning the chip(s) */ create_bbt (mtd, buf, bd, chipsel); - + td->version[i] = 1; if (md) - md->version[i] = 1; -writecheck: + md->version[i] = 1; +writecheck: /* read back first ? */ if (rd) read_abs_bbt (mtd, buf, rd, chipsel); @@ -705,7 +705,7 @@ writecheck: if (res < 0) return res; } - + /* Write the mirror bad block table to the device ? */ if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { res = write_bbt (mtd, buf, md, td, chipsel); @@ -713,11 +713,11 @@ writecheck: return res; } } - return 0; + return 0; } /** - * mark_bbt_regions - [GENERIC] mark the bad block table regions + * mark_bbt_regions - [GENERIC] mark the bad block table regions * @mtd: MTD device structure * @td: bad block table descriptor * @@ -738,14 +738,14 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) } else { chips = 1; nrblocks = (int)(mtd->size >> this->bbt_erase_shift); - } - + } + for (i = 0; i < chips; i++) { if ((td->options & NAND_BBT_ABSPAGE) || !(td->options & NAND_BBT_WRITE)) { if (td->pages[i] == -1) continue; block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); - block <<= 1; + block <<= 1; oldval = this->bbt[(block >> 3)]; newval = oldval | (0x2 << (block & 0x06)); this->bbt[(block >> 3)] = newval; @@ -756,16 +756,16 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) update = 0; if (td->options & NAND_BBT_LASTBLOCK) block = ((i + 1) * nrblocks) - td->maxblocks; - else + else block = i * nrblocks; - block <<= 1; + block <<= 1; for (j = 0; j < td->maxblocks; j++) { oldval = this->bbt[(block >> 3)]; newval = oldval | (0x2 << (block & 0x06)); this->bbt[(block >> 3)] = newval; if (oldval != newval) update = 1; block += 2; - } + } /* If we want reserved blocks to be recorded to flash, and some new ones have been marked, then we need to update the stored bbts. This should only happen once. */ @@ -779,7 +779,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) * @mtd: MTD device structure * @bd: descriptor for the good/bad block search pattern * - * The function checks, if a bad block table(s) is/are already + * The function checks, if a bad block table(s) is/are already * available. If not it scans the device for manufacturer * marked good / bad blocks and writes the bad block table(s) to * the selected place. @@ -822,30 +822,30 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) this->bbt = NULL; return -ENOMEM; } - + /* Is the bbt at a given page ? */ if (td->options & NAND_BBT_ABSPAGE) { res = read_abs_bbts (mtd, buf, td, md); - } else { + } else { /* Search the bad block table using a pattern in oob */ res = search_read_bbts (mtd, buf, td, md); - } + } - if (res) + if (res) res = check_create (mtd, buf, bd); - + /* Prevent the bbt regions from erasing / writing */ mark_bbt_region (mtd, td); if (md) mark_bbt_region (mtd, md); - + kfree (buf); return res; } /** - * nand_update_bbt - [NAND Interface] update bad block table(s) + * nand_update_bbt - [NAND Interface] update bad block table(s) * @mtd: MTD device structure * @offs: the offset of the newly marked block * @@ -872,7 +872,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs) printk (KERN_ERR "nand_update_bbt: Out of memory\n"); return -ENOMEM; } - + writeops = md != NULL ? 0x03 : 0x01; /* Do we have a bbt per chip ? */ @@ -886,7 +886,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs) td->version[chip]++; if (md) - md->version[chip]++; + md->version[chip]++; /* Write the bad block table to the device ? */ if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { @@ -899,15 +899,15 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs) res = write_bbt (mtd, buf, md, td, chipsel); } -out: +out: kfree (buf); return res; } -/* Define some generic bad / good block scan pattern which are used +/* Define some generic bad / good block scan pattern which are used * while scanning a device for factory marked good / bad blocks - * - * The memory based patterns just + * + * The memory based patterns just */ static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; @@ -954,7 +954,7 @@ static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; static struct nand_bbt_descr bbt_main_descr = { - .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, .offs = 8, .len = 4, @@ -964,7 +964,7 @@ static struct nand_bbt_descr bbt_main_descr = { }; static struct nand_bbt_descr bbt_mirror_descr = { - .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, .offs = 8, .len = 4, @@ -974,7 +974,7 @@ static struct nand_bbt_descr bbt_mirror_descr = { }; /** - * nand_default_bbt - [NAND Interface] Select a default bad block table for the device + * nand_default_bbt - [NAND Interface] Select a default bad block table for the device * @mtd: MTD device structure * * This function selects the default bad block table @@ -984,29 +984,29 @@ static struct nand_bbt_descr bbt_mirror_descr = { int nand_default_bbt (struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; - - /* Default for AG-AND. We must use a flash based + + /* Default for AG-AND. We must use a flash based * bad block table as the devices have factory marked * _good_ blocks. Erasing those blocks leads to loss * of the good / bad information, so we _must_ store - * this information in a good / bad table during + * this information in a good / bad table during * startup */ if (this->options & NAND_IS_AND) { /* Use the default pattern descriptors */ - if (!this->bbt_td) { + if (!this->bbt_td) { this->bbt_td = &bbt_main_descr; this->bbt_md = &bbt_mirror_descr; - } + } this->options |= NAND_USE_FLASH_BBT; return nand_scan_bbt (mtd, &agand_flashbased); } - - + + /* Is a flash based bad block table requested ? */ if (this->options & NAND_USE_FLASH_BBT) { - /* Use the default pattern descriptors */ - if (!this->bbt_td) { + /* Use the default pattern descriptors */ + if (!this->bbt_td) { this->bbt_td = &bbt_main_descr; this->bbt_md = &bbt_mirror_descr; } @@ -1026,23 +1026,23 @@ int nand_default_bbt (struct mtd_info *mtd) } /** - * nand_isbad_bbt - [NAND Interface] Check if a block is bad + * nand_isbad_bbt - [NAND Interface] Check if a block is bad * @mtd: MTD device structure * @offs: offset in the device * @allowbbt: allow access to bad block table region * -*/ + */ int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt) { struct nand_chip *this = mtd->priv; int block; uint8_t res; - + /* Get block number * 2 */ block = (int) (offs >> (this->bbt_erase_shift - 1)); res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; - DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", + DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", (unsigned int)offs, res, block >> 1); switch ((int)res) { diff --git a/drivers/nand/nand_ecc.c b/drivers/nand/nand_ecc.c index dc9db4b480..6e11c22858 100644 --- a/drivers/nand/nand_ecc.c +++ b/drivers/nand/nand_ecc.c @@ -13,16 +13,16 @@ * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 or (at your option) any * later version. - * + * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. - * + * * You should have received a copy of the GNU General Public License along * with this file; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * + * * As a special exception, if other files instantiate templates or use * macros or inline functions from these files, or you compile these * files and link them with other works to produce a work based on these @@ -30,7 +30,7 @@ * covered by the GNU General Public License. However the source code for * these files must still be made available in accordance with section (3) * of the GNU General Public License. - * + * * This exception does not invalidate any other reasons why a work based on * this file might be covered by the GNU General Public License. */ @@ -66,7 +66,7 @@ static const u_char nand_ecc_precalc_table[] = { * nand_trans_result - [GENERIC] create non-inverted ECC * @reg2: line parity reg 2 * @reg3: line parity reg 3 - * @ecc_code: ecc + * @ecc_code: ecc * * Creates non-inverted ECC code from line parity */ @@ -74,11 +74,11 @@ static void nand_trans_result(u_char reg2, u_char reg3, u_char *ecc_code) { u_char a, b, i, tmp1, tmp2; - + /* Initialize variables */ a = b = 0x80; tmp1 = tmp2 = 0; - + /* Calculate first ECC byte */ for (i = 0; i < 4; i++) { if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ @@ -89,7 +89,7 @@ static void nand_trans_result(u_char reg2, u_char reg3, b >>= 1; a >>= 1; } - + /* Calculate second ECC byte */ b = 0x80; for (i = 0; i < 4; i++) { @@ -101,7 +101,7 @@ static void nand_trans_result(u_char reg2, u_char reg3, b >>= 1; a >>= 1; } - + /* Store two of the ECC bytes */ ecc_code[0] = tmp1; ecc_code[1] = tmp2; @@ -117,28 +117,28 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code { u_char idx, reg1, reg2, reg3; int j; - + /* Initialize variables */ reg1 = reg2 = reg3 = 0; ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; - - /* Build up column parity */ + + /* Build up column parity */ for(j = 0; j < 256; j++) { - + /* Get CP0 - CP5 from table */ idx = nand_ecc_precalc_table[dat[j]]; reg1 ^= (idx & 0x3f); - + /* All bit XOR = 1 ? */ if (idx & 0x40) { reg3 ^= (u_char) j; reg2 ^= ~((u_char) j); } } - + /* Create non-inverted ECC code from line parity */ nand_trans_result(reg2, reg3, ecc_code); - + /* Calculate final ECC code */ ecc_code[0] = ~ecc_code[0]; ecc_code[1] = ~ecc_code[1]; @@ -158,12 +158,12 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { u_char a, b, c, d1, d2, d3, add, bit, i; - - /* Do error detection */ + + /* Do error detection */ d1 = calc_ecc[0] ^ read_ecc[0]; d2 = calc_ecc[1] ^ read_ecc[1]; d3 = calc_ecc[2] ^ read_ecc[2]; - + if ((d1 | d2 | d3) == 0) { /* No errors */ return 0; @@ -172,7 +172,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha a = (d1 ^ (d1 >> 1)) & 0x55; b = (d2 ^ (d2 >> 1)) & 0x55; c = (d3 ^ (d3 >> 1)) & 0x54; - + /* Found and will correct single bit error in the data */ if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { c = 0x80; @@ -205,8 +205,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha a ^= (b << bit); dat[add] = a; return 1; - } - else { + } else { i = 0; while (d1) { if (d1 & 0x01) @@ -236,7 +235,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha } } } - + /* Should never happen */ return -1; } diff --git a/drivers/nand/nand_ids.c b/drivers/nand/nand_ids.c index 5df1e8971d..39882cc76b 100644 --- a/drivers/nand/nand_ids.c +++ b/drivers/nand/nand_ids.c @@ -18,14 +18,14 @@ /* * Chip ID list -* +* * Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, * options -* +* * Pagesize; 0, 256, 512 * 0 get this information from the extended chip ID + 256 256 Byte page size -* 512 512 Byte page size +* 512 512 Byte page size */ struct nand_flash_dev nand_flash_ids[] = { {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, @@ -38,36 +38,36 @@ struct nand_flash_dev nand_flash_ids[] = { {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, - + {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, - + {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, - + {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, - + {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, - + {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16}, {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, - + {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, {"NAND 512MiB 3,3V 8-bit", 0xDC, 512, 512, 0x4000, 0}, - + /* These are the new chips with large page size. The pagesize * and the erasesize is determined from the extended id bytes */ @@ -82,13 +82,13 @@ struct nand_flash_dev nand_flash_ids[] = { {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, - + /* 4 Gigabit */ {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, - + /* 8 Gigabit */ {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, @@ -101,11 +101,11 @@ struct nand_flash_dev nand_flash_ids[] = { {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, - /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! + /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go - * There are more speed improvements for reads and writes possible, but not implemented now + * There are more speed improvements for reads and writes possible, but not implemented now */ {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY}, diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index e53aa31eff..6658512b20 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -143,7 +143,7 @@ /* keeps pointer to currentlu processed partition */ static struct part_info *current_part; -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) /* * Support for jffs2 on top of NAND-flash * @@ -290,7 +290,7 @@ static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf) return get_fl_mem_nor(off); #endif -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) if (id->type == MTD_DEV_TYPE_NAND) return get_fl_mem_nand(off, size, ext_buf); #endif @@ -308,7 +308,7 @@ static inline void *get_node_mem(u32 off) return get_node_mem_nor(off); #endif -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) if (id->type == MTD_DEV_TYPE_NAND) return get_node_mem_nand(off); #endif @@ -319,7 +319,7 @@ static inline void *get_node_mem(u32 off) static inline void put_fl_mem(void *buf) { -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) struct mtdids *id = current_part->dev->id; if (id->type == MTD_DEV_TYPE_NAND) diff --git a/fs/jffs2/jffs2_nand_1pass.c b/fs/jffs2/jffs2_nand_1pass.c index ce80a43fa1..e5c2a7dd41 100644 --- a/fs/jffs2/jffs2_nand_1pass.c +++ b/fs/jffs2/jffs2_nand_1pass.c @@ -1,6 +1,6 @@ #include -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) +#if defined(CONFIG_NEW_NAND_CODE) && (CONFIG_COMMANDS & CFG_CMD_JFFS2) #include #include @@ -12,12 +12,12 @@ #include "jffs2_nand_private.h" -#define NODE_CHUNK 1024 /* size of memory allocation chunk in b_nodes */ +#define NODE_CHUNK 1024 /* size of memory allocation chunk in b_nodes */ /* Debugging switches */ #undef DEBUG_DIRENTS /* print directory entry list after scan */ #undef DEBUG_FRAGMENTS /* print fragment list after scan */ -#undef DEBUG /* enable debugging messages */ +#undef DEBUG /* enable debugging messages */ #ifdef DEBUG # define DEBUGF(fmt,args...) printf(fmt ,##args) @@ -25,7 +25,6 @@ # define DEBUGF(fmt,args...) #endif -static int nanddev = -1; /* nand device of current partition */ static nand_info_t *nand; /* Compression names */ @@ -385,10 +384,10 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino) continue; if (jDir->version == version && inode != 0) { - /* I'm pretty sure this isn't legal */ + /* I'm pretty sure this isn't legal */ putstr(" ** ERROR ** "); -// putnstr(jDir->name, jDir->nsize); -// putLabeledWord(" has dup version =", version); +/* putnstr(jDir->name, jDir->nsize); */ +/* putLabeledWord(" has dup version =", version); */ } inode = jDir->ino; version = jDir->version; @@ -574,15 +573,15 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) /* we need to search all and return the inode with the highest version */ for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) { if (ino == jDir->ino) { - if (jDir->version < version) + if (jDir->version < version) continue; if (jDir->version == version && jDirFoundType) { - /* I'm pretty sure this isn't legal */ + /* I'm pretty sure this isn't legal */ putstr(" ** ERROR ** "); -// putnstr(jDir->name, jDir->nsize); -// putLabeledWord(" has dup version (resolve) = ", -// version); +/* putnstr(jDir->name, jDir->nsize); */ +/* putLabeledWord(" has dup version (resolve) = ", */ +/* version); */ } jDirFoundType = jDir->type; @@ -686,12 +685,6 @@ jffs2_1pass_rescan_needed(struct part_info *part) return 1; } -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) - if (nanddev != (int)part->usr_priv - 1) { - DEBUGF ("rescan: nand device changed\n"); - return -1; - } -#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ /* FIXME */ #if 0 /* but suppose someone reflashed a partition at the same offset... */ @@ -806,10 +799,8 @@ jffs2_1pass_build_lists(struct part_info * part) u32 counterF = 0; u32 counterN = 0; -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) - nanddev = (int)part->usr_priv - 1; - nand = &nand_info[nanddev]; -#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ + struct mtdids *id = part->dev->id; + nand = nand_info + id->num; /* if we are building a list we need to refresh the cache. */ jffs_init_1pass_list(part); @@ -993,7 +984,7 @@ jffs2_1pass_load(char *dest, struct part_info * part, const char *fname) long ret = 0; u32 inode; - if (! (pl = jffs2_get_list(part, "load"))) + if (! (pl = jffs2_get_list(part, "load"))) return 0; if (! (inode = jffs2_1pass_search_inode(pl, fname, 1))) { @@ -1025,7 +1016,7 @@ jffs2_1pass_info(struct part_info * part) struct b_lists *pl; int i; - if (! (pl = jffs2_get_list(part, "info"))) + if (! (pl = jffs2_get_list(part, "info"))) return 0; jffs2_1pass_fill_info(pl, &info); diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index c2b69fb2dd..648a10dd92 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -58,6 +58,14 @@ extern void __raw_readsl(unsigned int addr, void *data, int longlen); #define __raw_readw(a) __arch_getw(a) #define __raw_readl(a) __arch_getl(a) +#define writeb(v,a) __arch_putb(v,a) +#define writew(v,a) __arch_putw(v,a) +#define writel(v,a) __arch_putl(v,a) + +#define readb(a) __arch_getb(a) +#define readw(a) __arch_getw(a) +#define readl(a) __arch_getl(a) + /* * The compiler seems to be incapable of optimising constants * properly. Spell it out to the compiler in some cases. diff --git a/include/configs/netstar.h b/include/configs/netstar.h new file mode 100644 index 0000000000..30d2654732 --- /dev/null +++ b/include/configs/netstar.h @@ -0,0 +1,265 @@ +/* + * (C) Copyright 2005 2N TELEKOMUNIKACE, Ladislav Michl + * + * Configuation settings for the TI OMAP NetStar board. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +/* + * High Level Configuration Options + * (easy to change) + */ +#define CONFIG_ARM925T 1 /* This is an arm925t CPU */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ +#define CONFIG_OMAP1510 1 /* which is in a 5910 */ + +/* Input clock of PLL */ +#define CONFIG_SYS_CLK_FREQ 150000000 /* 150MHz input clock */ +#define CONFIG_XTAL_FREQ 12000000 + +#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ + +#define CONFIG_MISC_INIT_R /* There is nothing to really init */ +#define BOARD_LATE_INIT /* but we flash the LEDs here */ + +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 + +#define CFG_DEVICE_NULLDEV 1 /* enable null device */ +#define CONFIG_SILENT_CONSOLE 1 /* enable silent startup */ + +/* + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ +#define PHYS_SDRAM_1 0x10000000 /* SDRAM Bank #1 */ +#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ + +/* + * FLASH organization + */ +#define CFG_FLASH_BASE PHYS_FLASH_1 +#define CFG_MAX_FLASH_BANKS 1 +#if (PHYS_SDRAM_1_SIZE == SZ_32M) +/*#if 1*/ +#define CFG_FLASH_CFI /* Flash is CFI conformant */ +#define CFG_FLASH_CFI_DRIVER /* Use the common driver */ +#define CFG_FLASH_EMPTY_INFO +#define CFG_MAX_FLASH_SECT 128 +#else +#define PHYS_FLASH_1_SIZE SZ_1M +#define CFG_MAX_FLASH_SECT 19 +#define CFG_FLASH_ERASE_TOUT (5*CFG_HZ) /* in ticks */ +#define CFG_FLASH_WRITE_TOUT (5*CFG_HZ) +#endif + +#define CFG_MONITOR_BASE PHYS_FLASH_1 +#define CFG_MONITOR_LEN SZ_256K + +/* + * Environment settings + */ +#define CFG_ENV_IS_IN_FLASH +#define ENV_IS_SOLITARY +#define CFG_ENV_ADDR 0x4000 +#define CFG_ENV_SIZE SZ_8K +#define CFG_ENV_SECT_SIZE SZ_8K +#define CFG_ENV_ADDR_REDUND 0x6000 +#define CFG_ENV_SIZE_REDUND CFG_ENV_SIZE +#define CONFIG_ENV_OVERWRITE + +/* + * Size of malloc() pool + */ +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ +/* XXX #define CFG_MALLOC_LEN (SZ_64K - CFG_GBL_DATA_SIZE)*/ +#define CFG_MALLOC_LEN SZ_4M + +/* + * The stack size is set up in start.S using the settings below + */ +/* XXX #define CONFIG_STACKSIZE SZ_8K /XXX* regular stack */ +#define CONFIG_STACKSIZE SZ_1M /* regular stack */ + +/* + * Hardware drivers + */ +#define CONFIG_DRIVER_SMC91111 +#define CONFIG_SMC91111_BASE 0x04000300 + +/* + * NS16550 Configuration + */ +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE (-4) +#define CFG_NS16550_CLK (CONFIG_XTAL_FREQ) /* can be 12M/32Khz or 48Mhz */ +#define CFG_NS16550_COM1 OMAP1510_UART1_BASE /* uart1 */ + +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 115200 +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/*#define CONFIG_SKIP_RELOCATE_UBOOT*/ +/*#define CONFIG_SKIP_LOWLEVEL_INIT */ + +/* + * NAND flash + */ +#define CFG_MAX_NAND_DEVICE 1 +#define CFG_NAND_BASE 0x04000000 + (2 << 23) +#define CONFIG_NEW_NAND_CODE + +/* + * JFFS2 partitions (mtdparts command line support) + */ +#define CONFIG_JFFS2_CMDLINE +#define MTDIDS_DEFAULT "nor0=omapflash.0,nand0=omapnand.0" +#define MTDPARTS_DEFAULT "mtdparts=omapflash.0:8k@16k(env),8k(r_env),448k@576k(u-boot);omapnand.0:48M(rootfs0),48M(rootfs1),-(data)" + +#if 0 +#define CONFIG_COMMANDS (CFG_CMD_BDI | \ + CFG_CMD_BOOTD | \ + CFG_CMD_DHCP | \ + CFG_CMD_ENV | \ + CFG_CMD_FLASH | \ + CFG_CMD_IMI | \ + CFG_CMD_LOADB | \ + CFG_CMD_NET | \ + CFG_CMD_MEMORY | \ + CFG_CMD_PING | \ + CFG_CMD_RUN) + +#else +#define CONFIG_COMMANDS (CFG_CMD_BDI | \ + CFG_CMD_BOOTD | \ + CFG_CMD_DHCP | \ + CFG_CMD_ENV | \ + CFG_CMD_FLASH | \ + CFG_CMD_NAND | \ + CFG_CMD_IMI | \ + CFG_CMD_JFFS2 | \ + CFG_CMD_LOADB | \ + CFG_CMD_NET | \ + CFG_CMD_MEMORY | \ + CFG_CMD_PING | \ + CFG_CMD_RUN) + +#define CONFIG_JFFS2_NAND 1 /* jffs2 on nand support */ +#endif + +#define CONFIG_BOOTP_MASK CONFIG_BOOTP_DEFAULT +#define CONFIG_LOOPW + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK /* allow to break in always */ +#undef CONFIG_BOOTARGS /* the boot command will set bootargs*/ +#define CFG_AUTOLOAD "n" /* No autoload */ +#define CONFIG_BOOTCOMMAND "run nboot" +#define CONFIG_PREBOOT "run setup" +#define CONFIG_EXTRA_ENV_SETTINGS \ + "setup=setenv bootargs console=ttyS0,$baudrate " \ + "$mtdparts\0" \ + "ospart=0\0" \ + "setpart=" \ + "if test -n $swapos; then " \ + "if test $ospart -eq 0; then chpart nand0,1; else chpart nand0,0; fi; "\ + "setenv swapos; saveenv; " \ + "else " \ + "chpart nand0,$ospart; " \ + "fi\0" \ + "nfsargs=setenv bootargs $bootargs " \ + "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname::off " \ + "nfsroot=$rootpath root=/dev/nfs\0" \ + "flashargs=run setpart;setenv bootargs $bootargs " \ + "root=/dev/mtdblock$partition ro " \ + "rootfstype=jffs2\0" \ + "initrdargs=setenv bootargs $bootargs " \ + "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname::off\0" \ + "iboot=bootp;run initrdargs;tftp;bootm\0" \ + "fboot=run flashargs;fsload /boot/uImage;bootm\0" \ + "nboot=bootp;run nfsargs;tftp;bootm\0" + +#if 0 /* feel free to disable for development */ +#define CONFIG_AUTOBOOT_KEYED /* Enable password protection */ +#define CONFIG_AUTOBOOT_PROMPT "\nNetStar PBX - boot in %d sec...\n" +#define CONFIG_AUTOBOOT_DELAY_STR "R" /* 1st "password" */ +#define CONFIG_BOOT_RETRY_TIME 30 +#endif + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "# " /* Monitor Command Prompt */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#define CONFIG_AUTO_COMPLETE + +#define CFG_MEMTEST_START PHYS_SDRAM_1 +#define CFG_MEMTEST_END PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +#define CFG_LOAD_ADDR PHYS_SDRAM_1 + 0x400000 /* default load address */ + +/* The 1510 has 3 timers, they can be driven by the RefClk (12Mhz) or by DPLL1. + * This time is further subdivided by a local divisor. + */ +#define CFG_TIMERBASE OMAP1510_TIMER1_BASE +#define CFG_PVT 7 /* 2^(pvt+1), divide by 256 */ +#define CFG_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CFG_PVT)) + +#define OMAP5910_DPLL_DIV 1 +#define OMAP5910_DPLL_MUL ((CONFIG_SYS_CLK_FREQ * \ + (1 << OMAP5910_DPLL_DIV)) / CONFIG_XTAL_FREQ) + +#define OMAP5910_ARM_PER_DIV 2 /* CKL/4 */ +#define OMAP5910_LCD_DIV 2 /* CKL/4 */ +#define OMAP5910_ARM_DIV 0 /* CKL/1 */ +#define OMAP5910_DSP_DIV 0 /* CKL/1 */ +#define OMAP5910_TC_DIV 1 /* CKL/2 */ +#define OMAP5910_DSP_MMU_DIV 1 /* CKL/2 */ +#define OMAP5910_ARM_TIM_SEL 1 /* CKL used for MPU timers */ + +#define OMAP5910_ARM_EN_CLK 0x03d6 /* 0000 0011 1101 0110b Clock Enable */ +#define OMAP5910_ARM_CKCTL ((OMAP5910_ARM_PER_DIV) | \ + (OMAP5910_LCD_DIV << 2) | \ + (OMAP5910_ARM_DIV << 4) | \ + (OMAP5910_DSP_DIV << 6) | \ + (OMAP5910_TC_DIV << 8) | \ + (OMAP5910_DSP_MMU_DIV << 10) | \ + (OMAP5910_ARM_TIM_SEL << 12)) + +#endif /* __CONFIG_H */ diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h index afe96b59cb..3d1d416810 100644 --- a/include/linux/mtd/mtd-abi.h +++ b/include/linux/mtd/mtd-abi.h @@ -1,7 +1,7 @@ /* * $Id: mtd-abi.h,v 1.7 2004/11/23 15:37:32 gleixner Exp $ * - * Portions of MTD ABI definition which are shared by kernel and user space + * Portions of MTD ABI definition which are shared by kernel and user space */ #ifndef __MTD_ABI_H__ @@ -27,17 +27,17 @@ struct mtd_oob_buf { #define MTD_OTHER 14 #define MTD_UNKNOWN 15 -#define MTD_CLEAR_BITS 1 // Bits can be cleared (flash) -#define MTD_SET_BITS 2 // Bits can be set -#define MTD_ERASEABLE 4 // Has an erase function -#define MTD_WRITEB_WRITEABLE 8 // Direct IO is possible -#define MTD_VOLATILE 16 // Set for RAMs -#define MTD_XIP 32 // eXecute-In-Place possible -#define MTD_OOB 64 // Out-of-band data (NAND flash) -#define MTD_ECC 128 // Device capable of automatic ECC -#define MTD_NO_VIRTBLOCKS 256 // Virtual blocks not allowed +#define MTD_CLEAR_BITS 1 /* Bits can be cleared (flash) */ +#define MTD_SET_BITS 2 /* Bits can be set */ +#define MTD_ERASEABLE 4 /* Has an erase function */ +#define MTD_WRITEB_WRITEABLE 8 /* Direct IO is possible */ +#define MTD_VOLATILE 16 /* Set for RAMs */ +#define MTD_XIP 32 /* eXecute-In-Place possible */ +#define MTD_OOB 64 /* Out-of-band data (NAND flash) */ +#define MTD_ECC 128 /* Device capable of automatic ECC */ +#define MTD_NO_VIRTBLOCKS 256 /* Virtual blocks not allowed */ -// Some common devices / combinations of capabilities +/* Some common devices / combinations of capabilities */ #define MTD_CAP_ROM 0 #define MTD_CAP_RAM (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE) #define MTD_CAP_NORFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE) @@ -45,31 +45,31 @@ struct mtd_oob_buf { #define MTD_WRITEABLE (MTD_CLEAR_BITS|MTD_SET_BITS) -// Types of automatic ECC/Checksum available -#define MTD_ECC_NONE 0 // No automatic ECC available -#define MTD_ECC_RS_DiskOnChip 1 // Automatic ECC on DiskOnChip -#define MTD_ECC_SW 2 // SW ECC for Toshiba & Samsung devices +/* Types of automatic ECC/Checksum available */ +#define MTD_ECC_NONE 0 /* No automatic ECC available */ +#define MTD_ECC_RS_DiskOnChip 1 /* Automatic ECC on DiskOnChip */ +#define MTD_ECC_SW 2 /* SW ECC for Toshiba & Samsung devices */ /* ECC byte placement */ -#define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended) -#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode) -#define MTD_NANDECC_AUTOPLACE 2 // Use the default placement scheme -#define MTD_NANDECC_PLACEONLY 3 // Use the given placement in the structure (Do not store ecc result on read) -#define MTD_NANDECC_AUTOPL_USR 4 // Use the given autoplacement scheme rather than using the default +#define MTD_NANDECC_OFF 0 /* Switch off ECC (Not recommended) */ +#define MTD_NANDECC_PLACE 1 /* Use the given placement in the structure (YAFFS1 legacy mode) */ +#define MTD_NANDECC_AUTOPLACE 2 /* Use the default placement scheme */ +#define MTD_NANDECC_PLACEONLY 3 /* Use the given placement in the structure (Do not store ecc result on read) */ +#define MTD_NANDECC_AUTOPL_USR 4 /* Use the given autoplacement scheme rather than using the default */ struct mtd_info_user { uint8_t type; uint32_t flags; - uint32_t size; // Total size of the MTD + uint32_t size; /* Total size of the MTD */ uint32_t erasesize; - uint32_t oobblock; // Size of OOB blocks (e.g. 512) - uint32_t oobsize; // Amount of OOB data per block (e.g. 16) + uint32_t oobblock; /* Size of OOB blocks (e.g. 512) */ + uint32_t oobsize; /* Amount of OOB data per block (e.g. 16) */ uint32_t ecctype; uint32_t eccsize; }; struct region_info_user { - uint32_t offset; /* At which this region starts, + uint32_t offset; /* At which this region starts, * from the beginning of the MTD */ uint32_t erasesize; /* For this region */ uint32_t numblocks; /* Number of blocks in this region */ diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 9ef4cced5e..13e90803a1 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -1,4 +1,4 @@ -/* +/* * $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $ * * Copyright (C) 1999-2003 David Woodhouse et al. @@ -46,7 +46,7 @@ struct mtd_erase_region_info { struct mtd_info { u_char type; u_int32_t flags; - u_int32_t size; // Total size of the MTD + u_int32_t size; /* Total size of the MTD */ /* "Major" erase size for the device. Naïve users may take this * to be the only erase size available, or may use the more detailed @@ -54,25 +54,25 @@ struct mtd_info { */ u_int32_t erasesize; - u_int32_t oobblock; // Size of OOB blocks (e.g. 512) - u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) - u_int32_t oobavail; // Number of bytes in OOB area available for fs + u_int32_t oobblock; /* Size of OOB blocks (e.g. 512) */ + u_int32_t oobsize; /* Amount of OOB data per block (e.g. 16) */ + u_int32_t oobavail; /* Number of bytes in OOB area available for fs */ u_int32_t ecctype; u_int32_t eccsize; - - // Kernel-only stuff starts here. + + /* Kernel-only stuff starts here. */ char *name; int index; - // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) + /* oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) */ struct nand_oobinfo oobinfo; /* Data for variable erase regions. If numeraseregions is zero, - * it means that the whole device has erasesize as given above. + * it means that the whole device has erasesize as given above. */ int numeraseregions; - struct mtd_erase_region_info *eraseregions; + struct mtd_erase_region_info *eraseregions; /* This really shouldn't be here. It can go away in 2.5 */ u_int32_t bank_size; @@ -95,10 +95,10 @@ struct mtd_info { int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); - /* - * Methods to access the protection register area, present in some + /* + * Methods to access the protection register area, present in some * flash devices. The user data is one time programmable but the - * factory data is read only. + * factory data is read only. */ int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); @@ -109,14 +109,14 @@ struct mtd_info { #if 0 /* kvec-based read/write methods. We need these especially for NAND flash, with its limited number of write cycles per erase. - NB: The 'count' parameter is the number of _vectors_, each of + NB: The 'count' parameter is the number of _vectors_, each of which contains an (ofs, len) tuple. */ int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); - int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, + int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); - int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, + int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); #endif /* Sync */ @@ -179,7 +179,7 @@ int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, #define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) #define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) #define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) -#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) +#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) #ifdef CONFIG_MTD_PARTITIONS diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 9a0108f78c..065e1cb4e4 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -24,7 +24,7 @@ * bat later if I did something naughty. * 10-11-2000 SJH Added private NAND flash structure for driver * 10-24-2000 SJH Added prototype for 'nand_scan' function - * 10-29-2001 TG changed nand_chip structure to support + * 10-29-2001 TG changed nand_chip structure to support * hardwarespecific function for accessing control lines * 02-21-2002 TG added support for different read/write adress and * ready/busy line access function @@ -36,14 +36,14 @@ * CONFIG_MTD_NAND_ECC_JFFS2 is not set * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC * - * 08-29-2002 tglx nand_chip structure: data_poi for selecting + * 08-29-2002 tglx nand_chip structure: data_poi for selecting * internal / fs-driver buffer * support for 6byte/512byte hardware ECC * read_ecc, write_ecc extended for different oob-layout * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB, * NAND_YAFFS_OOB * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL - * Split manufacturer and device ID structures + * Split manufacturer and device ID structures * * 02-08-2004 tglx added option field to nand structure for chip anomalities * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id @@ -120,7 +120,7 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_ #define NAND_STATUS_READY 0x40 #define NAND_STATUS_WP 0x80 -/* +/* * Constants for ECC_MODES */ @@ -162,12 +162,12 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_ #define NAND_CACHEPRG 0x00000008 /* Chip has copy back function */ #define NAND_COPYBACK 0x00000010 -/* AND Chip which has 4 banks and a confusing page / block +/* AND Chip which has 4 banks and a confusing page / block * assignment. See Renesas datasheet for further information */ #define NAND_IS_AND 0x00000020 /* Chip has a array of 4 pages which can be read without * additional ready /busy waits */ -#define NAND_4PAGE_ARRAY 0x00000040 +#define NAND_4PAGE_ARRAY 0x00000040 /* Options valid for Samsung large page devices */ #define NAND_SAMSUNG_LP_OPTIONS \ @@ -186,8 +186,8 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_ /* Use a flash based bad block table. This option is passed to the * default bad block table function. */ #define NAND_USE_FLASH_BBT 0x00010000 -/* The hw ecc generator provides a syndrome instead a ecc value on read - * This can only work if we have the ecc bytes directly behind the +/* The hw ecc generator provides a syndrome instead a ecc value on read + * This can only work if we have the ecc bytes directly behind the * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ #define NAND_HWECC_SYNDROME 0x00020000 @@ -218,7 +218,7 @@ struct nand_chip; #if 0 /** * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices - * @lock: protection lock + * @lock: protection lock * @active: the mtd device which holds the controller currently */ struct nand_hw_control { @@ -229,8 +229,8 @@ struct nand_hw_control { /** * struct nand_chip - NAND Private Flash Chip Data - * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device - * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device + * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device + * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device * @read_byte: [REPLACEABLE] read one byte from the chip * @write_byte: [REPLACEABLE] write one byte to the chip * @read_word: [REPLACEABLE] read one word from the chip @@ -253,7 +253,7 @@ struct nand_hw_control { * be provided if a hardware ECC is available * @erase_cmd: [INTERN] erase command write function, selectable due to AND support * @scan_bbt: [REPLACEABLE] function to scan bad block table - * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines + * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines * @eccsize: [INTERN] databytes used per ecc-calculation * @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step * @eccsteps: [INTERN] number of ecc calculation steps per page @@ -265,7 +265,7 @@ struct nand_hw_control { * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry * @chip_shift: [INTERN] number of address bits in one chip - * @data_buf: [INTERN] internal buffer for one page + oob + * @data_buf: [INTERN] internal buffer for one page + oob * @oob_buf: [INTERN] oob buffer for one eraseblock * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized * @data_poi: [INTERN] pointer to a data buffer @@ -280,20 +280,20 @@ struct nand_hw_control { * @bbt: [INTERN] bad block table pointer * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup * @bbt_md: [REPLACEABLE] bad block table mirror descriptor - * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan + * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices * @priv: [OPTIONAL] pointer to private chip date */ - + struct nand_chip { void __iomem *IO_ADDR_R; void __iomem *IO_ADDR_W; - + u_char (*read_byte)(struct mtd_info *mtd); void (*write_byte)(struct mtd_info *mtd, u_char byte); u16 (*read_word)(struct mtd_info *mtd); void (*write_word)(struct mtd_info *mtd, u16 word); - + void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len); int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len); @@ -358,7 +358,7 @@ struct nand_chip { * @name: Identify the device type * @id: device ID code * @pagesize: Pagesize in bytes. Either 256 or 512 or 0 - * If the pagesize is 0, then the real pagesize + * If the pagesize is 0, then the real pagesize * and the eraseize are determined from the * extended id bytes in the chip * @erasesize: Size of an erase block in the flash device. @@ -387,7 +387,7 @@ struct nand_manufacturers { extern struct nand_flash_dev nand_flash_ids[]; extern struct nand_manufacturers nand_manuf_ids[]; -/** +/** * struct nand_bbt_descr - bad block table descriptor * @options: options for this descriptor * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE @@ -398,14 +398,14 @@ extern struct nand_manufacturers nand_manuf_ids[]; * @version: version read from the bbt page during scan * @len: length of the pattern, if 0 no pattern check is performed * @maxblocks: maximum number of blocks to search for a bbt. This number of - * blocks is reserved at the end of the device where the tables are + * blocks is reserved at the end of the device where the tables are * written. * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than * bad) block in the stored bbt - * @pattern: pattern to identify bad block table or factory marked good / + * @pattern: pattern to identify bad block table or factory marked good / * bad blocks, can be NULL, if len = 0 * - * Descriptor for the bad block table marker and the descriptor for the + * Descriptor for the bad block table marker and the descriptor for the * pattern which identifies good and bad blocks. The assumption is made * that the pattern and the version count are always located in the oob area * of the first block. diff --git a/include/nand.h b/include/nand.h index 29580da4fe..6dbaa42402 100644 --- a/include/nand.h +++ b/include/nand.h @@ -24,7 +24,7 @@ #ifndef _NAND_H_ #define _NAND_H_ -#include +#include #include #include From 8e9655f863246db60c51140153186acc2afdc855 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 2 Nov 2005 14:29:12 +0100 Subject: [PATCH 003/102] * Add hook to NAND erase and implement nand_wait function. Patch by Mike Rapoport, 01 Nov 2005 Signed-off-by: Ladislav Michl --- common/Makefile | 2 +- drivers/nand/nand_base.c | 36 +++++++++++++++++++++++++++++++++--- include/nand.h | 9 ++++++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/common/Makefile b/common/Makefile index 209e17d816..9bfc11ab50 100644 --- a/common/Makefile +++ b/common/Makefile @@ -37,7 +37,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o \ cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \ cmd_load.o cmd_log.o \ cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \ - cmd_nand.o cmd_net.o cmd_nvedit.o \ + cmd_nand.o cmd_nand_new.o cmd_net.o cmd_nvedit.o \ cmd_pci.o cmd_pcmcia.o cmd_portio.o \ cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o cmd_usb.o cmd_vfd.o \ command.o console.o devices.o dlmalloc.o docecc.o \ diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c index a7ab8c27ad..9ec5af9d71 100644 --- a/drivers/nand/nand_base.c +++ b/drivers/nand/nand_base.c @@ -189,7 +189,11 @@ static void nand_release_device (struct mtd_info *mtd) spin_unlock (&this->chip_lock); } #else -#define nand_release_device(mtd) do {} while(0) +static void nand_release_device (struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + this->select_chip(mtd, -1); /* De-select the NAND device */ +} #endif /** @@ -831,8 +835,34 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) #else static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) { - /* TODO */ - return 0; + unsigned long timeo; + + if (state == FL_ERASING) + timeo = CFG_HZ * 400; + else + timeo = CFG_HZ * 20; + + if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) + this->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1); + else + this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); + + reset_timer_masked(); + + while (1) { + if (get_timer_masked() > timeo) + return 0; + + if (this->dev_ready) { + if (this->dev_ready(mtd)) + break; + } else { + if (this->read_byte(mtd) & NAND_STATUS_READY) + break; + } + } + + return this->read_byte(mtd); } #endif diff --git a/include/nand.h b/include/nand.h index 6dbaa42402..3490347723 100644 --- a/include/nand.h +++ b/include/nand.h @@ -50,7 +50,14 @@ static inline int nand_block_isbad(nand_info_t *info, ulong ofs) static inline int nand_erase(nand_info_t *info, ulong off, ulong size) { - return 0; /* FIXME */ + struct erase_info instr; + + instr.mtd = info; + instr.addr = off; + instr.len = size; + instr.callback = 0; + + return info->erase(info, &instr); } #endif From e0269579a5b546b8f4e9ede82dc1cc3fa3796e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Tue, 7 Feb 2006 20:04:48 +0100 Subject: [PATCH 004/102] This is the first commit for the u-boot zylonite port. The following has be done so far: * created zylonite board dir (based on lubbock) * extended some - but not all pxa sources and headers for Intel Monahans support (CONFIG_CPU_MONAHANS) * created Makefile zylonite target + MAKEALL entry * added some debug nonsense, remove later, grep for mk@tbd Status: compiles (eldk-4.0), and can be started with BDI, but runs forever and doesn't halt at breakpoints. Hmmm... --- MAKEALL | 2 +- Makefile | 5 +- config.mk | 4 + cpu/pxa/cpu.c | 3 + cpu/pxa/serial.c | 12 + cpu/pxa/start.S | 42 +- include/asm-arm/arch-pxa/hardware.h | 155 +- include/asm-arm/arch-pxa/pxa-regs.h | 2634 +++++++++++++++++++++------ lib_arm/board.c | 2 + 9 files changed, 2253 insertions(+), 606 deletions(-) diff --git a/MAKEALL b/MAKEALL index fcbab47cab..2587741ee7 100755 --- a/MAKEALL +++ b/MAKEALL @@ -204,7 +204,7 @@ LIST_ARM11=" \ LIST_pxa=" \ adsvix cerf250 cradle csb226 \ innokom lubbock pxa255_idp wepep250 \ - xaeniax xm250 xsengine \ + xaeniax xm250 xsengine zylonite \ " LIST_ixp="ixdp425" diff --git a/Makefile b/Makefile index 9305cab38b..63e0a20662 100644 --- a/Makefile +++ b/Makefile @@ -1633,6 +1633,9 @@ xm250_config : unconfig xsengine_config : unconfig @./mkconfig $(@:_config=) arm pxa xsengine +zylonite_config : + @./mkconfig $(@:_config=) arm pxa zylonite + ######################################################################### ## ARM1136 Systems ######################################################################### @@ -1838,7 +1841,7 @@ clobber: clean -o -name '*.srec' -o -name '*.bin' -o -name u-boot.img \) \ -print0 \ | xargs -0 rm -f - rm -f $(OBJS) *.bak tags TAGS + rm -f $(OBJS) *.bak tags rm -fr *.*~ rm -f u-boot u-boot.map u-boot.hex $(ALL) rm -f tools/crc32.c tools/environment.c tools/env/crc32.c diff --git a/config.mk b/config.mk index d85ac36b5e..2c6cfb4b3c 100644 --- a/config.mk +++ b/config.mk @@ -131,6 +131,10 @@ else CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes endif +ifdef WILD_WILD_WEST +CFLAGS := $(CFLAGS) -Werror +endif + # avoid trigraph warnings while parsing pci.h (produced by NIOS gcc-2.9) # this option have to be placed behind -Wall -- that's why it is here ifeq ($(ARCH),nios) diff --git a/cpu/pxa/cpu.c b/cpu/pxa/cpu.c index d1551ddc38..445ba18756 100644 --- a/cpu/pxa/cpu.c +++ b/cpu/pxa/cpu.c @@ -143,6 +143,7 @@ int dcache_status (void) return 0; /* always off */ } +#ifndef CONFIG_CPU_MONAHANS void set_GPIO_mode(int gpio_mode) { int gpio = gpio_mode & GPIO_MD_MASK_NR; @@ -160,3 +161,5 @@ void set_GPIO_mode(int gpio_mode) gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); } +#endif /* CONFIG_CPU_MONAHANS */ + diff --git a/cpu/pxa/serial.c b/cpu/pxa/serial.c index cedebfe496..9bf2a7cf4f 100644 --- a/cpu/pxa/serial.c +++ b/cpu/pxa/serial.c @@ -54,7 +54,11 @@ void serial_setbrg (void) hang (); #ifdef CONFIG_FFUART +#ifdef CONFIG_CPU_MONAHANS + CKENA |= CKENA_22_FFUART; +#else CKEN |= CKEN6_FFUART; +#endif /* CONFIG_CPU_MONAHANS */ FFIER = 0; /* Disable for now */ FFFCR = 0; /* No fifos enabled */ @@ -68,7 +72,11 @@ void serial_setbrg (void) FFIER = IER_UUE; /* Enable FFUART */ #elif defined(CONFIG_BTUART) +#ifdef CONFIG_CPU_MONAHANS + CKENA |= CKENA_21_BTUART; +#else CKEN |= CKEN7_BTUART; +#endif /* CONFIG_CPU_MONAHANS */ BTIER = 0; BTFCR = 0; @@ -82,7 +90,11 @@ void serial_setbrg (void) BTIER = IER_UUE; /* Enable BFUART */ #elif defined(CONFIG_STUART) +#ifdef CONFIG_CPU_MONAHANS + CKENA |= CKENA_23_STUART; +#else CKEN |= CKEN5_STUART; +#endif /* CONFIG_CPU_MONAHANS */ STIER = 0; STFCR = 0; diff --git a/cpu/pxa/start.S b/cpu/pxa/start.S index a8cc0800b0..994082691d 100644 --- a/cpu/pxa/start.S +++ b/cpu/pxa/start.S @@ -190,10 +190,10 @@ cpuspeed: .word CFG_CPUSPEED #endif - /* RS: ??? */ - .macro CPWAIT - mrc p15,0,r0,c2,c0,0 - mov r0,r0 + /* takes care the CP15 update has taken place */ + .macro CPWAIT reg + mrc p15,0,\reg,c2,c0,0 + mov \reg,\reg sub pc,pc,#4 .endm @@ -201,13 +201,28 @@ cpuspeed: .word CFG_CPUSPEED cpu_init_crit: /* mask all IRQs */ +#ifndef CONFIG_CPU_MONAHANS + ldr r0, IC_BASE mov r1, #0x00 str r1, [r0, #ICMR] +#else + /* Step 1 - Enable CP6 permission */ + mrc p15, 0, r1, c15, c1, 0 @ read CPAR + orr r1, r1, #0x40 + mcr p15, 0, r1, c15, c1, 0 + CPWAIT r1 -#if defined(CFG_CPUSPEED) + /* Step 2 - Mask ICMR & ICMR2 */ + mov r1, #0 + mcr p6, 0, r1, c1, c0, 0 @ ICMR + mcr p6, 0, r1, c7, c0, 0 @ ICMR2 +#endif - /* set clock speed */ +#ifndef CONFIG_CPU_MONAHANS +#ifdef CFG_CPUSPEED + + /* set clock speed tbd@mk: required for monahans? */ ldr r0, CC_BASE ldr r1, cpuspeed str r1, [r0, #CCCR] @@ -215,7 +230,10 @@ cpu_init_crit: mcr p14, 0, r0, c6, c0, 0 setspeed_done: -#endif + +#endif /* CFG_CPUSPEED */ +#endif /* CONFIG_CPU_MONAHANS */ + /* * before relocating, we have to setup RAM timing @@ -227,19 +245,21 @@ setspeed_done: mov lr, ip /* Memory interfaces are working. Disable MMU and enable I-cache. */ + /* mk: hmm, this is not in the monahans docs, leave it now but + * check here if it doesn't work :-) */ ldr r0, =0x2001 /* enable access to all coproc. */ mcr p15, 0, r0, c15, c1, 0 - CPWAIT + CPWAIT r0 mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */ - CPWAIT + CPWAIT r0 mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */ - CPWAIT + CPWAIT r0 mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */ - CPWAIT + CPWAIT r0 /* Enable the Icache */ /* diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index 3ff1d26145..a12aea14c4 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -8,11 +8,6 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - * - * Note: This file was taken from linux-2.4.19-rmk4-pxa1 - * - * - 2003/01/20 implementation specifics activated - * Robert Schwebel */ #ifndef __ASM_ARCH_HARDWARE_H @@ -21,16 +16,6 @@ #include #include - -/* - * These are statically mapped PCMCIA IO space for designs using it as a - * generic IO bus, typically with ISA parts, hardwired IDE interfaces, etc. - * The actual PCMCIA code is mapping required IO region at run time. - */ -#define PCMCIA_IO_0_BASE 0xf6000000 -#define PCMCIA_IO_1_BASE 0xf7000000 - - /* * We requires absolute addresses. */ @@ -44,22 +29,63 @@ #define UNCACHED_ADDR UNCACHED_PHYS_0 /* - * Intel PXA internal I/O mappings: + * Intel PXA2xx internal register mapping: * - * 0x40000000 - 0x41ffffff <--> 0xf8000000 - 0xf9ffffff - * 0x44000000 - 0x45ffffff <--> 0xfa000000 - 0xfbffffff - * 0x48000000 - 0x49ffffff <--> 0xfc000000 - 0xfdffffff + * 0x40000000 - 0x41ffffff <--> 0xf2000000 - 0xf3ffffff + * 0x44000000 - 0x45ffffff <--> 0xf4000000 - 0xf5ffffff + * 0x48000000 - 0x49ffffff <--> 0xf6000000 - 0xf7ffffff + * 0x4c000000 - 0x4dffffff <--> 0xf8000000 - 0xf9ffffff + * 0x50000000 - 0x51ffffff <--> 0xfa000000 - 0xfbffffff + * 0x54000000 - 0x55ffffff <--> 0xfc000000 - 0xfdffffff + * 0x58000000 - 0x59ffffff <--> 0xfe000000 - 0xffffffff + * + * Note that not all PXA2xx chips implement all those addresses, and the + * kernel only maps the minimum needed range of this mapping. + */ +#ifndef CONFIG_CPU_MONAHANS +#define io_p2v(x) (0xf2000000 + ((x) & 0x01ffffff) + (((x) & 0x1c000000) >> 1)) +#define io_v2p(x) (0x3c000000 + ((x) & 0x01ffffff) + (((x) & 0x0e000000) << 1)) +#else + +/* There are too many IO area needed to map, so I divide them into 3 areas + * 0x40000000 - 0x41ffffff <--> 0xf6000000 - 0xf7ffffff Devs + */ +#define io_p2v(x) ((((x) & 0xfc000000)>>4) + 0xf2000000 + ((x)&0x01ffffff)) +#define io_v2p(x) (((((x) - 0xf2000000)&0xfc000000)<<4) + ((x)&0x01ffffff)) + +/* + * 0x42000000 - 0x421fffff <--> 0xf8000000 - 0xf81fffff MMC2 & USIM2 + * 0x43000000 - 0x430fffff <--> 0xf8200000 - 0xf82fffff Caddo + * 0x43100000 - 0x431fffff <--> 0xf8300000 - 0xf83fffff NAND + * 0x44000000 - 0x440fffff <--> 0xf8400000 - 0xf84fffff LCD + * 0x46000000 - 0x460fffff <--> 0xf8800000 - 0xf88fffff Mini LCD + * 0x48100000 - 0x481fffff <--> 0xf8d00000 - 0xf8dfffff Dynamic Mem Ctl + * 0x4a000000 - 0x4a0fffff <--> 0xf9000000 - 0xf90fffff Static Mem Ctl + * 0x4c000000 - 0x4c0fffff <--> 0xf9400000 - 0xf94fffff USB Host */ -/* FIXME: Only this does work for u-boot... find out why... [RS] */ -#define UBOOT_REG_FIX 1 +#define io_p2v_2(x) (((((x) - 0x42000000) & 0xff000000) >> 3) + 0xf8000000\ + + ((x) & 0x001fffff)) +#define io_v2p_2(x) (((((x) & 0xffe00000) - 0xf8000000) << 3) + 0x42000000\ + + (x & 0x001fffff)) +/* + * 0x50000000 - 0x500fffff <--> 0xfa000000 - 0xfa0fffff Camera Interface + * 0x54000000 - 0x540fffff <--> 0xfa400000 - 0xfa4fffff 2D Graphics Ctrl + * 0x54100000 - 0x541fffff <--> 0xfa500000 - 0xfa5fffff USB Device 2.0 Ctrl + * 0x58000000 - 0x580fffff <--> 0xfa800000 - 0xfa8fffff Internal SRAM Ctrl + */ + +#define io_p2v_3(x) ((((x) & 0xfc000000) >> 4) + 0xf5000000 + \ + ((x) & 0x001fffff)) +#define io_v2p_3(x) (((((x) - 0xf5000000) & 0x0fc00000) << 4) + \ + ((x) & 0x001fffff)) +#endif /* CONFIG_CPU_MONAHANS */ -#ifndef UBOOT_REG_FIX #ifndef __ASSEMBLY__ -#define io_p2v(x) ( ((x) | 0xbe000000) ^ (~((x) >> 1) & 0x06000000) ) -#define io_v2p( x ) ( ((x) & 0x41ffffff) ^ ( ((x) & 0x06000000) << 1) ) - +#if 0 +# define __REG(x) (*((volatile u32 *)io_p2v(x))) +#else /* * This __REG() version gives the same results as the one above, except * that we are fooling gcc somehow so it generates far better and smaller @@ -70,62 +96,56 @@ typedef struct { volatile u32 offset[4096]; } __regbase; # define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2] # define __REG(x) __REGP(io_p2v(x)) -#endif -/* Let's kick gcc's ass again... */ -# define __REG2(x,y) \ - ( __builtin_constant_p(y) ? (__REG((x) + (y))) \ - : (*(volatile u32 *)((u32)&__REG(x) + (y))) ) +/* __REG_2 is for NAND, LCD etc. + * __REG_3 is for Camera Interface, 2D Graphics, U2D etc.*/ +#ifdef CONFIG_CPU_MONAHANS +#define __REG_2(x) __REGP(io_p2v_2(x)) +#define __REG_3(x) __REGP(io_p2v_3(x)) + +#endif /* CONFIG_CPU_MONAHANS */ +#endif /* if 0 */ + +/* With indexed regs we don't want to feed the index through io_p2v() + especially if it is a variable, otherwise horrible code will result. */ +# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y))) # define __PREG(x) (io_v2p((u32)&(x))) -#else +#else /* ifndef __ASSEMBLY__ */ # define __REG(x) io_p2v(x) # define __PREG(x) io_v2p(x) -# undef io_p2v -# undef __REG -# ifndef __ASSEMBLY__ -# define io_p2v(PhAdd) (PhAdd) -# define __REG(x) (*((volatile u32 *)io_p2v(x))) -# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y))) -# else -# define __REG(x) (x) -# endif -#endif /* UBOOT_REG_FIX */ +#ifdef CONFIG_CPU_MONAHANS +# define __REG_2(x) io_p2v(x) +# define __REG_3(x) io_p2v(x) +#endif /* CONFIG_CPU_MONAHANS */ -#include "pxa-regs.h" +#endif /* ifndef __ASSEMBLY__ */ #ifndef __ASSEMBLY__ -/* - * GPIO edge detection for IRQs: - * IRQs are generated on Falling-Edge, Rising-Edge, or both. - * This must be called *before* the corresponding IRQ is registered. - * Use this instead of directly setting GRER/GFER. - */ -#define GPIO_FALLING_EDGE 1 -#define GPIO_RISING_EDGE 2 -#define GPIO_BOTH_EDGES 3 -extern void set_GPIO_IRQ_edge( int gpio_nr, int edge_mask ); +#ifdef CONFIG_MACH_ZYLONITE +#include "zylonite.h" +#endif /* * Handy routine to set GPIO alternate functions */ -extern void set_GPIO_mode( int gpio_mode ); +extern void pxa_gpio_mode( int gpio_mode ); /* - * return current lclk frequency in units of 10kHz + * Routine to enable or disable CKEN */ -extern unsigned int get_lclk_frequency_10khz(void); - -#endif - +extern void pxa_set_cken(int clock, int enable); /* - * Implementation specifics + * return current memory and LCD clock frequency in units of 10kHz */ +extern unsigned int get_memclk_frequency_10khz(void); +extern unsigned int get_lcdclk_frequency_10khz(void); +#endif /* __ASSEMBLY__ */ #ifdef CONFIG_ARCH_LUBBOCK #include "lubbock.h" @@ -139,6 +159,15 @@ extern unsigned int get_lclk_frequency_10khz(void); #include "cerf.h" #endif +#if CONFIG_CPU_MONAHANS_L2CACHE +#define __cpuc_flush_l2cache_all xscale_flush_l2cache_all +extern void __cpuc_flush_l2cache_all(void); +#define flush_l2cache_all __cpuc_flush_l2cache_all +#else +#define __cpuc_flush_l2cache_all() do {} while (0) +#define flush_l2cache_all() do {} while (0) +#endif + #ifdef CONFIG_ARCH_CSB226 #include "csb226.h" #endif @@ -151,4 +180,10 @@ extern unsigned int get_lclk_frequency_10khz(void); #include "pleb.h" #endif -#endif /* _ASM_ARCH_HARDWARE_H */ +#ifdef CONFIG_MACH_MAINSTONE +#include "mainstone.h" +#endif + +#include "pxa-regs.h" + +#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 41d37d791a..3e59f89063 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -5,16 +5,15 @@ * Created: Jun 15, 2001 * Copyright: MontaVista Software Inc. * + * Copyright (C) 2004, Intel Corporation. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - * - * - 2003/01/20: Robert Schwebel Status Register */ +#define DRQSR1 __REG(0x400000e4) /* DMA DREQ<1> Status Register */ +#define DRQSR2 __REG(0x400000e8) /* DMA DREQ<2> Status Register */ + +#define DALGN __REG(0x400000a0) /* DMA Alignment Register */ +#endif /* CONFIG_CPU_MONAHANS */ + #define DINT __REG(0x400000f0) /* DMA Interrupt Register */ +#define DRCMR(n) __REG2(0x40000100, (n)<<2) #define DRCMR0 __REG(0x40000100) /* Request to Channel Map Register for DREQ 0 */ #define DRCMR1 __REG(0x40000104) /* Request to Channel Map Register for DREQ 1 */ #define DRCMR2 __REG(0x40000108) /* Request to Channel Map Register for I2S receive Request */ @@ -142,29 +183,75 @@ typedef void (*ExcpHndlr) (void) ; #define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */ #define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */ #define DRCMR20 __REG(0x40000150) /* Request to Channel Map Register for STUART transmit Request */ -#define DRCMR21 __REG(0x40000154) /* Request to Channel Map Register for MMC receive Request */ -#define DRCMR22 __REG(0x40000158) /* Request to Channel Map Register for MMC transmit Request */ +#define DRCMR21 __REG(0x40000154) /* Request to Channel Map Register for MMC/SDIO 1 receive Request */ +#define DRCMR22 __REG(0x40000158) /* Request to Channel Map Register for MMC/SDIO 2 transmit Request */ #define DRCMR23 __REG(0x4000015c) /* Reserved */ -#define DRCMR24 __REG(0x40000160) /* Reserved */ +#define DRCMR24 __REG(0x40000160) /* Request to Channel Map Register for USB endpoint 0 request */ #define DRCMR25 __REG(0x40000164) /* Request to Channel Map Register for USB endpoint 1 Request */ #define DRCMR26 __REG(0x40000168) /* Request to Channel Map Register for USB endpoint 2 Request */ #define DRCMR27 __REG(0x4000016C) /* Request to Channel Map Register for USB endpoint 3 Request */ #define DRCMR28 __REG(0x40000170) /* Request to Channel Map Register for USB endpoint 4 Request */ -#define DRCMR29 __REG(0x40000174) /* Reserved */ +#define DRCMR29 __REG(0x40000174) /* Request to Channel Map Register for USB endpoint 5 Request */ #define DRCMR30 __REG(0x40000178) /* Request to Channel Map Register for USB endpoint 6 Request */ #define DRCMR31 __REG(0x4000017C) /* Request to Channel Map Register for USB endpoint 7 Request */ #define DRCMR32 __REG(0x40000180) /* Request to Channel Map Register for USB endpoint 8 Request */ #define DRCMR33 __REG(0x40000184) /* Request to Channel Map Register for USB endpoint 9 Request */ -#define DRCMR34 __REG(0x40000188) /* Reserved */ +#define DRCMR34 __REG(0x40000188) /* Request to Channel Map Register for USB endpoint 10 Request */ #define DRCMR35 __REG(0x4000018C) /* Request to Channel Map Register for USB endpoint 11 Request */ #define DRCMR36 __REG(0x40000190) /* Request to Channel Map Register for USB endpoint 12 Request */ #define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */ #define DRCMR38 __REG(0x40000198) /* Request to Channel Map Register for USB endpoint 14 Request */ -#define DRCMR39 __REG(0x4000019C) /* Reserved */ +#define DRCMR39 __REG(0x4000019C) /* Request to Channel Map Register for USB endpoint 15 Request */ +#define DRCMR40 __REG(0x400001A0) /* Request to Channel Map Register for USB endpoint 15 Request */ +#define DRCMR41 __REG(0x400001A4) /* Request to Channel Map Register for USB endpoint 15 Request */ +#define DRCMR42 __REG(0x400001A8) /* Request to Channel Map Register for USB endpoint 15 Request */ +#define DRCMR43 __REG(0x400001AC) /* Request to Channel Map Register for USB endpoint 15 Request */ +#define DRCMR44 __REG(0x400001B0) /* Request to Channel Map Register for USB endpoint 15 Request */ +#define DRCMR45 __REG(0x400001B4) /* Request to Channel Map Register for USB endpoint 15 Request */ +#define DRCMR46 __REG(0x400001B8) /* Request to Channel Map Register for USB endpoint 15 Request */ +#define DRCMR47 __REG(0x400001BC) /* Request to Channel Map Register for USB endpoint 15 Request */ +#define DRCMR48 __REG(0x400001C0) /* Request to Channel Map Register for MSL Receive Request 1 */ +#define DRCMR49 __REG(0x400001C4) /* Request to Channel Map Register for MSL Transmit Request 1 */ +#define DRCMR50 __REG(0x400001C8) /* Request to Channel Map Register for MSL Receive Request 2 */ +#define DRCMR51 __REG(0x400001CC) /* Request to Channel Map Register for MSL Transmit Request 2 */ +#define DRCMR52 __REG(0x400001D0) /* Request to Channel Map Register for MSL Receive Request 3 */ +#define DRCMR53 __REG(0x400001D4) /* Request to Channel Map Register for MSL Transmit Request 3 */ +#define DRCMR54 __REG(0x400001D8) /* Request to Channel Map Register for MSL Receive Request 4 */ +#define DRCMR55 __REG(0x400001DC) /* Request to Channel Map Register for MSL Transmit Request 4 */ +#define DRCMR56 __REG(0x400001E0) /* Request to Channel Map Register for MSL Receive Request 5 */ +#define DRCMR57 __REG(0x400001E4) /* Request to Channel Map Register for MSL Transmit Request 5 */ +#define DRCMR58 __REG(0x400001E8) /* Request to Channel Map Register for MSL Receive Request 6 */ +#define DRCMR59 __REG(0x400001EC) /* Request to Channel Map Register for MSL Transmit Request 6 */ +#define DRCMR60 __REG(0x400001F0) /* Request to Channel Map Register for MSL Receive Request 7 */ +#define DRCMR61 __REG(0x400001F4) /* Request to Channel Map Register for MSL Transmit Request 7 */ +#define DRCMR62 __REG(0x400001F8) /* Request to Channel Map Register for USIM 1 Receive Request */ +#define DRCMR63 __REG(0x400001FC) /* Request to Channel Map Register for USIM 1 Transimit Request */ + +#define DRCMR64 __REG(0x40001100) /* Reserved */ +#define DRCMR65 __REG(0x40001104) /* Reserved */ +#define DRCMR66 __REG(0x40001108) /* Request to channel Map Register for SSP3 Receive Request */ +#define DRCMR67 __REG(0x4000110C) /* Request to channel Map Register for SSP3 Receive Request */ + +#define DRCMR68 __REG(0x40001110) /* Reserved */ +#define DRCMR69 __REG(0x40001114) /* Reserved */ +#define DRCMR70 __REG(0x40001118) /* Reserved */ + +#define DRCMR71 __REG(0x4000111C) /* Request to Channel Map Register for TPM Receive Request */ +#define DRCMR72 __REG(0x40001120) /* Request to Channel Map Register for TPM Transmit Request 1 */ +#define DRCMR73 __REG(0x40001124) /* Request to Channel Map Register for TPM Transmit Request 2 */ +#define DRCMR74 __REG(0x40001128) /* Request to Channel Map Register for DREQ<2> */ + +#define DRCMR91 __REG(0x4000116C) /* Request to Channel Map Register for USIM 2 Receive Request */ +#define DRCMR92 __REG(0x40001170) /* Request to Channel Map Register for USIM 2 Transmit Request */ + +#define DRCMR93 __REG(0x40001174) /* Request to Channel Map Register for MMC Controller 1 Request */ +#define DRCMR94 __REG(0x40001178) /* Request to Channel Map Register for MMC Controller 2 Request */ +#define DRCMR95 __REG(0x4000117C) /* Request to Channel Map Register for AC97 Surround Transmit Request */ +#define DRCMR96 __REG(0x40001180) /* Request to Channel Map Register for AC97 centre/LFE Transmit Request */ +#define DRCMR97 __REG(0x40001184) /* Request to Channel Map Register for NAND interface data transmit & receive Request */ +#define DRCMR98 __REG(0x40001188) /* Reserved */ +#define DRCMR99 __REG(0x4000118C) /* Request to Channel Map Register for NAND interface command transmit Request */ -#define DRCMR68 __REG(0x40001110) /* Request to Channel Map Register for Camera FIFO 0 Request */ -#define DRCMR69 __REG(0x40001114) /* Request to Channel Map Register for Camera FIFO 1 Request */ -#define DRCMR70 __REG(0x40001118) /* Request to Channel Map Register for Camera FIFO 2 Request */ #define DRCMRRXSADR DRCMR2 #define DRCMRTXSADR DRCMR3 @@ -185,9 +272,12 @@ typedef void (*ExcpHndlr) (void) ; #define DRCMRTXSTTHR DRCMR20 #define DRCMRRXMMC DRCMR21 #define DRCMRTXMMC DRCMR22 +#define DRCMRRXMMC2 DRCMR93 +#define DRCMRTXMMC2 DRCMR94 +#define DRCMRUDC(x) DRCMR((x) + 24) #define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */ -#define DRCMR_CHLNUM 0x0f /* mask for Channel Number (read / write) */ +#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */ #define DDADR0 __REG(0x40000200) /* DMA Descriptor Address Register Channel 0 */ #define DSADR0 __REG(0x40000204) /* DMA Source Address Register Channel 0 */ @@ -262,11 +352,11 @@ typedef void (*ExcpHndlr) (void) ; #define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */ #define DDADR_STOP (1 << 0) /* Stop (read / write) */ -#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */ -#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */ +#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */ +#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */ #define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */ #define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */ -#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */ +#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */ #define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */ #define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */ #define DCMD_BURST8 (1 << 16) /* 8 byte burst */ @@ -282,9 +372,11 @@ typedef void (*ExcpHndlr) (void) ; #define DCMD_RXMCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4) #define DCMD_TXPCDR (DCMD_INCSRCADDR|DCMD_FLOWTRG|DCMD_BURST32|DCMD_WIDTH4) + /* * UARTs */ + /* Full Function UART (FFUART) */ #define FFUART FFRBR #define FFRBR __REG(0x40100000) /* Receive Buffer Register (read only) */ @@ -377,7 +469,7 @@ typedef void (*ExcpHndlr) (void) ; #define LSR_OE (1 << 1) /* Overrun Error */ #define LSR_DR (1 << 0) /* Data Ready */ -#define MCR_LOOP (1 << 4) */ +#define MCR_LOOP (1 << 4) #define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */ #define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */ #define MCR_RTS (1 << 1) /* Request to Send */ @@ -395,6 +487,13 @@ typedef void (*ExcpHndlr) (void) ; /* * IrSR (Infrared Selection Register) */ +#ifdef CONFIG_CPU_MONAHANS +#define STISR_RXPL (1 << 4) /* Receive Data Polarity */ +#define STISR_TXPL (1 << 3) /* Transmit Data Polarity */ +#define STISR_XMODE (1 << 2) /* Transmit Pulse Width Select */ +#define STISR_RCVEIR (1 << 1) /* Receiver SIR Enable */ +#define STISR_XMITIR (1 << 0) /* Transmitter SIR Enable */ +#else #define IrSR_OFFSET 0x20 #define IrSR_RXPL_NEG_IS_ZERO (1<<4) @@ -409,85 +508,85 @@ typedef void (*ExcpHndlr) (void) ; #define IrSR_XMITIR_UART_MODE 0x0 #define IrSR_IR_RECEIVE_ON (\ - IrSR_RXPL_NEG_IS_ZERO | \ - IrSR_TXPL_POS_IS_ZERO | \ - IrSR_XMODE_PULSE_3_16 | \ - IrSR_RCVEIR_IR_MODE | \ - IrSR_XMITIR_UART_MODE) + IrSR_RXPL_NEG_IS_ZERO | \ + IrSR_TXPL_POS_IS_ZERO | \ + IrSR_XMODE_PULSE_3_16 | \ + IrSR_RCVEIR_IR_MODE | \ + IrSR_XMITIR_UART_MODE) #define IrSR_IR_TRANSMIT_ON (\ - IrSR_RXPL_NEG_IS_ZERO | \ - IrSR_TXPL_POS_IS_ZERO | \ - IrSR_XMODE_PULSE_3_16 | \ - IrSR_RCVEIR_UART_MODE | \ - IrSR_XMITIR_IR_MODE) + IrSR_RXPL_NEG_IS_ZERO | \ + IrSR_TXPL_POS_IS_ZERO | \ + IrSR_XMODE_PULSE_3_16 | \ + IrSR_RCVEIR_UART_MODE | \ + IrSR_XMITIR_IR_MODE) +#endif /* not CONFIG_CPU_MONAHANS */ /* * I2C registers */ + #define IBMR __REG(0x40301680) /* I2C Bus Monitor Register - IBMR */ #define IDBR __REG(0x40301688) /* I2C Data Buffer Register - IDBR */ #define ICR __REG(0x40301690) /* I2C Control Register - ICR */ #define ISR __REG(0x40301698) /* I2C Status Register - ISR */ #define ISAR __REG(0x403016A0) /* I2C Slave Address Register - ISAR */ -#define PWRIBMR __REG(0x40f00180) /* Power I2C Bus Monitor Register-IBMR */ -#define PWRIDBR __REG(0x40f00188) /* Power I2C Data Buffer Register-IDBR */ -#define PWRICR __REG(0x40f00190) /* Power I2C Control Register - ICR */ -#define PWRISR __REG(0x40f00198) /* Power I2C Status Register - ISR */ -#define PWRISAR __REG(0x40f001A0) /* Power I2C Slave Address Register-ISAR */ +#define PWRIBMR __REG(0x40f00180) /* Power I2C Bus Monitor Register-IBMR */ +#define PWRIDBR __REG(0x40f00188) /* Power I2C Data Buffer Register-IDBR */ +#define PWRICR __REG(0x40f00190) /* Power I2C Control Register - ICR */ +#define PWRISR __REG(0x40f00198) /* Power I2C Status Register - ISR */ +#define PWRISAR __REG(0x40f001A0) /*Power I2C Slave Address Register-ISAR */ -/* ----- Control register bits ---------------------------------------- */ +#define ICR_START (1 << 0) /* start bit */ +#define ICR_STOP (1 << 1) /* stop bit */ +#define ICR_ACKNAK (1 << 2) /* send ACK(0) or NAK(1) */ +#define ICR_TB (1 << 3) /* transfer byte bit */ +#define ICR_MA (1 << 4) /* master abort */ +#define ICR_SCLE (1 << 5) /* master clock enable */ +#define ICR_IUE (1 << 6) /* unit enable */ +#define ICR_GCD (1 << 7) /* general call disable */ +#define ICR_ITEIE (1 << 8) /* enable tx interrupts */ +#define ICR_IRFIE (1 << 9) /* enable rx interrupts */ +#define ICR_BEIE (1 << 10) /* enable bus error ints */ +#define ICR_SSDIE (1 << 11) /* slave STOP detected int enable */ +#define ICR_ALDIE (1 << 12) /* enable arbitration interrupt */ +#define ICR_SADIE (1 << 13) /* slave address detected int enable */ +#define ICR_UR (1 << 14) /* unit reset */ -#define ICR_START 0x1 /* start bit */ -#define ICR_STOP 0x2 /* stop bit */ -#define ICR_ACKNAK 0x4 /* send ACK(0) or NAK(1) */ -#define ICR_TB 0x8 /* transfer byte bit */ -#define ICR_MA 0x10 /* master abort */ -#define ICR_SCLE 0x20 /* master clock enable */ -#define ICR_IUE 0x40 /* unit enable */ -#define ICR_GCD 0x80 /* general call disable */ -#define ICR_ITEIE 0x100 /* enable tx interrupts */ -#define ICR_IRFIE 0x200 /* enable rx interrupts */ -#define ICR_BEIE 0x400 /* enable bus error ints */ -#define ICR_SSDIE 0x800 /* slave STOP detected int enable */ -#define ICR_ALDIE 0x1000 /* enable arbitration interrupt */ -#define ICR_SADIE 0x2000 /* slave address detected int enable */ -#define ICR_UR 0x4000 /* unit reset */ -#define ICR_FM 0x8000 /* Fast Mode */ +#define ISR_RWM (1 << 0) /* read/write mode */ +#define ISR_ACKNAK (1 << 1) /* ack/nak status */ +#define ISR_UB (1 << 2) /* unit busy */ +#define ISR_IBB (1 << 3) /* bus busy */ +#define ISR_SSD (1 << 4) /* slave stop detected */ +#define ISR_ALD (1 << 5) /* arbitration loss detected */ +#define ISR_ITE (1 << 6) /* tx buffer empty */ +#define ISR_IRF (1 << 7) /* rx buffer full */ +#define ISR_GCAD (1 << 8) /* general call address detected */ +#define ISR_SAD (1 << 9) /* slave address detected */ +#define ISR_BED (1 << 10) /* bus error no ACK/NAK */ -/* ----- Status register bits ----------------------------------------- */ - -#define ISR_RWM 0x1 /* read/write mode */ -#define ISR_ACKNAK 0x2 /* ack/nak status */ -#define ISR_UB 0x4 /* unit busy */ -#define ISR_IBB 0x8 /* bus busy */ -#define ISR_SSD 0x10 /* slave stop detected */ -#define ISR_ALD 0x20 /* arbitration loss detected */ -#define ISR_ITE 0x40 /* tx buffer empty */ -#define ISR_IRF 0x80 /* rx buffer full */ -#define ISR_GCAD 0x100 /* general call address detected */ -#define ISR_SAD 0x200 /* slave address detected */ -#define ISR_BED 0x400 /* bus error no ACK/NAK */ /* * Serial Audio Controller */ -/* FIXME the audio defines collide w/ the SA1111 defines. I don't like these - * short defines because there is too much chance of namespace collision - */ -/*#define SACR0 __REG(0x40400000) / Global Control Register */ -/*#define SACR1 __REG(0x40400004) / Serial Audio I 2 S/MSB-Justified Control Register */ -/*#define SASR0 __REG(0x4040000C) / Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */ -/*#define SAIMR __REG(0x40400014) / Serial Audio Interrupt Mask Register */ -/*#define SAICR __REG(0x40400018) / Serial Audio Interrupt Clear Register */ -/*#define SADIV __REG(0x40400060) / Audio Clock Divider Register. */ -/*#define SADR __REG(0x40400080) / Serial Audio Data Register (TX and RX FIFO access Register). */ + +/* FIXME: This clash with SA1111 defines */ +#ifndef CONFIG_SA1111 +#define SACR0 __REG(0x40400000) /* Global Control Register */ +#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */ +#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */ +#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */ +#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */ +#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */ +#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */ +#endif /* * AC97 Controller registers */ + #define POCR __REG(0x40500000) /* PCM Out Control Register */ #define POCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */ @@ -561,9 +660,13 @@ typedef void (*ExcpHndlr) (void) ; #define PMC_REG_BASE __REG(0x40500400) /* Primary Modem Codec */ #define SMC_REG_BASE __REG(0x40500500) /* Secondary Modem Codec */ + /* * USB Device Controller + * PXA25x and PXA27x USB device controller registers are different. */ +#if defined(CONFIG_PXA25x) + #define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */ #define UDC_RES2 __REG(0x40600008) /* UDC Undocumented - Reserved2 */ #define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented - Reserved3 */ @@ -719,63 +822,250 @@ typedef void (*ExcpHndlr) (void) ; #define USIR1_IR14 (1 << 6) /* Interrup request ep 14 */ #define USIR1_IR15 (1 << 7) /* Interrup request ep 15 */ -#if defined(CONFIG_PXA27X) -/* - * USB Host Controller - */ -#define UHCREV __REG(0x4C000000) -#define UHCHCON __REG(0x4C000004) -#define UHCCOMS __REG(0x4C000008) -#define UHCINTS __REG(0x4C00000C) -#define UHCINTE __REG(0x4C000010) -#define UHCINTD __REG(0x4C000014) -#define UHCHCCA __REG(0x4C000018) -#define UHCPCED __REG(0x4C00001C) -#define UHCCHED __REG(0x4C000020) -#define UHCCCED __REG(0x4C000024) -#define UHCBHED __REG(0x4C000028) -#define UHCBCED __REG(0x4C00002C) -#define UHCDHEAD __REG(0x4C000030) -#define UHCFMI __REG(0x4C000034) -#define UHCFMR __REG(0x4C000038) -#define UHCFMN __REG(0x4C00003C) -#define UHCPERS __REG(0x4C000040) -#define UHCLST __REG(0x4C000044) -#define UHCRHDA __REG(0x4C000048) -#define UHCRHDB __REG(0x4C00004C) -#define UHCRHS __REG(0x4C000050) -#define UHCRHPS1 __REG(0x4C000054) -#define UHCRHPS2 __REG(0x4C000058) -#define UHCRHPS3 __REG(0x4C00005C) -#define UHCSTAT __REG(0x4C000060) -#define UHCHR __REG(0x4C000064) -#define UHCHIE __REG(0x4C000068) -#define UHCHIT __REG(0x4C00006C) +#elif defined(CONFIG_PXA27X)||( CONFIG_CPU_MONAHANS) -#define UHCHR_FSBIR (1<<0) -#define UHCHR_FHR (1<<1) -#define UHCHR_CGR (1<<2) -#define UHCHR_SSDC (1<<3) -#define UHCHR_UIT (1<<4) -#define UHCHR_SSE (1<<5) -#define UHCHR_PSPL (1<<6) -#define UHCHR_PCPL (1<<7) -#define UHCHR_SSEP0 (1<<9) -#define UHCHR_SSEP1 (1<<10) -#define UHCHR_SSEP2 (1<<11) +#define UDCCR __REG(0x40600000) /* UDC Control Register */ +#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */ +#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation + Protocol Port Support */ +#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol + Support */ +#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol + Enable */ +#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */ +#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */ +#define UDCCR_ACN_S 11 +#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */ +#define UDCCR_AIN_S 8 +#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface + Setting Number */ +#define UDCCR_AAISN_S 5 +#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active + Configuration */ +#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration + Error */ +#define UDCCR_UDR (1 << 2) /* UDC Resume */ +#define UDCCR_UDA (1 << 1) /* UDC Active */ +#define UDCCR_UDE (1 << 0) /* UDC Enable */ -#define UHCHIE_UPRIE (1<<13) -#define UHCHIE_UPS2IE (1<<12) -#define UHCHIE_UPS1IE (1<<11) -#define UHCHIE_TAIE (1<<10) -#define UHCHIE_HBAIE (1<<8) -#define UHCHIE_RWIE (1<<7) +#define UDCICR0 __REG(0x40600004) /* UDC Interrupt Control Register0 */ +#define UDCICR1 __REG(0x40600008) /* UDC Interrupt Control Register1 */ +#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */ +#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */ +#define UDC_INT_FIFOERROR (0x2) +#define UDC_INT_PACKETCMP (0x1) + +#define UDCICR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) +#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */ +#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */ +#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */ +#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */ +#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */ + +#define UDCISR0 __REG(0x4060000C) /* UDC Interrupt Status Register 0 */ +#define UDCISR1 __REG(0x40600010) /* UDC Interrupt Status Register 1 */ +#define UDCISR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) +#define UDCISR1_IRCC (1 << 31) /* IntEn - Configuration Change */ +#define UDCISR1_IRSOF (1 << 30) /* IntEn - Start of Frame */ +#define UDCISR1_IRRU (1 << 29) /* IntEn - Resume */ +#define UDCISR1_IRSU (1 << 28) /* IntEn - Suspend */ +#define UDCISR1_IRRS (1 << 27) /* IntEn - Reset */ + +#define UDCFNR __REG(0x40600014) /* UDC Frame Number Register */ +#define UDCOTGICR __REG(0x40600018) /* UDC On-The-Go interrupt control */ +#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */ +#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt + Rising Edge Interrupt Enable */ +#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt + Falling Edge Interrupt Enable */ +#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising + Edge Interrupt Enable */ +#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling + Edge Interrupt Enable */ +#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge + Interrupt Enable */ +#define UDCOTGISR __REG(0x4060001C) /* UDC OTG Interrupt Status Register*/ +#define UP2OCR __REG(0x40600020) /* Port 2 control register */ +#define UP3OCR __REG(0x40600024) /* Port 3 control register */ + +#define UDCCSN(x) __REG2(0x40600100, (x) << 2) +#define UDCCSR0 __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */ +#define UDCCSR0_ACM (1 << 9) /* ACK control mode */ +#define UDCCSR0_AREN (1 << 8) /* ACK response enable */ +#define UDCCSR0_SA (1 << 7) /* Setup Active */ +#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */ +#define UDCCSR0_FST (1 << 5) /* Force Stall */ +#define UDCCSR0_SST (1 << 4) /* Sent Stall */ +#define UDCCSR0_DME (1 << 3) /* DMA Enable */ +#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */ +#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */ +#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */ + +#define UDCCSRA __REG(0x40600104) /* UDC Control/Status register - Endpoint A */ +#define UDCCSRB __REG(0x40600108) /* UDC Control/Status register - Endpoint B */ +#define UDCCSRC __REG(0x4060010C) /* UDC Control/Status register - Endpoint C */ +#define UDCCSRD __REG(0x40600110) /* UDC Control/Status register - Endpoint D */ +#define UDCCSRE __REG(0x40600114) /* UDC Control/Status register - Endpoint E */ +#define UDCCSRF __REG(0x40600118) /* UDC Control/Status register - Endpoint F */ +#define UDCCSRG __REG(0x4060011C) /* UDC Control/Status register - Endpoint G */ +#define UDCCSRH __REG(0x40600120) /* UDC Control/Status register - Endpoint H */ +#define UDCCSRI __REG(0x40600124) /* UDC Control/Status register - Endpoint I */ +#define UDCCSRJ __REG(0x40600128) /* UDC Control/Status register - Endpoint J */ +#define UDCCSRK __REG(0x4060012C) /* UDC Control/Status register - Endpoint K */ +#define UDCCSRL __REG(0x40600130) /* UDC Control/Status register - Endpoint L */ +#define UDCCSRM __REG(0x40600134) /* UDC Control/Status register - Endpoint M */ +#define UDCCSRN __REG(0x40600138) /* UDC Control/Status register - Endpoint N */ +#define UDCCSRP __REG(0x4060013C) /* UDC Control/Status register - Endpoint P */ +#define UDCCSRQ __REG(0x40600140) /* UDC Control/Status register - Endpoint Q */ +#define UDCCSRR __REG(0x40600144) /* UDC Control/Status register - Endpoint R */ +#define UDCCSRS __REG(0x40600148) /* UDC Control/Status register - Endpoint S */ +#define UDCCSRT __REG(0x4060014C) /* UDC Control/Status register - Endpoint T */ +#define UDCCSRU __REG(0x40600150) /* UDC Control/Status register - Endpoint U */ +#define UDCCSRV __REG(0x40600154) /* UDC Control/Status register - Endpoint V */ +#define UDCCSRW __REG(0x40600158) /* UDC Control/Status register - Endpoint W */ +#define UDCCSRX __REG(0x4060015C) /* UDC Control/Status register - Endpoint X */ + +#define UDCCSR_DPE (1 << 9) /* Data Packet Error */ +#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */ +#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */ +#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */ +#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */ +#define UDCCSR_FST (1 << 5) /* Force STALL */ +#define UDCCSR_SST (1 << 4) /* Sent STALL */ +#define UDCCSR_DME (1 << 3) /* DMA Enable */ +#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */ +#define UDCCSR_PC (1 << 1) /* Packet Complete */ +#define UDCCSR_FS (1 << 0) /* FIFO needs service */ + +#define UDCBCN(x) __REG2(0x40600200, (x)<<2) +#define UDCBCR0 __REG(0x40600200) /* Byte Count Register - EP0 */ +#define UDCBCRA __REG(0x40600204) /* Byte Count Register - EPA */ +#define UDCBCRB __REG(0x40600208) /* Byte Count Register - EPB */ +#define UDCBCRC __REG(0x4060020C) /* Byte Count Register - EPC */ +#define UDCBCRD __REG(0x40600210) /* Byte Count Register - EPD */ +#define UDCBCRE __REG(0x40600214) /* Byte Count Register - EPE */ +#define UDCBCRF __REG(0x40600218) /* Byte Count Register - EPF */ +#define UDCBCRG __REG(0x4060021C) /* Byte Count Register - EPG */ +#define UDCBCRH __REG(0x40600220) /* Byte Count Register - EPH */ +#define UDCBCRI __REG(0x40600224) /* Byte Count Register - EPI */ +#define UDCBCRJ __REG(0x40600228) /* Byte Count Register - EPJ */ +#define UDCBCRK __REG(0x4060022C) /* Byte Count Register - EPK */ +#define UDCBCRL __REG(0x40600230) /* Byte Count Register - EPL */ +#define UDCBCRM __REG(0x40600234) /* Byte Count Register - EPM */ +#define UDCBCRN __REG(0x40600238) /* Byte Count Register - EPN */ +#define UDCBCRP __REG(0x4060023C) /* Byte Count Register - EPP */ +#define UDCBCRQ __REG(0x40600240) /* Byte Count Register - EPQ */ +#define UDCBCRR __REG(0x40600244) /* Byte Count Register - EPR */ +#define UDCBCRS __REG(0x40600248) /* Byte Count Register - EPS */ +#define UDCBCRT __REG(0x4060024C) /* Byte Count Register - EPT */ +#define UDCBCRU __REG(0x40600250) /* Byte Count Register - EPU */ +#define UDCBCRV __REG(0x40600254) /* Byte Count Register - EPV */ +#define UDCBCRW __REG(0x40600258) /* Byte Count Register - EPW */ +#define UDCBCRX __REG(0x4060025C) /* Byte Count Register - EPX */ + +#define UDCDN(x) __REG2(0x40600300, (x)<<2) +#define PHYS_UDCDN(x) (0x40600300 + ((x)<<2)) +#define PUDCDN(x) (volatile u32 *)(io_p2v(PHYS_UDCDN((x)))) +#define UDCDR0 __REG(0x40600300) /* Data Register - EP0 */ +#define UDCDRA __REG(0x40600304) /* Data Register - EPA */ +#define UDCDRB __REG(0x40600308) /* Data Register - EPB */ +#define UDCDRC __REG(0x4060030C) /* Data Register - EPC */ +#define UDCDRD __REG(0x40600310) /* Data Register - EPD */ +#define UDCDRE __REG(0x40600314) /* Data Register - EPE */ +#define UDCDRF __REG(0x40600318) /* Data Register - EPF */ +#define UDCDRG __REG(0x4060031C) /* Data Register - EPG */ +#define UDCDRH __REG(0x40600320) /* Data Register - EPH */ +#define UDCDRI __REG(0x40600324) /* Data Register - EPI */ +#define UDCDRJ __REG(0x40600328) /* Data Register - EPJ */ +#define UDCDRK __REG(0x4060032C) /* Data Register - EPK */ +#define UDCDRL __REG(0x40600330) /* Data Register - EPL */ +#define UDCDRM __REG(0x40600334) /* Data Register - EPM */ +#define UDCDRN __REG(0x40600338) /* Data Register - EPN */ +#define UDCDRP __REG(0x4060033C) /* Data Register - EPP */ +#define UDCDRQ __REG(0x40600340) /* Data Register - EPQ */ +#define UDCDRR __REG(0x40600344) /* Data Register - EPR */ +#define UDCDRS __REG(0x40600348) /* Data Register - EPS */ +#define UDCDRT __REG(0x4060034C) /* Data Register - EPT */ +#define UDCDRU __REG(0x40600350) /* Data Register - EPU */ +#define UDCDRV __REG(0x40600354) /* Data Register - EPV */ +#define UDCDRW __REG(0x40600358) /* Data Register - EPW */ +#define UDCDRX __REG(0x4060035C) /* Data Register - EPX */ + +#define UDCCN(x) __REG2(0x40600400, (x)<<2) +#define UDCCRA __REG(0x40600404) /* Configuration register EPA */ +#define UDCCRB __REG(0x40600408) /* Configuration register EPB */ +#define UDCCRC __REG(0x4060040C) /* Configuration register EPC */ +#define UDCCRD __REG(0x40600410) /* Configuration register EPD */ +#define UDCCRE __REG(0x40600414) /* Configuration register EPE */ +#define UDCCRF __REG(0x40600418) /* Configuration register EPF */ +#define UDCCRG __REG(0x4060041C) /* Configuration register EPG */ +#define UDCCRH __REG(0x40600420) /* Configuration register EPH */ +#define UDCCRI __REG(0x40600424) /* Configuration register EPI */ +#define UDCCRJ __REG(0x40600428) /* Configuration register EPJ */ +#define UDCCRK __REG(0x4060042C) /* Configuration register EPK */ +#define UDCCRL __REG(0x40600430) /* Configuration register EPL */ +#define UDCCRM __REG(0x40600434) /* Configuration register EPM */ +#define UDCCRN __REG(0x40600438) /* Configuration register EPN */ +#define UDCCRP __REG(0x4060043C) /* Configuration register EPP */ +#define UDCCRQ __REG(0x40600440) /* Configuration register EPQ */ +#define UDCCRR __REG(0x40600444) /* Configuration register EPR */ +#define UDCCRS __REG(0x40600448) /* Configuration register EPS */ +#define UDCCRT __REG(0x4060044C) /* Configuration register EPT */ +#define UDCCRU __REG(0x40600450) /* Configuration register EPU */ +#define UDCCRV __REG(0x40600454) /* Configuration register EPV */ +#define UDCCRW __REG(0x40600458) /* Configuration register EPW */ +#define UDCCRX __REG(0x4060045C) /* Configuration register EPX */ + +#define UDCCONR_CN (0x03 << 25) /* Configuration Number */ +#define UDCCONR_CN_S (25) +#define UDCCONR_IN (0x07 << 22) /* Interface Number */ +#define UDCCONR_IN_S (22) +#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */ +#define UDCCONR_AISN_S (19) +#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */ +#define UDCCONR_EN_S (15) +#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */ +#define UDCCONR_ET_S (13) +#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */ +#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */ +#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */ +#define UDCCONR_ET_NU (0x00 << 13) /* Not used */ +#define UDCCONR_ED (1 << 12) /* Endpoint Direction */ +#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */ +#define UDCCONR_MPS_S (2) +#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */ +#define UDCCONR_EE (1 << 0) /* Endpoint Enable */ + + +#define UDC_INT_FIFOERROR (0x2) +#define UDC_INT_PACKETCMP (0x1) + +#define UDC_FNR_MASK (0x7ff) + +#define UDCCSR_WR_MASK (UDCCSR_DME|UDCCSR_FST) +#define UDC_BCR_MASK (0x3ff) #endif /* * Fast Infrared Communication Port */ + +#define FICP __REG(0x40800000) /* Start of FICP area */ #define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */ #define ICCR1 __REG(0x40800004) /* ICP Control Register 1 */ #define ICCR2 __REG(0x40800008) /* ICP Control Register 2 */ @@ -783,45 +1073,78 @@ typedef void (*ExcpHndlr) (void) ; #define ICSR0 __REG(0x40800014) /* ICP Status Register 0 */ #define ICSR1 __REG(0x40800018) /* ICP Status Register 1 */ +#define ICCR0_AME (1 << 7) /* Adress match enable */ +#define ICCR0_TIE (1 << 6) /* Transmit FIFO interrupt enable */ +#define ICCR0_RIE (1 << 5) /* Recieve FIFO interrupt enable */ +#define ICCR0_RXE (1 << 4) /* Receive enable */ +#define ICCR0_TXE (1 << 3) /* Transmit enable */ +#define ICCR0_TUS (1 << 2) /* Transmit FIFO underrun select */ +#define ICCR0_LBM (1 << 1) /* Loopback mode */ +#define ICCR0_ITR (1 << 0) /* IrDA transmission */ + +#ifdef CONFIG_PXA27X +#define ICCR2_RXP (1 << 3) /* Receive Pin Polarity select */ +#define ICCR2_TXP (1 << 2) /* Transmit Pin Polarity select */ +#define ICCR2_TRIG (3 << 0) /* Receive FIFO Trigger threshold */ +#define ICCR2_TRIG_8 (0 << 0) /* >= 8 bytes */ +#define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */ +#define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */ +#endif + +#ifdef CONFIG_PXA27X +#define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */ +#endif +#define ICSR0_FRE (1 << 5) /* Framing error */ +#define ICSR0_RFS (1 << 4) /* Receive FIFO service request */ +#define ICSR0_TFS (1 << 3) /* Transnit FIFO service request */ +#define ICSR0_RAB (1 << 2) /* Receiver abort */ +#define ICSR0_TUR (1 << 1) /* Trunsmit FIFO underun */ +#define ICSR0_EIF (1 << 0) /* End/Error in FIFO */ + +#define ICSR1_ROR (1 << 6) /* Receiver FIFO underrun */ +#define ICSR1_CRE (1 << 5) /* CRC error */ +#define ICSR1_EOF (1 << 4) /* End of frame */ +#define ICSR1_TNF (1 << 3) /* Transmit FIFO not full */ +#define ICSR1_RNE (1 << 2) /* Receive FIFO not empty */ +#define ICSR1_TBY (1 << 1) /* Tramsmiter busy flag */ +#define ICSR1_RSY (1 << 0) /* Recevier synchronized flag */ + + /* * Real Time Clock */ + #define RCNR __REG(0x40900000) /* RTC Count Register */ #define RTAR __REG(0x40900004) /* RTC Alarm Register */ #define RTSR __REG(0x40900008) /* RTC Status Register */ #define RTTR __REG(0x4090000C) /* RTC Timer Trim Register */ -#define RDAR1 __REG(0x40900018) /* Wristwatch Day Alarm Reg 1 */ -#define RDAR2 __REG(0x40900020) /* Wristwatch Day Alarm Reg 2 */ -#define RYAR1 __REG(0x4090001C) /* Wristwatch Year Alarm Reg 1 */ -#define RYAR2 __REG(0x40900024) /* Wristwatch Year Alarm Reg 2 */ -#define SWAR1 __REG(0x4090002C) /* Stopwatch Alarm Register 1 */ -#define SWAR2 __REG(0x40900030) /* Stopwatch Alarm Register 2 */ -#define PIAR __REG(0x40900038) /* Periodic Interrupt Alarm Register */ -#define RDCR __REG(0x40900010) /* RTC Day Count Register. */ -#define RYCR __REG(0x40900014) /* RTC Year Count Register. */ -#define SWCR __REG(0x40900028) /* Stopwatch Count Register */ -#define RTCPICR __REG(0x40900034) /* Periodic Interrupt Counter Register */ +#define PIAR __REG(0x40900038) /* Periodic Interrupt Alarm Register */ -#define RTSR_PICE (1 << 15) /* Peridoc interrupt count enable */ -#define RTSR_PIALE (1 << 14) /* Peridoc interrupt Alarm enable */ -#define RTSR_PIAL (1 << 13) /* Peridoc interrupt Alarm status */ +#define RTSR_PICE (1 << 15) /* Periodic interrupt count enable */ +#define RTSR_PIALE (1 << 14) /* Periodic interrupt Alarm enable */ #define RTSR_HZE (1 << 3) /* HZ interrupt enable */ #define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ #define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ #define RTSR_AL (1 << 0) /* RTC alarm detected */ + /* * OS Timer & Match Registers */ + #define OSMR0 __REG(0x40A00000) /* */ #define OSMR1 __REG(0x40A00004) /* */ #define OSMR2 __REG(0x40A00008) /* */ #define OSMR3 __REG(0x40A0000C) /* */ +#define OSMR4 __REG(0x40A00080) /* */ #define OSCR __REG(0x40A00010) /* OS Timer Counter Register */ +#define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register */ +#define OMCR4 __REG(0x40A000C0) /* */ #define OSSR __REG(0x40A00014) /* OS Timer Status Register */ #define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */ #define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */ +#define OSSR_M4 (1 << 4) /* Match status channel 4 */ #define OSSR_M3 (1 << 3) /* Match status channel 3 */ #define OSSR_M2 (1 << 2) /* Match status channel 2 */ #define OSSR_M1 (1 << 1) /* Match status channel 1 */ @@ -829,14 +1152,17 @@ typedef void (*ExcpHndlr) (void) ; #define OWER_WME (1 << 0) /* Watchdog Match Enable */ +#define OIER_E4 (1 << 4) /* Interrupt enable channel 4 */ #define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */ #define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */ #define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */ #define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */ + /* * Pulse Width Modulator */ + #define PWM_CTRL0 __REG(0x40B00000) /* PWM 0 Control Register */ #define PWM_PWDUTY0 __REG(0x40B00004) /* PWM 0 Duty Cycle Register */ #define PWM_PERVAL0 __REG(0x40B00008) /* PWM 0 Period Control Register */ @@ -845,19 +1171,25 @@ typedef void (*ExcpHndlr) (void) ; #define PWM_PWDUTY1 __REG(0x40C00004) /* PWM 1 Duty Cycle Register */ #define PWM_PERVAL1 __REG(0x40C00008) /* PWM 1 Period Control Register */ + /* * Interrupt Controller */ +/* ICIP to ICPR can only be accessed by coprocessor */ +/* #ifndef CONFIG_CPU_MONAHANS*/ #define ICIP __REG(0x40D00000) /* Interrupt Controller IRQ Pending Register */ #define ICMR __REG(0x40D00004) /* Interrupt Controller Mask Register */ #define ICLR __REG(0x40D00008) /* Interrupt Controller Level Register */ #define ICFP __REG(0x40D0000C) /* Interrupt Controller FIQ Pending Register */ #define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */ +/* #endif // CONFIG_CPU_MONAHANS */ #define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */ + /* * General Purpose I/O */ + #define GPLR0 __REG(0x40E00000) /* GPIO Pin-Level Register GPIO<31:0> */ #define GPLR1 __REG(0x40E00004) /* GPIO Pin-Level Register GPIO<63:32> */ #define GPLR2 __REG(0x40E00008) /* GPIO Pin-Level Register GPIO<80:64> */ @@ -886,26 +1218,39 @@ typedef void (*ExcpHndlr) (void) ; #define GEDR1 __REG(0x40E0004C) /* GPIO Edge Detect Status Register GPIO<63:32> */ #define GEDR2 __REG(0x40E00050) /* GPIO Edge Detect Status Register GPIO<80:64> */ +#ifndef CONFIG_CPU_MONAHANS #define GAFR0_L __REG(0x40E00054) /* GPIO Alternate Function Select Register GPIO<15:0> */ #define GAFR0_U __REG(0x40E00058) /* GPIO Alternate Function Select Register GPIO<31:16> */ #define GAFR1_L __REG(0x40E0005C) /* GPIO Alternate Function Select Register GPIO<47:32> */ #define GAFR1_U __REG(0x40E00060) /* GPIO Alternate Function Select Register GPIO<63:48> */ #define GAFR2_L __REG(0x40E00064) /* GPIO Alternate Function Select Register GPIO<79:64> */ -#define GAFR2_U __REG(0x40E00068) /* GPIO Alternate Function Select Register GPIO 80 */ +#define GAFR2_U __REG(0x40E00068) /* GPIO Alternate Function Select Register GPIO<95-80> */ +#define GAFR3_L __REG(0x40E0006C) /* GPIO Alternate Function Select Register GPIO<111:96> */ +#define GAFR3_U __REG(0x40E00070) /* GPIO Alternate Function Select Register GPIO<127:112> */ +#endif + +#define GPLR3 __REG(0x40E00100) /* GPIO Pin-Level Register GPIO<127:96> */ +#define GPDR3 __REG(0x40E0010C) /* GPIO Pin Direction Register GPIO<127:96> */ +#define GPSR3 __REG(0x40E00118) /* GPIO Pin Output Set Register GPIO<127:96> */ +#define GPCR3 __REG(0x40E00124) /* GPIO Pin Output Clear Register GPIO<127:96> */ +#define GRER3 __REG(0x40E00130) /* GPIO Rising-Edge Detect Register GPIO<127:96> */ +#define GFER3 __REG(0x40E0013C) /* GPIO Falling-Edge Detect Register GPIO<127:96> */ +#define GEDR3 __REG(0x40E00148) /* GPIO Edge Detect Status Register GPIO<127:96> */ /* More handy macros. The argument is a literal GPIO number. */ #define GPIO_bit(x) (1 << ((x) & 0x1f)) -#ifdef CONFIG_PXA27X +#if defined (CONFIG_PXA27X) || (CONFIG_CPU_MONAHANS) /* Interrupt Controller */ - +/* #ifndef CONFIG_CPU_MONAHANS */ #define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */ #define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */ #define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */ #define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */ #define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */ +/* #endif //CONFIG_CPU_MONAHANS */ #define _GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3) #define _GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3) @@ -916,15 +1261,51 @@ typedef void (*ExcpHndlr) (void) ; #define _GEDR(x) __REG2(0x40E00048, ((x) & 0x60) >> 3) #define _GAFR(x) __REG2(0x40E00054, ((x) & 0x70) >> 2) -#define GPLR(x) ((((x) & 0x7f) < 96) ? _GPLR(x) : GPLR3) -#define GPDR(x) ((((x) & 0x7f) < 96) ? _GPDR(x) : GPDR3) -#define GPSR(x) ((((x) & 0x7f) < 96) ? _GPSR(x) : GPSR3) -#define GPCR(x) ((((x) & 0x7f) < 96) ? _GPCR(x) : GPCR3) -#define GRER(x) ((((x) & 0x7f) < 96) ? _GRER(x) : GRER3) -#define GFER(x) ((((x) & 0x7f) < 96) ? _GFER(x) : GFER3) -#define GEDR(x) ((((x) & 0x7f) < 96) ? _GEDR(x) : GEDR3) -#define GAFR(x) ((((x) & 0x7f) < 96) ? _GAFR(x) : \ - ((((x) & 0x7f) < 112) ? GAFR3_L : GAFR3_U)) +#define GPLR(x) (*((((x) & 0x7f) < 96) ? &_GPLR(x) : &GPLR3)) +#define GPDR(x) (*((((x) & 0x7f) < 96) ? &_GPDR(x) : &GPDR3)) +#define GPSR(x) (*((((x) & 0x7f) < 96) ? &_GPSR(x) : &GPSR3)) +#define GPCR(x) (*((((x) & 0x7f) < 96) ? &_GPCR(x) : &GPCR3)) +#define GRER(x) (*((((x) & 0x7f) < 96) ? &_GRER(x) : &GRER3)) +#define GFER(x) (*((((x) & 0x7f) < 96) ? &_GFER(x) : &GFER3)) +#define GEDR(x) (*((((x) & 0x7f) < 96) ? &_GEDR(x) : &GEDR3)) +#define GAFR(x) (*((((x) & 0x7f) < 96) ? &_GAFR(x) : \ + ((((x) & 0x7f) < 112) ? &GAFR3_L : &GAFR3_U))) + +#ifdef CONFIG_CPU_MONAHANS +#define GSDR0 __REG(0x40E00400) /* Bit-wise Set of GPDR[31:0] */ +#define GSDR1 __REG(0x40E00404) /* Bit-wise Set of GPDR[63:32] */ +#define GSDR2 __REG(0x40E00408) /* Bit-wise Set of GPDR[95:64] */ +#define GSDR3 __REG(0x40E0040C) /* Bit-wise Set of GPDR[127:96] */ + +#define GCDR0 __REG(0x40E00420) /* Bit-wise Clear of GPDR[31:0] */ +#define GCDR1 __REG(0x40E00424) /* Bit-wise Clear of GPDR[63:32] */ +#define GCDR2 __REG(0x40E00428) /* Bit-wise Clear of GPDR[95:64] */ +#define GCDR3 __REG(0x40E0042C) /* Bit-wise Clear of GPDR[127:96] */ + +#define GSRER0 __REG(0x40E00440) /* Set Rising Edge Det. Enable [31:0] */ +#define GSRER1 __REG(0x40E00444) /* Set Rising Edge Det. Enable [63:32] */ +#define GSRER2 __REG(0x40E00448) /* Set Rising Edge Det. Enable [95:64] */ +#define GSRER3 __REG(0x40E0044C) /* Set Rising Edge Det. Enable [127:96] */ + +#define GCRER0 __REG(0x40E00460) /* Clear Rising Edge Det. Enable [31:0] */ +#define GCRER1 __REG(0x40E00464) /* Clear Rising Edge Det. Enable [63:32] */ +#define GCRER2 __REG(0x40E00468) /* Clear Rising Edge Det. Enable [95:64] */ +#define GCRER3 __REG(0x40E0046C) /* Clear Rising Edge Det. Enable[127:96] */ + +#define GSFER0 __REG(0x40E00480) /* Set Falling Edge Det. Enable [31:0] */ +#define GSFER1 __REG(0x40E00484) /* Set Falling Edge Det. Enable [63:32] */ +#define GSFER2 __REG(0x40E00488) /* Set Falling Edge Det. Enable [95:64] */ +#define GSFER3 __REG(0x40E0048C) /* Set Falling Edge Det. Enable[127:96] */ + +#define GCFER0 __REG(0x40E004A0) /* Clr Falling Edge Det. Enable [31:0] */ +#define GCFER1 __REG(0x40E004A4) /* Clr Falling Edge Det. Enable [63:32] */ +#define GCFER2 __REG(0x40E004A8) /* Clr Falling Edge Det. Enable [95:64] */ +#define GCFER3 __REG(0x40E004AC) /* Clr Falling Edge Det. Enable[127:96] */ + +#define GSDR(x) __REG2(0x40E00400, ((x) & 0x60) >> 3) +#define GCDR(x) __REG2(0x40300420, ((x) & 0x60) >> 3) +#endif + #else #define GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3) @@ -938,11 +1319,13 @@ typedef void (*ExcpHndlr) (void) ; #endif + /* GPIO alternate function assignments */ +#ifndef CONFIG_CPU_MONAHANS /* Monahans has its different definition */ #define GPIO1_RST 1 /* reset */ #define GPIO6_MMCCLK 6 /* MMC Clock */ -#define GPIO8_48MHz 7 /* 48 MHz clock output */ +#define GPIO7_48MHz 7 /* 48 MHz clock output */ #define GPIO8_MMCCS0 8 /* MMC Chip Select 0 */ #define GPIO9_MMCCS1 9 /* MMC Chip Select 1 */ #define GPIO10_RTCCLK 10 /* real time clock (1 Hz) */ @@ -966,6 +1349,7 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO30_SDATA_OUT 30 /* AC97/I2S Sdata_out */ #define GPIO31_SYNC 31 /* AC97/I2S sync */ #define GPIO32_SDATA_IN1 32 /* AC97 Sdata_in1 */ +#define GPIO32_MMCCLK 32 /* MMC Clock (PXA270) */ #define GPIO33_nCS_5 33 /* chip select 5 */ #define GPIO34_FFRXD 34 /* FFUART receive */ #define GPIO34_MMCCS0 34 /* MMC Chip Select 0 */ @@ -994,6 +1378,7 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO53_MMCCLK 53 /* MMC Clock */ #define GPIO54_MMCCLK 54 /* MMC Clock */ #define GPIO54_pSKTSEL 54 /* Socket Select for Card Space */ +#define GPIO54_nPCE_2 54 /* Card Enable for Card Space (PXA27X) */ #define GPIO55_nPREG 55 /* Card Address bit 26 */ #define GPIO56_nPWAIT 56 /* Wait signal for Card Space */ #define GPIO57_nIOIS16 57 /* Bus Width select for I/O Card Space */ @@ -1028,6 +1413,15 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO78_nCS_2 78 /* chip select 2 */ #define GPIO79_nCS_3 79 /* chip select 3 */ #define GPIO80_nCS_4 80 /* chip select 4 */ +#define GPIO85_nPCE_1 85 /* Card Enable for Card Space (PXA27x) */ +#define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */ +#define GPIO109_MMCDAT1 109 /* MMC DAT1 (PXA27x) */ +#define GPIO110_MMCDAT2 110 /* MMC DAT2 (PXA27x) */ +#define GPIO110_MMCCS0 110 /* MMC Chip Select 0 (PXA27x) */ +#define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */ +#define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */ +#define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ +#define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ /* GPIO alternate function mode & direction */ @@ -1045,7 +1439,7 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO1_RTS_MD ( 1 | GPIO_ALT_FN_1_IN) #define GPIO6_MMCCLK_MD ( 6 | GPIO_ALT_FN_1_OUT) -#define GPIO8_48MHz_MD ( 8 | GPIO_ALT_FN_1_OUT) +#define GPIO7_48MHz_MD ( 7 | GPIO_ALT_FN_1_OUT) #define GPIO8_MMCCS0_MD ( 8 | GPIO_ALT_FN_1_OUT) #define GPIO9_MMCCS1_MD ( 9 | GPIO_ALT_FN_1_OUT) #define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT) @@ -1066,13 +1460,14 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO27_SEXTCLK_MD (27 | GPIO_ALT_FN_1_IN) #define GPIO28_BITCLK_AC97_MD (28 | GPIO_ALT_FN_1_IN) #define GPIO28_BITCLK_I2S_MD (28 | GPIO_ALT_FN_2_IN) -#define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN) +#define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN) #define GPIO29_SDATA_IN_I2S_MD (29 | GPIO_ALT_FN_2_IN) #define GPIO30_SDATA_OUT_AC97_MD (30 | GPIO_ALT_FN_2_OUT) -#define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT) +#define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT) #define GPIO31_SYNC_AC97_MD (31 | GPIO_ALT_FN_2_OUT) #define GPIO31_SYNC_I2S_MD (31 | GPIO_ALT_FN_1_OUT) #define GPIO32_SDATA_IN1_AC97_MD (32 | GPIO_ALT_FN_1_IN) +#define GPIO32_MMCCLK_MD ( 32 | GPIO_ALT_FN_2_OUT) #define GPIO33_nCS_5_MD (33 | GPIO_ALT_FN_2_OUT) #define GPIO34_FFRXD_MD (34 | GPIO_ALT_FN_1_IN) #define GPIO34_MMCCS0_MD (34 | GPIO_ALT_FN_2_OUT) @@ -1088,6 +1483,7 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT) #define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN) #define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT) +#define GPIO45_SYSCLK_AC97_MD (45 | GPIO_ALT_FN_1_OUT) #define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN) #define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN) #define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT) @@ -1100,6 +1496,7 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT) #define GPIO53_MMCCLK_MD (53 | GPIO_ALT_FN_1_OUT) #define GPIO54_MMCCLK_MD (54 | GPIO_ALT_FN_1_OUT) +#define GPIO54_nPCE_2_MD (54 | GPIO_ALT_FN_2_OUT) #define GPIO54_pSKTSEL_MD (54 | GPIO_ALT_FN_2_OUT) #define GPIO55_nPREG_MD (55 | GPIO_ALT_FN_2_OUT) #define GPIO56_nPWAIT_MD (56 | GPIO_ALT_FN_1_IN) @@ -1134,14 +1531,99 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO77_LCD_ACBIAS_MD (77 | GPIO_ALT_FN_2_OUT) #define GPIO78_nCS_2_MD (78 | GPIO_ALT_FN_2_OUT) #define GPIO79_nCS_3_MD (79 | GPIO_ALT_FN_2_OUT) +#define GPIO79_pSKTSEL_MD (79 | GPIO_ALT_FN_1_OUT) #define GPIO80_nCS_4_MD (80 | GPIO_ALT_FN_2_OUT) +#define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) +#define GPIO88_USBH1_PWR_MD (88 | GPIO_ALT_FN_1_IN) +#define GPIO89_USBH1_PEN_MD (89 | GPIO_ALT_FN_2_OUT) +#define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) +#define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT) +#define GPIO110_MMCDAT2_MD (110 | GPIO_ALT_FN_1_OUT) +#define GPIO110_MMCCS0_MD (110 | GPIO_ALT_FN_1_OUT) +#define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT) +#define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT) +#define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) +#define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) +#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT) +#define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) -#define GPIO117_SCL (117 | GPIO_ALT_FN_1_OUT) -#define GPIO118_SDA (118 | GPIO_ALT_FN_1_OUT) - +#endif /* * Power Manager */ +#ifdef CONFIG_CPU_MONAHANS + +#define ASCR __REG(0x40F40000) /* Application Subsystem Power Status/Control Register */ +#define ARSR __REG(0x40F40004) /* Application Subsystem Reset Status Register */ +#define AD3ER __REG(0x40F40008) /* Application Subsystem D3 state Wakeup Enable Register */ +#define AD3SR __REG(0x40F4000C) /* Application Subsystem D3 state Wakeup Status Register */ +#define AD2D0ER __REG(0x40F40010) /* Application Subsystem D2 to D0 state Wakeup Enable Register */ +#define AD2D0SR __REG(0x40F40014) /* Application Subsystem D2 to D0 state Wakeup Status Register */ +#define AD2D1ER __REG(0x40F40018) /* Application Subsystem D2 to D1 state Wakeup Enable Register */ +#define AD2D1SR __REG(0x40F4001C) /* Application Subsystem D2 to D1 state Wakeup Status Register */ +#define AD1D0ER __REG(0x40F40020) /* Application Subsystem D1 to D0 state Wakeup Enable Register */ +#define AD1D0SR __REG(0x40F40024) /* Application Subsystem D1 to D0 state Wakeup Status Register */ +#define ASDCNT __REG(0x40F40028) /* Application Subsystem SRAM Drowsy Count Register */ +#define AD3R __REG(0x40F40030) /* Application Subsystem D3 State Configuration Register */ +#define AD2R __REG(0x40F40034) /* Application Subsystem D2 State Configuration Register */ +#define AD1R __REG(0x40F40038) /* Application Subsystem D1 State Configuration Register */ + +#define PMCR __REG(0x40F50000) /* Power Manager Control Register */ +#define PSR __REG(0x40F50004) /* Power Manager S2 Status Register */ +#define PSPR __REG(0x40F50008) /* Power Manager Scratch Pad Register */ +#define PCFR __REG(0x40F5000C) /* Power Manager General Configuration Register */ +#define PWER __REG(0x40F50010) /* Power Manager Wake-up Enable Register */ +#define PWSR __REG(0x40F50014) /* Power Manager Wake-up Status Register */ +#define PECR __REG(0x40F50018) /* Power Manager EXT_WAKEUP[1:0] Control Register */ +#define DCDCSR __REG(0x40F50080) /* DC-DC Controller Status Register */ +#define PVCR __REG(0x40F50100) /* Power Manager Voltage Change Control Register */ +#define PCMD(x) __REG(0x40F50110 + x*4) +#define PCMD0 __REG(0x40F50110 + 0 * 4) +#define PCMD1 __REG(0x40F50110 + 1 * 4) +#define PCMD2 __REG(0x40F50110 + 2 * 4) +#define PCMD3 __REG(0x40F50110 + 3 * 4) +#define PCMD4 __REG(0x40F50110 + 4 * 4) +#define PCMD5 __REG(0x40F50110 + 5 * 4) +#define PCMD6 __REG(0x40F50110 + 6 * 4) +#define PCMD7 __REG(0x40F50110 + 7 * 4) +#define PCMD8 __REG(0x40F50110 + 8 * 4) +#define PCMD9 __REG(0x40F50110 + 9 * 4) +#define PCMD10 __REG(0x40F50110 + 10 * 4) +#define PCMD11 __REG(0x40F50110 + 11 * 4) +#define PCMD12 __REG(0x40F50110 + 12 * 4) +#define PCMD13 __REG(0x40F50110 + 13 * 4) +#define PCMD14 __REG(0x40F50110 + 14 * 4) +#define PCMD15 __REG(0x40F50110 + 15 * 4) +#define PCMD16 __REG(0x40F50110 + 16 * 4) +#define PCMD17 __REG(0x40F50110 + 17 * 4) +#define PCMD18 __REG(0x40F50110 + 18 * 4) +#define PCMD19 __REG(0x40F50110 + 19 * 4) +#define PCMD20 __REG(0x40F50110 + 20 * 4) +#define PCMD21 __REG(0x40F50110 + 21 * 4) +#define PCMD22 __REG(0x40F50110 + 22 * 4) +#define PCMD23 __REG(0x40F50110 + 23 * 4) +#define PCMD24 __REG(0x40F50110 + 24 * 4) +#define PCMD25 __REG(0x40F50110 + 25 * 4) +#define PCMD26 __REG(0x40F50110 + 26 * 4) +#define PCMD27 __REG(0x40F50110 + 27 * 4) +#define PCMD28 __REG(0x40F50110 + 28 * 4) +#define PCMD29 __REG(0x40F50110 + 29 * 4) +#define PCMD30 __REG(0x40F50110 + 30 * 4) +#define PCMD31 __REG(0x40F50110 + 31 * 4) + +#define PCMD_MBC (1<<12) +#define PCMD_DCE (1<<11) +#define PCMD_LC (1<<10) +#define PCMD_SQC (3<<8) /* only 00 and 01 are valid */ + +#define PVCR_FVC (0x1 << 28) +#define PVCR_VCSA (0x1<<14) +#define PVCR_CommandDelay (0xf80) +#define PVCR_ReadPointer (0x01f00000) +#define PVCR_SlaveAddress (0x7f) + +#else + #define PMCR __REG(0x40F00000) /* Power Manager Control Register */ #define PSSR __REG(0x40F00004) /* Power Manager Sleep Status Register */ #define PSPR __REG(0x40F00008) /* Power Manager Scratch Pad Register */ @@ -1156,57 +1638,55 @@ typedef void (*ExcpHndlr) (void) ; #define PGSR3 __REG(0x40F0002C) /* Power Manager GPIO Sleep State Register for GP[118-96] */ #define RCSR __REG(0x40F00030) /* Reset Controller Status Register */ -#define PSLR __REG(0x40F00034) /* Power Manager Sleep Config Register */ -#define PSTR __REG(0x40F00038) /* Power Manager Standby Config Register */ -#define PSNR __REG(0x40F0003C) /* Power Manager Sense Config Register */ -#define PVCR __REG(0x40F00040) /* Power Manager VoltageControl Register */ -#define PKWR __REG(0x40F00050) /* Power Manager KB Wake-up Enable Reg */ -#define PKSR __REG(0x40F00054) /* Power Manager KB Level-Detect Register */ -#define PCMD(x) __REG(0x40F00080 + x*4) -#define PCMD0 __REG(0x40F00080 + 0 * 4) -#define PCMD1 __REG(0x40F00080 + 1 * 4) -#define PCMD2 __REG(0x40F00080 + 2 * 4) -#define PCMD3 __REG(0x40F00080 + 3 * 4) -#define PCMD4 __REG(0x40F00080 + 4 * 4) -#define PCMD5 __REG(0x40F00080 + 5 * 4) -#define PCMD6 __REG(0x40F00080 + 6 * 4) -#define PCMD7 __REG(0x40F00080 + 7 * 4) -#define PCMD8 __REG(0x40F00080 + 8 * 4) -#define PCMD9 __REG(0x40F00080 + 9 * 4) -#define PCMD10 __REG(0x40F00080 + 10 * 4) -#define PCMD11 __REG(0x40F00080 + 11 * 4) -#define PCMD12 __REG(0x40F00080 + 12 * 4) -#define PCMD13 __REG(0x40F00080 + 13 * 4) -#define PCMD14 __REG(0x40F00080 + 14 * 4) -#define PCMD15 __REG(0x40F00080 + 15 * 4) -#define PCMD16 __REG(0x40F00080 + 16 * 4) -#define PCMD17 __REG(0x40F00080 + 17 * 4) -#define PCMD18 __REG(0x40F00080 + 18 * 4) -#define PCMD19 __REG(0x40F00080 + 19 * 4) -#define PCMD20 __REG(0x40F00080 + 20 * 4) -#define PCMD21 __REG(0x40F00080 + 21 * 4) -#define PCMD22 __REG(0x40F00080 + 22 * 4) -#define PCMD23 __REG(0x40F00080 + 23 * 4) -#define PCMD24 __REG(0x40F00080 + 24 * 4) -#define PCMD25 __REG(0x40F00080 + 25 * 4) -#define PCMD26 __REG(0x40F00080 + 26 * 4) -#define PCMD27 __REG(0x40F00080 + 27 * 4) -#define PCMD28 __REG(0x40F00080 + 28 * 4) -#define PCMD29 __REG(0x40F00080 + 29 * 4) -#define PCMD30 __REG(0x40F00080 + 30 * 4) -#define PCMD31 __REG(0x40F00080 + 31 * 4) +#define PSLR __REG(0x40F00034) /* Power Manager Sleep Config Register */ +#define PSTR __REG(0x40F00038) /*Power Manager Standby Config Register */ +#define PSNR __REG(0x40F0003C) /*Power Manager Sense Config Register */ +#define PVCR __REG(0x40F00040) /*Power Manager VoltageControl Register */ +#define PKWR __REG(0x40F00050) /* Power Manager KB Wake-up Enable Reg */ +#define PKSR __REG(0x40F00054) /* Power Manager KB Level-Detect Register */ +#define PCMD(x) __REG2(0x40F00080, (x)<<2) +#define PCMD0 __REG(0x40F00080 + 0 * 4) +#define PCMD1 __REG(0x40F00080 + 1 * 4) +#define PCMD2 __REG(0x40F00080 + 2 * 4) +#define PCMD3 __REG(0x40F00080 + 3 * 4) +#define PCMD4 __REG(0x40F00080 + 4 * 4) +#define PCMD5 __REG(0x40F00080 + 5 * 4) +#define PCMD6 __REG(0x40F00080 + 6 * 4) +#define PCMD7 __REG(0x40F00080 + 7 * 4) +#define PCMD8 __REG(0x40F00080 + 8 * 4) +#define PCMD9 __REG(0x40F00080 + 9 * 4) +#define PCMD10 __REG(0x40F00080 + 10 * 4) +#define PCMD11 __REG(0x40F00080 + 11 * 4) +#define PCMD12 __REG(0x40F00080 + 12 * 4) +#define PCMD13 __REG(0x40F00080 + 13 * 4) +#define PCMD14 __REG(0x40F00080 + 14 * 4) +#define PCMD15 __REG(0x40F00080 + 15 * 4) +#define PCMD16 __REG(0x40F00080 + 16 * 4) +#define PCMD17 __REG(0x40F00080 + 17 * 4) +#define PCMD18 __REG(0x40F00080 + 18 * 4) +#define PCMD19 __REG(0x40F00080 + 19 * 4) +#define PCMD20 __REG(0x40F00080 + 20 * 4) +#define PCMD21 __REG(0x40F00080 + 21 * 4) +#define PCMD22 __REG(0x40F00080 + 22 * 4) +#define PCMD23 __REG(0x40F00080 + 23 * 4) +#define PCMD24 __REG(0x40F00080 + 24 * 4) +#define PCMD25 __REG(0x40F00080 + 25 * 4) +#define PCMD26 __REG(0x40F00080 + 26 * 4) +#define PCMD27 __REG(0x40F00080 + 27 * 4) +#define PCMD28 __REG(0x40F00080 + 28 * 4) +#define PCMD29 __REG(0x40F00080 + 29 * 4) +#define PCMD30 __REG(0x40F00080 + 30 * 4) +#define PCMD31 __REG(0x40F00080 + 31 * 4) -#define PCMD_MBC (1<<12) -#define PCMD_DCE (1<<11) -#define PCMD_LC (1<<10) +#define PCMD_MBC (1<<12) +#define PCMD_DCE (1<<11) +#define PCMD_LC (1<<10) /* FIXME: PCMD_SQC need be checked. */ -#define PCMD_SQC (3<<8) /* currently only bit 8 is changerable, */ - /* bit 9 should be 0 all day. */ -#define PVCR_VCSA (0x1<<14) -#define PVCR_CommandDelay (0xf80) -/* define MACRO for Power Manager General Configuration Register (PCFR) */ -#define PCFR_FVC (0x1 << 10) -#define PCFR_PI2C_EN (0x1 << 6) +#define PCMD_SQC (3<<8) /* currently only bit 8 is changeable, + bit 9 should be 0 all day. */ +#define PVCR_VCSA (0x1<<14) +#define PVCR_CommandDelay (0xf80) +#define PCFR_PI2C_EN (0x1 << 6) #define PSSR_OTGPH (1 << 6) /* OTG Peripheral control Hold */ #define PSSR_RDH (1 << 5) /* Read Disable Hold */ @@ -1215,6 +1695,13 @@ typedef void (*ExcpHndlr) (void) ; #define PSSR_BFS (1 << 1) /* Battery Fault Status */ #define PSSR_SSS (1 << 0) /* Software Sleep Status */ +#define PCFR_RO (1 << 15) /* RDH Override */ +#define PCFR_PO (1 << 14) /* PH Override */ +#define PCFR_GPROD (1 << 12) /* GPIO nRESET_OUT Disable */ +#define PCFR_L1_EN (1 << 11) /* Sleep Mode L1 converter Enable */ +#define PCFR_FVC (1 << 10) /* Frequency/Voltage Change */ +#define PCFR_DC_EN (1 << 7) /* Sleep/deep-sleep DC-DC Converter Enable */ +#define PCFR_PI2CEN (1 << 6) /* Enable PI2C controller */ #define PCFR_DS (1 << 3) /* Deep Sleep Mode */ #define PCFR_FS (1 << 2) /* Float Static Chip Selects */ #define PCFR_FP (1 << 1) /* Float PCMCIA controls */ @@ -1224,19 +1711,52 @@ typedef void (*ExcpHndlr) (void) ; #define RCSR_SMR (1 << 2) /* Sleep Mode */ #define RCSR_WDR (1 << 1) /* Watchdog Reset */ #define RCSR_HWR (1 << 0) /* Hardware Reset */ +#endif /* CONFIG_CPU_MONAHANS */ /* * SSP Serial Port Registers */ + #define SSCR0 __REG(0x41000000) /* SSP Control Register 0 */ #define SSCR1 __REG(0x41000004) /* SSP Control Register 1 */ #define SSSR __REG(0x41000008) /* SSP Status Register */ #define SSITR __REG(0x4100000C) /* SSP Interrupt Test Register */ #define SSDR __REG(0x41000010) /* (Write / Read) SSP Data Write Register/SSP Data Read Register */ +#define SSCR0_DSS (0x0000000f) /* Data Size Select (mask) */ +#define SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..16] */ +#define SSCR0_FRF (0x00000030) /* FRame Format (mask) */ +#define SSCR0_Motorola (0x0 << 4) /* Motorola's Serial Peripheral Interface (SPI) */ +#define SSCR0_TI (0x1 << 4) /* Texas Instruments' Synchronous Serial Protocol (SSP) */ +#define SSCR0_National (0x2 << 4) /* National Microwire */ +#define SSCR0_ECS (1 << 6) /* External clock select */ +#define SSCR0_SSE (1 << 7) /* Synchronous Serial Port Enable */ +#define SSCR0_SCR (0x0000ff00) /* Serial Clock Rate (mask) */ +#define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */ + +#define SSCR1_RIE (1 << 0) /* Receive FIFO Interrupt Enable */ +#define SSCR1_TIE (1 << 1) /* Transmit FIFO Interrupt Enable */ +#define SSCR1_LBM (1 << 2) /* Loop-Back Mode */ +#define SSCR1_SPO (1 << 3) /* Motorola SPI SSPSCLK polarity setting */ +#define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ +#define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ +#define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */ +#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ +#define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ +#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ + +#define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ +#define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ +#define SSSR_BSY (1 << 4) /* SSP Busy */ +#define SSSR_TFS (1 << 5) /* Transmit FIFO Service Request */ +#define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ +#define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ + + /* * MultiMediaCard (MMC) controller */ + #define MMC_STRPCL __REG(0x41100000) /* Control to start and stop MMC clock */ #define MMC_STAT __REG(0x41100004) /* MMC Status Register (read only) */ #define MMC_CLKRT __REG(0x41100008) /* MMC clock rate */ @@ -1256,19 +1776,102 @@ typedef void (*ExcpHndlr) (void) ; #define MMC_RXFIFO __REG(0x41100040) /* Receive FIFO (read only) */ #define MMC_TXFIFO __REG(0x41100044) /* Transmit FIFO (write only) */ +/* + * MultiMediaCard (MMC2) controller + */ + +#define MMC2_STRPCL __REG_2(0x42000000) /* Control to start and stop MMC clock */ +#define MMC2_STAT __REG_2(0x42000004) /* MMC Status Register (read only) */ +#define MMC2_CLKRT __REG_2(0x42000008) /* MMC clock rate */ +#define MMC2_SPI __REG_2(0x4200000c) /* SPI mode control bits */ +#define MMC2_CMDAT __REG_2(0x42000010) /* Command/response/data sequence control */ +#define MMC2_RESTO __REG_2(0x42000014) /* Expected response time out */ +#define MMC2_RDTO __REG_2(0x42000018) /* Expected data read time out */ +#define MMC2_BLKLEN __REG_2(0x4200001c) /* Block length of data transaction */ +#define MMC2_NOB __REG_2(0x42000020) /* Number of blocks, for block mode */ +#define MMC2_PRTBUF __REG_2(0x42000024) /* Partial MMC_TXFIFO FIFO written */ +#define MMC2_I_MASK __REG_2(0x42000028) /* Interrupt Mask */ +#define MMC2_I_REG __REG_2(0x4200002c) /* Interrupt Register (read only) */ +#define MMC2_CMD __REG_2(0x42000030) /* Index of current command */ +#define MMC2_ARGH __REG_2(0x42000034) /* MSW part of the current command argument */ +#define MMC2_ARGL __REG_2(0x42000038) /* LSW part of the current command argument */ +#define MMC2_RES __REG_2(0x4200003c) /* Response FIFO (read only) */ +#define MMC2_RXFIFO __REG_2(0x42000040) /* Receive FIFO (read only) */ +#define MMC2_TXFIFO __REG_2(0x42000044) /* Transmit FIFO (write only) */ + /* * Core Clock */ +#if defined(CONFIG_CPU_MONAHANS) +#define ACCR __REG(0x41340000) /* Application Subsystem Clock Configuration Register */ +#define ACSR __REG(0x41340004) /* Application Subsystem Clock Status Register */ +#define AICSR __REG(0x41340008) /* Application Subsystem Interrupt Control/Status Register */ +#define CKENA __REG(0x4134000C) /* A Clock Enable Register */ +#define CKENB __REG(0x41340010) /* B Clock Enable Register */ +#define AC97_DIV __REG(0x41340014) /* AC97 clock divisor value register */ + +#define ACCR_SMC_MASK 0x03800000 /* Static Memory Controller Frequency Select */ +#define ACCR_SRAM_MASK 0x000c0000 /* SRAM Controller Frequency Select */ +#define ACCR_FC_MASK 0x00030000 /* Frequency Change Frequency Select */ +#define ACCR_HSIO_MASK 0x0000c000 /* High Speed IO Frequency Select */ +#define ACCR_DDR_MASK 0x00003000 /* DDR Memory Controller Frequency Select */ +#define ACCR_XN_MASK 0x00000700 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ +#define ACCR_XL_MASK 0x0000001f /* Crystal Frequency to Memory Frequency Multiplier */ +#define ACCR_XPDIS (1 << 31) +#define ACCR_SPDIS (1 << 30) +#define ACCR_13MEND1 (1 << 27) +#define ACCR_D0CS (1 << 26) +#define ACCR_13MEND2 (1 << 21) +#define ACCR_PCCE (1 << 11) + +#define CKENA_30_MSL0 (1 << 30) /* MSL0 Interface Unit Clock Enable */ +#define CKENA_29_SSP4 (1 << 29) /* SSP3 Unit Clock Enable */ +#define CKENA_28_SSP3 (1 << 28) /* SSP2 Unit Clock Enable */ +#define CKENA_27_SSP2 (1 << 27) /* SSP1 Unit Clock Enable */ +#define CKENA_26_SSP1 (1 << 26) /* SSP0 Unit Clock Enable */ +#define CKENA_25_TSI (1 << 25) /* TSI Clock Enable */ +#define CKENA_24_AC97 (1 << 24) /* AC97 Unit Clock Enable */ +#define CKENA_23_STUART (1 << 23) /* STUART Unit Clock Enable */ +#define CKENA_22_FFUART (1 << 22) /* FFUART Unit Clock Enable */ +#define CKENA_21_BTUART (1 << 21) /* BTUART Unit Clock Enable */ +#define CKENA_20_UDC (1 << 20) /* UDC Clock Enable */ +#define CKENA_19_TPM (1 << 19) /* TPM Unit Clock Enable */ +#define CKENA_18_USIM1 (1 << 18) /* USIM1 Unit Clock Enable */ +#define CKENA_17_USIM0 (1 << 17) /* USIM0 Unit Clock Enable */ +#define CKENA_15_CIR (1 << 15) /* Consumer IR Clock Enable */ +#define CKENA_14_KEY (1 << 14) /* Keypad Controller Clock Enable */ +#define CKENA_13_MMC1 (1 << 13) /* MMC1 Clock Enable */ +#define CKENA_12_MMC0 (1 << 12) /* MMC0 Clock Enable */ +#define CKENA_11_FLASH (1 << 11) /* Boot ROM Clock Enable */ +#define CKENA_10_SRAM (1 << 10) /* SRAM Controller Clock Enable */ +#define CKENA_9_SMC (1 << 9) /* Static Memory Controller */ +#define CKENA_8_DMC (1 << 8) /* Dynamic Memory Controller */ +#define CKENA_7_GRAPHICS (1 << 7) /* 2D Graphics Clock Enable */ +#define CKENA_6_USBCLI (1 << 6) /* USB Client Unit Clock Enable */ +#define CKENA_4_NAND (1 << 4) /* NAND Flash Controller Clock Enable */ +#define CKENA_3_CAMERA (1 << 3) /* Camera Interface Clock Enable */ +#define CKENA_2_USBHOST (1 << 2) /* USB Host Unit Clock Enable */ +#define CKENA_1_LCD (1 << 1) /* LCD Unit Clock Enable */ + +#define CKENB_8_1WIRE ((1 << 8) + 32) /* One Wire Interface Unit Clock Enable */ +#define CKENB_7_GPIO ((1 << 7) + 32) /* GPIO Clock Enable */ +#define CKENB_6_IRQ ((1 << 6) + 32) /* Interrupt Controller Clock Enable */ +#define CKENB_4_I2C ((1 << 4) + 32) /* I2C Unit Clock Enable */ +#define CKENB_1_PWM1 ((1 << 1) + 32) /* PWM2 & PWM3 Clock Enable */ +#define CKENB_0_PWM0 ((1 << 0) + 32) /* PWM0 & PWM1 Clock Enable */ + +#else /* if defined CONFIG_CPU_MONAHANS */ + #define CCCR __REG(0x41300000) /* Core Clock Configuration Register */ #define CKEN __REG(0x41300004) /* Clock Enable Register */ #define OSCC __REG(0x41300008) /* Oscillator Configuration Register */ +#define CCSR __REG(0x4130000C) /* Core Clock Status Register */ #define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ -#if !defined(CONFIG_PXA27X) #define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */ -#endif #define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */ +#define CKEN31_AC97 (1 << 31) #define CKEN24_CAMERA (1 << 24) /* Camera Interface Clock Enable */ #define CKEN23_SSP1 (1 << 23) /* SSP1 Unit Clock Enable */ #define CKEN22_MEMC (1 << 22) /* Memory Controller Clock Enable */ @@ -1283,15 +1886,15 @@ typedef void (*ExcpHndlr) (void) ; #define CKEN13_FICP (1 << 13) /* FICP Unit Clock Enable */ #define CKEN12_MMC (1 << 12) /* MMC Unit Clock Enable */ #define CKEN11_USB (1 << 11) /* USB Unit Clock Enable */ -#if defined(CONFIG_PXA27X) #define CKEN10_USBHOST (1 << 10) /* USB Host Unit Clock Enable */ -#define CKEN24_CAMERA (1 << 24) /* Camera Unit Clock Enable */ -#endif +#define CKEN9_OSTIMER (1 << 9) /* OS Timer Unit Clock Enable */ #define CKEN8_I2S (1 << 8) /* I2S Unit Clock Enable */ #define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */ #define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */ #define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */ +#define CKEN4_SSP3 (1 << 4) /* SSP3 Unit Clock Enable */ #define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */ +#define CKEN3_SSP2 (1 << 3) /* SSP2 Unit Clock Enable */ #define CKEN2_AC97 (1 << 2) /* AC97 Unit Clock Enable */ #define CKEN1_PWM1 (1 << 1) /* PWM1 Clock Enable */ #define CKEN0_PWM0 (1 << 0) /* PWM0 Clock Enable */ @@ -1300,39 +1903,54 @@ typedef void (*ExcpHndlr) (void) ; #define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */ #if !defined(CONFIG_PXA27X) -#define CCCR_L09 (0x1F) -#define CCCR_L27 (0x1) -#define CCCR_L32 (0x2) -#define CCCR_L36 (0x3) -#define CCCR_L40 (0x4) -#define CCCR_L45 (0x5) +#define CCCR_L09 (0x1F) +#define CCCR_L27 (0x1) +#define CCCR_L32 (0x2) +#define CCCR_L36 (0x3) +#define CCCR_L40 (0x4) +#define CCCR_L45 (0x5) -#define CCCR_M1 (0x1 << 5) -#define CCCR_M2 (0x2 << 5) -#define CCCR_M4 (0x3 << 5) +#define CCCR_M1 (0x1 << 5) +#define CCCR_M2 (0x2 << 5) +#define CCCR_M4 (0x3 << 5) -#define CCCR_N10 (0x2 << 7) -#define CCCR_N15 (0x3 << 7) -#define CCCR_N20 (0x4 << 7) -#define CCCR_N25 (0x5 << 7) -#define CCCR_N30 (0x6 << 7) +#define CCCR_N10 (0x2 << 7) +#define CCCR_N15 (0x3 << 7) +#define CCCR_N20 (0x4 << 7) +#define CCCR_N25 (0x5 << 7) +#define CCCR_N30 (0x6 << 7) #endif +#endif /* CONFIG_CPU_MONAHANS */ + /* * LCD */ +#ifndef CONFIG_CPU_MONAHANS + #define LCCR0 __REG(0x44000000) /* LCD Controller Control Register 0 */ #define LCCR1 __REG(0x44000004) /* LCD Controller Control Register 1 */ #define LCCR2 __REG(0x44000008) /* LCD Controller Control Register 2 */ #define LCCR3 __REG(0x4400000C) /* LCD Controller Control Register 3 */ #define DFBR0 __REG(0x44000020) /* DMA Channel 0 Frame Branch Register */ #define DFBR1 __REG(0x44000024) /* DMA Channel 1 Frame Branch Register */ +#define LCSR __REG(0x44000038) /* LCD Controller Status Register */ #define LCSR0 __REG(0x44000038) /* LCD Controller Status Register */ #define LCSR1 __REG(0x44000034) /* LCD Controller Status Register */ #define LIIDR __REG(0x4400003C) /* LCD Controller Interrupt ID Register */ #define TMEDRGBR __REG(0x44000040) /* TMED RGB Seed Register */ #define TMEDCR __REG(0x44000044) /* TMED Control Register */ +#define LCCR3_1BPP (0 << 24) +#define LCCR3_2BPP (1 << 24) +#define LCCR3_4BPP (2 << 24) +#define LCCR3_8BPP (3 << 24) +#define LCCR3_16BPP (4 << 24) +#define LCCR3_18BPP (6 << 24) /* packed pixel format */ +#define LCCR3_19BPP (8 << 24) /* packed pixel format */ +#define LCCR3_24BPP (9 << 24) +#define LCCR3_25BPP (10<< 24) + #define FDADR0 __REG(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */ #define FSADR0 __REG(0x44000204) /* DMA Channel 0 Frame Source Address Register */ #define FIDR0 __REG(0x44000208) /* DMA Channel 0 Frame ID Register */ @@ -1342,71 +1960,116 @@ typedef void (*ExcpHndlr) (void) ; #define FIDR1 __REG(0x44000218) /* DMA Channel 1 Frame ID Register */ #define LDCMD1 __REG(0x4400021C) /* DMA Channel 1 Command Register */ +#else + +#define LCCR0 __REG_2(0x44000000) /* LCD Controller Control Register 0 */ +#define LCCR1 __REG_2(0x44000004) /* LCD Controller Control Register 1 */ +#define LCCR2 __REG_2(0x44000008) /* LCD Controller Control Register 2 */ +#define LCCR3 __REG_2(0x4400000C) /* LCD Controller Control Register 3 */ +#define DFBR0 __REG_2(0x44000020) /* DMA Channel 0 Frame Branch Register */ +#define DFBR1 __REG_2(0x44000024) /* DMA Channel 1 Frame Branch Register */ +#define LCSR __REG_2(0x44000038) /* LCD Controller Status Register */ +#define LCSR1 __REG_2(0x44000034) /* LCD Controller Status Register */ +#define LIIDR __REG_2(0x4400003C) /* LCD Controller Interrupt ID Register */ +#define TMEDRGBR __REG_2(0x44000040) /* TMED RGB Seed Register */ +#define TMEDCR __REG_2(0x44000044) /* TMED Control Register */ + +#define LCCR3_1BPP (0 << 24) +#define LCCR3_2BPP (1 << 24) +#define LCCR3_4BPP (2 << 24) +#define LCCR3_8BPP (3 << 24) +#define LCCR3_16BPP (4 << 24) +#define LCCR3_18BPP (6 << 24) /* packed pixel format */ +#define LCCR3_19BPP (8 << 24) /* packed pixel format */ +#define LCCR3_24BPP (9 << 24) +#define LCCR3_25BPP (10<< 24) + +#define FDADR0 __REG_2(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */ +#define FSADR0 __REG_2(0x44000204) /* DMA Channel 0 Frame Source Address Register */ +#define FIDR0 __REG_2(0x44000208) /* DMA Channel 0 Frame ID Register */ +#define LDCMD0 __REG_2(0x4400020C) /* DMA Channel 0 Command Register */ +#define FDADR1 __REG_2(0x44000210) /* DMA Channel 1 Frame Descriptor Address Register */ +#define FSADR1 __REG_2(0x44000214) /* DMA Channel 1 Frame Source Address Register */ +#define FIDR1 __REG_2(0x44000218) /* DMA Channel 1 Frame ID Register */ +#define LDCMD1 __REG_2(0x4400021C) /* DMA Channel 1 Command Register */ + +#endif + #define LCCR0_ENB (1 << 0) /* LCD Controller enable */ -#define LCCR0_CMS (1 << 1) /* Color = 0, Monochrome = 1 */ -#define LCCR0_SDS (1 << 2) /* Single Panel = 0, Dual Panel = 1 */ +#define LCCR0_CMS (1 << 1) /* Color/Monochrome Display Select */ +#define LCCR0_Color (LCCR0_CMS*0) /* Color display */ +#define LCCR0_Mono (LCCR0_CMS*1) /* Monochrome display */ +#define LCCR0_SDS (1 << 2) /* Single/Dual Panel Display */ + /* Select */ +#define LCCR0_Sngl (LCCR0_SDS*0) /* Single panel display */ +#define LCCR0_Dual (LCCR0_SDS*1) /* Dual panel display */ + #define LCCR0_LDM (1 << 3) /* LCD Disable Done Mask */ #define LCCR0_SFM (1 << 4) /* Start of frame mask */ #define LCCR0_IUM (1 << 5) /* Input FIFO underrun mask */ #define LCCR0_EFM (1 << 6) /* End of Frame mask */ -#define LCCR0_PAS (1 << 7) /* Passive = 0, Active = 1 */ -#define LCCR0_BLE (1 << 8) /* Little Endian = 0, Big Endian = 1 */ -#define LCCR0_DPD (1 << 9) /* Double Pixel mode, 4 pixel value = 0, 8 pixle values = 1 */ +#define LCCR0_PAS (1 << 7) /* Passive/Active display Select */ +#define LCCR0_Pas (LCCR0_PAS*0) /* Passive display (STN) */ +#define LCCR0_Act (LCCR0_PAS*1) /* Active display (TFT) */ +#define LCCR0_DPD (1 << 9) /* Double Pixel Data (monochrome */ + /* display mode) */ +#define LCCR0_4PixMono (LCCR0_DPD*0) /* 4-Pixel/clock Monochrome */ + /* display */ +#define LCCR0_8PixMono (LCCR0_DPD*1) /* 8-Pixel/clock Monochrome */ + /* display */ #define LCCR0_DIS (1 << 10) /* LCD Disable */ #define LCCR0_QDM (1 << 11) /* LCD Quick Disable mask */ #define LCCR0_PDD (0xff << 12) /* Palette DMA request delay */ #define LCCR0_PDD_S 12 -#define LCCR0_BM (1 << 20) /* Branch mask */ +#define LCCR0_BM (1 << 20) /* Branch mask */ #define LCCR0_OUM (1 << 21) /* Output FIFO underrun mask */ -#if defined(CONFIG_PXA27X) -#define LCCR0_LCDT (1 << 22) /* LCD Panel Type */ -#define LCCR0_RDSTM (1 << 23) /* Read Status Interrupt Mask */ -#define LCCR0_CMDIM (1 << 24) /* Command Interrupt Mask */ -#endif +#define LCCR0_LCDT (1 << 22) /* LCD Panel Type */ +#define LCCR0_RDSTM (1 << 23) /* Read Status Interrupt Mask */ +#define LCCR0_CMDIM (1 << 24) /* Command Interrupt Mask */ -#define LCCR1_PPL Fld (10, 0) /* Pixels Per Line - 1 */ -#define LCCR1_DisWdth(Pixel) /* Display Width [1..800 pix.] */ \ - (((Pixel) - 1) << FShft (LCCR1_PPL)) +#define LCCR1_PPL Fld (10, 0) /* Pixels Per Line - 1 */ +#define LCCR1_DisWdth(Pixel) /* Display Width [1..800 pix.] */ \ + (((Pixel) - 1) << FShft (LCCR1_PPL)) -#define LCCR1_HSW Fld (6, 10) /* Horizontal Synchronization */ -#define LCCR1_HorSnchWdth(Tpix) /* Horizontal Synchronization */ \ - /* pulse Width [1..64 Tpix] */ \ - (((Tpix) - 1) << FShft (LCCR1_HSW)) +#define LCCR1_HSW Fld (6, 10) /* Horizontal Synchronization */ +#define LCCR1_HorSnchWdth(Tpix) /* Horizontal Synchronization */ \ + /* pulse Width [1..64 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_HSW)) -#define LCCR1_ELW Fld (8, 16) /* End-of-Line pixel clock Wait */ - /* count - 1 [Tpix] */ -#define LCCR1_EndLnDel(Tpix) /* End-of-Line Delay */ \ - /* [1..256 Tpix] */ \ - (((Tpix) - 1) << FShft (LCCR1_ELW)) +#define LCCR1_ELW Fld (8, 16) /* End-of-Line pixel clock Wait */ + /* count - 1 [Tpix] */ +#define LCCR1_EndLnDel(Tpix) /* End-of-Line Delay */ \ + /* [1..256 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_ELW)) -#define LCCR1_BLW Fld (8, 24) /* Beginning-of-Line pixel clock */ - /* Wait count - 1 [Tpix] */ -#define LCCR1_BegLnDel(Tpix) /* Beginning-of-Line Delay */ \ - /* [1..256 Tpix] */ \ - (((Tpix) - 1) << FShft (LCCR1_BLW)) +#define LCCR1_BLW Fld (8, 24) /* Beginning-of-Line pixel clock */ + /* Wait count - 1 [Tpix] */ +#define LCCR1_BegLnDel(Tpix) /* Beginning-of-Line Delay */ \ + /* [1..256 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_BLW)) -#define LCCR2_LPP Fld (10, 0) /* Line Per Panel - 1 */ -#define LCCR2_DisHght(Line) /* Display Height [1..1024 lines] */ \ - (((Line) - 1) << FShft (LCCR2_LPP)) +#define LCCR2_LPP Fld (10, 0) /* Line Per Panel - 1 */ +#define LCCR2_DisHght(Line) /* Display Height [1..1024 lines] */ \ + (((Line) - 1) << FShft (LCCR2_LPP)) -#define LCCR2_VSW Fld (6, 10) /* Vertical Synchronization pulse */ - /* Width - 1 [Tln] (L_FCLK) */ -#define LCCR2_VrtSnchWdth(Tln) /* Vertical Synchronization pulse */ \ - /* Width [1..64 Tln] */ \ - (((Tln) - 1) << FShft (LCCR2_VSW)) +#define LCCR2_VSW Fld (6, 10) /* Vertical Synchronization pulse */ + /* Width - 1 [Tln] (L_FCLK) */ +#define LCCR2_VrtSnchWdth(Tln) /* Vertical Synchronization pulse */ \ + /* Width [1..64 Tln] */ \ + (((Tln) - 1) << FShft (LCCR2_VSW)) -#define LCCR2_EFW Fld (8, 16) /* End-of-Frame line clock Wait */ - /* count [Tln] */ -#define LCCR2_EndFrmDel(Tln) /* End-of-Frame Delay */ \ - /* [0..255 Tln] */ \ - ((Tln) << FShft (LCCR2_EFW)) +#define LCCR2_EFW Fld (8, 16) /* End-of-Frame line clock Wait */ + /* count [Tln] */ +#define LCCR2_EndFrmDel(Tln) /* End-of-Frame Delay */ \ + /* [0..255 Tln] */ \ + ((Tln) << FShft (LCCR2_EFW)) -#define LCCR2_BFW Fld (8, 24) /* Beginning-of-Frame line clock */ - /* Wait count [Tln] */ -#define LCCR2_BegFrmDel(Tln) /* Beginning-of-Frame Delay */ \ - /* [0..255 Tln] */ \ - ((Tln) << FShft (LCCR2_BFW)) +#define LCCR2_BFW Fld (8, 24) /* Beginning-of-Frame line clock */ + /* Wait count [Tln] */ +#define LCCR2_BegFrmDel(Tln) /* Beginning-of-Frame Delay */ \ + /* [0..255 Tln] */ \ + ((Tln) << FShft (LCCR2_BFW)) #if 0 #define LCCR3_PCD (0xff) /* Pixel clock divisor */ @@ -1418,54 +2081,73 @@ typedef void (*ExcpHndlr) (void) ; #define LCCR3_API_S 16 #define LCCR3_VSP (1 << 20) /* vertical sync polarity */ #define LCCR3_HSP (1 << 21) /* horizontal sync polarity */ -#define LCCR3_PCP (1 << 22) /* pixel clock polarity */ -#define LCCR3_OEP (1 << 23) /* output enable polarity */ +#define LCCR3_PCP (1 << 22) /* Pixel Clock Polarity (L_PCLK) */ +#define LCCR3_PixRsEdg (LCCR3_PCP*0) /* Pixel clock Rising-Edge */ +#define LCCR3_PixFlEdg (LCCR3_PCP*1) /* Pixel clock Falling-Edge */ + +#define LCCR3_OEP (1 << 23) /* Output Enable Polarity (L_BIAS, */ + /* active display mode) */ +#define LCCR3_OutEnH (LCCR3_OEP*0) /* Output Enable active High */ +#define LCCR3_OutEnL (LCCR3_OEP*1) /* Output Enable active Low */ + #if 0 #define LCCR3_BPP (7 << 24) /* bits per pixel */ #define LCCR3_BPP_S 24 #endif #define LCCR3_DPC (1 << 27) /* double pixel clock mode */ -#define LCCR3_PDFOR_0 (0 << 30) -#define LCCR3_PDFOR_1 (1 << 30) -#define LCCR3_PDFOR_2 (2 << 30) -#define LCCR3_PDFOR_3 (3 << 30) + +#define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor */ +#define LCCR3_PixClkDiv(Div) /* Pixel Clock Divisor */ \ + (((Div) << FShft (LCCR3_PCD))) -#define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor */ -#define LCCR3_PixClkDiv(Div) /* Pixel Clock Divisor */ \ - (((Div) << FShft (LCCR3_PCD))) +#define LCCR3_BPP Fld (3, 24) /* Bit Per Pixel */ +#define LCCR3_Bpp(Bpp) /* Bit Per Pixel */ \ + (((Bpp) << FShft (LCCR3_BPP))) +#define LCCR3_ACB Fld (8, 8) /* AC Bias */ +#define LCCR3_Acb(Acb) /* BAC Bias */ \ + (((Acb) << FShft (LCCR3_ACB))) -#define LCCR3_BPP Fld (3, 24) /* Bit Per Pixel */ -#define LCCR3_Bpp(Bpp) /* Bit Per Pixel */ \ - ((((Bpp&0x7) << FShft (LCCR3_BPP)))|(((Bpp&0x8)<<26))) +#define LCCR3_HorSnchH (LCCR3_HSP*0) /* Horizontal Synchronization */ + /* pulse active High */ +#define LCCR3_HorSnchL (LCCR3_HSP*1) /* Horizontal Synchronization */ -#define LCCR3_ACB Fld (8, 8) /* AC Bias */ -#define LCCR3_Acb(Acb) /* BAC Bias */ \ - (((Acb) << FShft (LCCR3_ACB))) +#define LCCR3_VrtSnchH (LCCR3_VSP*0) /* Vertical Synchronization pulse */ + /* active High */ +#define LCCR3_VrtSnchL (LCCR3_VSP*1) /* Vertical Synchronization pulse */ + /* active Low */ -#define LCCR3_HorSnchH (LCCR3_HSP*0) /* Horizontal Synchronization */ - /* pulse active High */ -#define LCCR3_HorSnchL (LCCR3_HSP*1) /* Horizontal Synchronization */ +#define LCSR_LDD (1 << 0) /* LCD Disable Done */ +#define LCSR_SOF (1 << 1) /* Start of frame */ +#define LCSR_BER (1 << 2) /* Bus error */ +#define LCSR_ABC (1 << 3) /* AC Bias count */ +#define LCSR_IUL (1 << 4) /* input FIFO underrun Lower panel */ +#define LCSR_IUU (1 << 5) /* input FIFO underrun Upper panel */ +#define LCSR_OU (1 << 6) /* output FIFO underrun */ +#define LCSR_QD (1 << 7) /* quick disable */ +#define LCSR_EOF (1 << 8) /* end of frame */ +#define LCSR_BS (1 << 9) /* branch status */ +#define LCSR_SINT (1 << 10) /* subsequent interrupt */ -#define LCCR3_VrtSnchH (LCCR3_VSP*0) /* Vertical Synchronization pulse */ - /* active High */ -#define LCCR3_VrtSnchL (LCCR3_VSP*1) /* Vertical Synchronization pulse */ - /* active Low */ +#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */ -#define LCSR0_LDD (1 << 0) /* LCD Disable Done */ -#define LCSR0_SOF (1 << 1) /* Start of frame */ -#define LCSR0_BER (1 << 2) /* Bus error */ -#define LCSR0_ABC (1 << 3) /* AC Bias count */ -#define LCSR0_IUL (1 << 4) /* input FIFO underrun Lower panel */ -#define LCSR0_IUU (1 << 5) /* input FIFO underrun Upper panel */ -#define LCSR0_OU (1 << 6) /* output FIFO underrun */ -#define LCSR0_QD (1 << 7) /* quick disable */ -#define LCSR0_EOF0 (1 << 8) /* end of frame */ -#define LCSR0_BS (1 << 9) /* branch status */ -#define LCSR0_SINT (1 << 10) /* subsequent interrupt */ +#define LCSR_LDD (1 << 0) /* LCD Disable Done */ +#define LCSR_SOF (1 << 1) /* Start of frame */ +#define LCSR_BER (1 << 2) /* Bus error */ +#define LCSR_ABC (1 << 3) /* AC Bias count */ +#define LCSR_IUL (1 << 4) /* input FIFO underrun Lower panel */ +#define LCSR_IUU (1 << 5) /* input FIFO underrun Upper panel */ +#define LCSR_OU (1 << 6) /* output FIFO underrun */ +#define LCSR_QD (1 << 7) /* quick disable */ +#define LCSR_EOF (1 << 8) /* end of frame */ +#define LCSR_BS (1 << 9) /* branch status */ +#define LCSR_SINT (1 << 10) /* subsequent interrupt */ +#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */ + +/* Overlay1 & Overlay2 & Hardware Cursor */ #define LCSR1_SOF1 (1 << 0) #define LCSR1_SOF2 (1 << 1) #define LCSR1_SOF3 (1 << 2) @@ -1493,124 +2175,43 @@ typedef void (*ExcpHndlr) (void) ; #define LCSR1_IU5 (1 << 28) #define LCSR1_IU6 (1 << 29) -#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */ -#if defined(CONFIG_PXA27X) #define LDCMD_SOFINT (1 << 22) #define LDCMD_EOFINT (1 << 21) -#endif -/* - * Memory controller - */ -#define MEMC_BASE __REG(0x48000000) /* Base of Memory Controller */ -#define MDCNFG_OFFSET 0x0 -#define MDREFR_OFFSET 0x4 -#define MSC0_OFFSET 0x8 -#define MSC1_OFFSET 0xC -#define MSC2_OFFSET 0x10 -#define MECR_OFFSET 0x14 -#define SXLCR_OFFSET 0x18 -#define SXCNFG_OFFSET 0x1C -#define FLYCNFG_OFFSET 0x20 -#define SXMRS_OFFSET 0x24 -#define MCMEM0_OFFSET 0x28 -#define MCMEM1_OFFSET 0x2C -#define MCATT0_OFFSET 0x30 -#define MCATT1_OFFSET 0x34 -#define MCIO0_OFFSET 0x38 -#define MCIO1_OFFSET 0x3C -#define MDMRS_OFFSET 0x40 +#define LCCR0_LDDALT (1<<26) /* LDD Alternate mapping bit when base pixel is RGBT16 */ +#define LCCR0_OUC (1<<25) /* Overlay Underlay Control Bit */ -#define MDCNFG __REG(0x48000000) /* SDRAM Configuration Register 0 */ -#define MDCNFG_DE0 0x00000001 -#define MDCNFG_DE1 0x00000002 -#define MDCNFG_DE2 0x00010000 -#define MDCNFG_DE3 0x00020000 -#define MDCNFG_DWID0 0x00000004 +#define LCCR5_SOFM1 (1<<0) /* Start Of Frame Mask for Overlay 1 (channel 1) */ +#define LCCR5_SOFM2 (1<<1) /* Start Of Frame Mask for Overlay 2 (channel 2) */ +#define LCCR5_SOFM3 (1<<2) /* Start Of Frame Mask for Overlay 2 (channel 3) */ +#define LCCR5_SOFM4 (1<<3) /* Start Of Frame Mask for Overlay 2 (channel 4) */ +#define LCCR5_SOFM5 (1<<4) /* Start Of Frame Mask for cursor (channel 5) */ +#define LCCR5_SOFM6 (1<<5) /* Start Of Frame Mask for command data (channel 6) */ -#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */ -#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */ -#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */ -#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */ -#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */ -#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */ -#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */ -#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */ -#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */ -#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */ -#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */ -#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */ -#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */ -#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */ -#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */ -#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */ +#define LCCR5_EOFM1 (1<<8) /* End Of Frame Mask for Overlay 1 (channel 1) */ +#define LCCR5_EOFM2 (1<<9) /* End Of Frame Mask for Overlay 2 (channel 2) */ +#define LCCR5_EOFM3 (1<<10) /* End Of Frame Mask for Overlay 2 (channel 3) */ +#define LCCR5_EOFM4 (1<<11) /* End Of Frame Mask for Overlay 2 (channel 4) */ +#define LCCR5_EOFM5 (1<<12) /* End Of Frame Mask for cursor (channel 5) */ +#define LCCR5_EOFM6 (1<<13) /* End Of Frame Mask for command data (channel 6) */ -#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */ -#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */ -#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */ -#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */ -#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */ -#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */ -#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */ -#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */ -#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */ -#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */ -#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */ -#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */ -#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */ +#define LCCR5_BSM1 (1<<16) /* Branch mask for Overlay 1 (channel 1) */ +#define LCCR5_BSM2 (1<<17) /* Branch mask for Overlay 2 (channel 2) */ +#define LCCR5_BSM3 (1<<18) /* Branch mask for Overlay 2 (channel 3) */ +#define LCCR5_BSM4 (1<<19) /* Branch mask for Overlay 2 (channel 4) */ +#define LCCR5_BSM5 (1<<20) /* Branch mask for cursor (channel 5) */ +#define LCCR5_BSM6 (1<<21) /* Branch mask for data command (channel 6) */ -#if defined(CONFIG_PXA27X) +#define LCCR5_IUM1 (1<<24) /* Input FIFO Underrun Mask for Overlay 1 */ +#define LCCR5_IUM2 (1<<25) /* Input FIFO Underrun Mask for Overlay 2 */ +#define LCCR5_IUM3 (1<<26) /* Input FIFO Underrun Mask for Overlay 2 */ +#define LCCR5_IUM4 (1<<27) /* Input FIFO Underrun Mask for Overlay 2 */ +#define LCCR5_IUM5 (1<<28) /* Input FIFO Underrun Mask for cursor */ +#define LCCR5_IUM6 (1<<29) /* Input FIFO Underrun Mask for data command */ -#define ARB_CNTRL __REG(0x48000048) /* Arbiter Control Register */ - -#define ARB_DMA_SLV_PARK (1<<31) /* Be parked with DMA slave when idle */ -#define ARB_CI_PARK (1<<30) /* Be parked with Camera Interface when idle */ -#define ARB_EX_MEM_PARK (1<<29) /* Be parked with external MEMC when idle */ -#define ARB_INT_MEM_PARK (1<<28) /* Be parked with internal MEMC when idle */ -#define ARB_USB_PARK (1<<27) /* Be parked with USB when idle */ -#define ARB_LCD_PARK (1<<26) /* Be parked with LCD when idle */ -#define ARB_DMA_PARK (1<<25) /* Be parked with DMA when idle */ -#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ -#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ - -/* Interrupt Controller */ - -#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */ -#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */ -#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */ -#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */ -#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */ - -/* General Purpose I/O */ - -#define GAFR3_L __REG(0x40E0006C) /* GPIO Alternate Function Select Register GPIO<111:96> */ -#define GAFR3_U __REG(0x40E00070) /* GPIO Alternate Function Select Register GPIO<127:112> */ -#define GPLR3 __REG(0x40E00100) /* GPIO Pin-Level Register GPIO<127:96> */ -#define GPDR3 __REG(0x40E0010C) /* GPIO Pin Direction Register GPIO<127:96> */ -#define GPSR3 __REG(0x40E00118) /* GPIO Pin Output Set Register GPIO<127:96> */ -#define GPCR3 __REG(0x40E00124) /* GPIO Pin Output Clear Register GPIO <127:96> */ -#define GRER3 __REG(0x40E00130) /* GPIO Rising-Edge Detect Register GPIO<127:96> */ -#define GFER3 __REG(0x40E0013C) /* GPIO Falling-Edge Detect Register GPIO<31:0> */ -#define GEDR3 __REG(0x40E00148) /* GPIO Edge Detect Status Register GPIO<127:96> */ - -/* Core Clock */ - -#define CCSR __REG(0x4130000C) /* Core Clock Status Register */ - -#define CKEN23_SSP1 (1 << 23) /* SSP1 Unit Clock Enable */ -#define CKEN22_MEMC (1 << 22) /* Memory Controler */ -#define CKEN21_MSHC (1 << 21) /* Memery Stick Host Controller */ -#define CKEN20_IM (1 << 20) /* Internal Memory Clock Enable */ -#define CKEN19_KEYPAD (1 << 19) /* Keypad Interface Clock Enable */ -#define CKEN18_USIM (1 << 18) /* USIM Unit Clock Enable */ -#define CKEN17_MSL (1 << 17) /* MSL Interface Unit Clock Enable */ -#define CKEN15_PWR_I2C (1 << 15) /* PWR_I2C Unit Clock Enable */ -#define CKEN9_OST (1 << 9) /* OS Timer Unit Clock Enable */ -#define CKEN4_SSP3 (1 << 4) /* SSP3 Unit Clock Enable */ - -/* Memory controller */ - -#define MDREFR_K0DB4 (1 << 29) /* SDCLK[0] divide by 4 */ +#define OVL1C1_O1EN (1<<31) /* Enable bit for Overlay 1 */ +#define OVL2C1_O2EN (1<<31) /* Enable bit for Overlay 2 */ +#define CCR_CEN (1<<31) /* Enable bit for Cursor */ /* LCD registers */ #define LCCR4 __REG(0x44000010) /* LCD Controller Control Register 4 */ @@ -1646,104 +2247,1071 @@ typedef void (*ExcpHndlr) (void) ; #define FBR5 __REG(0x44000110) /* DMA Channel 5 Frame Branch Register */ #define FBR6 __REG(0x44000114) /* DMA Channel 6 Frame Branch Register */ -#define LCCR0_LDDALT (1<<26) /* LDD Alternate mapping bit when base pixel is RGBT16 */ -#define LCCR0_OUC (1<<25) /* Overlay Underlay Control Bit */ +/* +* Touch screen interface +*/ +#ifdef CONFIG_CPU_MONAHANS +#define ADCD __REG(0x41c00000) /*Analog-to-Digital Converter Data register*/ +#define ADCS __REG(0x41c00004) /*Analog-to-Digital Converter Setup register*/ +#define ADCE __REG(0x41c00008) /*Analog-to-Digital Converter Enable register*/ +#endif -#define LCCR5_SOFM1 (1<<0) /* Start Of Frame Mask for Overlay 1 (channel 1) */ -#define LCCR5_SOFM2 (1<<1) /* Start Of Frame Mask for Overlay 2 (channel 2) */ -#define LCCR5_SOFM3 (1<<2) /* Start Of Frame Mask for Overlay 2 (channel 3) */ -#define LCCR5_SOFM4 (1<<3) /* Start Of Frame Mask for Overlay 2 (channel 4) */ -#define LCCR5_SOFM5 (1<<4) /* Start Of Frame Mask for cursor (channel 5) */ -#define LCCR5_SOFM6 (1<<5) /* Start Of Frame Mask for command data (channel 6) */ -#define LCCR5_EOFM1 (1<<8) /* End Of Frame Mask for Overlay 1 (channel 1) */ -#define LCCR5_EOFM2 (1<<9) /* End Of Frame Mask for Overlay 2 (channel 2) */ -#define LCCR5_EOFM3 (1<<10) /* End Of Frame Mask for Overlay 2 (channel 3) */ -#define LCCR5_EOFM4 (1<<11) /* End Of Frame Mask for Overlay 2 (channel 4) */ -#define LCCR5_EOFM5 (1<<12) /* End Of Frame Mask for cursor (channel 5) */ -#define LCCR5_EOFM6 (1<<13) /* End Of Frame Mask for command data (channel 6) */ +/* + * Memory controller + */ +#ifndef CONFIG_CPU_MONAHANS +#define MEMC_BASE __REG(0x48000000) /* Base of Memory Controller */ +#define MDCNFG_OFFSET 0x0 +#define MDREFR_OFFSET 0x4 +#define MSC0_OFFSET 0x8 +#define MSC1_OFFSET 0xC +#define MSC2_OFFSET 0x10 +#define MECR_OFFSET 0x14 +#define SXLCR_OFFSET 0x18 +#define SXCNFG_OFFSET 0x1C +#define FLYCNFG_OFFSET 0x20 +#define SXMRS_OFFSET 0x24 +#define MCMEM0_OFFSET 0x28 +#define MCMEM1_OFFSET 0x2C +#define MCATT0_OFFSET 0x30 +#define MCATT1_OFFSET 0x34 +#define MCIO0_OFFSET 0x38 +#define MCIO1_OFFSET 0x3C +#define MDMRS_OFFSET 0x40 + +#define MDCNFG __REG((0x48000000) /* SDRAM Configuration Register 0 */ +#define MDCNFG_DE0 0x00000001 +#define MDCNFG_DE1 0x00000002 +#define MDCNFG_DE2 0x00010000 +#define MDCNFG_DE3 0x00020000 +#define MDCNFG_DWID0 0x00000004 +#endif -#define LCCR5_BSM1 (1<<16) /* Branch mask for Overlay 1 (channel 1) */ -#define LCCR5_BSM2 (1<<17) /* Branch mask for Overlay 2 (channel 2) */ -#define LCCR5_BSM3 (1<<18) /* Branch mask for Overlay 2 (channel 3) */ -#define LCCR5_BSM4 (1<<19) /* Branch mask for Overlay 2 (channel 4) */ -#define LCCR5_BSM5 (1<<20) /* Branch mask for cursor (channel 5) */ -#define LCCR5_BSM6 (1<<21) /* Branch mask for data command (channel 6) */ +#ifdef CONFIG_CPU_MONAHANS +/* Static Memory Controller Registers */ +#define MSC0 __REG_2(0x4A000008) /* Static Memory Control Register 0 */ +#define MSC1 __REG_2(0x4A00000C) /* Static Memory Control Register 1 */ +#define MECR __REG_2(0x4A000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */ +#define SXCNFG __REG_2(0x4A00001C) /* Synchronous Static Memory Control Register */ +#define MCMEM0 __REG_2(0x4A000028) /* Card interface Common Memory Space Socket 0 Timing */ +#define MCATT0 __REG_2(0x4A000030) /* Card interface Attribute Space Socket 0 Timing Configuration */ +#define MCIO0 __REG_2(0x4A000038) /* Card interface I/O Space Socket 0 Timing Configuration */ +#define MEMCLKCFG __REG_2(0x4A000068) /* SCLK speed configuration */ +#define CSADRCFG0 __REG_2(0x4A000080) /* Address Configuration for chip select 0 */ +#define CSADRCFG1 __REG_2(0x4A000084) /* Address Configuration for chip select 1 */ +#define CSADRCFG2 __REG_2(0x4A000088) /* Address Configuration for chip select 2 */ +#define CSADRCFG3 __REG_2(0x4A00008C) /* Address Configuration for chip select 3 */ +#define CSADRCFG_P __REG_2(0x4A000090) /* Address Configuration for pcmcia card interface */ +#define CSMSADRCFG __REG_2(0x4A0000A0) /* Master Address Configuration Register */ -#define LCCR5_IUM1 (1<<24) /* Input FIFO Underrun Mask for Overlay 1 */ -#define LCCR5_IUM2 (1<<25) /* Input FIFO Underrun Mask for Overlay 2 */ -#define LCCR5_IUM3 (1<<26) /* Input FIFO Underrun Mask for Overlay 2 */ -#define LCCR5_IUM4 (1<<27) /* Input FIFO Underrun Mask for Overlay 2 */ -#define LCCR5_IUM5 (1<<28) /* Input FIFO Underrun Mask for cursor */ -#define LCCR5_IUM6 (1<<29) /* Input FIFO Underrun Mask for data command */ +/* Dynamic Memory Controller Registers */ +#define MDCNFG __REG_2(0x48100000) /* SDRAM Configuration Register 0 */ +#define MDREFR __REG_2(0x48100004) /* SDRAM Refresh Control Register */ +#define FLYCNFG __REG_2(0x48100020) /* Fly-by DMA DVAL[1:0] polarities */ +#define MDMRS __REG_2(0x48100040) /* MRS value to be written to SDRAM */ +#define DDR_SCAL __REG_2(0x48100050) /* Software Delay Line Calibration/Configuration for external DDR memory. */ +#define DDR_HCAL __REG_2(0x48100060) /* Hardware Delay Line Calibration/Configuration for external DDR memory. */ +#define DMCIER __REG_2(0x48100070) /* Dynamic MC Interrupt Enable Register. */ +#define DMCISR __REG_2(0x48100078) /* Dynamic MC Interrupt Status Register. */ +#define DDR_DLS __REG_2(0x48100080) /* DDR Delay Line Value Status register for external DDR memory. */ +#define EMPI __REG_2(0x48100090) /* EMPI Control Register */ +#define RCOMP __REG_2(0x48100100) +#define PAD_MA __REG_2(0x48100110) +#define PAD_MDMSB __REG_2(0x48100114) +#define PAD_MDLSB __REG_2(0x48100118) +#define PAD_DMEM __REG_2(0x4810011c) +#define PAD_SDCLK __REG_2(0x48100120) +#define PAD_SDCS __REG_2(0x48100124) +#define PAD_SMEM __REG_2(0x48100128) +#define PAD_SCLK __REG_2(0x4810012C) -#define OVL1C1_O1EN (1<<31) /* Enable bit for Overlay 1 */ -#define OVL2C1_O2EN (1<<31) /* Enable bit for Overlay 2 */ -#define CCR_CEN (1<<31) /* Enable bit for Cursor */ -/* Keypad controller */ +/* Data Flash Controller Registers */ -#define KPC __REG(0x41500000) /* Keypad Interface Control register */ -#define KPDK __REG(0x41500008) /* Keypad Interface Direct Key register */ -#define KPREC __REG(0x41500010) /* Keypad Intefcace Rotary Encoder register */ -#define KPMK __REG(0x41500018) /* Keypad Intefcace Matrix Key register */ -#define KPAS __REG(0x41500020) /* Keypad Interface Automatic Scan register */ -#define KPASMKP0 __REG(0x41500028) /* Keypad Interface Automatic Scan Multiple Key Presser register 0 */ -#define KPASMKP1 __REG(0x41500030) /* Keypad Interface Automatic Scan Multiple Key Presser register 1 */ -#define KPASMKP2 __REG(0x41500038) /* Keypad Interface Automatic Scan Multiple Key Presser register 2 */ -#define KPASMKP3 __REG(0x41500040) /* Keypad Interface Automatic Scan Multiple Key Presser register 3 */ -#define KPKDI __REG(0x41500048) /* Keypad Interface Key Debounce Interval register */ +#define NDCR __REG_2(0x43100000) /* Data Flash Control register */ +#define NDTR0CS0 __REG_2(0x43100004) /* Data Controller Timing Parameter 0 Register for ND_nCS0 */ +#define NDTR0CS1 __REG_2(0x43100008) /* Data Controller Timing Parameter 0 Register for ND_nCS1 */ +#define NDTR1CS0 __REG_2(0x4310000C) /* Data Controller Timing Parameter 1 Register for ND_nCS0 */ +#define NDTR1CS1 __REG_2(0x43100010) /* Data Controller Timing Parameter 1 Register for ND_nCS1 */ +#define NDSR __REG_2(0x43100014) /* Data Controller Status Register */ +#define NDPCR __REG_2(0x43100018) /* Data Controller Page Count Register */ +#define NDBDR0 __REG_2(0x4310001C) /* Data Controller Bad Block Register 0 */ +#define NDBDR1 __REG_2(0x43100020) /* Data Controller Bad Block Register 1 */ +#define NDDB __REG_2(0x43100040) /* Data Controller Data Buffer */ +#define NDCB0 __REG_2(0x43100048) /* Data Controller Command Buffer0 */ +#define NDCB1 __REG_2(0x4310004C) /* Data Controller Command Buffer1 */ +#define NDCB2 __REG_2(0x43100050) /* Data Controller Command Buffer2 */ -#define KPC_AS (0x1 << 30) /* Automatic Scan bit */ -#define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */ -#define KPC_MI (0x1 << 22) /* Matrix interrupt bit */ -#define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */ -#define KPC_MS7 (0x1 << 20) /* Matrix scan line 7 */ -#define KPC_MS6 (0x1 << 19) /* Matrix scan line 6 */ -#define KPC_MS5 (0x1 << 18) /* Matrix scan line 5 */ -#define KPC_MS4 (0x1 << 17) /* Matrix scan line 4 */ -#define KPC_MS3 (0x1 << 16) /* Matrix scan line 3 */ -#define KPC_MS2 (0x1 << 15) /* Matrix scan line 2 */ -#define KPC_MS1 (0x1 << 14) /* Matrix scan line 1 */ -#define KPC_MS0 (0x1 << 13) /* Matrix scan line 0 */ -#define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */ -#define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */ -#define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Key Debounce select */ -#define KPC_DI (0x1 << 5) /* Direct key interrupt bit */ -#define KPC_DEE0 (0x1 << 2) /* Rotary Encoder 0 Enable */ -#define KPC_DE (0x1 << 1) /* Direct Keypad Enable */ -#define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */ +#define NDCR_SPARE_EN (0x1<<31) +#define NDCR_ECC_EN (0x1<<30) +#define NDCR_DMA_EN (0x1<<29) +#define NDCR_ND_RUN (0x1<<28) +#define NDCR_DWIDTH_C (0x1<<27) +#define NDCR_DWIDTH_M (0x1<<26) +#define NDCR_PAGE_SZ (0x3<<24) +#define NDCR_NCSX (0x1<<23) +#define NDCR_ND_MODE (0x3<<21) +#define NDCR_NAND_MODE 0x0 +#define NDCR_CLR_PG_CNT (0x1<<20) +#define NDCR_CLR_ECC (0x1<<19) +#define NDCR_RD_ID_CNT (0x7<<16) +#define NDCR_RA_START (0x1<<15) +#define NDCR_PG_PER_BLK (0x1<<14) +#define NDCR_ND_ARB_EN (0x1<<12) -#define KPDK_DKP (0x1 << 31) -#define KPDK_DK7 (0x1 << 7) -#define KPDK_DK6 (0x1 << 6) -#define KPDK_DK5 (0x1 << 5) -#define KPDK_DK4 (0x1 << 4) -#define KPDK_DK3 (0x1 << 3) -#define KPDK_DK2 (0x1 << 2) -#define KPDK_DK1 (0x1 << 1) -#define KPDK_DK0 (0x1 << 0) +#define NDSR_RDY (0x1<<11) +#define NDSR_CS0_PAGED (0x1<<10) +#define NDSR_CS1_PAGED (0x1<<9) +#define NDSR_CS0_CMDD (0x1<<8) +#define NDSR_CS1_CMDD (0x1<<7) +#define NDSR_CS0_BBD (0x1<<6) +#define NDSR_CS1_BBD (0x1<<5) +#define NDSR_BDERR (0x1<<4) +#define NDSR_SBERR (0x1<<3) +#define NDSR_WRDREQ (0x1<<2) +#define NDSR_RDDREQ (0x1<<1) +#define NDSR_WRCMDREQ (0x1) -#define KPREC_OF1 (0x1 << 31) -#define kPREC_UF1 (0x1 << 30) -#define KPREC_OF0 (0x1 << 15) -#define KPREC_UF0 (0x1 << 14) +#define NDCB0_AUTO_RS (0x1<<25) +#define NDCB0_CSEL (0x1<<24) +#define NDCB0_CMD_TYPE (0x7<<21) +#define NDCB0_NC (0x1<<20) +#define NDCB0_DBC (0x1<<19) +#define NDCB0_ADDR_CYC (0x7<<16) +#define NDCB0_CMD2 (0xff<<8) +#define NDCB0_CMD1 (0xff) +#define MCMEM(s) MCMEM0 +#define MCATT(s) MCATT0 +#define MCIO(s) MCIO0 +#define MECR_CIT (1 << 1)/* Card Is There: 0 -> no card, 1 -> card inserted */ +#else /* CONFIG_CPU_MONAHANS */ -#define KPMK_MKP (0x1 << 31) -#define KPAS_SO (0x1 << 31) -#define KPASMKPx_SO (0x1 << 31) +/* mk: defined @2253 #define MDCNFG __REG(0x48000000) /\* SDRAM Configuration Register 0 *\/ */ +#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */ +#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */ +#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */ +#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */ +#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */ +#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */ +#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */ +#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */ +#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */ +#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */ +#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */ +#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */ +#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */ +#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */ +#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */ +#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */ -#define GPIO113_BIT (1 << 17)/* GPIO113 in GPSR, GPCR, bit 17 */ -#define PSLR __REG(0x40F00034) -#define PSTR __REG(0x40F00038) /* Power Manager Standby Configuration Reg */ -#define PSNR __REG(0x40F0003C) /* Power Manager Sense Configuration Reg */ -#define PVCR __REG(0x40F00040) /* Power Manager Voltage Change Control Reg */ -#define PKWR __REG(0x40F00050) /* Power Manager KB Wake-Up Enable Reg */ -#define PKSR __REG(0x40F00054) /* Power Manager KB Level-Detect Status Reg */ -#define OSMR4 __REG(0x40A00080) /* */ -#define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register */ -#define OMCR4 __REG(0x40A000C0) /* */ +/* + * More handy macros for PCMCIA + * + * Arg is socket number + */ +#define MCMEM(s) __REG2(0x48000028, (s)<<2 ) /* Card interface Common Memory Space Socket s Timing */ +#define MCATT(s) __REG2(0x48000030, (s)<<2 ) /* Card interface Attribute Space Socket s Timing Configuration */ +#define MCIO(s) __REG2(0x48000038, (s)<<2 ) /* Card interface I/O Space Socket s Timing Configuration */ -#endif /* CONFIG_PXA27X */ +/* MECR register defines */ +#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */ +#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */ -#endif /* _PXA_REGS_H_ */ +#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */ +#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */ +#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */ +#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */ +#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */ +#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */ +#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */ +#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */ +#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */ +#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */ +#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */ +#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */ +#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */ +#endif + +#ifdef CONFIG_PXA27X + +#define ARB_CNTRL __REG(0x48000048) /* Arbiter Control Register */ + +#define ARB_DMA_SLV_PARK (1<<31) /* Be parked with DMA slave when idle */ +#define ARB_CI_PARK (1<<30) /* Be parked with Camera Interface when idle */ +#define ARB_EX_MEM_PARK (1<<29) /* Be parked with external MEMC when idle */ +#define ARB_INT_MEM_PARK (1<<28) /* Be parked with internal MEMC when idle */ +#define ARB_USB_PARK (1<<27) /* Be parked with USB when idle */ +#define ARB_LCD_PARK (1<<26) /* Be parked with LCD when idle */ +#define ARB_DMA_PARK (1<<25) /* Be parked with DMA when idle */ +#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ +#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ + +/* + * Keypad + */ +#define KPC __REG(0x41500000) /* Keypad Interface Control register */ +#define KPDK __REG(0x41500008) /* Keypad Interface Direct Key register */ +#define KPREC __REG(0x41500010) /* Keypad Interface Rotary Encoder register */ +#define KPMK __REG(0x41500018) /* Keypad Interface Matrix Key register */ +#define KPAS __REG(0x41500020) /* Keypad Interface Automatic Scan register */ +#define KPASMKP0 __REG(0x41500028) /* Keypad Interface Automatic Scan Multiple Key Presser register 0 */ +#define KPASMKP1 __REG(0x41500030) /* Keypad Interface Automatic Scan Multiple Key Presser register 1 */ +#define KPASMKP2 __REG(0x41500038) /* Keypad Interface Automatic Scan Multiple Key Presser register 2 */ +#define KPASMKP3 __REG(0x41500040) /* Keypad Interface Automatic Scan Multiple Key Presser register 3 */ +#define KPKDI __REG(0x41500048) /* Keypad Interface Key Debounce Interval register */ + +#define KPC_AS (0x1 << 30) /* Automatic Scan bit */ +#define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */ +#define KPC_MI (0x1 << 22) /* Matrix interrupt bit */ +#define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */ +#define KPC_MS7 (0x1 << 20) /* Matrix scan line 7 */ +#define KPC_MS6 (0x1 << 19) /* Matrix scan line 6 */ +#define KPC_MS5 (0x1 << 18) /* Matrix scan line 5 */ +#define KPC_MS4 (0x1 << 17) /* Matrix scan line 4 */ +#define KPC_MS3 (0x1 << 16) /* Matrix scan line 3 */ +#define KPC_MS2 (0x1 << 15) /* Matrix scan line 2 */ +#define KPC_MS1 (0x1 << 14) /* Matrix scan line 1 */ +#define KPC_MS0 (0x1 << 13) /* Matrix scan line 0 */ +#define KPC_MS_ALL (KPC_MS0 | KPC_MS1 | KPC_MS2 | KPC_MS3 | KPC_MS4 | KPC_MS5 | KPC_MS6 | KPC_MS7) +#define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */ +#define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */ +#define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Keypad Debounce Select */ +#define KPC_DI (0x1 << 5) /* Direct key interrupt bit */ +#define KPC_RE_ZERO_DEB (0x1 << 4) /* Rotary Encoder Zero Debounce */ +#define KPC_REE1 (0x1 << 3) /* Rotary Encoder1 Enable */ +#define KPC_REE0 (0x1 << 2) /* Rotary Encoder0 Enable */ +#define KPC_DE (0x1 << 1) /* Direct Keypad Enable */ +#define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */ + +#define KPDK_DKP (0x1 << 31) +#define KPDK_DK7 (0x1 << 7) +#define KPDK_DK6 (0x1 << 6) +#define KPDK_DK5 (0x1 << 5) +#define KPDK_DK4 (0x1 << 4) +#define KPDK_DK3 (0x1 << 3) +#define KPDK_DK2 (0x1 << 2) +#define KPDK_DK1 (0x1 << 1) +#define KPDK_DK0 (0x1 << 0) + +#define KPREC_OF1 (0x1 << 31) +#define kPREC_UF1 (0x1 << 30) +#define KPREC_OF0 (0x1 << 15) +#define KPREC_UF0 (0x1 << 14) + +#define KPMK_MKP (0x1 << 31) +#define KPAS_SO (0x1 << 31) +#define KPASMKPx_SO (0x1 << 31) + +/* + * UHC: USB Host Controller (OHCI-like) register definitions + */ +#define UHC_BASE_PHYS (0x4C000000) +#define UHCREV __REG(0x4C000000) /* UHC HCI Spec Revision */ +#define UHCHCON __REG(0x4C000004) /* UHC Host Control Register */ +#define UHCCOMS __REG(0x4C000008) /* UHC Command Status Register */ +#define UHCINTS __REG(0x4C00000C) /* UHC Interrupt Status Register */ +#define UHCINTE __REG(0x4C000010) /* UHC Interrupt Enable */ +#define UHCINTD __REG(0x4C000014) /* UHC Interrupt Disable */ +#define UHCHCCA __REG(0x4C000018) /* UHC Host Controller Comm. Area */ +#define UHCPCED __REG(0x4C00001C) /* UHC Period Current Endpt Descr */ +#define UHCCHED __REG(0x4C000020) /* UHC Control Head Endpt Descr */ +#define UHCCCED __REG(0x4C000024) /* UHC Control Current Endpt Descr */ +#define UHCBHED __REG(0x4C000028) /* UHC Bulk Head Endpt Descr */ +#define UHCBCED __REG(0x4C00002C) /* UHC Bulk Current Endpt Descr */ +#define UHCDHEAD __REG(0x4C000030) /* UHC Done Head */ +#define UHCFMI __REG(0x4C000034) /* UHC Frame Interval */ +#define UHCFMR __REG(0x4C000038) /* UHC Frame Remaining */ +#define UHCFMN __REG(0x4C00003C) /* UHC Frame Number */ +#define UHCPERS __REG(0x4C000040) /* UHC Periodic Start */ +#define UHCLS __REG(0x4C000044) /* UHC Low Speed Threshold */ +#define UHCRHDA __REG(0x4C000048) /* UHC Root Hub Descriptor A */ +#define UHCRHDB __REG(0x4C00004C) /* UHC Root Hub Descriptor B */ +#define UHCRHS __REG(0x4C000050) /* UHC Root Hub Status */ +#define UHCRHPS1 __REG(0x4C000054) /* UHC Root Hub Port 1 Status */ +#define UHCRHPS2 __REG(0x4C000058) /* UHC Root Hub Port 2 Status */ +#define UHCRHPS3 __REG(0x4C00005C) /* UHC Root Hub Port 3 Status */ +#define UHCRHPS(x) __REG2(0x4C000050, (x)<<2) + +#define UHCSTAT __REG(0x4C000060) /* UHC Status Register */ +#define UHCSTAT_UPS3 (1 << 16) /* USB Power Sense Port3 */ +#define UHCSTAT_SBMAI (1 << 15) /* System Bus Master Abort Interrupt*/ +#define UHCSTAT_SBTAI (1 << 14) /* System Bus Target Abort Interrupt*/ +#define UHCSTAT_UPRI (1 << 13) /* USB Port Resume Interrupt */ +#define UHCSTAT_UPS2 (1 << 12) /* USB Power Sense Port 2 */ +#define UHCSTAT_UPS1 (1 << 11) /* USB Power Sense Port 1 */ +#define UHCSTAT_HTA (1 << 10) /* HCI Target Abort */ +#define UHCSTAT_HBA (1 << 8) /* HCI Buffer Active */ +#define UHCSTAT_RWUE (1 << 7) /* HCI Remote Wake Up Event */ + +#define UHCHR __REG(0x4C000064) /* UHC Reset Register */ +#define UHCHR_SSEP3 (1 << 11) /* Sleep Standby Enable for Port3 */ +#define UHCHR_SSEP2 (1 << 10) /* Sleep Standby Enable for Port2 */ +#define UHCHR_SSEP1 (1 << 9) /* Sleep Standby Enable for Port1 */ +#define UHCHR_PCPL (1 << 7) /* Power control polarity low */ +#define UHCHR_PSPL (1 << 6) /* Power sense polarity low */ +#define UHCHR_SSE (1 << 5) /* Sleep Standby Enable */ +#define UHCHR_UIT (1 << 4) /* USB Interrupt Test */ +#define UHCHR_SSDC (1 << 3) /* Simulation Scale Down Clock */ +#define UHCHR_CGR (1 << 2) /* Clock Generation Reset */ +#define UHCHR_FHR (1 << 1) /* Force Host Controller Reset */ +#define UHCHR_FSBIR (1 << 0) /* Force System Bus Iface Reset */ + +#define UHCHIE __REG(0x4C000068) /* UHC Interrupt Enable Register*/ +#define UHCHIE_UPS3IE (1 << 14) /* Power Sense Port3 IntEn */ +#define UHCHIE_UPRIE (1 << 13) /* Port Resume IntEn */ +#define UHCHIE_UPS2IE (1 << 12) /* Power Sense Port2 IntEn */ +#define UHCHIE_UPS1IE (1 << 11) /* Power Sense Port1 IntEn */ +#define UHCHIE_TAIE (1 << 10) /* HCI Interface Transfer Abort + Interrupt Enable*/ +#define UHCHIE_HBAIE (1 << 8) /* HCI Buffer Active IntEn */ +#define UHCHIE_RWIE (1 << 7) /* Remote Wake-up IntEn */ + +#define UHCHIT __REG(0x4C00006C) /* UHC Interrupt Test register */ + +/* Camera Interface */ +#define CICR0 __REG(0x50000000) +#define CICR1 __REG(0x50000004) +#define CICR2 __REG(0x50000008) +#define CICR3 __REG(0x5000000C) +#define CICR4 __REG(0x50000010) +#define CISR __REG(0x50000014) +#define CIFR __REG(0x50000018) +#define CITOR __REG(0x5000001C) +#define CIBR0 __REG(0x50000028) +#define CIBR1 __REG(0x50000030) +#define CIBR2 __REG(0x50000038) + +#define CICR0_DMAEN (1 << 31) /* DMA request enable */ +#define CICR0_PAR_EN (1 << 30) /* Parity enable */ +#define CICR0_SL_CAP_EN (1 << 29) /* Capture enable for slave mode */ +#define CICR0_ENB (1 << 28) /* Camera interface enable */ +#define CICR0_DIS (1 << 27) /* Camera interface disable */ +#define CICR0_SIM (0x7 << 24) /* Sensor interface mode mask */ +#define CICR0_TOM (1 << 9) /* Time-out mask */ +#define CICR0_RDAVM (1 << 8) /* Receive-data-available mask */ +#define CICR0_FEM (1 << 7) /* FIFO-empty mask */ +#define CICR0_EOLM (1 << 6) /* End-of-line mask */ +#define CICR0_PERRM (1 << 5) /* Parity-error mask */ +#define CICR0_QDM (1 << 4) /* Quick-disable mask */ +#define CICR0_CDM (1 << 3) /* Disable-done mask */ +#define CICR0_SOFM (1 << 2) /* Start-of-frame mask */ +#define CICR0_EOFM (1 << 1) /* End-of-frame mask */ +#define CICR0_FOM (1 << 0) /* FIFO-overrun mask */ + +#define CICR1_TBIT (1 << 31) /* Transparency bit */ +#define CICR1_RGBT_CONV (0x3 << 30) /* RGBT conversion mask */ +#define CICR1_PPL (0x3f << 15) /* Pixels per line mask */ +#define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */ +#define CICR1_RGB_F (1 << 11) /* RGB format */ +#define CICR1_YCBCR_F (1 << 10) /* YCbCr format */ +#define CICR1_RGB_BPP (0x7 << 7) /* RGB bis per pixel mask */ +#define CICR1_RAW_BPP (0x3 << 5) /* Raw bis per pixel mask */ +#define CICR1_COLOR_SP (0x3 << 3) /* Color space mask */ +#define CICR1_DW (0x7 << 0) /* Data width mask */ + +#define CICR2_BLW (0xff << 24) /* Beginning-of-line pixel clock + wait count mask */ +#define CICR2_ELW (0xff << 16) /* End-of-line pixel clock + wait count mask */ +#define CICR2_HSW (0x3f << 10) /* Horizontal sync pulse width mask */ +#define CICR2_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock + wait count mask */ +#define CICR2_FSW (0x7 << 0) /* Frame stabilization + wait count mask */ + +#define CICR3_BFW (0xff << 24) /* Beginning-of-frame line clock + wait count mask */ +#define CICR3_EFW (0xff << 16) /* End-of-frame line clock + wait count mask */ +#define CICR3_VSW (0x3f << 10) /* Vertical sync pulse width mask */ +#define CICR3_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock + wait count mask */ +#define CICR3_LPF (0x3ff << 0) /* Lines per frame mask */ + +#define CICR4_MCLK_DLY (0x3 << 24) /* MCLK Data Capture Delay mask */ +#define CICR4_PCLK_EN (1 << 23) /* Pixel clock enable */ +#define CICR4_PCP (1 << 22) /* Pixel clock polarity */ +#define CICR4_HSP (1 << 21) /* Horizontal sync polarity */ +#define CICR4_VSP (1 << 20) /* Vertical sync polarity */ +#define CICR4_MCLK_EN (1 << 19) /* MCLK enable */ +#define CICR4_FR_RATE (0x7 << 8) /* Frame rate mask */ +#define CICR4_DIV (0xff << 0) /* Clock divisor mask */ + +#define CISR_FTO (1 << 15) /* FIFO time-out */ +#define CISR_RDAV_2 (1 << 14) /* Channel 2 receive data available */ +#define CISR_RDAV_1 (1 << 13) /* Channel 1 receive data available */ +#define CISR_RDAV_0 (1 << 12) /* Channel 0 receive data available */ +#define CISR_FEMPTY_2 (1 << 11) /* Channel 2 FIFO empty */ +#define CISR_FEMPTY_1 (1 << 10) /* Channel 1 FIFO empty */ +#define CISR_FEMPTY_0 (1 << 9) /* Channel 0 FIFO empty */ +#define CISR_EOL (1 << 8) /* End of line */ +#define CISR_PAR_ERR (1 << 7) /* Parity error */ +#define CISR_CQD (1 << 6) /* Camera interface quick disable */ +#define CISR_SOF (1 << 5) /* Start of frame */ +#define CISR_CDD (1 << 4) /* Camera interface disable done */ +#define CISR_EOF (1 << 3) /* End of frame */ +#define CISR_IFO_2 (1 << 2) /* FIFO overrun for Channel 2 */ +#define CISR_IFO_1 (1 << 1) /* FIFO overrun for Channel 1 */ +#define CISR_IFO_0 (1 << 0) /* FIFO overrun for Channel 0 */ + +#define CIFR_FLVL2 (0x7f << 23) /* FIFO 2 level mask */ +#define CIFR_FLVL1 (0x7f << 16) /* FIFO 1 level mask */ +#define CIFR_FLVL0 (0xff << 8) /* FIFO 0 level mask */ +#define CIFR_THL_0 (0x3 << 4) /* Threshold Level for Channel 0 FIFO */ +#define CIFR_RESET_F (1 << 3) /* Reset input FIFOs */ +#define CIFR_FEN2 (1 << 2) /* FIFO enable for channel 2 */ +#define CIFR_FEN1 (1 << 1) /* FIFO enable for channel 1 */ +#define CIFR_FEN0 (1 << 0) /* FIFO enable for channel 0 */ + +#define SRAM_SIZE 0x40000 /* 4x64K */ + +#define SRAM_MEM_PHYS 0x5C000000 + +#define IMPMCR __REG(0x58000000) /* IM Power Management Control Reg */ +#define IMPMSR __REG(0x58000008) /* IM Power Management Status Reg */ + +#define IMPMCR_PC3 (0x3 << 22) /* Bank 3 Power Control */ +#define IMPMCR_PC3_RUN_MODE (0x0 << 22) /* Run mode */ +#define IMPMCR_PC3_STANDBY_MODE (0x1 << 22) /* Standby mode */ +#define IMPMCR_PC3_AUTO_MODE (0x3 << 22) /* Automatically controlled */ + +#define IMPMCR_PC2 (0x3 << 20) /* Bank 2 Power Control */ +#define IMPMCR_PC2_RUN_MODE (0x0 << 20) /* Run mode */ +#define IMPMCR_PC2_STANDBY_MODE (0x1 << 20) /* Standby mode */ +#define IMPMCR_PC2_AUTO_MODE (0x3 << 20) /* Automatically controlled */ + +#define IMPMCR_PC1 (0x3 << 18) /* Bank 1 Power Control */ +#define IMPMCR_PC1_RUN_MODE (0x0 << 18) /* Run mode */ +#define IMPMCR_PC1_STANDBY_MODE (0x1 << 18) /* Standby mode */ +#define IMPMCR_PC1_AUTO_MODE (0x3 << 18) /* Automatically controlled */ + +#define IMPMCR_PC0 (0x3 << 16) /* Bank 0 Power Control */ +#define IMPMCR_PC0_RUN_MODE (0x0 << 16) /* Run mode */ +#define IMPMCR_PC0_STANDBY_MODE (0x1 << 16) /* Standby mode */ +#define IMPMCR_PC0_AUTO_MODE (0x3 << 16) /* Automatically controlled */ + +#define IMPMCR_AW3 (1 << 11) /* Bank 3 Automatic Wake-up enable */ +#define IMPMCR_AW2 (1 << 10) /* Bank 2 Automatic Wake-up enable */ +#define IMPMCR_AW1 (1 << 9) /* Bank 1 Automatic Wake-up enable */ +#define IMPMCR_AW0 (1 << 8) /* Bank 0 Automatic Wake-up enable */ + +#define IMPMCR_DST (0xFF << 0) /* Delay Standby Time, ms */ + +#define IMPMSR_PS3 (0x3 << 6) /* Bank 3 Power Status: */ +#define IMPMSR_PS3_RUN_MODE (0x0 << 6) /* Run mode */ +#define IMPMSR_PS3_STANDBY_MODE (0x1 << 6) /* Standby mode */ + +#define IMPMSR_PS2 (0x3 << 4) /* Bank 2 Power Status: */ +#define IMPMSR_PS2_RUN_MODE (0x0 << 4) /* Run mode */ +#define IMPMSR_PS2_STANDBY_MODE (0x1 << 4) /* Standby mode */ + +#define IMPMSR_PS1 (0x3 << 2) /* Bank 1 Power Status: */ +#define IMPMSR_PS1_RUN_MODE (0x0 << 2) /* Run mode */ +#define IMPMSR_PS1_STANDBY_MODE (0x1 << 2) /* Standby mode */ + +#define IMPMSR_PS0 (0x3 << 0) /* Bank 0 Power Status: */ +#define IMPMSR_PS0_RUN_MODE (0x0 << 0) /* Run mode */ +#define IMPMSR_PS0_STANDBY_MODE (0x1 << 0) /* Standby mode */ + +#endif + +/* MFPR */ +#ifdef CONFIG_CPU_MONAHANS + +#define SRAM_SIZE 0xC0000 /* 4x64K */ +#define SRAM_MEM_PHYS 0x5C000000 + +/* GPIO alternate function assignments */ +#define APPS_PAD_BASE 0x40E10000 + +/* MFPR regsiter locations for each pin */ +#define GPIO0_MFPR (APPS_PAD_BASE + 0x0124) +#define GPIO1_MFPR (APPS_PAD_BASE + 0x0128) +#define GPIO2_MFPR (APPS_PAD_BASE + 0x012C) +#define GPIO3_MFPR (APPS_PAD_BASE + 0x0130) +#define GPIO4_MFPR (APPS_PAD_BASE + 0x0134) +#define GPIO5_MFPR (APPS_PAD_BASE + 0x028C) +#define GPIO6_MFPR (APPS_PAD_BASE + 0x0290) +#define GPIO7_MFPR (APPS_PAD_BASE + 0x0294) +#define GPIO8_MFPR (APPS_PAD_BASE + 0x0298) +#define GPIO9_MFPR (APPS_PAD_BASE + 0x029C) +#define GPIO10_MFPR (APPS_PAD_BASE + 0x0458) +#define GPIO11_MFPR (APPS_PAD_BASE + 0x02A0) +#define GPIO12_MFPR (APPS_PAD_BASE + 0x02A4) +#define GPIO13_MFPR (APPS_PAD_BASE + 0x02A8) +#define GPIO14_MFPR (APPS_PAD_BASE + 0x02AC) +#define GPIO15_MFPR (APPS_PAD_BASE + 0x02B0) +#define GPIO16_MFPR (APPS_PAD_BASE + 0x02B4) +#define GPIO17_MFPR (APPS_PAD_BASE + 0x02B8) +#define GPIO18_MFPR (APPS_PAD_BASE + 0x02BC) +#define GPIO19_MFPR (APPS_PAD_BASE + 0x02C0) +#define GPIO20_MFPR (APPS_PAD_BASE + 0x02C4) +#define GPIO21_MFPR (APPS_PAD_BASE + 0x02C8) +#define GPIO22_MFPR (APPS_PAD_BASE + 0x02CC) +#define GPIO23_MFPR (APPS_PAD_BASE + 0x02D0) +#define GPIO24_MFPR (APPS_PAD_BASE + 0x02D4) +#define GPIO25_MFPR (APPS_PAD_BASE + 0x02D8) +#define GPIO26_MFPR (APPS_PAD_BASE + 0x02DC) +#define GPIO27_MFPR (APPS_PAD_BASE + 0x0400) +#define GPIO28_MFPR (APPS_PAD_BASE + 0x0404) +#define GPIO29_MFPR (APPS_PAD_BASE + 0x0408) +#define GPIO30_MFPR (APPS_PAD_BASE + 0x040C) +#define GPIO31_MFPR (APPS_PAD_BASE + 0x0410) +#define GPIO32_MFPR (APPS_PAD_BASE + 0x0414) +#define GPIO33_MFPR (APPS_PAD_BASE + 0x0418) +#define GPIO34_MFPR (APPS_PAD_BASE + 0x041C) +#define GPIO35_MFPR (APPS_PAD_BASE + 0x0420) +#define GPIO36_MFPR (APPS_PAD_BASE + 0x0424) +#define GPIO37_MFPR (APPS_PAD_BASE + 0x0428) +#define GPIO38_MFPR (APPS_PAD_BASE + 0x042C) +#define GPIO39_MFPR (APPS_PAD_BASE + 0x0430) +#define GPIO40_MFPR (APPS_PAD_BASE + 0x0434) +#define GPIO41_MFPR (APPS_PAD_BASE + 0x0438) +#define GPIO42_MFPR (APPS_PAD_BASE + 0x043C) +#define GPIO43_MFPR (APPS_PAD_BASE + 0x0440) +#define GPIO44_MFPR (APPS_PAD_BASE + 0x0444) +#define GPIO45_MFPR (APPS_PAD_BASE + 0x0448) +#define GPIO46_MFPR (APPS_PAD_BASE + 0x044C) +#define GPIO47_MFPR (APPS_PAD_BASE + 0x0450) +#define GPIO48_MFPR (APPS_PAD_BASE + 0x0454) +#define GPIO49_MFPR (APPS_PAD_BASE + 0x045C) +#define GPIO50_MFPR (APPS_PAD_BASE + 0x0460) +#define GPIO51_MFPR (APPS_PAD_BASE + 0x0464) +#define GPIO52_MFPR (APPS_PAD_BASE + 0x0468) +#define GPIO53_MFPR (APPS_PAD_BASE + 0x046C) +#define GPIO54_MFPR (APPS_PAD_BASE + 0x0470) +#define GPIO55_MFPR (APPS_PAD_BASE + 0x0474) +#define GPIO56_MFPR (APPS_PAD_BASE + 0x0478) +#define GPIO57_MFPR (APPS_PAD_BASE + 0x047C) +#define GPIO58_MFPR (APPS_PAD_BASE + 0x0480) +#define GPIO59_MFPR (APPS_PAD_BASE + 0x0484) +#define GPIO60_MFPR (APPS_PAD_BASE + 0x0488) +#define GPIO61_MFPR (APPS_PAD_BASE + 0x048C) +#define GPIO62_MFPR (APPS_PAD_BASE + 0x0490) +#define GPIO63_MFPR (APPS_PAD_BASE + 0x04B4) +#define GPIO64_MFPR (APPS_PAD_BASE + 0x04B8) +#define GPIO65_MFPR (APPS_PAD_BASE + 0x04BC) +#define GPIO66_MFPR (APPS_PAD_BASE + 0x04C0) +#define GPIO67_MFPR (APPS_PAD_BASE + 0x04C4) +#define GPIO68_MFPR (APPS_PAD_BASE + 0x04C8) +#define GPIO69_MFPR (APPS_PAD_BASE + 0x04CC) +#define GPIO70_MFPR (APPS_PAD_BASE + 0x04D0) +#define GPIO71_MFPR (APPS_PAD_BASE + 0x04D4) +#define GPIO72_MFPR (APPS_PAD_BASE + 0x04D8) +#define GPIO73_MFPR (APPS_PAD_BASE + 0x04DC) +#define GPIO74_MFPR (APPS_PAD_BASE + 0x04F0) +#define GPIO75_MFPR (APPS_PAD_BASE + 0x04F4) +#define GPIO76_MFPR (APPS_PAD_BASE + 0x04F8) +#define GPIO77_MFPR (APPS_PAD_BASE + 0x04FC) +#define GPIO78_MFPR (APPS_PAD_BASE + 0x0500) +#define GPIO79_MFPR (APPS_PAD_BASE + 0x0504) +#define GPIO80_MFPR (APPS_PAD_BASE + 0x0508) +#define GPIO81_MFPR (APPS_PAD_BASE + 0x050C) +#define GPIO82_MFPR (APPS_PAD_BASE + 0x0510) +#define GPIO83_MFPR (APPS_PAD_BASE + 0x0514) +#define GPIO84_MFPR (APPS_PAD_BASE + 0x0518) +#define GPIO85_MFPR (APPS_PAD_BASE + 0x051C) +#define GPIO86_MFPR (APPS_PAD_BASE + 0x0520) +#define GPIO87_MFPR (APPS_PAD_BASE + 0x0524) +#define GPIO88_MFPR (APPS_PAD_BASE + 0x0528) +#define GPIO89_MFPR (APPS_PAD_BASE + 0x052C) +#define GPIO90_MFPR (APPS_PAD_BASE + 0x0530) +#define GPIO91_MFPR (APPS_PAD_BASE + 0x0534) +#define GPIO92_MFPR (APPS_PAD_BASE + 0x0538) +#define GPIO93_MFPR (APPS_PAD_BASE + 0x053C) +#define GPIO94_MFPR (APPS_PAD_BASE + 0x0540) +#define GPIO95_MFPR (APPS_PAD_BASE + 0x0544) +#define GPIO96_MFPR (APPS_PAD_BASE + 0x0548) +#define GPIO97_MFPR (APPS_PAD_BASE + 0x054C) +#define GPIO98_MFPR (APPS_PAD_BASE + 0x0550) +#define GPIO99_MFPR (APPS_PAD_BASE + 0x0600) +#define GPIO100_MFPR (APPS_PAD_BASE + 0x0604) +#define GPIO101_MFPR (APPS_PAD_BASE + 0x0608) +#define GPIO102_MFPR (APPS_PAD_BASE + 0x060C) +#define GPIO103_MFPR (APPS_PAD_BASE + 0x0610) +#define GPIO104_MFPR (APPS_PAD_BASE + 0x0614) +#define GPIO105_MFPR (APPS_PAD_BASE + 0x0618) +#define GPIO106_MFPR (APPS_PAD_BASE + 0x061C) +#define GPIO107_MFPR (APPS_PAD_BASE + 0x0620) +#define GPIO108_MFPR (APPS_PAD_BASE + 0x0624) +#define GPIO109_MFPR (APPS_PAD_BASE + 0x0628) +#define GPIO110_MFPR (APPS_PAD_BASE + 0x062C) +#define GPIO111_MFPR (APPS_PAD_BASE + 0x0630) +#define GPIO112_MFPR (APPS_PAD_BASE + 0x0634) +#define GPIO113_MFPR (APPS_PAD_BASE + 0x0638) +#define GPIO114_MFPR (APPS_PAD_BASE + 0x063C) +#define GPIO115_MFPR (APPS_PAD_BASE + 0x0640) +#define GPIO116_MFPR (APPS_PAD_BASE + 0x0644) +#define GPIO117_MFPR (APPS_PAD_BASE + 0x0648) +#define GPIO118_MFPR (APPS_PAD_BASE + 0x064C) +#define GPIO119_MFPR (APPS_PAD_BASE + 0x0650) +#define GPIO120_MFPR (APPS_PAD_BASE + 0x0654) +#define GPIO121_MFPR (APPS_PAD_BASE + 0x0658) +#define GPIO122_MFPR (APPS_PAD_BASE + 0x065C) +#define GPIO123_MFPR (APPS_PAD_BASE + 0x0660) +#define GPIO124_MFPR (APPS_PAD_BASE + 0x0664) +#define GPIO125_MFPR (APPS_PAD_BASE + 0x0668) +#define GPIO126_MFPR (APPS_PAD_BASE + 0x066C) +#define GPIO127_MFPR (APPS_PAD_BASE + 0x0670) +#define GPIO0_2_MFPR (APPS_PAD_BASE + 0x0674) /* MFPR for GPIO0_2 */ +#define GPIO1_2_MFPR (APPS_PAD_BASE + 0x0678) /* MFPR for GPIO1_2 */ +#define GPIO2_2_MFPR (APPS_PAD_BASE + 0x067C) /* MFPR for GPIO2_2 */ +#define GPIO3_2_MFPR (APPS_PAD_BASE + 0x0680) /* MFPR for GPIO3_2 */ +#define GPIO4_2_MFPR (APPS_PAD_BASE + 0x0684) /* MFPR for GPIO4_2 */ +#define GPIO5_2_MFPR (APPS_PAD_BASE + 0x0688) /* MFPR for GPIO5_2 */ +#define GPIO6_2_MFPR (APPS_PAD_BASE + 0x0494) /* MFPR for GPIO6_2 */ +#define GPIO7_2_MFPR (APPS_PAD_BASE + 0x0498) /* MFPR for GPIO7_2 */ +#define GPIO8_2_MFPR (APPS_PAD_BASE + 0x049C) /* MFPR for GPIO8_2 */ +#define GPIO9_2_MFPR (APPS_PAD_BASE + 0x04A0) /* MFPR for GPIO9_2 */ +#define GPIO10_2_MFPR (APPS_PAD_BASE + 0x04A4) /* MFPR for GPIO10_2 */ +#define GPIO11_2_MFPR (APPS_PAD_BASE + 0x04A8) /* MFPR for GPIO11_2 */ +#define GPIO12_2_MFPR (APPS_PAD_BASE + 0x04AC) /* MFPR for GPIO12_2 */ +#define GPIO13_2_MFPR (APPS_PAD_BASE + 0x04B0) /* MFPR for GPIO13_2 */ +#define GPIO14_2_MFPR (APPS_PAD_BASE + 0x04E0) /* MFPR for GPIO14_2 */ +#define GPIO15_2_MFPR (APPS_PAD_BASE + 0x04E4) /* MFPR for GPIO15_2 */ +#define GPIO16_2_MFPR (APPS_PAD_BASE + 0x04E8) /* MFPR for GPIO16_2 */ +#define GPIO17_2_MFPR (APPS_PAD_BASE + 0x04EC) /* MFPR for GPIO17_2 */ + +#define PIN_nXCVREN_MFPR (APPS_PAD_BASE + 0x0138) +#define PIN_ND_CLE_MFPR (APPS_PAD_BASE + 0x0204) +#define PIN_DF_nADV1_ALE_MFPR (APPS_PAD_BASE + 0x0208) +#define PIN_DF_SCLK_S_MFPR (APPS_PAD_BASE + 0x020C) +#define PIN_DF_SCLK_E_MFPR (APPS_PAD_BASE + 0x0210) +#define PIN_nBE0_MFPR (APPS_PAD_BASE + 0x0214) +#define PIN_nBE1_MFPR (APPS_PAD_BASE + 0x0218) +#define PIN_DF_nADV2_ALE_MFPR (APPS_PAD_BASE + 0x021C) +#define PIN_DF_INT_RnB_MFPR (APPS_PAD_BASE + 0x0220) +#define PIN_DF_nCS0_MFPR (APPS_PAD_BASE + 0x0224) +#define PIN_DF_nCS1_MFPR (APPS_PAD_BASE + 0x0228) +#define PIN_DF_nWE_MFPR (APPS_PAD_BASE + 0x022C) +#define PIN_DF_nRE_nOE_MFPR (APPS_PAD_BASE + 0x0230) +#define PIN_nLUA_MFPR (APPS_PAD_BASE + 0x0234) +#define PIN_nLLA_MFPR (APPS_PAD_BASE + 0x0238) +#define PIN_DF_ADDR0_MFPR (APPS_PAD_BASE + 0x023C) +#define PIN_DF_ADDR1_MFPR (APPS_PAD_BASE + 0x0240) +#define PIN_DF_ADDR2_MFPR (APPS_PAD_BASE + 0x0244) +#define PIN_DF_ADDR3_MFPR (APPS_PAD_BASE + 0x0248) +#define PIN_DF_IO0_MFPR (APPS_PAD_BASE + 0x024C) +#define PIN_DF_IO1_MFPR (APPS_PAD_BASE + 0x0254) +#define PIN_DF_IO2_MFPR (APPS_PAD_BASE + 0x025C) +#define PIN_DF_IO3_MFPR (APPS_PAD_BASE + 0x0264) +#define PIN_DF_IO4_MFPR (APPS_PAD_BASE + 0x026C) +#define PIN_DF_IO5_MFPR (APPS_PAD_BASE + 0x0274) +#define PIN_DF_IO6_MFPR (APPS_PAD_BASE + 0x027C) +#define PIN_DF_IO7_MFPR (APPS_PAD_BASE + 0x0294) +#define PIN_DF_IO8_MFPR (APPS_PAD_BASE + 0x0298) +#define PIN_DF_IO9_MFPR (APPS_PAD_BASE + 0x029C) +#define PIN_DF_IO10_MFPR (APPS_PAD_BASE + 0x0260) +#define PIN_DF_IO11_MFPR (APPS_PAD_BASE + 0x0268) +#define PIN_DF_IO12_MFPR (APPS_PAD_BASE + 0x0270) +#define PIN_DF_IO13_MFPR (APPS_PAD_BASE + 0x0278) +#define PIN_DF_IO14_MFPR (APPS_PAD_BASE + 0x0280) +#define PIN_DF_IO15_MFPR (APPS_PAD_BASE + 0x0288) + +/* GPIO mode encodings: Direction, Number, MFPR value */ + +#define MFPR_PS 0x80000000 /* MFPR bit 15: pull_sel */ +#define MFPR_PUE 0x40000000 /* MFPR bit 14: pullup_en */ +#define MFPR_PDE 0x20000000 /* MFPR bit 13: pulldown_en */ +#define MFPR_DF1 0x00000000 /* MFPR bit 12-10: drive, fast 1ma */ +#define MFPR_DF2 0x04000000 /* MFPR bit 12-10: drive, fast 2ma */ +#define MFPR_DF3 0x08000000 /* MFPR bit 12-10: drive, fast 3ma */ +#define MFPR_DF4 0x0c000000 /* MFPR bit 12-10: drive, fast 4ma */ +#define MFPR_DS6 0x10000000 /* MFPR bit 12-10: drive, slow 6ma */ +#define MFPR_DF6 0x14000000 /* MFPR bit 12-10: drive, fast 6ma */ +#define MFPR_DS10 0x18000000 /* MFPR bit 12-10: drive, slow 10ma */ +#define MFPR_DF10 0x1c000000 /* MFPR bit 12-10: drive, fast 10ma */ +#define MFPR_SS 0x02000000 /* MFPR bit 9: sleep_sel */ +#define MFPR_SD 0x01000000 /* MFPR bit 8: sleep_data */ +#define MFPR_SE 0x00800000 /* MFPR bit 7: sleep_oe */ +#define MFPR_EC 0x00400000 /* MFPR bit 6: edge_clear */ +#define MFPR_EF 0x00200000 /* MFPR bit 5: edge_fall_en */ +#define MFPR_ER 0x00100000 /* MFPR bit 4: edge_rise_en */ +#define MFPR_ALT0 0x00000000 /* MFPR bit 2-0: alternate function 0 */ +#define MFPR_ALT1 0x00010000 /* MFPR bit 2-0: alternate function 1 */ +#define MFPR_ALT2 0x00020000 /* MFPR bit 2-0: alternate function 2 */ +#define MFPR_ALT3 0x00030000 /* MFPR bit 2-0: alternate function 3 */ +#define MFPR_ALT4 0x00040000 /* MFPR bit 2-0: alternate function 4 */ +#define MFPR_ALT5 0x00050000 /* MFPR bit 2-0: alternate function 5 */ +#define MFPR_ALT6 0x00060000 /* MFPR bit 2-0: alternate function 6 */ +#define MFPR_ALT7 0x00070000 /* MFPR bit 2-0: alternate function 7 */ +#define GPIO_MD_MASK_NR 0x0000ffff +#define GPIO_MD_MASK_MFPR 0xffff0000 +#define GPIO_MD_SHIFT_MFPR 16 + +#define GPIO3_NCS_2 (3|MFPR_DS6|MFPR_ALT1) +#define GPIO11_PWM0 (11|MFPR_DS6|MFPR_ALT1) +#define GPIO12_PWM1 (12|MFPR_DS6|MFPR_ALT1) +#define GPIO14_LCD_BACKLIGHT_PWM3 (14|MFPR_DS6|MFPR_ALT1) + +#define GPIO18_MMC_DAT_0 (18|MFPR_DS6|MFPR_ALT4) +#define GPIO19_MMC_DAT_1 (19|MFPR_DS6|MFPR_ALT4) +#define GPIO20_MMC_DAT_2 (20|MFPR_DS6|MFPR_ALT4) +#define GPIO21_MMC_DAT_3 (21|MFPR_DS6|MFPR_ALT4) +#define GPIO22_CLK_MMC (22|MFPR_DS6|MFPR_ALT4) +#define GPIO23_MMC_CMD (23|MFPR_DS6|MFPR_ALT4) +#define GPIO24_MMC2_DAT_0 (24|MFPR_DS6|MFPR_ALT4) +#define GPIO25_MMC2_DAT_1 (25|MFPR_DS6|MFPR_ALT4) +#define GPIO26_MMC2_DAT_2 (26|MFPR_DS6|MFPR_ALT4) +#define GPIO27_MMC2_DAT_3 (27|MFPR_DS6|MFPR_ALT4) +#define GPIO28_CLK_MMC2 (28|MFPR_DS6|MFPR_ALT4) +#define GPIO29_MMC2_CMD (29|MFPR_DS6|MFPR_ALT4) +#define GPIO30_CLK_MMC (30|MFPR_DS6|MFPR_ALT4) +#define GPIO31_MMC_CMD (31|MFPR_DS6|MFPR_ALT4) +#define GPIO34_AC97_SYSCLK (34|MFPR_DF6|MFPR_ALT1) +#define GPIO35_AC97_SDATA_IN0 (35|MFPR_DF6|MFPR_ALT1) +#define GPIO36_AC97_SDATA_IN1 (36|MFPR_DF6|MFPR_ALT1) +#define GPIO37_AC97_SDATA_OUT (37|MFPR_DF6|MFPR_ALT1) +#define GPIO38_AC97_SYNC (38|MFPR_DF6|MFPR_ALT1) +#define GPIO39_AC97_BITCLK (39|MFPR_DF6|MFPR_ALT1) +#define GPIO40_AC97_RESET_N (40|MFPR_DF6|MFPR_ALT1) +#define GPIO41_FF_UART1_RXD (41|MFPR_DS6|MFPR_ALT2) +#define GPIO42_FF_UART1_TXD (42|MFPR_DS6|MFPR_ALT2) +#define GPIO43_FF_UART1_CTS (43|MFPR_DS6|MFPR_ALT2) +#define GPIO44_FF_UART1_DCD (44|MFPR_DF10|MFPR_SD|MFPR_ALT2) +#define GPIO45_FF_UART1_DSR (45|MFPR_DS6|MFPR_ALT2) +#define GPIO46_FF_UART1_RI (46|MFPR_DS6|MFPR_ALT2) +#define GPIO47_FF_UART1_DTR (47|MFPR_DS6|MFPR_ALT2) +#define GPIO48_FF_UART1_RTS (48|MFPR_DS6|MFPR_ALT2) +#define GPIO49_CIF_DD0 (49|MFPR_DF6|MFPR_ALT1) +#define GPIO50_CIF_DD1 (50|MFPR_DF6|MFPR_ALT1) +#define GPIO51_CIF_DD2 (51|MFPR_DF6|MFPR_ALT1) +#define GPIO52_CIF_DD3 (52|MFPR_DF6|MFPR_ALT1) +#define GPIO53_CIF_DD4 (53|MFPR_DF6|MFPR_ALT1) +#define GPIO54_CIF_DD5 (54|MFPR_DF6|MFPR_ALT1) +#define GPIO55_CIF_DD6 (55|MFPR_DF6|MFPR_ALT1) +#define GPIO56_CIF_DD7 (56|MFPR_DF6|MFPR_ALT1) +#define GPIO57_CIF_DD8 (57|MFPR_DF6|MFPR_ALT1) +#define GPIO58_CIF_DD9 (58|MFPR_DF6|MFPR_ALT1) +#define GPIO59_CIF_MCLK (59|MFPR_DF6|MFPR_ALT1) +#define GPIO60_CIF_PCLK (60|MFPR_DF6|MFPR_ALT1) +#define GPIO61_CIF_LV (61|MFPR_DF6|MFPR_ALT1) +#define GPIO62_CIF_FV (62|MFPR_DF6|MFPR_ALT1) +#define GPIO63_LCD_LDD_8 (63|MFPR_DF6|MFPR_ALT1) +#define GPIO64_LCD_LDD_9 (64|MFPR_DF6|MFPR_ALT1) +#define GPIO65_LCD_LDD_10 (65|MFPR_DF6|MFPR_ALT1) +#define GPIO66_LCD_LDD_11 (66|MFPR_DF6|MFPR_ALT1) +#define GPIO67_LCD_LDD_12 (67|MFPR_DF6|MFPR_ALT1) +#define GPIO68_LCD_LDD_13 (68|MFPR_DF6|MFPR_ALT1) +#define GPIO69_LCD_LDD_14 (69|MFPR_DF6|MFPR_ALT1) +#define GPIO70_LCD_LDD_15 (70|MFPR_DF6|MFPR_ALT1) +#define GPIO71_LCD_LDD_16 (71|MFPR_DF6|MFPR_ALT1) +#define GPIO72_LCD_LDD_17 (72|MFPR_DF6|MFPR_ALT1) +#define GPIO73_LCD_CS (73|MFPR_DF6|MFPR_ALT2) +#define GPIO74_LCD_VSYNC (74|MFPR_DF6|MFPR_ALT2) +#define GPIO89_SSP3_SCLK (89|MFPR_DS6|MFPR_ALT1) +#define GPIO90_SSP3_SFRM (90|MFPR_DS6|MFPR_ALT1) +#define GPIO91_SSP3_TXD (91|MFPR_DS6|MFPR_ALT1) +#define GPIO92_SSP3_RXD (92|MFPR_DS6|MFPR_ALT1) +#define GPIO93_SSP4_SCLK (93|MFPR_DS6|MFPR_ALT1) +#define GPIO94_SSP4_SFRM (94|MFPR_DS6|MFPR_ALT1) +#define GPIO95_SSP4_TXD (95|MFPR_DS6|MFPR_ALT1) +#define GPIO96_SSP4_RXD (96|MFPR_DS6|MFPR_ALT1) +#define GPIO100_USB_P2_4 (100|MFPR_DS6|MFPR_ALT2) +#define GPIO101_USB_P2_8 (101|MFPR_DS6|MFPR_ALT2) +#define GPIO102_USB_P2_3 (102|MFPR_DS6|MFPR_ALT2) +#define GPIO103_USB_P2_5 (103|MFPR_DS6|MFPR_ALT2) +#define GPIO104_USB_P2_7 (104|MFPR_DS6|MFPR_ALT2) +#define GPIO105_KP_DKIN_0 (105|MFPR_DS6|MFPR_ALT2) +#define GPIO106_KP_DKIN_1 (106|MFPR_DS6|MFPR_ALT2) +#define GPIO107_STD_UART3_TXD (107|MFPR_DS6|MFPR_ALT1) +#define GPIO108_STD_UART3_RXD (108|MFPR_DS6|MFPR_ALT1) +#define GPIO109_BT_UART2_RTS (109|MFPR_DS6|MFPR_ALT1) +#define GPIO110_BT_UART2_RXD (110|MFPR_DS6|MFPR_ALT1) +#define GPIO111_BT_UART2_TXD (111|MFPR_DS6|MFPR_ALT1) +#define GPIO112_BT_UART2_CTS (112|MFPR_DS6|MFPR_ALT1) +#define GPIO113_KP_MKIN_0 (113|MFPR_DS6|MFPR_ALT1) +#define GPIO114_KP_MKIN_1 (114|MFPR_DS6|MFPR_ALT1) +#define GPIO115_KP_MKIN_2 (115|MFPR_DS6|MFPR_ALT1) +#define GPIO116_KP_MKIN_3 (116|MFPR_DS6|MFPR_ALT1) +#define GPIO117_KP_MKIN_4 (117|MFPR_DS6|MFPR_ALT1) +#define GPIO118_KP_MKIN_5 (118|MFPR_DS6|MFPR_ALT1) +#define GPIO119_KP_MKIN_6 (119|MFPR_DS6|MFPR_ALT1) +#define GPIO120_KP_MKIN_7 (120|MFPR_DS6|MFPR_ALT1) +#define GPIO121_KP_MKOUT_0 (121|MFPR_DS6|MFPR_ALT1) +#define GPIO122_KP_MKOUT_1 (122|MFPR_DS6|MFPR_ALT1) +#define GPIO123_KP_MKOUT_2 (123|MFPR_DS6|MFPR_ALT1) +#define GPIO124_KP_MKOUT_3 (124|MFPR_DS6|MFPR_ALT1) +#define GPIO125_KP_MKOUT_4 (125|MFPR_DS6|MFPR_ALT1) +#define GPIO126_KP_MKOUT_5 (126|MFPR_DS6|MFPR_ALT1) +#define GPIO127_KP_MKOUT_6 (127|MFPR_DS6|MFPR_ALT1) +#define GPIO5_2_KP_MKOUT_7 (133|MFPR_DS6|MFPR_ALT1) +#define GPIO6_2_LCD_LDD_0 (134|MFPR_DS6|MFPR_ALT1) +#define GPIO7_2_LCD_LDD_1 (135|MFPR_DS6|MFPR_ALT1) +#define GPIO8_2_LCD_LDD_2 (136|MFPR_DS6|MFPR_ALT1) +#define GPIO9_2_LCD_LDD_3 (137|MFPR_DS6|MFPR_ALT1) +#define GPIO10_2_LCD_LDD_4 (138|MFPR_DS6|MFPR_ALT1) +#define GPIO11_2_LCD_LDD_5 (139|MFPR_DS6|MFPR_ALT1) +#define GPIO12_2_LCD_LDD_6 (140|MFPR_DS6|MFPR_ALT1) +#define GPIO13_2_LCD_LDD_7 (141|MFPR_DS6|MFPR_ALT1) +#define GPIO14_2_LCD_FCLK (142|MFPR_DS6|MFPR_ALT1) +#define GPIO15_2_LCD_LCLK (143|MFPR_DS6|MFPR_ALT1) +#define GPIO16_2_LCD_PCLK (144|MFPR_DS6|MFPR_ALT1) +#define GPIO17_2_LCD_BIAS (145|MFPR_DS6|MFPR_ALT1) + +/* Internal System Bus Arbiter */ +#define ARB_CNTRL1 __REG_2(0x4600FE00) /* PX1 Bus Arbiter Control Register */ +#define ARB_CNTRL2 __REG_2(0x4600FE80) /* PX2 Bus Arbiter Control Register */ + +/* + * Keypad + */ +#define KPC __REG(0x41500000) /* Keypad Interface Control register */ +#define KPDK __REG(0x41500008) /* Keypad Interface Direct Key register */ +#define KPREC __REG(0x41500010) /* Keypad Interface Rotary Encoder register */ +#define KPMK __REG(0x41500018) /* Keypad Interface Matrix Key register */ +#define KPAS __REG(0x41500020) /* Keypad Interface Automatic Scan register */ +#define KPASMKP0 __REG(0x41500028) /* Keypad Interface Automatic Scan Multiple Key Presser register 0 */ +#define KPASMKP1 __REG(0x41500030) /* Keypad Interface Automatic Scan Multiple Key Presser register 1 */ +#define KPASMKP2 __REG(0x41500038) /* Keypad Interface Automatic Scan Multiple Key Presser register 2 */ +#define KPASMKP3 __REG(0x41500040) /* Keypad Interface Automatic Scan Multiple Key Presser register 3 */ +#define KPKDI __REG(0x41500048) /* Keypad Interface Key Debounce Interval register */ + +#define KPC_AS (0x1 << 30) /* Automatic Scan bit */ +#define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */ +#define KPC_MI (0x1 << 22) /* Matrix interrupt bit */ +#define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */ +#define KPC_MS7 (0x1 << 20) /* Matrix scan line 7 */ +#define KPC_MS6 (0x1 << 19) /* Matrix scan line 6 */ +#define KPC_MS5 (0x1 << 18) /* Matrix scan line 5 */ +#define KPC_MS4 (0x1 << 17) /* Matrix scan line 4 */ +#define KPC_MS3 (0x1 << 16) /* Matrix scan line 3 */ +#define KPC_MS2 (0x1 << 15) /* Matrix scan line 2 */ +#define KPC_MS1 (0x1 << 14) /* Matrix scan line 1 */ +#define KPC_MS0 (0x1 << 13) /* Matrix scan line 0 */ +#define KPC_MS_ALL (KPC_MS0 | KPC_MS1 | KPC_MS2 | KPC_MS3 | KPC_MS4 | KPC_MS5 | KPC_MS6 | KPC_MS7) +#define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */ +#define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */ +#define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Keypad Debounce Select */ +#define KPC_DI (0x1 << 5) /* Direct key interrupt bit */ +#define KPC_RE_ZERO_DEB (0x1 << 4) /* Rotary Encoder Zero Debounce */ +#define KPC_REE1 (0x1 << 3) /* Rotary Encoder1 Enable */ +#define KPC_REE0 (0x1 << 2) /* Rotary Encoder0 Enable */ +#define KPC_DE (0x1 << 1) /* Direct Keypad Enable */ +#define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */ + +#define KPDK_DKP (0x1 << 31) +#define KPDK_DK7 (0x1 << 7) +#define KPDK_DK6 (0x1 << 6) +#define KPDK_DK5 (0x1 << 5) +#define KPDK_DK4 (0x1 << 4) +#define KPDK_DK3 (0x1 << 3) +#define KPDK_DK2 (0x1 << 2) +#define KPDK_DK1 (0x1 << 1) +#define KPDK_DK0 (0x1 << 0) + +#define KPREC_OF1 (0x1 << 31) +#define kPREC_UF1 (0x1 << 30) +#define KPREC_OF0 (0x1 << 15) +#define KPREC_UF0 (0x1 << 14) + +#define KPMK_MKP (0x1 << 31) +#define KPAS_SO (0x1 << 31) +#define KPASMKPx_SO (0x1 << 31) + +/* + * UHC: USB Host Controller (OHCI-like) register definitions + */ +#define UHC_BASE_PHYS (0x4C000000) +#define UHCREV __REG_2(0x4C000000) /* UHC HCI Spec Revision */ +#define UHCHCON __REG_2(0x4C000004) /* UHC Host Control Register */ +#define UHCCOMS __REG_2(0x4C000008) /* UHC Command Status Register */ +#define UHCINTS __REG_2(0x4C00000C) /* UHC Interrupt Status Register */ +#define UHCINTE __REG_2(0x4C000010) /* UHC Interrupt Enable */ +#define UHCINTD __REG_2(0x4C000014) /* UHC Interrupt Disable */ +#define UHCHCCA __REG_2(0x4C000018) /* UHC Host Controller Comm. Area */ +#define UHCPCED __REG_2(0x4C00001C) /* UHC Period Current Endpt Descr */ +#define UHCCHED __REG_2(0x4C000020) /* UHC Control Head Endpt Descr */ +#define UHCCCED __REG_2(0x4C000024) /* UHC Control Current Endpt Descr */ +#define UHCBHED __REG_2(0x4C000028) /* UHC Bulk Head Endpt Descr */ +#define UHCBCED __REG_2(0x4C00002C) /* UHC Bulk Current Endpt Descr */ +#define UHCDHEAD __REG_2(0x4C000030) /* UHC Done Head */ +#define UHCFMI __REG_2(0x4C000034) /* UHC Frame Interval */ +#define UHCFMR __REG_2(0x4C000038) /* UHC Frame Remaining */ +#define UHCFMN __REG_2(0x4C00003C) /* UHC Frame Number */ +#define UHCPERS __REG_2(0x4C000040) /* UHC Periodic Start */ +#define UHCLS __REG_2(0x4C000044) /* UHC Low Speed Threshold */ +#define UHCRHDA __REG_2(0x4C000048) /* UHC Root Hub Descriptor A */ +#define UHCRHDB __REG_2(0x4C00004C) /* UHC Root Hub Descriptor B */ +#define UHCRHS __REG_2(0x4C000050) /* UHC Root Hub Status */ +#define UHCRHPS1 __REG_2(0x4C000054) /* UHC Root Hub Port 1 Status */ +#define UHCRHPS2 __REG_2(0x4C000058) /* UHC Root Hub Port 2 Status */ +#define UHCRHPS3 __REG_2(0x4C00005C) /* UHC Root Hub Port 3 Status */ +#define UHCRHPS(x) __REG2_2(0x4C000050, (x)<<2) + +#define UHCSTAT __REG_2(0x4C000060) /* UHC Status Register */ +#define UHCSTAT_UPS3 (1 << 16) /* USB Power Sense Port3 */ +#define UHCSTAT_SBMAI (1 << 15) /* System Bus Master Abort Interrupt*/ +#define UHCSTAT_SBTAI (1 << 14) /* System Bus Target Abort Interrupt*/ +#define UHCSTAT_UPRI (1 << 13) /* USB Port Resume Interrupt */ +#define UHCSTAT_UPS2 (1 << 12) /* USB Power Sense Port 2 */ +#define UHCSTAT_UPS1 (1 << 11) /* USB Power Sense Port 1 */ +#define UHCSTAT_HTA (1 << 10) /* HCI Target Abort */ +#define UHCSTAT_HBA (1 << 8) /* HCI Buffer Active */ +#define UHCSTAT_RWUE (1 << 7) /* HCI Remote Wake Up Event */ + +#define UHCHR __REG_2(0x4C000064) /* UHC Reset Register */ +#define UHCHR_SSEP3 (1 << 11) /* Sleep Standby Enable for Port3 */ +#define UHCHR_SSEP2 (1 << 10) /* Sleep Standby Enable for Port2 */ +#define UHCHR_SSEP1 (1 << 9) /* Sleep Standby Enable for Port1 */ +#define UHCHR_PCPL (1 << 7) /* Power control polarity low */ +#define UHCHR_PSPL (1 << 6) /* Power sense polarity low */ +#define UHCHR_SSE (1 << 5) /* Sleep Standby Enable */ +#define UHCHR_UIT (1 << 4) /* USB Interrupt Test */ +#define UHCHR_SSDC (1 << 3) /* Simulation Scale Down Clock */ +#define UHCHR_CGR (1 << 2) /* Clock Generation Reset */ +#define UHCHR_FHR (1 << 1) /* Force Host Controller Reset */ +#define UHCHR_FSBIR (1 << 0) /* Force System Bus Iface Reset */ + +#define UHCHIE __REG_2(0x4C000068) /* UHC Interrupt Enable Register*/ +#define UHCHIE_UPS3IE (1 << 14) /* Power Sense Port3 IntEn */ +#define UHCHIE_UPRIE (1 << 13) /* Port Resume IntEn */ +#define UHCHIE_UPS2IE (1 << 12) /* Power Sense Port2 IntEn */ +#define UHCHIE_UPS1IE (1 << 11) /* Power Sense Port1 IntEn */ +#define UHCHIE_TAIE (1 << 10) /* HCI Interface Transfer Abort + Interrupt Enable*/ +#define UHCHIE_HBAIE (1 << 8) /* HCI Buffer Active IntEn */ +#define UHCHIE_RWIE (1 << 7) /* Remote Wake-up IntEn */ + +#define UHCHIT __REG_2(0x4C00006C) /* UHC Interrupt Test register */ + +/* Camera Interface / Quick Capture Interface */ +#define CICR0 __REG_3(0x50000000) /* Control register 0 */ +#define CICR1 __REG_3(0x50000004) /* Control register 1 */ +#define CICR2 __REG_3(0x50000008) /* Control register 2 */ +#define CICR3 __REG_3(0x5000000C) /* Control register 3 */ +#define CICR4 __REG_3(0x50000010) /* Control register 4 */ +#define CISR __REG_3(0x50000014) /* Status register */ +#define CITOR __REG_3(0x5000001C) /* Time-Out register */ +#define CIBR0 __REG_3(0x50000028) /* Channel 0 Receive Buffer */ +#define CIBR1 __REG_3(0x50000030) /* Channel 1 Receive Buffer */ +#define CIBR2 __REG_3(0x50000038) /* Channel 2 Receive Buffer */ +#define CIBR3 __REG_3(0x50000040) /* Channel 3 Receive Buffer */ + +#define CIPSS __REG_3(0x50000064) /* Pixel Substitution Status register */ +#define CIPBUF __REG_3(0x50000068) /* Pixel Substitution Buffer */ +#define CIHST __REG_3(0x5000006C) /* Histogram Configuration */ +#define CISUM __REG_3(0x50000070) /* Histogram Summation register */ +#define CICCR __REG_3(0x50000074) /* Compander Configuration */ +#define CISSC __REG_3(0x5000007C) /* Spatial Scaling Configuration */ + +#define CICMR __REG_3(0x50000090) /* Color Management register */ +#define CICMC0 __REG_3(0x50000094) /* Color Management Coefficients 0 */ +#define CICMC1 __REG_3(0x50000098) /* Color Management Coefficients 1 */ +#define CICMC2 __REG_3(0x5000009C) /* Color Management Coefficients 2 */ + +#define CIFR0 __REG_3(0x500000B0) /* FIFO Control register 0 */ +#define CIFR1 __REG_3(0x500000B4) /* FIFO Control register 1 */ +#define CIFSR __REG_3(0x500000C0) /* FIFO Status register */ + +#define CIDADR0 __REG_3(0x50000240) /* DMA Descriptor Address Channel 0 register */ +#define CIDADR1 __REG_3(0x50000250) /* DMA Descriptor Address Channel 1 register */ +#define CIDADR2 __REG_3(0x50000260) /* DMA Descriptor Address Channel 2 register */ +#define CIDADR3 __REG_3(0x50000270) /* DMA Descriptor Address Channel 3 register */ +#define CITADR0 __REG_3(0x50000244) /* DMA Target Address Channel 0 register */ +#define CITADR1 __REG_3(0x50000254) /* DMA Target Address Channel 1 register */ +#define CITADR2 __REG_3(0x50000264) /* DMA Target Address Channel 2 register */ +#define CITADR3 __REG_3(0x50000274) /* DMA Target Address Channel 3 register */ +#define CISADR0 __REG_3(0x50000248) /* DMA Source Address Channel 0 register */ +#define CISADR1 __REG_3(0x50000258) /* DMA Source Address Channel 1 register */ +#define CISADR2 __REG_3(0x50000268) /* DMA Source Address Channel 2 register */ +#define CISADR3 __REG_3(0x50000278) /* DMA Source Address Channel 3 register */ +#define CICMD0 __REG_3(0x5000024C) /* DMA Command Channel 0 register*/ +#define CICMD1 __REG_3(0x5000025C) /* DMA Command Channel 1 register*/ +#define CICMD2 __REG_3(0x5000026C) /* DMA Command Channel 2 register*/ +#define CICMD3 __REG_3(0x5000027C) /* DMA Command Channel 3 register*/ +#define CIDBR0 __REG_3(0x50000220) /* DMA Branch Channel 0 register*/ +#define CIDBR1 __REG_3(0x50000224) /* DMA Branch Channel 1 register*/ +#define CIDBR2 __REG_3(0x50000228) /* DMA Branch Channel 2 register*/ +#define CIDBR3 __REG_3(0x5000022C) /* DMA Branch Channel 3 register*/ +#define CIDCSR0 __REG_3(0x50000200) /* DMA Ctrl/Status Channel 0 register*/ +#define CIDCSR1 __REG_3(0x50000204) /* DMA Ctrl/Status Channel 1 register*/ +#define CIDCSR2 __REG_3(0x50000208) /* DMA Ctrl/Status Channel 2 register*/ +#define CIDCSR3 __REG_3(0x5000020C) /* DMA Ctrl/Status Channel 3 register*/ + +#define CICR0_DMAEN (1 << 31) /* DMA request enable */ +#define CICR0_PAR_EN (1 << 30) /* Parity enable */ +#define CICR0_SL_CAP_EN (1 << 29) /* Capture enable for slave mode */ +#define CICR0_ENB (1 << 28) /* Camera interface enable */ +#define CICR0_DIS (1 << 27) /* Camera interface disable */ +#define CICR0_SIM (0x7 << 24) /* Sensor interface mode mask */ +#define CICR0_TOM (1 << 9) /* Time-out mask */ +#define CICR0_RDAVM (1 << 8) /* Receive-data-available mask */ +#define CICR0_FEM (1 << 7) /* FIFO-empty mask */ +#define CICR0_EOLM (1 << 6) /* End-of-line mask */ +#define CICR0_PERRM (1 << 5) /* Parity-error mask */ +#define CICR0_QDM (1 << 4) /* Quick-disable mask */ +#define CICR0_CDM (1 << 3) /* Disable-done mask */ +#define CICR0_SOFM (1 << 2) /* Start-of-frame mask */ +#define CICR0_EOFM (1 << 1) /* End-of-frame mask */ +#define CICR0_FOM (1 << 0) /* FIFO-overrun mask */ + +#define CICR1_TBIT (1 << 31) /* Transparency bit */ +#define CICR1_RGBT_CONV (0x3 << 30) /* RGBT conversion mask */ +#define CICR1_PPL (0x3f << 15) /* Pixels per line mask */ +#define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */ +#define CICR1_RGB_F (1 << 11) /* RGB format */ +#define CICR1_YCBCR_F (1 << 10) /* YCbCr format */ +#define CICR1_RGB_BPP (0x7 << 7) /* RGB bis per pixel mask */ +#define CICR1_RAW_BPP (0x3 << 5) /* Raw bis per pixel mask */ +#define CICR1_COLOR_SP (0x3 << 3) /* Color space mask */ +#define CICR1_DW (0x7 << 0) /* Data width mask */ + +#define CICR2_BLW (0xff << 24) /* Beginning-of-line pixel clock + wait count mask */ +#define CICR2_ELW (0xff << 16) /* End-of-line pixel clock + wait count mask */ +#define CICR2_HSW (0x3f << 10) /* Horizontal sync pulse width mask */ +#define CICR2_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock + wait count mask */ +#define CICR2_FSW (0x7 << 0) /* Frame stabilization + wait count mask */ + +#define CICR3_BFW (0xff << 24) /* Beginning-of-frame line clock + wait count mask */ +#define CICR3_EFW (0xff << 16) /* End-of-frame line clock + wait count mask */ +#define CICR3_VSW (0x3f << 10) /* Vertical sync pulse width mask */ +#define CICR3_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock + wait count mask */ +#define CICR3_LPF (0x3ff << 0) /* Lines per frame mask */ + +#define CICR4_MCLK_DLY (0x3 << 24) /* MCLK Data Capture Delay mask */ +#define CICR4_PCLK_EN (1 << 23) /* Pixel clock enable */ +#define CICR4_PCP (1 << 22) /* Pixel clock polarity */ +#define CICR4_HSP (1 << 21) /* Horizontal sync polarity */ +#define CICR4_VSP (1 << 20) /* Vertical sync polarity */ +#define CICR4_MCLK_EN (1 << 19) /* MCLK enable */ +#define CICR4_FR_RATE (0x7 << 8) /* Frame rate mask */ +#define CICR4_DIV (0xff << 0) /* Clock divisor mask */ + +#define CISR_FTO (1 << 15) /* FIFO time-out */ +#define CISR_RDAV_2 (1 << 14) /* Channel 2 receive data available */ +#define CISR_RDAV_1 (1 << 13) /* Channel 1 receive data available */ +#define CISR_RDAV_0 (1 << 12) /* Channel 0 receive data available */ +#define CISR_FEMPTY_2 (1 << 11) /* Channel 2 FIFO empty */ +#define CISR_FEMPTY_1 (1 << 10) /* Channel 1 FIFO empty */ +#define CISR_FEMPTY_0 (1 << 9) /* Channel 0 FIFO empty */ +#define CISR_EOL (1 << 8) /* End of line */ +#define CISR_PAR_ERR (1 << 7) /* Parity error */ +#define CISR_CQD (1 << 6) /* Camera interface quick disable */ +#define CISR_SOF (1 << 5) /* Start of frame */ +#define CISR_CDD (1 << 4) /* Camera interface disable done */ +#define CISR_EOF (1 << 3) /* End of frame */ +#define CISR_IFO_2 (1 << 2) /* FIFO overrun for Channel 2 */ +#define CISR_IFO_1 (1 << 1) /* FIFO overrun for Channel 1 */ +#define CISR_IFO_0 (1 << 0) /* FIFO overrun for Channel 0 */ + +#define CIFR_FLVL2 (0x7f << 23) /* FIFO 2 level mask */ +#define CIFR_FLVL1 (0x7f << 16) /* FIFO 1 level mask */ +#define CIFR_FLVL0 (0xff << 8) /* FIFO 0 level mask */ +#define CIFR_THL_0 (0x3 << 4) /* Threshold Level for Channel 0 FIFO */ +#define CIFR_RESET_F (1 << 3) /* Reset input FIFOs */ +#define CIFR_FEN2 (1 << 2) /* FIFO enable for channel 2 */ +#define CIFR_FEN1 (1 << 1) /* FIFO enable for channel 1 */ +#define CIFR_FEN0 (1 << 0) /* FIFO enable for channel 0 */ + +#endif /* CONFIG_CPU_MONAHANS */ + +#endif diff --git a/lib_arm/board.c b/lib_arm/board.c index 3048cbe408..9c9eb6826e 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -38,6 +38,8 @@ * FIQ Stack: 00ebef7c */ +#define DEBUG 1 + #include #include #include From af646e865f4bc67623ca957dfe3d3e4a95ff0468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Tue, 7 Feb 2006 20:48:45 +0100 Subject: [PATCH 005/102] Forgot to add files to zylonite branch. --- board/zylonite/Makefile | 48 ++++ board/zylonite/config.mk | 4 + board/zylonite/flash.c | 431 +++++++++++++++++++++++++++++++++ board/zylonite/lowlevel_init.S | 266 ++++++++++++++++++++ board/zylonite/u-boot.lds | 56 +++++ board/zylonite/zylonite.c | 75 ++++++ include/configs/zylonite.h | 242 ++++++++++++++++++ 7 files changed, 1122 insertions(+) create mode 100644 board/zylonite/Makefile create mode 100644 board/zylonite/config.mk create mode 100644 board/zylonite/flash.c create mode 100644 board/zylonite/lowlevel_init.S create mode 100644 board/zylonite/u-boot.lds create mode 100644 board/zylonite/zylonite.c create mode 100644 include/configs/zylonite.h diff --git a/board/zylonite/Makefile b/board/zylonite/Makefile new file mode 100644 index 0000000000..999647f185 --- /dev/null +++ b/board/zylonite/Makefile @@ -0,0 +1,48 @@ + +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := zylonite.o flash.o +SOBJS := lowlevel_init.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) $(SOBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/zylonite/config.mk b/board/zylonite/config.mk new file mode 100644 index 0000000000..09b0f71557 --- /dev/null +++ b/board/zylonite/config.mk @@ -0,0 +1,4 @@ +#TEXT_BASE = 0x0 +#TEXT_BASE = 0xa1700000 +#TEXT_BASE = 0xa3080000 +TEXT_BASE = 0xa3008000 diff --git a/board/zylonite/flash.c b/board/zylonite/flash.c new file mode 100644 index 0000000000..ba82892dde --- /dev/null +++ b/board/zylonite/flash.c @@ -0,0 +1,431 @@ +/* + * (C) Copyright 2001 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/* Board support for 1 or 2 flash devices */ +#define FLASH_PORT_WIDTH32 +#undef FLASH_PORT_WIDTH16 + +#ifdef FLASH_PORT_WIDTH16 +#define FLASH_PORT_WIDTH ushort +#define FLASH_PORT_WIDTHV vu_short +#define SWAP(x) __swab16(x) +#else +#define FLASH_PORT_WIDTH ulong +#define FLASH_PORT_WIDTHV vu_long +#define SWAP(x) __swab32(x) +#endif + +#define FPW FLASH_PORT_WIDTH +#define FPWV FLASH_PORT_WIDTHV + +#define mb() __asm__ __volatile__ ("" : : : "memory") + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (FPW *addr, flash_info_t *info); +static int write_data (flash_info_t *info, ulong dest, FPW data); +static void flash_get_offsets (ulong base, flash_info_t *info); +void inline spin_wheel (void); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + int i; + ulong size = 0; + + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { + switch (i) { + case 0: + flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]); + flash_get_offsets (PHYS_FLASH_1, &flash_info[i]); + break; + case 1: + flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]); + flash_get_offsets (PHYS_FLASH_2, &flash_info[i]); + break; + default: + panic ("configured too many flash banks!\n"); + break; + } + size += flash_info[i].size; + } + + /* Protect monitor and environment sectors + */ + flash_protect ( FLAG_PROTECT_SET, + CFG_FLASH_BASE, + CFG_FLASH_BASE + monitor_flash_len - 1, + &flash_info[0] ); + + flash_protect ( FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] ); + + return size; +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + return; + } + + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { + for (i = 0; i < info->sector_count; i++) { + info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE); + info->protect[i] = 0; + } + } +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: + printf ("INTEL "); + break; + default: + printf ("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F128J3A: + printf ("28F128J3A\n"); + break; + default: + printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " "); + } + printf ("\n"); + return; +} + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (FPW *addr, flash_info_t *info) +{ + volatile FPW value; + + /* Write auto select command: read Manufacturer ID */ + addr[0x5555] = (FPW) 0x00AA00AA; + addr[0x2AAA] = (FPW) 0x00550055; + addr[0x5555] = (FPW) 0x00900090; + + mb (); + value = addr[0]; + + switch (value) { + + case (FPW) INTEL_MANUFACT: + info->flash_id = FLASH_MAN_INTEL; + break; + + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ + return (0); /* no or unknown flash */ + } + + mb (); + value = addr[1]; /* device ID */ + + switch (value) { + + case (FPW) INTEL_ID_28F128J3A: + info->flash_id += FLASH_28F128J3A; + info->sector_count = 128; + info->size = 0x02000000; + break; /* => 16 MB */ + + default: + info->flash_id = FLASH_UNKNOWN; + break; + } + + if (info->sector_count > CFG_MAX_FLASH_SECT) { + printf ("** ERROR: sector count %d > max (%d) **\n", + info->sector_count, CFG_MAX_FLASH_SECT); + info->sector_count = CFG_MAX_FLASH_SECT; + } + + addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ + + return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + int flag, prot, sect; + ulong type, start, last; + int rcode = 0; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + type = (info->flash_id & FLASH_VENDMASK); + if ((type != FLASH_MAN_INTEL)) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + start = get_timer (0); + last = start; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + FPWV *addr = (FPWV *) (info->start[sect]); + FPW status; + + printf ("Erasing sector %2d ... ", sect); + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked (); + + *addr = (FPW) 0x00500050; /* clear status register */ + *addr = (FPW) 0x00200020; /* erase setup */ + *addr = (FPW) 0x00D000D0; /* erase confirm */ + + while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { + if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + *addr = (FPW) 0x00B000B0; /* suspend erase */ + *addr = (FPW) 0x00FF00FF; /* reset to read mode */ + rcode = 1; + break; + } + } + + *addr = 0x00500050; /* clear status register cmd. */ + *addr = 0x00FF00FF; /* resest to read mode */ + + printf (" done\n"); + } + } + return rcode; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - Flash not identified + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp; + FPW data; + int count, i, l, rc, port_width; + + if (info->flash_id == FLASH_UNKNOWN) { + return 4; + } +/* get lower word aligned address */ +#ifdef FLASH_PORT_WIDTH16 + wp = (addr & ~1); + port_width = 2; +#else + wp = (addr & ~3); + port_width = 4; +#endif + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + for (; i < port_width && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt == 0 && i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + if ((rc = write_data (info, wp, SWAP (data))) != 0) { + return (rc); + } + wp += port_width; + } + + /* + * handle word aligned part + */ + count = 0; + while (cnt >= port_width) { + data = 0; + for (i = 0; i < port_width; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_data (info, wp, SWAP (data))) != 0) { + return (rc); + } + wp += port_width; + cnt -= port_width; + if (count++ > 0x800) { + spin_wheel (); + count = 0; + } + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + return (write_data (info, wp, SWAP (data))); +} + +/*----------------------------------------------------------------------- + * Write a word or halfword to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_data (flash_info_t *info, ulong dest, FPW data) +{ + FPWV *addr = (FPWV *) dest; + ulong status; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & data) != data) { + printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr); + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + *addr = (FPW) 0x00400040; /* write setup */ + *addr = data; + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked (); + + /* wait while polling the status register */ + while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { + if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) { + *addr = (FPW) 0x00FF00FF; /* restore read mode */ + return (1); + } + } + + *addr = (FPW) 0x00FF00FF; /* restore read mode */ + + return (0); +} + +void inline spin_wheel (void) +{ + static int p = 0; + static char w[] = "\\/-"; + + printf ("\010%c", w[p]); + (++p == 3) ? (p = 0) : 0; +} diff --git a/board/zylonite/lowlevel_init.S b/board/zylonite/lowlevel_init.S new file mode 100644 index 0000000000..54c2adfaf3 --- /dev/null +++ b/board/zylonite/lowlevel_init.S @@ -0,0 +1,266 @@ +/* + * Most of this taken from Redboot hal_platform_setup.h with cleanup + * + * NOTE: I haven't clean this up considerably, just enough to get it + * running. See hal_platform_setup.h for the source. See + * board/cradle/lowlevel_init.S for another PXA250 setup that is + * much cleaner. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +DRAM_SIZE: .long CFG_DRAM_SIZE + +/* wait for coprocessor write complete */ + .macro CPWAIT reg + mrc p15,0,\reg,c2,c0,0 + mov \reg,\reg + sub pc,pc,#4 + .endm + + +/* + * Memory setup + */ + +.globl lowlevel_init +lowlevel_init: + /* Set up GPIO pins first ----------------------------------------- */ + mov r10, lr + + /* GPIO41, 42, 43, 44, 45, 46, 47, 48 */ + ldr r0, =0x40E10438 @ GPIO41 FFRXD + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E1043C @ GPIO42 FFTXD + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E10440 @ GPIO43 FFCTS + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E10444 @ GPIO 44 FFDCD + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E10448 @ GPIO 45 FFDSR + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E1044C @ GPIO 46 FFRI + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E10450 @ GPIO 47 FFDTR + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E10454 @ GPIO 48 + ldr r1, =0x802 + str r1, [r0] + + /* tebrandt - ASCR, clear the RDH bit */ + ldr r0, =ASCR + ldr r1, [r0] + bic r1, r1, #0x80000000 + str r1, [r0] + + /* ---------------------------------------------------------------- */ + /* Enable memory interface */ + /* */ + /* The sequence below is based on the recommended init steps */ + /* detailed in the Intel PXA250 Operating Systems Developers Guide, */ + /* Chapter 10. */ + /* ---------------------------------------------------------------- */ + + /* ---------------------------------------------------------------- */ + /* Step 1: Wait for at least 200 microsedonds to allow internal */ + /* clocks to settle. Only necessary after hard reset... */ + /* FIXME: can be optimized later */ + /* ---------------------------------------------------------------- */ + + ldr r3, =OSCR /* reset the OS Timer Count to zero */ + mov r2, #0 + str r2, [r3] + ldr r4, =0x300 /* really 0x2E1 is about 200usec, */ + /* so 0x300 should be plenty */ +1: + ldr r2, [r3] + cmp r4, r2 + bgt 1b + +mem_init: + + /* configure the MEMCLKCFG register */ + ldr r1, =MEMCLKCFG + ldr r2, =0x00010001 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set CSADRCFG[0] to data flash SRAM mode */ + ldr r1, =CSADRCFG0 + ldr r2, =0x00320809 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set CSADRCFG[1] to data flash SRAM mode */ + ldr r1, =CSADRCFG1 + ldr r2, =0x00320809 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set MSC 0 register for SRAM memory */ + ldr r1, =MSC0 + ldr r2, =0x11191119 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set CSADRCFG[2] to data flash SRAM mode */ + ldr r1, =CSADRCFG2 + ldr r2, =0x00320809 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set CSADRCFG[3] to VLIO mode */ + ldr r1, =CSADRCFG3 + ldr r2, =0x0032080B + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set MSC 1 register for VLIO memory */ + ldr r1, =MSC1 + ldr r2, =0x123C1119 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + +#if 0 + /* This does not work in Zylonite. -SC */ + ldr r0, =0x15fffff0 + ldr r1, =0xb10b + str r1, [r0] + str r1, [r0, #4] +#endif + + /* Configure ACCR Register */ + ldr r0, =ACCR @ ACCR + ldr r1, =0x0180b108 + str r1, [r0] + ldr r1, [r0] + + /* Configure MDCNFG Register */ + ldr r0, =MDCNFG @ MDCNFG + ldr r1, =0x403 + str r1, [r0] + ldr r1, [r0] + + /* Perform Resistive Compensation by configuring RCOMP register */ + ldr r1, =RCOMP @ RCOMP + ldr r2, =0x000000ff + str r2, [r1] + ldr r2, [r1] + + /* Configure MDMRS Register for SDCS0 */ + ldr r1, =MDMRS @ MDMRS + ldr r2, =0x60000023 + ldr r3, [r1] + orr r2, r2, r3 + str r2, [r1] + ldr r2, [r1] + + /* Configure MDMRS Register for SDCS1 */ + ldr r1, =MDMRS @ MDMRS + ldr r2, =0xa0000023 + ldr r3, [r1] + orr r2, r2, r3 + str r2, [r1] + ldr r2, [r1] + + /* Configure MDREFR */ + ldr r1, =MDREFR @ MDREFR + ldr r2, =0x00000006 + str r2, [r1] + ldr r2, [r1] + + /* Configure EMPI */ + ldr r1, =EMPI @ EMPI + ldr r2, =0x80000000 + str r2, [r1] + ldr r2, [r1] + + /* DDR Read-Strobe Delay Calibration */ + /* bl ddr_calibration */ + + /* Here we assume the hardware calibration alwasy be successful. -SC */ + /* Set DMCEN bit in MDCNFG Register */ + ldr r0, =MDCNFG @ MDCNFG + ldr r1, [r0] + orr r1, r1, #0x40000000 @ enable SDRAM for Normal Access + str r1, [r0] + + /* scrub/init SDRAM if enabled/present */ + ldr r11, =0xa0000000 //RAM_BASE // base address of SDRAM + ldr r12, =0x04000000 // size of memory to scrub + mov r8,r12 // save DRAM size + mov r0, #0 // scrub with 0x0000:0000 + mov r1, #0 + mov r2, #0 + mov r3, #0 + mov r4, #0 + mov r5, #0 + mov r6, #0 + mov r7, #0 +10: /* fastScrubLoop */ + subs r12, r12, #32 // 32 bytes/line + stmia r11!, {r0-r7} + beq 15f + b 10b + +15: + /* Mask all interrupts */ + mov r1, #0 + mcr p6, 0, r1, c1, c0, 0 @ ICMR + + /* Disable software and data breakpoints */ + mov r0, #0 + mcr p15,0,r0,c14,c8,0 // ibcr0 + mcr p15,0,r0,c14,c9,0 // ibcr1 + mcr p15,0,r0,c14,c4,0 // dbcon + + /* Enable all debug functionality */ + mov r0,#0x80000000 + mcr p14,0,r0,c10,c0,0 // dcsr + + + + /* We are finished with Intel's memory controller initialisation */ + + + /* ---------------------------------------------------------------- */ + /* End lowlevel_init */ + /* ---------------------------------------------------------------- */ + +endlowlevel_init: + + mov pc, lr diff --git a/board/zylonite/u-boot.lds b/board/zylonite/u-boot.lds new file mode 100644 index 0000000000..f0102391b3 --- /dev/null +++ b/board/zylonite/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/pxa/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} diff --git a/board/zylonite/zylonite.c b/board/zylonite/zylonite.c new file mode 100644 index 0000000000..e618ab96a1 --- /dev/null +++ b/board/zylonite/zylonite.c @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2002 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +/* ------------------------------------------------------------------------- */ + + +/* + * Miscelaneous platform dependent initialisations + */ + +int board_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + /* memory and cpu-speed are setup before relocation */ + /* so we do _nothing_ here */ + + /* arch number of Lubbock-Board */ + gd->bd->bi_arch_number = MACH_TYPE_LUBBOCK; + + /* adress of boot parameters */ + gd->bd->bi_boot_params = 0xa0000100; + + return 0; +} + +int board_late_init(void) +{ + setenv("stdout", "serial"); + setenv("stderr", "serial"); + return 0; +} + + +int dram_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; + gd->bd->bi_dram[2].start = PHYS_SDRAM_3; + gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE; + gd->bd->bi_dram[3].start = PHYS_SDRAM_4; + gd->bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE; + + return 0; +} diff --git a/include/configs/zylonite.h b/include/configs/zylonite.h new file mode 100644 index 0000000000..99d6a93959 --- /dev/null +++ b/include/configs/zylonite.h @@ -0,0 +1,242 @@ +/* + * (C) Copyright 2002 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * Configuation settings for the Zylonite board. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ +#define CONFIG_CPU_MONAHANS 1 /* Intel Monahan CPU */ +#define CONFIG_ZYLONITE 1 /* Zylonite board */ +/* #define CONFIG_LCD 1 */ +#ifdef CONFIG_LCD +#define CONFIG_SHARP_LM8V31 +#endif +/* #define CONFIG_MMC 1 */ +#define BOARD_LATE_INIT 1 + +#undef CONFIG_SKIP_RELOCATE_UBOOT +#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ + +/* + * Size of malloc() pool + */ +#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ + +/* + * Hardware drivers + */ +/* #define CONFIG_DRIVER_LAN91C96 */ +/* #define CONFIG_LAN91C96_BASE 0x0C000000 */ + +/* + * select serial console configuration + */ +#define CONFIG_FFUART 1 /* we use FFUART on LUBBOCK */ + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_BAUDRATE 115200 + +/* #define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_MMC | CFG_CMD_FAT) */ +#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_REISER & ~CFG_CMD_NET) + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ETHADDR 08:00:3e:26:0a:5b +#define CONFIG_NETMASK 255.255.0.0 +#define CONFIG_IPADDR 192.168.0.21 +#define CONFIG_SERVERIP 192.168.0.250 +#define CONFIG_BOOTCOMMAND "bootm 80000" +#define CONFIG_BOOTARGS "root=/dev/mtdblock2 rootfstype=cramfs console=ttyS0,115200" +#define CONFIG_CMDLINE_TAG +#define CONFIG_TIMESTAMP + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + +/* + * Miscellaneous configurable options + */ +#define CFG_HUSH_PARSER 1 +#define CFG_PROMPT_HUSH_PS2 "> " + +#define CFG_LONGHELP /* undef to save memory */ +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT "$ " /* Monitor Command Prompt */ +#else +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#endif +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_DEVICE_NULLDEV 1 + +#define CFG_MEMTEST_START 0xa0400000 /* memtest works on */ +#define CFG_MEMTEST_END 0xa0800000 /* 4 ... 8 MB in DRAM */ + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +#define CFG_LOAD_ADDR (CFG_DRAM_BASE + 0x8000) /* default load address */ + +#define CFG_HZ 3686400 /* incrementer freq: 3.6864 MHz */ +#define CFG_CPUSPEED 0x161 /* set core clock to 400/200/100 MHz */ + + /* valid baudrates */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* #define CFG_MMC_BASE 0xF0000000 */ + +/* + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ +#endif + +/* + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 4 /* we have 2 banks of DRAM */ +#define PHYS_SDRAM_1 0xa0000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */ +#define PHYS_SDRAM_2 0xa4000000 /* SDRAM Bank #2 */ +#define PHYS_SDRAM_2_SIZE 0x00000000 /* 0 MB */ +#define PHYS_SDRAM_3 0xa8000000 /* SDRAM Bank #3 */ +#define PHYS_SDRAM_3_SIZE 0x00000000 /* 0 MB */ +#define PHYS_SDRAM_4 0xac000000 /* SDRAM Bank #4 */ +#define PHYS_SDRAM_4_SIZE 0x00000000 /* 0 MB */ + +#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ +#define PHYS_FLASH_2 0x04000000 /* Flash Bank #2 */ +#define PHYS_FLASH_SIZE 0x02000000 /* 32 MB */ +#define PHYS_FLASH_BANK_SIZE 0x02000000 /* 32 MB Banks */ +#define PHYS_FLASH_SECT_SIZE 0x00040000 /* 256 KB sectors (x2) */ + +#define CFG_DRAM_BASE 0xa0000000 +#define CFG_DRAM_SIZE 0x04000000 + +#define CFG_FLASH_BASE PHYS_FLASH_1 + +#define FPGA_REGS_BASE_PHYSICAL 0x08000000 + +/* + * GPIO settings + */ +#define CFG_GPSR0_VAL 0x00008000 +#define CFG_GPSR1_VAL 0x00FC0382 +#define CFG_GPSR2_VAL 0x0001FFFF +#define CFG_GPCR0_VAL 0x00000000 +#define CFG_GPCR1_VAL 0x00000000 +#define CFG_GPCR2_VAL 0x00000000 +#define CFG_GPDR0_VAL 0x0060A800 +#define CFG_GPDR1_VAL 0x00FF0382 +#define CFG_GPDR2_VAL 0x0001C000 +#define CFG_GAFR0_L_VAL 0x98400000 +#define CFG_GAFR0_U_VAL 0x00002950 +#define CFG_GAFR1_L_VAL 0x000A9558 +#define CFG_GAFR1_U_VAL 0x0005AAAA +#define CFG_GAFR2_L_VAL 0xA0000000 +#define CFG_GAFR2_U_VAL 0x00000002 + +#define CFG_PSSR_VAL 0x20 + +/* + * Memory settings + */ +#define CFG_MSC0_VAL 0x23F223F2 +#define CFG_MSC1_VAL 0x3FF1A441 +#define CFG_MSC2_VAL 0x7FF97FF1 +#define CFG_MDCNFG_VAL 0x00001AC9 +#define CFG_MDREFR_VAL 0x00018018 +#define CFG_MDMRS_VAL 0x00000000 + +/* + * PCMCIA and CF Interfaces + */ +#define CFG_MECR_VAL 0x00000000 +#define CFG_MCMEM0_VAL 0x00010504 +#define CFG_MCMEM1_VAL 0x00010504 +#define CFG_MCATT0_VAL 0x00010504 +#define CFG_MCATT1_VAL 0x00010504 +#define CFG_MCIO0_VAL 0x00004715 +#define CFG_MCIO1_VAL 0x00004715 + +#define _LED 0x08000010 +#define LED_BLANK 0x08000040 + +/* + * FLASH and environment organization + */ +#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ + +/* timeout values are in ticks */ +#define CFG_FLASH_ERASE_TOUT (25*CFG_HZ) /* Timeout for Flash Erase */ +#define CFG_FLASH_WRITE_TOUT (25*CFG_HZ) /* Timeout for Flash Write */ + +/* NOTE: many default partitioning schemes assume the kernel starts at the + * second sector, not an environment. You have been warned! + */ +#define CFG_MONITOR_LEN PHYS_FLASH_SECT_SIZE +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_ENV_ADDR (PHYS_FLASH_1 + PHYS_FLASH_SECT_SIZE) +#define CFG_ENV_SECT_SIZE PHYS_FLASH_SECT_SIZE +#define CFG_ENV_SIZE (PHYS_FLASH_SECT_SIZE / 16) + + +/* + * FPGA Offsets + */ +#define WHOAMI_OFFSET 0x00 +#define HEXLED_OFFSET 0x10 +#define BLANKLED_OFFSET 0x40 +#define DISCRETELED_OFFSET 0x40 +#define CNFG_SWITCHES_OFFSET 0x50 +#define USER_SWITCHES_OFFSET 0x60 +#define MISC_WR_OFFSET 0x80 +#define MISC_RD_OFFSET 0x90 +#define INT_MASK_OFFSET 0xC0 +#define INT_CLEAR_OFFSET 0xD0 +#define GP_OFFSET 0x100 + +#endif /* __CONFIG_H */ From 9d803d8c0b7fd9aeb2e708e9e48dd76d7287856d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Wed, 8 Feb 2006 18:56:28 +0100 Subject: [PATCH 006/102] Changes: * lots of bugfixes in the assembler code * reverted hardware.h back to original * enabled hardware DRAM calibration * GCC-4 fix: modified GLOBAL_DATA_POINTER macro --- board/zylonite/lowlevel_init.S | 149 ++++++++++++++++++++++---- include/asm-arm/arch-pxa/hardware.h | 159 +++++++++++----------------- include/asm-arm/global_data.h | 7 +- 3 files changed, 199 insertions(+), 116 deletions(-) diff --git a/board/zylonite/lowlevel_init.S b/board/zylonite/lowlevel_init.S index 54c2adfaf3..4d62be5d5e 100644 --- a/board/zylonite/lowlevel_init.S +++ b/board/zylonite/lowlevel_init.S @@ -39,6 +39,16 @@ DRAM_SIZE: .long CFG_DRAM_SIZE .endm +.macro wait time + ldr r2, =OSCR + mov r3, #0 + str r3, [r2] +0: + ldr r3, [r2] + cmp r3, \time + bls 0b +.endm + /* * Memory setup */ @@ -48,7 +58,7 @@ lowlevel_init: /* Set up GPIO pins first ----------------------------------------- */ mov r10, lr - /* GPIO41, 42, 43, 44, 45, 46, 47, 48 */ + /* Configure GPIO Pins 41 - 48 as UART1 / altern. Fkt. 2 */ ldr r0, =0x40E10438 @ GPIO41 FFRXD ldr r1, =0x802 str r1, [r0] @@ -82,7 +92,7 @@ lowlevel_init: str r1, [r0] /* tebrandt - ASCR, clear the RDH bit */ - ldr r0, =ASCR + ldr r0, =ASCR ldr r1, [r0] bic r1, r1, #0x80000000 str r1, [r0] @@ -101,16 +111,18 @@ lowlevel_init: /* FIXME: can be optimized later */ /* ---------------------------------------------------------------- */ - ldr r3, =OSCR /* reset the OS Timer Count to zero */ - mov r2, #0 - str r2, [r3] - ldr r4, =0x300 /* really 0x2E1 is about 200usec, */ - /* so 0x300 should be plenty */ -1: - ldr r2, [r3] - cmp r4, r2 - bgt 1b - + /* mk: replaced with wait macro */ +/* ldr r3, =OSCR /\* reset the OS Timer Count to zero *\/ */ +/* mov r2, #0 */ +/* str r2, [r3] */ +/* ldr r4, =0x300 /\* really 0x2E1 is about 200usec, *\/ */ +/* /\* so 0x300 should be plenty *\/ */ +/* 1: */ +/* ldr r2, [r3] */ +/* cmp r4, r2 */ +/* bgt 1b */ + wait #300 + mem_init: /* configure the MEMCLKCFG register */ @@ -209,8 +221,12 @@ mem_init: str r2, [r1] ldr r2, [r1] - /* DDR Read-Strobe Delay Calibration */ - /* bl ddr_calibration */ + /* Hardware DDR Read-Strobe Delay Calibration */ + ldr r0, =DDR_HCAL @ DDR_HCAL + ldr r1, =0x803ffc07 @ the offset is correct? -SC + str r1, [r0] + wait #5 + ldr r1, [r0] /* Here we assume the hardware calibration alwasy be successful. -SC */ /* Set DMCEN bit in MDCNFG Register */ @@ -220,10 +236,12 @@ mem_init: str r1, [r0] /* scrub/init SDRAM if enabled/present */ - ldr r11, =0xa0000000 //RAM_BASE // base address of SDRAM - ldr r12, =0x04000000 // size of memory to scrub - mov r8,r12 // save DRAM size - mov r0, #0 // scrub with 0x0000:0000 +/* ldr r11, =0xa0000000 /\* base address of SDRAM (CFG_DRAM_BASE) *\/ */ +/* ldr r12, =0x04000000 /\* size of memory to scrub (CFG_DRAM_SIZE) *\/ */ +/* mov r8,r12 /\* save DRAM size (mk: why???) *\/ */ + ldr r8, =0xa0000000 /* base address of SDRAM (CFG_DRAM_BASE) */ + ldr r9, =0x04000000 /* size of memory to scrub (CFG_DRAM_SIZE) */ + mov r0, #0 /* scrub with 0x0000:0000 */ mov r1, #0 mov r2, #0 mov r3, #0 @@ -232,8 +250,8 @@ mem_init: mov r6, #0 mov r7, #0 10: /* fastScrubLoop */ - subs r12, r12, #32 // 32 bytes/line - stmia r11!, {r0-r7} + subs r9, r9, #32 // 32 bytes/line + stmia r8!, {r0-r7} beq 15f b 10b @@ -264,3 +282,94 @@ mem_init: endlowlevel_init: mov pc, lr + + +/* +@******************************************************************************** +@ DDR calibration +@ +@ This function is used to calibrate DQS delay lines. +@ Monahans supports three ways to do it. One is software +@ calibration. Two is hardware calibration. Three is hybrid +@ calibration. +@ +@ TBD +@ -SC +ddr_calibration: + + @ Case 1: Write the correct delay value once + @ Configure DDR_SCAL Register + ldr r0, =DDR_SCAL @ DDR_SCAL +q ldr r1, =0xaf2f2f2f + str r1, [r0] + ldr r1, [r0] +*/ +/* @ Case 2: Software Calibration + @ Write test pattern to memory + ldr r5, =0x0faf0faf @ Data Pattern + ldr r4, =0xa0000000 @ DDR ram + str r5, [r4] + + mov r1, =0x0 @ delay count + mov r6, =0x0 + mov r7, =0x0 +ddr_loop1: + add r1, r1, =0x1 + cmp r1, =0xf + ble end_loop + mov r3, r1 + mov r0, r1, lsl #30 + orr r3, r3, r0 + mov r0, r1, lsl #22 + orr r3, r3, r0 + mov r0, r1, lsl #14 + orr r3, r3, r0 + orr r3, r3, =0x80000000 + ldr r2, =DDR_SCAL + str r3, [r2] + + ldr r2, [r4] + cmp r2, r5 + bne ddr_loop1 + mov r6, r1 +ddr_loop2: + add r1, r1, =0x1 + cmp r1, =0xf + ble end_loop + mov r3, r1 + mov r0, r1, lsl #30 + orr r3, r3, r0 + mov r0, r1, lsl #22 + orr r3, r3, r0 + mov r0, r1, lsl #14 + orr r3, r3, r0 + orr r3, r3, =0x80000000 + ldr r2, =DDR_SCAL + str r3, [r2] + + ldr r2, [r4] + cmp r2, r5 + be ddr_loop2 + mov r7, r2 + + add r3, r6, r7 + lsr r3, r3, =0x1 + mov r0, r1, lsl #30 + orr r3, r3, r0 + mov r0, r1, lsl #22 + orr r3, r3, r0 + mov r0, r1, lsl #14 + orr r3, r3, r0 + orr r3, r3, =0x80000000 + ldr r2, =DDR_SCAL + +end_loop: + + @ Case 3: Hardware Calibratoin + ldr r0, =DDR_HCAL @ DDR_HCAL + ldr r1, =0x803ffc07 @ the offset is correct? -SC + str r1, [r0] + wait #5 + ldr r1, [r0] + mov pc, lr +*/ diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index a12aea14c4..c8c479a186 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -8,6 +8,11 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. + * + * Note: This file was taken from linux-2.4.19-rmk4-pxa1 + * + * - 2003/01/20 implementation specifics activated + * Robert Schwebel */ #ifndef __ASM_ARCH_HARDWARE_H @@ -16,6 +21,16 @@ #include #include + +/* + * These are statically mapped PCMCIA IO space for designs using it as a + * generic IO bus, typically with ISA parts, hardwired IDE interfaces, etc. + * The actual PCMCIA code is mapping required IO region at run time. + */ +#define PCMCIA_IO_0_BASE 0xf6000000 +#define PCMCIA_IO_1_BASE 0xf7000000 + + /* * We requires absolute addresses. */ @@ -29,63 +44,22 @@ #define UNCACHED_ADDR UNCACHED_PHYS_0 /* - * Intel PXA2xx internal register mapping: + * Intel PXA internal I/O mappings: * - * 0x40000000 - 0x41ffffff <--> 0xf2000000 - 0xf3ffffff - * 0x44000000 - 0x45ffffff <--> 0xf4000000 - 0xf5ffffff - * 0x48000000 - 0x49ffffff <--> 0xf6000000 - 0xf7ffffff - * 0x4c000000 - 0x4dffffff <--> 0xf8000000 - 0xf9ffffff - * 0x50000000 - 0x51ffffff <--> 0xfa000000 - 0xfbffffff - * 0x54000000 - 0x55ffffff <--> 0xfc000000 - 0xfdffffff - * 0x58000000 - 0x59ffffff <--> 0xfe000000 - 0xffffffff - * - * Note that not all PXA2xx chips implement all those addresses, and the - * kernel only maps the minimum needed range of this mapping. - */ -#ifndef CONFIG_CPU_MONAHANS -#define io_p2v(x) (0xf2000000 + ((x) & 0x01ffffff) + (((x) & 0x1c000000) >> 1)) -#define io_v2p(x) (0x3c000000 + ((x) & 0x01ffffff) + (((x) & 0x0e000000) << 1)) -#else - -/* There are too many IO area needed to map, so I divide them into 3 areas - * 0x40000000 - 0x41ffffff <--> 0xf6000000 - 0xf7ffffff Devs - */ -#define io_p2v(x) ((((x) & 0xfc000000)>>4) + 0xf2000000 + ((x)&0x01ffffff)) -#define io_v2p(x) (((((x) - 0xf2000000)&0xfc000000)<<4) + ((x)&0x01ffffff)) - -/* - * 0x42000000 - 0x421fffff <--> 0xf8000000 - 0xf81fffff MMC2 & USIM2 - * 0x43000000 - 0x430fffff <--> 0xf8200000 - 0xf82fffff Caddo - * 0x43100000 - 0x431fffff <--> 0xf8300000 - 0xf83fffff NAND - * 0x44000000 - 0x440fffff <--> 0xf8400000 - 0xf84fffff LCD - * 0x46000000 - 0x460fffff <--> 0xf8800000 - 0xf88fffff Mini LCD - * 0x48100000 - 0x481fffff <--> 0xf8d00000 - 0xf8dfffff Dynamic Mem Ctl - * 0x4a000000 - 0x4a0fffff <--> 0xf9000000 - 0xf90fffff Static Mem Ctl - * 0x4c000000 - 0x4c0fffff <--> 0xf9400000 - 0xf94fffff USB Host + * 0x40000000 - 0x41ffffff <--> 0xf8000000 - 0xf9ffffff + * 0x44000000 - 0x45ffffff <--> 0xfa000000 - 0xfbffffff + * 0x48000000 - 0x49ffffff <--> 0xfc000000 - 0xfdffffff */ -#define io_p2v_2(x) (((((x) - 0x42000000) & 0xff000000) >> 3) + 0xf8000000\ - + ((x) & 0x001fffff)) -#define io_v2p_2(x) (((((x) & 0xffe00000) - 0xf8000000) << 3) + 0x42000000\ - + (x & 0x001fffff)) -/* - * 0x50000000 - 0x500fffff <--> 0xfa000000 - 0xfa0fffff Camera Interface - * 0x54000000 - 0x540fffff <--> 0xfa400000 - 0xfa4fffff 2D Graphics Ctrl - * 0x54100000 - 0x541fffff <--> 0xfa500000 - 0xfa5fffff USB Device 2.0 Ctrl - * 0x58000000 - 0x580fffff <--> 0xfa800000 - 0xfa8fffff Internal SRAM Ctrl - */ - -#define io_p2v_3(x) ((((x) & 0xfc000000) >> 4) + 0xf5000000 + \ - ((x) & 0x001fffff)) -#define io_v2p_3(x) (((((x) - 0xf5000000) & 0x0fc00000) << 4) + \ - ((x) & 0x001fffff)) -#endif /* CONFIG_CPU_MONAHANS */ +/* FIXME: Only this does work for u-boot... find out why... [RS] */ +#define UBOOT_REG_FIX 1 +#ifndef UBOOT_REG_FIX #ifndef __ASSEMBLY__ -#if 0 -# define __REG(x) (*((volatile u32 *)io_p2v(x))) -#else +#define io_p2v(x) ( ((x) | 0xbe000000) ^ (~((x) >> 1) & 0x06000000) ) +#define io_v2p( x ) ( ((x) & 0x41ffffff) ^ ( ((x) & 0x06000000) << 1) ) + /* * This __REG() version gives the same results as the one above, except * that we are fooling gcc somehow so it generates far better and smaller @@ -96,56 +70,66 @@ typedef struct { volatile u32 offset[4096]; } __regbase; # define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2] # define __REG(x) __REGP(io_p2v(x)) +#endif -/* __REG_2 is for NAND, LCD etc. - * __REG_3 is for Camera Interface, 2D Graphics, U2D etc.*/ -#ifdef CONFIG_CPU_MONAHANS -#define __REG_2(x) __REGP(io_p2v_2(x)) -#define __REG_3(x) __REGP(io_p2v_3(x)) - -#endif /* CONFIG_CPU_MONAHANS */ -#endif /* if 0 */ - -/* With indexed regs we don't want to feed the index through io_p2v() - especially if it is a variable, otherwise horrible code will result. */ -# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y))) +/* Let's kick gcc's ass again... */ +# define __REG2(x,y) \ + ( __builtin_constant_p(y) ? (__REG((x) + (y))) \ + : (*(volatile u32 *)((u32)&__REG(x) + (y))) ) # define __PREG(x) (io_v2p((u32)&(x))) -#else /* ifndef __ASSEMBLY__ */ +#else # define __REG(x) io_p2v(x) # define __PREG(x) io_v2p(x) -#ifdef CONFIG_CPU_MONAHANS -# define __REG_2(x) io_p2v(x) -# define __REG_3(x) io_p2v(x) -#endif /* CONFIG_CPU_MONAHANS */ +# undef io_p2v +# undef __REG +# ifndef __ASSEMBLY__ +# define io_p2v(PhAdd) (PhAdd) +# define __REG(x) (*((volatile u32 *)io_p2v(x))) +# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y))) +# else +# define __REG(x) (x) +# ifdef CONFIG_CPU_MONAHANS /* Hack to make this work with mona's pxa-regs.h */ +# define __REG_2(x) (x) +# define __REG_3(x) (x) +# endif +# endif +#endif /* UBOOT_REG_FIX */ -#endif /* ifndef __ASSEMBLY__ */ +#include "pxa-regs.h" #ifndef __ASSEMBLY__ -#ifdef CONFIG_MACH_ZYLONITE -#include "zylonite.h" -#endif +/* + * GPIO edge detection for IRQs: + * IRQs are generated on Falling-Edge, Rising-Edge, or both. + * This must be called *before* the corresponding IRQ is registered. + * Use this instead of directly setting GRER/GFER. + */ +#define GPIO_FALLING_EDGE 1 +#define GPIO_RISING_EDGE 2 +#define GPIO_BOTH_EDGES 3 +extern void set_GPIO_IRQ_edge( int gpio_nr, int edge_mask ); /* * Handy routine to set GPIO alternate functions */ -extern void pxa_gpio_mode( int gpio_mode ); +extern void set_GPIO_mode( int gpio_mode ); /* - * Routine to enable or disable CKEN + * return current lclk frequency in units of 10kHz */ -extern void pxa_set_cken(int clock, int enable); +extern unsigned int get_lclk_frequency_10khz(void); + +#endif + /* - * return current memory and LCD clock frequency in units of 10kHz + * Implementation specifics */ -extern unsigned int get_memclk_frequency_10khz(void); -extern unsigned int get_lcdclk_frequency_10khz(void); -#endif /* __ASSEMBLY__ */ #ifdef CONFIG_ARCH_LUBBOCK #include "lubbock.h" @@ -159,15 +143,6 @@ extern unsigned int get_lcdclk_frequency_10khz(void); #include "cerf.h" #endif -#if CONFIG_CPU_MONAHANS_L2CACHE -#define __cpuc_flush_l2cache_all xscale_flush_l2cache_all -extern void __cpuc_flush_l2cache_all(void); -#define flush_l2cache_all __cpuc_flush_l2cache_all -#else -#define __cpuc_flush_l2cache_all() do {} while (0) -#define flush_l2cache_all() do {} while (0) -#endif - #ifdef CONFIG_ARCH_CSB226 #include "csb226.h" #endif @@ -180,10 +155,4 @@ extern void __cpuc_flush_l2cache_all(void); #include "pleb.h" #endif -#ifdef CONFIG_MACH_MAINSTONE -#include "mainstone.h" -#endif - -#include "pxa-regs.h" - -#endif /* _ASM_ARCH_HARDWARE_H */ +#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/global_data.h b/include/asm-arm/global_data.h index c2d52915a8..b3c7084352 100644 --- a/include/asm-arm/global_data.h +++ b/include/asm-arm/global_data.h @@ -61,6 +61,11 @@ typedef struct global_data { #define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */ #define GD_FLG_SILENT 0x00004 /* Silent mode */ -#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8") +#define GCC_4_SCREW_GDP 1 +#ifdef GCC_4_SCREW_GDP +# define DECLARE_GLOBAL_DATA_PTR register gd_t* volatile gd asm ("r8"); +#else +# define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8") +#endif #endif /* __ASM_GBL_DATA_H */ From b3c36e6b9427b8d05c8982d7ebe46be59662c4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Thu, 9 Feb 2006 13:19:25 +0100 Subject: [PATCH 007/102] basic u-boot is working, boots into the command shell. --- board/zylonite/flash.c | 3 +++ include/configs/zylonite.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/board/zylonite/flash.c b/board/zylonite/flash.c index ba82892dde..883c1ba3b3 100644 --- a/board/zylonite/flash.c +++ b/board/zylonite/flash.c @@ -62,6 +62,7 @@ void inline spin_wheel (void); unsigned long flash_init (void) { +#if 0 int i; ulong size = 0; @@ -94,6 +95,8 @@ unsigned long flash_init (void) CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] ); return size; +#endif + return 0; } /*----------------------------------------------------------------------- diff --git a/include/configs/zylonite.h b/include/configs/zylonite.h index 99d6a93959..c5fb07654b 100644 --- a/include/configs/zylonite.h +++ b/include/configs/zylonite.h @@ -61,7 +61,7 @@ /* * select serial console configuration */ -#define CONFIG_FFUART 1 /* we use FFUART on LUBBOCK */ +#define CONFIG_FFUART 1 /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE From b2b43463af8e39ea57bca95bcb24d64e12bbd510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Fri, 10 Feb 2006 11:25:41 +0100 Subject: [PATCH 008/102] Changed gcc-4.0 global data pointer fix to conform with the fix for this on other platforms (see c75eba3b4140187cd0d9bd8049f5df4c49b6889b) --- include/asm-arm/global_data.h | 2 +- lib_arm/board.c | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/include/asm-arm/global_data.h b/include/asm-arm/global_data.h index b3c7084352..0b6c8171ed 100644 --- a/include/asm-arm/global_data.h +++ b/include/asm-arm/global_data.h @@ -61,7 +61,7 @@ typedef struct global_data { #define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */ #define GD_FLG_SILENT 0x00004 /* Silent mode */ -#define GCC_4_SCREW_GDP 1 +#undef GCC_4_SCREW_GDP #ifdef GCC_4_SCREW_GDP # define DECLARE_GLOBAL_DATA_PTR register gd_t* volatile gd asm ("r8"); #else diff --git a/lib_arm/board.c b/lib_arm/board.c index 9c9eb6826e..a420de15e5 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -54,6 +54,8 @@ #include "../drivers/lan91c96.h" #endif +DECLARE_GLOBAL_DATA_PTR; + #if (CONFIG_COMMANDS & CFG_CMD_NAND) void nand_init (void); #endif @@ -121,8 +123,6 @@ void *sbrk (ptrdiff_t increment) static int init_baudrate (void) { - DECLARE_GLOBAL_DATA_PTR; - uchar tmp[64]; /* long enough for environment variables */ int i = getenv_r ("baudrate", tmp, sizeof (tmp)); gd->bd->bi_baudrate = gd->baudrate = (i > 0) @@ -157,7 +157,6 @@ static int display_banner (void) */ static int display_dram_config (void) { - DECLARE_GLOBAL_DATA_PTR; int i; #ifdef DEBUG @@ -236,8 +235,6 @@ init_fnc_t *init_sequence[] = { void start_armboot (void) { - DECLARE_GLOBAL_DATA_PTR; - ulong size; init_fnc_t **init_fnc_ptr; char *s; From 6ece03f2677df79a983877fff8be737d8888f26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Fri, 10 Feb 2006 17:08:26 +0100 Subject: [PATCH 009/102] Config updated for compiling the SMC911111 network driver --- include/configs/zylonite.h | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/include/configs/zylonite.h b/include/configs/zylonite.h index c5fb07654b..f23300d004 100644 --- a/include/configs/zylonite.h +++ b/include/configs/zylonite.h @@ -55,8 +55,15 @@ /* * Hardware drivers */ -/* #define CONFIG_DRIVER_LAN91C96 */ -/* #define CONFIG_LAN91C96_BASE 0x0C000000 */ + +#undef TURN_ON_ETHERNET +#ifdef TURN_ON_ETHERNET +# define CONFIG_DRIVER_SMC91111 1 +# define CONFIG_SMC91111_BASE 0x14000300 +# define CONFIG_SMC91111_EXT_PHY +# define CONFIG_SMC_USE_32_BIT +# undef CONFIG_SMC_USE_IOFUNCS +#endif /* * select serial console configuration @@ -68,8 +75,13 @@ #define CONFIG_BAUDRATE 115200 -/* #define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_MMC | CFG_CMD_FAT) */ -#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_REISER & ~CFG_CMD_NET) +/* #define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_MMC | CFG_CMD_FAT) */ +#ifdef TURN_ON_ETHERNET +# define CONFIG_COMMANDS (CONFIG_CMD_DFL) +#else +# define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_NET) +#endif + /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include @@ -218,7 +230,7 @@ * second sector, not an environment. You have been warned! */ #define CFG_MONITOR_LEN PHYS_FLASH_SECT_SIZE -#define CFG_ENV_IS_IN_FLASH 1 +#undef CFG_ENV_IS_IN_FLASH #define CFG_ENV_ADDR (PHYS_FLASH_1 + PHYS_FLASH_SECT_SIZE) #define CFG_ENV_SECT_SIZE PHYS_FLASH_SECT_SIZE #define CFG_ENV_SIZE (PHYS_FLASH_SECT_SIZE / 16) From bf5988e5334b9fe6b8acd4ea412b8cefac39147f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Fri, 10 Feb 2006 17:12:14 +0100 Subject: [PATCH 010/102] Reverting pxa-regs.h back to original, because the intel Monahans one breaks backward compatibility and I don't trust it. Instead, i'll verify and merge the parts I need while porting. --- include/asm-arm/arch-pxa/pxa-regs.h | 2662 ++++++--------------------- 1 file changed, 547 insertions(+), 2115 deletions(-) diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 3e59f89063..41d37d791a 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -5,15 +5,16 @@ * Created: Jun 15, 2001 * Copyright: MontaVista Software Inc. * - * Copyright (C) 2004, Intel Corporation. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. + * + * - 2003/01/20: Robert Schwebel Status Register */ -#define DRQSR1 __REG(0x400000e4) /* DMA DREQ<1> Status Register */ -#define DRQSR2 __REG(0x400000e8) /* DMA DREQ<2> Status Register */ - -#define DALGN __REG(0x400000a0) /* DMA Alignment Register */ -#endif /* CONFIG_CPU_MONAHANS */ - #define DINT __REG(0x400000f0) /* DMA Interrupt Register */ -#define DRCMR(n) __REG2(0x40000100, (n)<<2) #define DRCMR0 __REG(0x40000100) /* Request to Channel Map Register for DREQ 0 */ #define DRCMR1 __REG(0x40000104) /* Request to Channel Map Register for DREQ 1 */ #define DRCMR2 __REG(0x40000108) /* Request to Channel Map Register for I2S receive Request */ @@ -183,75 +142,29 @@ typedef void (*ExcpHndlr) (void) ; #define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */ #define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */ #define DRCMR20 __REG(0x40000150) /* Request to Channel Map Register for STUART transmit Request */ -#define DRCMR21 __REG(0x40000154) /* Request to Channel Map Register for MMC/SDIO 1 receive Request */ -#define DRCMR22 __REG(0x40000158) /* Request to Channel Map Register for MMC/SDIO 2 transmit Request */ +#define DRCMR21 __REG(0x40000154) /* Request to Channel Map Register for MMC receive Request */ +#define DRCMR22 __REG(0x40000158) /* Request to Channel Map Register for MMC transmit Request */ #define DRCMR23 __REG(0x4000015c) /* Reserved */ -#define DRCMR24 __REG(0x40000160) /* Request to Channel Map Register for USB endpoint 0 request */ +#define DRCMR24 __REG(0x40000160) /* Reserved */ #define DRCMR25 __REG(0x40000164) /* Request to Channel Map Register for USB endpoint 1 Request */ #define DRCMR26 __REG(0x40000168) /* Request to Channel Map Register for USB endpoint 2 Request */ #define DRCMR27 __REG(0x4000016C) /* Request to Channel Map Register for USB endpoint 3 Request */ #define DRCMR28 __REG(0x40000170) /* Request to Channel Map Register for USB endpoint 4 Request */ -#define DRCMR29 __REG(0x40000174) /* Request to Channel Map Register for USB endpoint 5 Request */ +#define DRCMR29 __REG(0x40000174) /* Reserved */ #define DRCMR30 __REG(0x40000178) /* Request to Channel Map Register for USB endpoint 6 Request */ #define DRCMR31 __REG(0x4000017C) /* Request to Channel Map Register for USB endpoint 7 Request */ #define DRCMR32 __REG(0x40000180) /* Request to Channel Map Register for USB endpoint 8 Request */ #define DRCMR33 __REG(0x40000184) /* Request to Channel Map Register for USB endpoint 9 Request */ -#define DRCMR34 __REG(0x40000188) /* Request to Channel Map Register for USB endpoint 10 Request */ +#define DRCMR34 __REG(0x40000188) /* Reserved */ #define DRCMR35 __REG(0x4000018C) /* Request to Channel Map Register for USB endpoint 11 Request */ #define DRCMR36 __REG(0x40000190) /* Request to Channel Map Register for USB endpoint 12 Request */ #define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */ #define DRCMR38 __REG(0x40000198) /* Request to Channel Map Register for USB endpoint 14 Request */ -#define DRCMR39 __REG(0x4000019C) /* Request to Channel Map Register for USB endpoint 15 Request */ -#define DRCMR40 __REG(0x400001A0) /* Request to Channel Map Register for USB endpoint 15 Request */ -#define DRCMR41 __REG(0x400001A4) /* Request to Channel Map Register for USB endpoint 15 Request */ -#define DRCMR42 __REG(0x400001A8) /* Request to Channel Map Register for USB endpoint 15 Request */ -#define DRCMR43 __REG(0x400001AC) /* Request to Channel Map Register for USB endpoint 15 Request */ -#define DRCMR44 __REG(0x400001B0) /* Request to Channel Map Register for USB endpoint 15 Request */ -#define DRCMR45 __REG(0x400001B4) /* Request to Channel Map Register for USB endpoint 15 Request */ -#define DRCMR46 __REG(0x400001B8) /* Request to Channel Map Register for USB endpoint 15 Request */ -#define DRCMR47 __REG(0x400001BC) /* Request to Channel Map Register for USB endpoint 15 Request */ -#define DRCMR48 __REG(0x400001C0) /* Request to Channel Map Register for MSL Receive Request 1 */ -#define DRCMR49 __REG(0x400001C4) /* Request to Channel Map Register for MSL Transmit Request 1 */ -#define DRCMR50 __REG(0x400001C8) /* Request to Channel Map Register for MSL Receive Request 2 */ -#define DRCMR51 __REG(0x400001CC) /* Request to Channel Map Register for MSL Transmit Request 2 */ -#define DRCMR52 __REG(0x400001D0) /* Request to Channel Map Register for MSL Receive Request 3 */ -#define DRCMR53 __REG(0x400001D4) /* Request to Channel Map Register for MSL Transmit Request 3 */ -#define DRCMR54 __REG(0x400001D8) /* Request to Channel Map Register for MSL Receive Request 4 */ -#define DRCMR55 __REG(0x400001DC) /* Request to Channel Map Register for MSL Transmit Request 4 */ -#define DRCMR56 __REG(0x400001E0) /* Request to Channel Map Register for MSL Receive Request 5 */ -#define DRCMR57 __REG(0x400001E4) /* Request to Channel Map Register for MSL Transmit Request 5 */ -#define DRCMR58 __REG(0x400001E8) /* Request to Channel Map Register for MSL Receive Request 6 */ -#define DRCMR59 __REG(0x400001EC) /* Request to Channel Map Register for MSL Transmit Request 6 */ -#define DRCMR60 __REG(0x400001F0) /* Request to Channel Map Register for MSL Receive Request 7 */ -#define DRCMR61 __REG(0x400001F4) /* Request to Channel Map Register for MSL Transmit Request 7 */ -#define DRCMR62 __REG(0x400001F8) /* Request to Channel Map Register for USIM 1 Receive Request */ -#define DRCMR63 __REG(0x400001FC) /* Request to Channel Map Register for USIM 1 Transimit Request */ - -#define DRCMR64 __REG(0x40001100) /* Reserved */ -#define DRCMR65 __REG(0x40001104) /* Reserved */ -#define DRCMR66 __REG(0x40001108) /* Request to channel Map Register for SSP3 Receive Request */ -#define DRCMR67 __REG(0x4000110C) /* Request to channel Map Register for SSP3 Receive Request */ - -#define DRCMR68 __REG(0x40001110) /* Reserved */ -#define DRCMR69 __REG(0x40001114) /* Reserved */ -#define DRCMR70 __REG(0x40001118) /* Reserved */ - -#define DRCMR71 __REG(0x4000111C) /* Request to Channel Map Register for TPM Receive Request */ -#define DRCMR72 __REG(0x40001120) /* Request to Channel Map Register for TPM Transmit Request 1 */ -#define DRCMR73 __REG(0x40001124) /* Request to Channel Map Register for TPM Transmit Request 2 */ -#define DRCMR74 __REG(0x40001128) /* Request to Channel Map Register for DREQ<2> */ - -#define DRCMR91 __REG(0x4000116C) /* Request to Channel Map Register for USIM 2 Receive Request */ -#define DRCMR92 __REG(0x40001170) /* Request to Channel Map Register for USIM 2 Transmit Request */ - -#define DRCMR93 __REG(0x40001174) /* Request to Channel Map Register for MMC Controller 1 Request */ -#define DRCMR94 __REG(0x40001178) /* Request to Channel Map Register for MMC Controller 2 Request */ -#define DRCMR95 __REG(0x4000117C) /* Request to Channel Map Register for AC97 Surround Transmit Request */ -#define DRCMR96 __REG(0x40001180) /* Request to Channel Map Register for AC97 centre/LFE Transmit Request */ -#define DRCMR97 __REG(0x40001184) /* Request to Channel Map Register for NAND interface data transmit & receive Request */ -#define DRCMR98 __REG(0x40001188) /* Reserved */ -#define DRCMR99 __REG(0x4000118C) /* Request to Channel Map Register for NAND interface command transmit Request */ +#define DRCMR39 __REG(0x4000019C) /* Reserved */ +#define DRCMR68 __REG(0x40001110) /* Request to Channel Map Register for Camera FIFO 0 Request */ +#define DRCMR69 __REG(0x40001114) /* Request to Channel Map Register for Camera FIFO 1 Request */ +#define DRCMR70 __REG(0x40001118) /* Request to Channel Map Register for Camera FIFO 2 Request */ #define DRCMRRXSADR DRCMR2 #define DRCMRTXSADR DRCMR3 @@ -272,12 +185,9 @@ typedef void (*ExcpHndlr) (void) ; #define DRCMRTXSTTHR DRCMR20 #define DRCMRRXMMC DRCMR21 #define DRCMRTXMMC DRCMR22 -#define DRCMRRXMMC2 DRCMR93 -#define DRCMRTXMMC2 DRCMR94 -#define DRCMRUDC(x) DRCMR((x) + 24) #define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */ -#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */ +#define DRCMR_CHLNUM 0x0f /* mask for Channel Number (read / write) */ #define DDADR0 __REG(0x40000200) /* DMA Descriptor Address Register Channel 0 */ #define DSADR0 __REG(0x40000204) /* DMA Source Address Register Channel 0 */ @@ -352,11 +262,11 @@ typedef void (*ExcpHndlr) (void) ; #define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */ #define DDADR_STOP (1 << 0) /* Stop (read / write) */ -#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */ -#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */ +#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */ +#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */ #define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */ #define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */ -#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */ +#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */ #define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */ #define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */ #define DCMD_BURST8 (1 << 16) /* 8 byte burst */ @@ -372,11 +282,9 @@ typedef void (*ExcpHndlr) (void) ; #define DCMD_RXMCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4) #define DCMD_TXPCDR (DCMD_INCSRCADDR|DCMD_FLOWTRG|DCMD_BURST32|DCMD_WIDTH4) - /* * UARTs */ - /* Full Function UART (FFUART) */ #define FFUART FFRBR #define FFRBR __REG(0x40100000) /* Receive Buffer Register (read only) */ @@ -469,7 +377,7 @@ typedef void (*ExcpHndlr) (void) ; #define LSR_OE (1 << 1) /* Overrun Error */ #define LSR_DR (1 << 0) /* Data Ready */ -#define MCR_LOOP (1 << 4) +#define MCR_LOOP (1 << 4) */ #define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */ #define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */ #define MCR_RTS (1 << 1) /* Request to Send */ @@ -487,13 +395,6 @@ typedef void (*ExcpHndlr) (void) ; /* * IrSR (Infrared Selection Register) */ -#ifdef CONFIG_CPU_MONAHANS -#define STISR_RXPL (1 << 4) /* Receive Data Polarity */ -#define STISR_TXPL (1 << 3) /* Transmit Data Polarity */ -#define STISR_XMODE (1 << 2) /* Transmit Pulse Width Select */ -#define STISR_RCVEIR (1 << 1) /* Receiver SIR Enable */ -#define STISR_XMITIR (1 << 0) /* Transmitter SIR Enable */ -#else #define IrSR_OFFSET 0x20 #define IrSR_RXPL_NEG_IS_ZERO (1<<4) @@ -508,85 +409,85 @@ typedef void (*ExcpHndlr) (void) ; #define IrSR_XMITIR_UART_MODE 0x0 #define IrSR_IR_RECEIVE_ON (\ - IrSR_RXPL_NEG_IS_ZERO | \ - IrSR_TXPL_POS_IS_ZERO | \ - IrSR_XMODE_PULSE_3_16 | \ - IrSR_RCVEIR_IR_MODE | \ - IrSR_XMITIR_UART_MODE) + IrSR_RXPL_NEG_IS_ZERO | \ + IrSR_TXPL_POS_IS_ZERO | \ + IrSR_XMODE_PULSE_3_16 | \ + IrSR_RCVEIR_IR_MODE | \ + IrSR_XMITIR_UART_MODE) #define IrSR_IR_TRANSMIT_ON (\ - IrSR_RXPL_NEG_IS_ZERO | \ - IrSR_TXPL_POS_IS_ZERO | \ - IrSR_XMODE_PULSE_3_16 | \ - IrSR_RCVEIR_UART_MODE | \ - IrSR_XMITIR_IR_MODE) -#endif /* not CONFIG_CPU_MONAHANS */ + IrSR_RXPL_NEG_IS_ZERO | \ + IrSR_TXPL_POS_IS_ZERO | \ + IrSR_XMODE_PULSE_3_16 | \ + IrSR_RCVEIR_UART_MODE | \ + IrSR_XMITIR_IR_MODE) /* * I2C registers */ - #define IBMR __REG(0x40301680) /* I2C Bus Monitor Register - IBMR */ #define IDBR __REG(0x40301688) /* I2C Data Buffer Register - IDBR */ #define ICR __REG(0x40301690) /* I2C Control Register - ICR */ #define ISR __REG(0x40301698) /* I2C Status Register - ISR */ #define ISAR __REG(0x403016A0) /* I2C Slave Address Register - ISAR */ -#define PWRIBMR __REG(0x40f00180) /* Power I2C Bus Monitor Register-IBMR */ -#define PWRIDBR __REG(0x40f00188) /* Power I2C Data Buffer Register-IDBR */ -#define PWRICR __REG(0x40f00190) /* Power I2C Control Register - ICR */ -#define PWRISR __REG(0x40f00198) /* Power I2C Status Register - ISR */ -#define PWRISAR __REG(0x40f001A0) /*Power I2C Slave Address Register-ISAR */ +#define PWRIBMR __REG(0x40f00180) /* Power I2C Bus Monitor Register-IBMR */ +#define PWRIDBR __REG(0x40f00188) /* Power I2C Data Buffer Register-IDBR */ +#define PWRICR __REG(0x40f00190) /* Power I2C Control Register - ICR */ +#define PWRISR __REG(0x40f00198) /* Power I2C Status Register - ISR */ +#define PWRISAR __REG(0x40f001A0) /* Power I2C Slave Address Register-ISAR */ -#define ICR_START (1 << 0) /* start bit */ -#define ICR_STOP (1 << 1) /* stop bit */ -#define ICR_ACKNAK (1 << 2) /* send ACK(0) or NAK(1) */ -#define ICR_TB (1 << 3) /* transfer byte bit */ -#define ICR_MA (1 << 4) /* master abort */ -#define ICR_SCLE (1 << 5) /* master clock enable */ -#define ICR_IUE (1 << 6) /* unit enable */ -#define ICR_GCD (1 << 7) /* general call disable */ -#define ICR_ITEIE (1 << 8) /* enable tx interrupts */ -#define ICR_IRFIE (1 << 9) /* enable rx interrupts */ -#define ICR_BEIE (1 << 10) /* enable bus error ints */ -#define ICR_SSDIE (1 << 11) /* slave STOP detected int enable */ -#define ICR_ALDIE (1 << 12) /* enable arbitration interrupt */ -#define ICR_SADIE (1 << 13) /* slave address detected int enable */ -#define ICR_UR (1 << 14) /* unit reset */ +/* ----- Control register bits ---------------------------------------- */ -#define ISR_RWM (1 << 0) /* read/write mode */ -#define ISR_ACKNAK (1 << 1) /* ack/nak status */ -#define ISR_UB (1 << 2) /* unit busy */ -#define ISR_IBB (1 << 3) /* bus busy */ -#define ISR_SSD (1 << 4) /* slave stop detected */ -#define ISR_ALD (1 << 5) /* arbitration loss detected */ -#define ISR_ITE (1 << 6) /* tx buffer empty */ -#define ISR_IRF (1 << 7) /* rx buffer full */ -#define ISR_GCAD (1 << 8) /* general call address detected */ -#define ISR_SAD (1 << 9) /* slave address detected */ -#define ISR_BED (1 << 10) /* bus error no ACK/NAK */ +#define ICR_START 0x1 /* start bit */ +#define ICR_STOP 0x2 /* stop bit */ +#define ICR_ACKNAK 0x4 /* send ACK(0) or NAK(1) */ +#define ICR_TB 0x8 /* transfer byte bit */ +#define ICR_MA 0x10 /* master abort */ +#define ICR_SCLE 0x20 /* master clock enable */ +#define ICR_IUE 0x40 /* unit enable */ +#define ICR_GCD 0x80 /* general call disable */ +#define ICR_ITEIE 0x100 /* enable tx interrupts */ +#define ICR_IRFIE 0x200 /* enable rx interrupts */ +#define ICR_BEIE 0x400 /* enable bus error ints */ +#define ICR_SSDIE 0x800 /* slave STOP detected int enable */ +#define ICR_ALDIE 0x1000 /* enable arbitration interrupt */ +#define ICR_SADIE 0x2000 /* slave address detected int enable */ +#define ICR_UR 0x4000 /* unit reset */ +#define ICR_FM 0x8000 /* Fast Mode */ +/* ----- Status register bits ----------------------------------------- */ + +#define ISR_RWM 0x1 /* read/write mode */ +#define ISR_ACKNAK 0x2 /* ack/nak status */ +#define ISR_UB 0x4 /* unit busy */ +#define ISR_IBB 0x8 /* bus busy */ +#define ISR_SSD 0x10 /* slave stop detected */ +#define ISR_ALD 0x20 /* arbitration loss detected */ +#define ISR_ITE 0x40 /* tx buffer empty */ +#define ISR_IRF 0x80 /* rx buffer full */ +#define ISR_GCAD 0x100 /* general call address detected */ +#define ISR_SAD 0x200 /* slave address detected */ +#define ISR_BED 0x400 /* bus error no ACK/NAK */ /* * Serial Audio Controller */ - -/* FIXME: This clash with SA1111 defines */ -#ifndef CONFIG_SA1111 -#define SACR0 __REG(0x40400000) /* Global Control Register */ -#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */ -#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */ -#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */ -#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */ -#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */ -#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */ -#endif +/* FIXME the audio defines collide w/ the SA1111 defines. I don't like these + * short defines because there is too much chance of namespace collision + */ +/*#define SACR0 __REG(0x40400000) / Global Control Register */ +/*#define SACR1 __REG(0x40400004) / Serial Audio I 2 S/MSB-Justified Control Register */ +/*#define SASR0 __REG(0x4040000C) / Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */ +/*#define SAIMR __REG(0x40400014) / Serial Audio Interrupt Mask Register */ +/*#define SAICR __REG(0x40400018) / Serial Audio Interrupt Clear Register */ +/*#define SADIV __REG(0x40400060) / Audio Clock Divider Register. */ +/*#define SADR __REG(0x40400080) / Serial Audio Data Register (TX and RX FIFO access Register). */ /* * AC97 Controller registers */ - #define POCR __REG(0x40500000) /* PCM Out Control Register */ #define POCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */ @@ -660,13 +561,9 @@ typedef void (*ExcpHndlr) (void) ; #define PMC_REG_BASE __REG(0x40500400) /* Primary Modem Codec */ #define SMC_REG_BASE __REG(0x40500500) /* Secondary Modem Codec */ - /* * USB Device Controller - * PXA25x and PXA27x USB device controller registers are different. */ -#if defined(CONFIG_PXA25x) - #define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */ #define UDC_RES2 __REG(0x40600008) /* UDC Undocumented - Reserved2 */ #define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented - Reserved3 */ @@ -822,250 +719,63 @@ typedef void (*ExcpHndlr) (void) ; #define USIR1_IR14 (1 << 6) /* Interrup request ep 14 */ #define USIR1_IR15 (1 << 7) /* Interrup request ep 15 */ -#elif defined(CONFIG_PXA27X)||( CONFIG_CPU_MONAHANS) +#if defined(CONFIG_PXA27X) +/* + * USB Host Controller + */ +#define UHCREV __REG(0x4C000000) +#define UHCHCON __REG(0x4C000004) +#define UHCCOMS __REG(0x4C000008) +#define UHCINTS __REG(0x4C00000C) +#define UHCINTE __REG(0x4C000010) +#define UHCINTD __REG(0x4C000014) +#define UHCHCCA __REG(0x4C000018) +#define UHCPCED __REG(0x4C00001C) +#define UHCCHED __REG(0x4C000020) +#define UHCCCED __REG(0x4C000024) +#define UHCBHED __REG(0x4C000028) +#define UHCBCED __REG(0x4C00002C) +#define UHCDHEAD __REG(0x4C000030) +#define UHCFMI __REG(0x4C000034) +#define UHCFMR __REG(0x4C000038) +#define UHCFMN __REG(0x4C00003C) +#define UHCPERS __REG(0x4C000040) +#define UHCLST __REG(0x4C000044) +#define UHCRHDA __REG(0x4C000048) +#define UHCRHDB __REG(0x4C00004C) +#define UHCRHS __REG(0x4C000050) +#define UHCRHPS1 __REG(0x4C000054) +#define UHCRHPS2 __REG(0x4C000058) +#define UHCRHPS3 __REG(0x4C00005C) +#define UHCSTAT __REG(0x4C000060) +#define UHCHR __REG(0x4C000064) +#define UHCHIE __REG(0x4C000068) +#define UHCHIT __REG(0x4C00006C) -#define UDCCR __REG(0x40600000) /* UDC Control Register */ -#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */ -#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation - Protocol Port Support */ -#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol - Support */ -#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol - Enable */ -#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */ -#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */ -#define UDCCR_ACN_S 11 -#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */ -#define UDCCR_AIN_S 8 -#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface - Setting Number */ -#define UDCCR_AAISN_S 5 -#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active - Configuration */ -#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration - Error */ -#define UDCCR_UDR (1 << 2) /* UDC Resume */ -#define UDCCR_UDA (1 << 1) /* UDC Active */ -#define UDCCR_UDE (1 << 0) /* UDC Enable */ +#define UHCHR_FSBIR (1<<0) +#define UHCHR_FHR (1<<1) +#define UHCHR_CGR (1<<2) +#define UHCHR_SSDC (1<<3) +#define UHCHR_UIT (1<<4) +#define UHCHR_SSE (1<<5) +#define UHCHR_PSPL (1<<6) +#define UHCHR_PCPL (1<<7) +#define UHCHR_SSEP0 (1<<9) +#define UHCHR_SSEP1 (1<<10) +#define UHCHR_SSEP2 (1<<11) -#define UDCICR0 __REG(0x40600004) /* UDC Interrupt Control Register0 */ -#define UDCICR1 __REG(0x40600008) /* UDC Interrupt Control Register1 */ -#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */ -#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */ +#define UHCHIE_UPRIE (1<<13) +#define UHCHIE_UPS2IE (1<<12) +#define UHCHIE_UPS1IE (1<<11) +#define UHCHIE_TAIE (1<<10) +#define UHCHIE_HBAIE (1<<8) +#define UHCHIE_RWIE (1<<7) -#define UDC_INT_FIFOERROR (0x2) -#define UDC_INT_PACKETCMP (0x1) - -#define UDCICR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) -#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */ -#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */ -#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */ -#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */ -#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */ - -#define UDCISR0 __REG(0x4060000C) /* UDC Interrupt Status Register 0 */ -#define UDCISR1 __REG(0x40600010) /* UDC Interrupt Status Register 1 */ -#define UDCISR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) -#define UDCISR1_IRCC (1 << 31) /* IntEn - Configuration Change */ -#define UDCISR1_IRSOF (1 << 30) /* IntEn - Start of Frame */ -#define UDCISR1_IRRU (1 << 29) /* IntEn - Resume */ -#define UDCISR1_IRSU (1 << 28) /* IntEn - Suspend */ -#define UDCISR1_IRRS (1 << 27) /* IntEn - Reset */ - -#define UDCFNR __REG(0x40600014) /* UDC Frame Number Register */ -#define UDCOTGICR __REG(0x40600018) /* UDC On-The-Go interrupt control */ -#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */ -#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt - Rising Edge Interrupt Enable */ -#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt - Falling Edge Interrupt Enable */ -#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising - Edge Interrupt Enable */ -#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling - Edge Interrupt Enable */ -#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge - Interrupt Enable */ -#define UDCOTGISR __REG(0x4060001C) /* UDC OTG Interrupt Status Register*/ -#define UP2OCR __REG(0x40600020) /* Port 2 control register */ -#define UP3OCR __REG(0x40600024) /* Port 3 control register */ - -#define UDCCSN(x) __REG2(0x40600100, (x) << 2) -#define UDCCSR0 __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */ -#define UDCCSR0_ACM (1 << 9) /* ACK control mode */ -#define UDCCSR0_AREN (1 << 8) /* ACK response enable */ -#define UDCCSR0_SA (1 << 7) /* Setup Active */ -#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */ -#define UDCCSR0_FST (1 << 5) /* Force Stall */ -#define UDCCSR0_SST (1 << 4) /* Sent Stall */ -#define UDCCSR0_DME (1 << 3) /* DMA Enable */ -#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */ -#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */ -#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */ - -#define UDCCSRA __REG(0x40600104) /* UDC Control/Status register - Endpoint A */ -#define UDCCSRB __REG(0x40600108) /* UDC Control/Status register - Endpoint B */ -#define UDCCSRC __REG(0x4060010C) /* UDC Control/Status register - Endpoint C */ -#define UDCCSRD __REG(0x40600110) /* UDC Control/Status register - Endpoint D */ -#define UDCCSRE __REG(0x40600114) /* UDC Control/Status register - Endpoint E */ -#define UDCCSRF __REG(0x40600118) /* UDC Control/Status register - Endpoint F */ -#define UDCCSRG __REG(0x4060011C) /* UDC Control/Status register - Endpoint G */ -#define UDCCSRH __REG(0x40600120) /* UDC Control/Status register - Endpoint H */ -#define UDCCSRI __REG(0x40600124) /* UDC Control/Status register - Endpoint I */ -#define UDCCSRJ __REG(0x40600128) /* UDC Control/Status register - Endpoint J */ -#define UDCCSRK __REG(0x4060012C) /* UDC Control/Status register - Endpoint K */ -#define UDCCSRL __REG(0x40600130) /* UDC Control/Status register - Endpoint L */ -#define UDCCSRM __REG(0x40600134) /* UDC Control/Status register - Endpoint M */ -#define UDCCSRN __REG(0x40600138) /* UDC Control/Status register - Endpoint N */ -#define UDCCSRP __REG(0x4060013C) /* UDC Control/Status register - Endpoint P */ -#define UDCCSRQ __REG(0x40600140) /* UDC Control/Status register - Endpoint Q */ -#define UDCCSRR __REG(0x40600144) /* UDC Control/Status register - Endpoint R */ -#define UDCCSRS __REG(0x40600148) /* UDC Control/Status register - Endpoint S */ -#define UDCCSRT __REG(0x4060014C) /* UDC Control/Status register - Endpoint T */ -#define UDCCSRU __REG(0x40600150) /* UDC Control/Status register - Endpoint U */ -#define UDCCSRV __REG(0x40600154) /* UDC Control/Status register - Endpoint V */ -#define UDCCSRW __REG(0x40600158) /* UDC Control/Status register - Endpoint W */ -#define UDCCSRX __REG(0x4060015C) /* UDC Control/Status register - Endpoint X */ - -#define UDCCSR_DPE (1 << 9) /* Data Packet Error */ -#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */ -#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */ -#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */ -#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */ -#define UDCCSR_FST (1 << 5) /* Force STALL */ -#define UDCCSR_SST (1 << 4) /* Sent STALL */ -#define UDCCSR_DME (1 << 3) /* DMA Enable */ -#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */ -#define UDCCSR_PC (1 << 1) /* Packet Complete */ -#define UDCCSR_FS (1 << 0) /* FIFO needs service */ - -#define UDCBCN(x) __REG2(0x40600200, (x)<<2) -#define UDCBCR0 __REG(0x40600200) /* Byte Count Register - EP0 */ -#define UDCBCRA __REG(0x40600204) /* Byte Count Register - EPA */ -#define UDCBCRB __REG(0x40600208) /* Byte Count Register - EPB */ -#define UDCBCRC __REG(0x4060020C) /* Byte Count Register - EPC */ -#define UDCBCRD __REG(0x40600210) /* Byte Count Register - EPD */ -#define UDCBCRE __REG(0x40600214) /* Byte Count Register - EPE */ -#define UDCBCRF __REG(0x40600218) /* Byte Count Register - EPF */ -#define UDCBCRG __REG(0x4060021C) /* Byte Count Register - EPG */ -#define UDCBCRH __REG(0x40600220) /* Byte Count Register - EPH */ -#define UDCBCRI __REG(0x40600224) /* Byte Count Register - EPI */ -#define UDCBCRJ __REG(0x40600228) /* Byte Count Register - EPJ */ -#define UDCBCRK __REG(0x4060022C) /* Byte Count Register - EPK */ -#define UDCBCRL __REG(0x40600230) /* Byte Count Register - EPL */ -#define UDCBCRM __REG(0x40600234) /* Byte Count Register - EPM */ -#define UDCBCRN __REG(0x40600238) /* Byte Count Register - EPN */ -#define UDCBCRP __REG(0x4060023C) /* Byte Count Register - EPP */ -#define UDCBCRQ __REG(0x40600240) /* Byte Count Register - EPQ */ -#define UDCBCRR __REG(0x40600244) /* Byte Count Register - EPR */ -#define UDCBCRS __REG(0x40600248) /* Byte Count Register - EPS */ -#define UDCBCRT __REG(0x4060024C) /* Byte Count Register - EPT */ -#define UDCBCRU __REG(0x40600250) /* Byte Count Register - EPU */ -#define UDCBCRV __REG(0x40600254) /* Byte Count Register - EPV */ -#define UDCBCRW __REG(0x40600258) /* Byte Count Register - EPW */ -#define UDCBCRX __REG(0x4060025C) /* Byte Count Register - EPX */ - -#define UDCDN(x) __REG2(0x40600300, (x)<<2) -#define PHYS_UDCDN(x) (0x40600300 + ((x)<<2)) -#define PUDCDN(x) (volatile u32 *)(io_p2v(PHYS_UDCDN((x)))) -#define UDCDR0 __REG(0x40600300) /* Data Register - EP0 */ -#define UDCDRA __REG(0x40600304) /* Data Register - EPA */ -#define UDCDRB __REG(0x40600308) /* Data Register - EPB */ -#define UDCDRC __REG(0x4060030C) /* Data Register - EPC */ -#define UDCDRD __REG(0x40600310) /* Data Register - EPD */ -#define UDCDRE __REG(0x40600314) /* Data Register - EPE */ -#define UDCDRF __REG(0x40600318) /* Data Register - EPF */ -#define UDCDRG __REG(0x4060031C) /* Data Register - EPG */ -#define UDCDRH __REG(0x40600320) /* Data Register - EPH */ -#define UDCDRI __REG(0x40600324) /* Data Register - EPI */ -#define UDCDRJ __REG(0x40600328) /* Data Register - EPJ */ -#define UDCDRK __REG(0x4060032C) /* Data Register - EPK */ -#define UDCDRL __REG(0x40600330) /* Data Register - EPL */ -#define UDCDRM __REG(0x40600334) /* Data Register - EPM */ -#define UDCDRN __REG(0x40600338) /* Data Register - EPN */ -#define UDCDRP __REG(0x4060033C) /* Data Register - EPP */ -#define UDCDRQ __REG(0x40600340) /* Data Register - EPQ */ -#define UDCDRR __REG(0x40600344) /* Data Register - EPR */ -#define UDCDRS __REG(0x40600348) /* Data Register - EPS */ -#define UDCDRT __REG(0x4060034C) /* Data Register - EPT */ -#define UDCDRU __REG(0x40600350) /* Data Register - EPU */ -#define UDCDRV __REG(0x40600354) /* Data Register - EPV */ -#define UDCDRW __REG(0x40600358) /* Data Register - EPW */ -#define UDCDRX __REG(0x4060035C) /* Data Register - EPX */ - -#define UDCCN(x) __REG2(0x40600400, (x)<<2) -#define UDCCRA __REG(0x40600404) /* Configuration register EPA */ -#define UDCCRB __REG(0x40600408) /* Configuration register EPB */ -#define UDCCRC __REG(0x4060040C) /* Configuration register EPC */ -#define UDCCRD __REG(0x40600410) /* Configuration register EPD */ -#define UDCCRE __REG(0x40600414) /* Configuration register EPE */ -#define UDCCRF __REG(0x40600418) /* Configuration register EPF */ -#define UDCCRG __REG(0x4060041C) /* Configuration register EPG */ -#define UDCCRH __REG(0x40600420) /* Configuration register EPH */ -#define UDCCRI __REG(0x40600424) /* Configuration register EPI */ -#define UDCCRJ __REG(0x40600428) /* Configuration register EPJ */ -#define UDCCRK __REG(0x4060042C) /* Configuration register EPK */ -#define UDCCRL __REG(0x40600430) /* Configuration register EPL */ -#define UDCCRM __REG(0x40600434) /* Configuration register EPM */ -#define UDCCRN __REG(0x40600438) /* Configuration register EPN */ -#define UDCCRP __REG(0x4060043C) /* Configuration register EPP */ -#define UDCCRQ __REG(0x40600440) /* Configuration register EPQ */ -#define UDCCRR __REG(0x40600444) /* Configuration register EPR */ -#define UDCCRS __REG(0x40600448) /* Configuration register EPS */ -#define UDCCRT __REG(0x4060044C) /* Configuration register EPT */ -#define UDCCRU __REG(0x40600450) /* Configuration register EPU */ -#define UDCCRV __REG(0x40600454) /* Configuration register EPV */ -#define UDCCRW __REG(0x40600458) /* Configuration register EPW */ -#define UDCCRX __REG(0x4060045C) /* Configuration register EPX */ - -#define UDCCONR_CN (0x03 << 25) /* Configuration Number */ -#define UDCCONR_CN_S (25) -#define UDCCONR_IN (0x07 << 22) /* Interface Number */ -#define UDCCONR_IN_S (22) -#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */ -#define UDCCONR_AISN_S (19) -#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */ -#define UDCCONR_EN_S (15) -#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */ -#define UDCCONR_ET_S (13) -#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */ -#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */ -#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */ -#define UDCCONR_ET_NU (0x00 << 13) /* Not used */ -#define UDCCONR_ED (1 << 12) /* Endpoint Direction */ -#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */ -#define UDCCONR_MPS_S (2) -#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */ -#define UDCCONR_EE (1 << 0) /* Endpoint Enable */ - - -#define UDC_INT_FIFOERROR (0x2) -#define UDC_INT_PACKETCMP (0x1) - -#define UDC_FNR_MASK (0x7ff) - -#define UDCCSR_WR_MASK (UDCCSR_DME|UDCCSR_FST) -#define UDC_BCR_MASK (0x3ff) #endif /* * Fast Infrared Communication Port */ - -#define FICP __REG(0x40800000) /* Start of FICP area */ #define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */ #define ICCR1 __REG(0x40800004) /* ICP Control Register 1 */ #define ICCR2 __REG(0x40800008) /* ICP Control Register 2 */ @@ -1073,78 +783,45 @@ typedef void (*ExcpHndlr) (void) ; #define ICSR0 __REG(0x40800014) /* ICP Status Register 0 */ #define ICSR1 __REG(0x40800018) /* ICP Status Register 1 */ -#define ICCR0_AME (1 << 7) /* Adress match enable */ -#define ICCR0_TIE (1 << 6) /* Transmit FIFO interrupt enable */ -#define ICCR0_RIE (1 << 5) /* Recieve FIFO interrupt enable */ -#define ICCR0_RXE (1 << 4) /* Receive enable */ -#define ICCR0_TXE (1 << 3) /* Transmit enable */ -#define ICCR0_TUS (1 << 2) /* Transmit FIFO underrun select */ -#define ICCR0_LBM (1 << 1) /* Loopback mode */ -#define ICCR0_ITR (1 << 0) /* IrDA transmission */ - -#ifdef CONFIG_PXA27X -#define ICCR2_RXP (1 << 3) /* Receive Pin Polarity select */ -#define ICCR2_TXP (1 << 2) /* Transmit Pin Polarity select */ -#define ICCR2_TRIG (3 << 0) /* Receive FIFO Trigger threshold */ -#define ICCR2_TRIG_8 (0 << 0) /* >= 8 bytes */ -#define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */ -#define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */ -#endif - -#ifdef CONFIG_PXA27X -#define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */ -#endif -#define ICSR0_FRE (1 << 5) /* Framing error */ -#define ICSR0_RFS (1 << 4) /* Receive FIFO service request */ -#define ICSR0_TFS (1 << 3) /* Transnit FIFO service request */ -#define ICSR0_RAB (1 << 2) /* Receiver abort */ -#define ICSR0_TUR (1 << 1) /* Trunsmit FIFO underun */ -#define ICSR0_EIF (1 << 0) /* End/Error in FIFO */ - -#define ICSR1_ROR (1 << 6) /* Receiver FIFO underrun */ -#define ICSR1_CRE (1 << 5) /* CRC error */ -#define ICSR1_EOF (1 << 4) /* End of frame */ -#define ICSR1_TNF (1 << 3) /* Transmit FIFO not full */ -#define ICSR1_RNE (1 << 2) /* Receive FIFO not empty */ -#define ICSR1_TBY (1 << 1) /* Tramsmiter busy flag */ -#define ICSR1_RSY (1 << 0) /* Recevier synchronized flag */ - - /* * Real Time Clock */ - #define RCNR __REG(0x40900000) /* RTC Count Register */ #define RTAR __REG(0x40900004) /* RTC Alarm Register */ #define RTSR __REG(0x40900008) /* RTC Status Register */ #define RTTR __REG(0x4090000C) /* RTC Timer Trim Register */ -#define PIAR __REG(0x40900038) /* Periodic Interrupt Alarm Register */ +#define RDAR1 __REG(0x40900018) /* Wristwatch Day Alarm Reg 1 */ +#define RDAR2 __REG(0x40900020) /* Wristwatch Day Alarm Reg 2 */ +#define RYAR1 __REG(0x4090001C) /* Wristwatch Year Alarm Reg 1 */ +#define RYAR2 __REG(0x40900024) /* Wristwatch Year Alarm Reg 2 */ +#define SWAR1 __REG(0x4090002C) /* Stopwatch Alarm Register 1 */ +#define SWAR2 __REG(0x40900030) /* Stopwatch Alarm Register 2 */ +#define PIAR __REG(0x40900038) /* Periodic Interrupt Alarm Register */ +#define RDCR __REG(0x40900010) /* RTC Day Count Register. */ +#define RYCR __REG(0x40900014) /* RTC Year Count Register. */ +#define SWCR __REG(0x40900028) /* Stopwatch Count Register */ +#define RTCPICR __REG(0x40900034) /* Periodic Interrupt Counter Register */ -#define RTSR_PICE (1 << 15) /* Periodic interrupt count enable */ -#define RTSR_PIALE (1 << 14) /* Periodic interrupt Alarm enable */ +#define RTSR_PICE (1 << 15) /* Peridoc interrupt count enable */ +#define RTSR_PIALE (1 << 14) /* Peridoc interrupt Alarm enable */ +#define RTSR_PIAL (1 << 13) /* Peridoc interrupt Alarm status */ #define RTSR_HZE (1 << 3) /* HZ interrupt enable */ #define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ #define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ #define RTSR_AL (1 << 0) /* RTC alarm detected */ - /* * OS Timer & Match Registers */ - #define OSMR0 __REG(0x40A00000) /* */ #define OSMR1 __REG(0x40A00004) /* */ #define OSMR2 __REG(0x40A00008) /* */ #define OSMR3 __REG(0x40A0000C) /* */ -#define OSMR4 __REG(0x40A00080) /* */ #define OSCR __REG(0x40A00010) /* OS Timer Counter Register */ -#define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register */ -#define OMCR4 __REG(0x40A000C0) /* */ #define OSSR __REG(0x40A00014) /* OS Timer Status Register */ #define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */ #define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */ -#define OSSR_M4 (1 << 4) /* Match status channel 4 */ #define OSSR_M3 (1 << 3) /* Match status channel 3 */ #define OSSR_M2 (1 << 2) /* Match status channel 2 */ #define OSSR_M1 (1 << 1) /* Match status channel 1 */ @@ -1152,17 +829,14 @@ typedef void (*ExcpHndlr) (void) ; #define OWER_WME (1 << 0) /* Watchdog Match Enable */ -#define OIER_E4 (1 << 4) /* Interrupt enable channel 4 */ #define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */ #define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */ #define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */ #define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */ - /* * Pulse Width Modulator */ - #define PWM_CTRL0 __REG(0x40B00000) /* PWM 0 Control Register */ #define PWM_PWDUTY0 __REG(0x40B00004) /* PWM 0 Duty Cycle Register */ #define PWM_PERVAL0 __REG(0x40B00008) /* PWM 0 Period Control Register */ @@ -1171,25 +845,19 @@ typedef void (*ExcpHndlr) (void) ; #define PWM_PWDUTY1 __REG(0x40C00004) /* PWM 1 Duty Cycle Register */ #define PWM_PERVAL1 __REG(0x40C00008) /* PWM 1 Period Control Register */ - /* * Interrupt Controller */ -/* ICIP to ICPR can only be accessed by coprocessor */ -/* #ifndef CONFIG_CPU_MONAHANS*/ #define ICIP __REG(0x40D00000) /* Interrupt Controller IRQ Pending Register */ #define ICMR __REG(0x40D00004) /* Interrupt Controller Mask Register */ #define ICLR __REG(0x40D00008) /* Interrupt Controller Level Register */ #define ICFP __REG(0x40D0000C) /* Interrupt Controller FIQ Pending Register */ #define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */ -/* #endif // CONFIG_CPU_MONAHANS */ #define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */ - /* * General Purpose I/O */ - #define GPLR0 __REG(0x40E00000) /* GPIO Pin-Level Register GPIO<31:0> */ #define GPLR1 __REG(0x40E00004) /* GPIO Pin-Level Register GPIO<63:32> */ #define GPLR2 __REG(0x40E00008) /* GPIO Pin-Level Register GPIO<80:64> */ @@ -1218,39 +886,26 @@ typedef void (*ExcpHndlr) (void) ; #define GEDR1 __REG(0x40E0004C) /* GPIO Edge Detect Status Register GPIO<63:32> */ #define GEDR2 __REG(0x40E00050) /* GPIO Edge Detect Status Register GPIO<80:64> */ -#ifndef CONFIG_CPU_MONAHANS #define GAFR0_L __REG(0x40E00054) /* GPIO Alternate Function Select Register GPIO<15:0> */ #define GAFR0_U __REG(0x40E00058) /* GPIO Alternate Function Select Register GPIO<31:16> */ #define GAFR1_L __REG(0x40E0005C) /* GPIO Alternate Function Select Register GPIO<47:32> */ #define GAFR1_U __REG(0x40E00060) /* GPIO Alternate Function Select Register GPIO<63:48> */ #define GAFR2_L __REG(0x40E00064) /* GPIO Alternate Function Select Register GPIO<79:64> */ -#define GAFR2_U __REG(0x40E00068) /* GPIO Alternate Function Select Register GPIO<95-80> */ -#define GAFR3_L __REG(0x40E0006C) /* GPIO Alternate Function Select Register GPIO<111:96> */ -#define GAFR3_U __REG(0x40E00070) /* GPIO Alternate Function Select Register GPIO<127:112> */ -#endif - -#define GPLR3 __REG(0x40E00100) /* GPIO Pin-Level Register GPIO<127:96> */ -#define GPDR3 __REG(0x40E0010C) /* GPIO Pin Direction Register GPIO<127:96> */ -#define GPSR3 __REG(0x40E00118) /* GPIO Pin Output Set Register GPIO<127:96> */ -#define GPCR3 __REG(0x40E00124) /* GPIO Pin Output Clear Register GPIO<127:96> */ -#define GRER3 __REG(0x40E00130) /* GPIO Rising-Edge Detect Register GPIO<127:96> */ -#define GFER3 __REG(0x40E0013C) /* GPIO Falling-Edge Detect Register GPIO<127:96> */ -#define GEDR3 __REG(0x40E00148) /* GPIO Edge Detect Status Register GPIO<127:96> */ +#define GAFR2_U __REG(0x40E00068) /* GPIO Alternate Function Select Register GPIO 80 */ /* More handy macros. The argument is a literal GPIO number. */ #define GPIO_bit(x) (1 << ((x) & 0x1f)) -#if defined (CONFIG_PXA27X) || (CONFIG_CPU_MONAHANS) +#ifdef CONFIG_PXA27X /* Interrupt Controller */ -/* #ifndef CONFIG_CPU_MONAHANS */ + #define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */ #define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */ #define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */ #define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */ #define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */ -/* #endif //CONFIG_CPU_MONAHANS */ #define _GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3) #define _GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3) @@ -1261,51 +916,15 @@ typedef void (*ExcpHndlr) (void) ; #define _GEDR(x) __REG2(0x40E00048, ((x) & 0x60) >> 3) #define _GAFR(x) __REG2(0x40E00054, ((x) & 0x70) >> 2) -#define GPLR(x) (*((((x) & 0x7f) < 96) ? &_GPLR(x) : &GPLR3)) -#define GPDR(x) (*((((x) & 0x7f) < 96) ? &_GPDR(x) : &GPDR3)) -#define GPSR(x) (*((((x) & 0x7f) < 96) ? &_GPSR(x) : &GPSR3)) -#define GPCR(x) (*((((x) & 0x7f) < 96) ? &_GPCR(x) : &GPCR3)) -#define GRER(x) (*((((x) & 0x7f) < 96) ? &_GRER(x) : &GRER3)) -#define GFER(x) (*((((x) & 0x7f) < 96) ? &_GFER(x) : &GFER3)) -#define GEDR(x) (*((((x) & 0x7f) < 96) ? &_GEDR(x) : &GEDR3)) -#define GAFR(x) (*((((x) & 0x7f) < 96) ? &_GAFR(x) : \ - ((((x) & 0x7f) < 112) ? &GAFR3_L : &GAFR3_U))) - -#ifdef CONFIG_CPU_MONAHANS -#define GSDR0 __REG(0x40E00400) /* Bit-wise Set of GPDR[31:0] */ -#define GSDR1 __REG(0x40E00404) /* Bit-wise Set of GPDR[63:32] */ -#define GSDR2 __REG(0x40E00408) /* Bit-wise Set of GPDR[95:64] */ -#define GSDR3 __REG(0x40E0040C) /* Bit-wise Set of GPDR[127:96] */ - -#define GCDR0 __REG(0x40E00420) /* Bit-wise Clear of GPDR[31:0] */ -#define GCDR1 __REG(0x40E00424) /* Bit-wise Clear of GPDR[63:32] */ -#define GCDR2 __REG(0x40E00428) /* Bit-wise Clear of GPDR[95:64] */ -#define GCDR3 __REG(0x40E0042C) /* Bit-wise Clear of GPDR[127:96] */ - -#define GSRER0 __REG(0x40E00440) /* Set Rising Edge Det. Enable [31:0] */ -#define GSRER1 __REG(0x40E00444) /* Set Rising Edge Det. Enable [63:32] */ -#define GSRER2 __REG(0x40E00448) /* Set Rising Edge Det. Enable [95:64] */ -#define GSRER3 __REG(0x40E0044C) /* Set Rising Edge Det. Enable [127:96] */ - -#define GCRER0 __REG(0x40E00460) /* Clear Rising Edge Det. Enable [31:0] */ -#define GCRER1 __REG(0x40E00464) /* Clear Rising Edge Det. Enable [63:32] */ -#define GCRER2 __REG(0x40E00468) /* Clear Rising Edge Det. Enable [95:64] */ -#define GCRER3 __REG(0x40E0046C) /* Clear Rising Edge Det. Enable[127:96] */ - -#define GSFER0 __REG(0x40E00480) /* Set Falling Edge Det. Enable [31:0] */ -#define GSFER1 __REG(0x40E00484) /* Set Falling Edge Det. Enable [63:32] */ -#define GSFER2 __REG(0x40E00488) /* Set Falling Edge Det. Enable [95:64] */ -#define GSFER3 __REG(0x40E0048C) /* Set Falling Edge Det. Enable[127:96] */ - -#define GCFER0 __REG(0x40E004A0) /* Clr Falling Edge Det. Enable [31:0] */ -#define GCFER1 __REG(0x40E004A4) /* Clr Falling Edge Det. Enable [63:32] */ -#define GCFER2 __REG(0x40E004A8) /* Clr Falling Edge Det. Enable [95:64] */ -#define GCFER3 __REG(0x40E004AC) /* Clr Falling Edge Det. Enable[127:96] */ - -#define GSDR(x) __REG2(0x40E00400, ((x) & 0x60) >> 3) -#define GCDR(x) __REG2(0x40300420, ((x) & 0x60) >> 3) -#endif - +#define GPLR(x) ((((x) & 0x7f) < 96) ? _GPLR(x) : GPLR3) +#define GPDR(x) ((((x) & 0x7f) < 96) ? _GPDR(x) : GPDR3) +#define GPSR(x) ((((x) & 0x7f) < 96) ? _GPSR(x) : GPSR3) +#define GPCR(x) ((((x) & 0x7f) < 96) ? _GPCR(x) : GPCR3) +#define GRER(x) ((((x) & 0x7f) < 96) ? _GRER(x) : GRER3) +#define GFER(x) ((((x) & 0x7f) < 96) ? _GFER(x) : GFER3) +#define GEDR(x) ((((x) & 0x7f) < 96) ? _GEDR(x) : GEDR3) +#define GAFR(x) ((((x) & 0x7f) < 96) ? _GAFR(x) : \ + ((((x) & 0x7f) < 112) ? GAFR3_L : GAFR3_U)) #else #define GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3) @@ -1319,13 +938,11 @@ typedef void (*ExcpHndlr) (void) ; #endif - /* GPIO alternate function assignments */ -#ifndef CONFIG_CPU_MONAHANS /* Monahans has its different definition */ #define GPIO1_RST 1 /* reset */ #define GPIO6_MMCCLK 6 /* MMC Clock */ -#define GPIO7_48MHz 7 /* 48 MHz clock output */ +#define GPIO8_48MHz 7 /* 48 MHz clock output */ #define GPIO8_MMCCS0 8 /* MMC Chip Select 0 */ #define GPIO9_MMCCS1 9 /* MMC Chip Select 1 */ #define GPIO10_RTCCLK 10 /* real time clock (1 Hz) */ @@ -1349,7 +966,6 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO30_SDATA_OUT 30 /* AC97/I2S Sdata_out */ #define GPIO31_SYNC 31 /* AC97/I2S sync */ #define GPIO32_SDATA_IN1 32 /* AC97 Sdata_in1 */ -#define GPIO32_MMCCLK 32 /* MMC Clock (PXA270) */ #define GPIO33_nCS_5 33 /* chip select 5 */ #define GPIO34_FFRXD 34 /* FFUART receive */ #define GPIO34_MMCCS0 34 /* MMC Chip Select 0 */ @@ -1378,7 +994,6 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO53_MMCCLK 53 /* MMC Clock */ #define GPIO54_MMCCLK 54 /* MMC Clock */ #define GPIO54_pSKTSEL 54 /* Socket Select for Card Space */ -#define GPIO54_nPCE_2 54 /* Card Enable for Card Space (PXA27X) */ #define GPIO55_nPREG 55 /* Card Address bit 26 */ #define GPIO56_nPWAIT 56 /* Wait signal for Card Space */ #define GPIO57_nIOIS16 57 /* Bus Width select for I/O Card Space */ @@ -1413,15 +1028,6 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO78_nCS_2 78 /* chip select 2 */ #define GPIO79_nCS_3 79 /* chip select 3 */ #define GPIO80_nCS_4 80 /* chip select 4 */ -#define GPIO85_nPCE_1 85 /* Card Enable for Card Space (PXA27x) */ -#define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */ -#define GPIO109_MMCDAT1 109 /* MMC DAT1 (PXA27x) */ -#define GPIO110_MMCDAT2 110 /* MMC DAT2 (PXA27x) */ -#define GPIO110_MMCCS0 110 /* MMC Chip Select 0 (PXA27x) */ -#define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */ -#define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */ -#define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ -#define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ /* GPIO alternate function mode & direction */ @@ -1439,7 +1045,7 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO1_RTS_MD ( 1 | GPIO_ALT_FN_1_IN) #define GPIO6_MMCCLK_MD ( 6 | GPIO_ALT_FN_1_OUT) -#define GPIO7_48MHz_MD ( 7 | GPIO_ALT_FN_1_OUT) +#define GPIO8_48MHz_MD ( 8 | GPIO_ALT_FN_1_OUT) #define GPIO8_MMCCS0_MD ( 8 | GPIO_ALT_FN_1_OUT) #define GPIO9_MMCCS1_MD ( 9 | GPIO_ALT_FN_1_OUT) #define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT) @@ -1460,14 +1066,13 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO27_SEXTCLK_MD (27 | GPIO_ALT_FN_1_IN) #define GPIO28_BITCLK_AC97_MD (28 | GPIO_ALT_FN_1_IN) #define GPIO28_BITCLK_I2S_MD (28 | GPIO_ALT_FN_2_IN) -#define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN) +#define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN) #define GPIO29_SDATA_IN_I2S_MD (29 | GPIO_ALT_FN_2_IN) #define GPIO30_SDATA_OUT_AC97_MD (30 | GPIO_ALT_FN_2_OUT) -#define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT) +#define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT) #define GPIO31_SYNC_AC97_MD (31 | GPIO_ALT_FN_2_OUT) #define GPIO31_SYNC_I2S_MD (31 | GPIO_ALT_FN_1_OUT) #define GPIO32_SDATA_IN1_AC97_MD (32 | GPIO_ALT_FN_1_IN) -#define GPIO32_MMCCLK_MD ( 32 | GPIO_ALT_FN_2_OUT) #define GPIO33_nCS_5_MD (33 | GPIO_ALT_FN_2_OUT) #define GPIO34_FFRXD_MD (34 | GPIO_ALT_FN_1_IN) #define GPIO34_MMCCS0_MD (34 | GPIO_ALT_FN_2_OUT) @@ -1483,7 +1088,6 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT) #define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN) #define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT) -#define GPIO45_SYSCLK_AC97_MD (45 | GPIO_ALT_FN_1_OUT) #define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN) #define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN) #define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT) @@ -1496,7 +1100,6 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT) #define GPIO53_MMCCLK_MD (53 | GPIO_ALT_FN_1_OUT) #define GPIO54_MMCCLK_MD (54 | GPIO_ALT_FN_1_OUT) -#define GPIO54_nPCE_2_MD (54 | GPIO_ALT_FN_2_OUT) #define GPIO54_pSKTSEL_MD (54 | GPIO_ALT_FN_2_OUT) #define GPIO55_nPREG_MD (55 | GPIO_ALT_FN_2_OUT) #define GPIO56_nPWAIT_MD (56 | GPIO_ALT_FN_1_IN) @@ -1531,99 +1134,14 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO77_LCD_ACBIAS_MD (77 | GPIO_ALT_FN_2_OUT) #define GPIO78_nCS_2_MD (78 | GPIO_ALT_FN_2_OUT) #define GPIO79_nCS_3_MD (79 | GPIO_ALT_FN_2_OUT) -#define GPIO79_pSKTSEL_MD (79 | GPIO_ALT_FN_1_OUT) #define GPIO80_nCS_4_MD (80 | GPIO_ALT_FN_2_OUT) -#define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) -#define GPIO88_USBH1_PWR_MD (88 | GPIO_ALT_FN_1_IN) -#define GPIO89_USBH1_PEN_MD (89 | GPIO_ALT_FN_2_OUT) -#define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) -#define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCDAT2_MD (110 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCCS0_MD (110 | GPIO_ALT_FN_1_OUT) -#define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT) -#define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) -#define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) -#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT) -#define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) -#endif +#define GPIO117_SCL (117 | GPIO_ALT_FN_1_OUT) +#define GPIO118_SDA (118 | GPIO_ALT_FN_1_OUT) + /* * Power Manager */ -#ifdef CONFIG_CPU_MONAHANS - -#define ASCR __REG(0x40F40000) /* Application Subsystem Power Status/Control Register */ -#define ARSR __REG(0x40F40004) /* Application Subsystem Reset Status Register */ -#define AD3ER __REG(0x40F40008) /* Application Subsystem D3 state Wakeup Enable Register */ -#define AD3SR __REG(0x40F4000C) /* Application Subsystem D3 state Wakeup Status Register */ -#define AD2D0ER __REG(0x40F40010) /* Application Subsystem D2 to D0 state Wakeup Enable Register */ -#define AD2D0SR __REG(0x40F40014) /* Application Subsystem D2 to D0 state Wakeup Status Register */ -#define AD2D1ER __REG(0x40F40018) /* Application Subsystem D2 to D1 state Wakeup Enable Register */ -#define AD2D1SR __REG(0x40F4001C) /* Application Subsystem D2 to D1 state Wakeup Status Register */ -#define AD1D0ER __REG(0x40F40020) /* Application Subsystem D1 to D0 state Wakeup Enable Register */ -#define AD1D0SR __REG(0x40F40024) /* Application Subsystem D1 to D0 state Wakeup Status Register */ -#define ASDCNT __REG(0x40F40028) /* Application Subsystem SRAM Drowsy Count Register */ -#define AD3R __REG(0x40F40030) /* Application Subsystem D3 State Configuration Register */ -#define AD2R __REG(0x40F40034) /* Application Subsystem D2 State Configuration Register */ -#define AD1R __REG(0x40F40038) /* Application Subsystem D1 State Configuration Register */ - -#define PMCR __REG(0x40F50000) /* Power Manager Control Register */ -#define PSR __REG(0x40F50004) /* Power Manager S2 Status Register */ -#define PSPR __REG(0x40F50008) /* Power Manager Scratch Pad Register */ -#define PCFR __REG(0x40F5000C) /* Power Manager General Configuration Register */ -#define PWER __REG(0x40F50010) /* Power Manager Wake-up Enable Register */ -#define PWSR __REG(0x40F50014) /* Power Manager Wake-up Status Register */ -#define PECR __REG(0x40F50018) /* Power Manager EXT_WAKEUP[1:0] Control Register */ -#define DCDCSR __REG(0x40F50080) /* DC-DC Controller Status Register */ -#define PVCR __REG(0x40F50100) /* Power Manager Voltage Change Control Register */ -#define PCMD(x) __REG(0x40F50110 + x*4) -#define PCMD0 __REG(0x40F50110 + 0 * 4) -#define PCMD1 __REG(0x40F50110 + 1 * 4) -#define PCMD2 __REG(0x40F50110 + 2 * 4) -#define PCMD3 __REG(0x40F50110 + 3 * 4) -#define PCMD4 __REG(0x40F50110 + 4 * 4) -#define PCMD5 __REG(0x40F50110 + 5 * 4) -#define PCMD6 __REG(0x40F50110 + 6 * 4) -#define PCMD7 __REG(0x40F50110 + 7 * 4) -#define PCMD8 __REG(0x40F50110 + 8 * 4) -#define PCMD9 __REG(0x40F50110 + 9 * 4) -#define PCMD10 __REG(0x40F50110 + 10 * 4) -#define PCMD11 __REG(0x40F50110 + 11 * 4) -#define PCMD12 __REG(0x40F50110 + 12 * 4) -#define PCMD13 __REG(0x40F50110 + 13 * 4) -#define PCMD14 __REG(0x40F50110 + 14 * 4) -#define PCMD15 __REG(0x40F50110 + 15 * 4) -#define PCMD16 __REG(0x40F50110 + 16 * 4) -#define PCMD17 __REG(0x40F50110 + 17 * 4) -#define PCMD18 __REG(0x40F50110 + 18 * 4) -#define PCMD19 __REG(0x40F50110 + 19 * 4) -#define PCMD20 __REG(0x40F50110 + 20 * 4) -#define PCMD21 __REG(0x40F50110 + 21 * 4) -#define PCMD22 __REG(0x40F50110 + 22 * 4) -#define PCMD23 __REG(0x40F50110 + 23 * 4) -#define PCMD24 __REG(0x40F50110 + 24 * 4) -#define PCMD25 __REG(0x40F50110 + 25 * 4) -#define PCMD26 __REG(0x40F50110 + 26 * 4) -#define PCMD27 __REG(0x40F50110 + 27 * 4) -#define PCMD28 __REG(0x40F50110 + 28 * 4) -#define PCMD29 __REG(0x40F50110 + 29 * 4) -#define PCMD30 __REG(0x40F50110 + 30 * 4) -#define PCMD31 __REG(0x40F50110 + 31 * 4) - -#define PCMD_MBC (1<<12) -#define PCMD_DCE (1<<11) -#define PCMD_LC (1<<10) -#define PCMD_SQC (3<<8) /* only 00 and 01 are valid */ - -#define PVCR_FVC (0x1 << 28) -#define PVCR_VCSA (0x1<<14) -#define PVCR_CommandDelay (0xf80) -#define PVCR_ReadPointer (0x01f00000) -#define PVCR_SlaveAddress (0x7f) - -#else - #define PMCR __REG(0x40F00000) /* Power Manager Control Register */ #define PSSR __REG(0x40F00004) /* Power Manager Sleep Status Register */ #define PSPR __REG(0x40F00008) /* Power Manager Scratch Pad Register */ @@ -1638,55 +1156,57 @@ typedef void (*ExcpHndlr) (void) ; #define PGSR3 __REG(0x40F0002C) /* Power Manager GPIO Sleep State Register for GP[118-96] */ #define RCSR __REG(0x40F00030) /* Reset Controller Status Register */ -#define PSLR __REG(0x40F00034) /* Power Manager Sleep Config Register */ -#define PSTR __REG(0x40F00038) /*Power Manager Standby Config Register */ -#define PSNR __REG(0x40F0003C) /*Power Manager Sense Config Register */ -#define PVCR __REG(0x40F00040) /*Power Manager VoltageControl Register */ -#define PKWR __REG(0x40F00050) /* Power Manager KB Wake-up Enable Reg */ -#define PKSR __REG(0x40F00054) /* Power Manager KB Level-Detect Register */ -#define PCMD(x) __REG2(0x40F00080, (x)<<2) -#define PCMD0 __REG(0x40F00080 + 0 * 4) -#define PCMD1 __REG(0x40F00080 + 1 * 4) -#define PCMD2 __REG(0x40F00080 + 2 * 4) -#define PCMD3 __REG(0x40F00080 + 3 * 4) -#define PCMD4 __REG(0x40F00080 + 4 * 4) -#define PCMD5 __REG(0x40F00080 + 5 * 4) -#define PCMD6 __REG(0x40F00080 + 6 * 4) -#define PCMD7 __REG(0x40F00080 + 7 * 4) -#define PCMD8 __REG(0x40F00080 + 8 * 4) -#define PCMD9 __REG(0x40F00080 + 9 * 4) -#define PCMD10 __REG(0x40F00080 + 10 * 4) -#define PCMD11 __REG(0x40F00080 + 11 * 4) -#define PCMD12 __REG(0x40F00080 + 12 * 4) -#define PCMD13 __REG(0x40F00080 + 13 * 4) -#define PCMD14 __REG(0x40F00080 + 14 * 4) -#define PCMD15 __REG(0x40F00080 + 15 * 4) -#define PCMD16 __REG(0x40F00080 + 16 * 4) -#define PCMD17 __REG(0x40F00080 + 17 * 4) -#define PCMD18 __REG(0x40F00080 + 18 * 4) -#define PCMD19 __REG(0x40F00080 + 19 * 4) -#define PCMD20 __REG(0x40F00080 + 20 * 4) -#define PCMD21 __REG(0x40F00080 + 21 * 4) -#define PCMD22 __REG(0x40F00080 + 22 * 4) -#define PCMD23 __REG(0x40F00080 + 23 * 4) -#define PCMD24 __REG(0x40F00080 + 24 * 4) -#define PCMD25 __REG(0x40F00080 + 25 * 4) -#define PCMD26 __REG(0x40F00080 + 26 * 4) -#define PCMD27 __REG(0x40F00080 + 27 * 4) -#define PCMD28 __REG(0x40F00080 + 28 * 4) -#define PCMD29 __REG(0x40F00080 + 29 * 4) -#define PCMD30 __REG(0x40F00080 + 30 * 4) -#define PCMD31 __REG(0x40F00080 + 31 * 4) +#define PSLR __REG(0x40F00034) /* Power Manager Sleep Config Register */ +#define PSTR __REG(0x40F00038) /* Power Manager Standby Config Register */ +#define PSNR __REG(0x40F0003C) /* Power Manager Sense Config Register */ +#define PVCR __REG(0x40F00040) /* Power Manager VoltageControl Register */ +#define PKWR __REG(0x40F00050) /* Power Manager KB Wake-up Enable Reg */ +#define PKSR __REG(0x40F00054) /* Power Manager KB Level-Detect Register */ +#define PCMD(x) __REG(0x40F00080 + x*4) +#define PCMD0 __REG(0x40F00080 + 0 * 4) +#define PCMD1 __REG(0x40F00080 + 1 * 4) +#define PCMD2 __REG(0x40F00080 + 2 * 4) +#define PCMD3 __REG(0x40F00080 + 3 * 4) +#define PCMD4 __REG(0x40F00080 + 4 * 4) +#define PCMD5 __REG(0x40F00080 + 5 * 4) +#define PCMD6 __REG(0x40F00080 + 6 * 4) +#define PCMD7 __REG(0x40F00080 + 7 * 4) +#define PCMD8 __REG(0x40F00080 + 8 * 4) +#define PCMD9 __REG(0x40F00080 + 9 * 4) +#define PCMD10 __REG(0x40F00080 + 10 * 4) +#define PCMD11 __REG(0x40F00080 + 11 * 4) +#define PCMD12 __REG(0x40F00080 + 12 * 4) +#define PCMD13 __REG(0x40F00080 + 13 * 4) +#define PCMD14 __REG(0x40F00080 + 14 * 4) +#define PCMD15 __REG(0x40F00080 + 15 * 4) +#define PCMD16 __REG(0x40F00080 + 16 * 4) +#define PCMD17 __REG(0x40F00080 + 17 * 4) +#define PCMD18 __REG(0x40F00080 + 18 * 4) +#define PCMD19 __REG(0x40F00080 + 19 * 4) +#define PCMD20 __REG(0x40F00080 + 20 * 4) +#define PCMD21 __REG(0x40F00080 + 21 * 4) +#define PCMD22 __REG(0x40F00080 + 22 * 4) +#define PCMD23 __REG(0x40F00080 + 23 * 4) +#define PCMD24 __REG(0x40F00080 + 24 * 4) +#define PCMD25 __REG(0x40F00080 + 25 * 4) +#define PCMD26 __REG(0x40F00080 + 26 * 4) +#define PCMD27 __REG(0x40F00080 + 27 * 4) +#define PCMD28 __REG(0x40F00080 + 28 * 4) +#define PCMD29 __REG(0x40F00080 + 29 * 4) +#define PCMD30 __REG(0x40F00080 + 30 * 4) +#define PCMD31 __REG(0x40F00080 + 31 * 4) -#define PCMD_MBC (1<<12) -#define PCMD_DCE (1<<11) -#define PCMD_LC (1<<10) +#define PCMD_MBC (1<<12) +#define PCMD_DCE (1<<11) +#define PCMD_LC (1<<10) /* FIXME: PCMD_SQC need be checked. */ -#define PCMD_SQC (3<<8) /* currently only bit 8 is changeable, - bit 9 should be 0 all day. */ -#define PVCR_VCSA (0x1<<14) -#define PVCR_CommandDelay (0xf80) -#define PCFR_PI2C_EN (0x1 << 6) +#define PCMD_SQC (3<<8) /* currently only bit 8 is changerable, */ + /* bit 9 should be 0 all day. */ +#define PVCR_VCSA (0x1<<14) +#define PVCR_CommandDelay (0xf80) +/* define MACRO for Power Manager General Configuration Register (PCFR) */ +#define PCFR_FVC (0x1 << 10) +#define PCFR_PI2C_EN (0x1 << 6) #define PSSR_OTGPH (1 << 6) /* OTG Peripheral control Hold */ #define PSSR_RDH (1 << 5) /* Read Disable Hold */ @@ -1695,13 +1215,6 @@ typedef void (*ExcpHndlr) (void) ; #define PSSR_BFS (1 << 1) /* Battery Fault Status */ #define PSSR_SSS (1 << 0) /* Software Sleep Status */ -#define PCFR_RO (1 << 15) /* RDH Override */ -#define PCFR_PO (1 << 14) /* PH Override */ -#define PCFR_GPROD (1 << 12) /* GPIO nRESET_OUT Disable */ -#define PCFR_L1_EN (1 << 11) /* Sleep Mode L1 converter Enable */ -#define PCFR_FVC (1 << 10) /* Frequency/Voltage Change */ -#define PCFR_DC_EN (1 << 7) /* Sleep/deep-sleep DC-DC Converter Enable */ -#define PCFR_PI2CEN (1 << 6) /* Enable PI2C controller */ #define PCFR_DS (1 << 3) /* Deep Sleep Mode */ #define PCFR_FS (1 << 2) /* Float Static Chip Selects */ #define PCFR_FP (1 << 1) /* Float PCMCIA controls */ @@ -1711,52 +1224,19 @@ typedef void (*ExcpHndlr) (void) ; #define RCSR_SMR (1 << 2) /* Sleep Mode */ #define RCSR_WDR (1 << 1) /* Watchdog Reset */ #define RCSR_HWR (1 << 0) /* Hardware Reset */ -#endif /* CONFIG_CPU_MONAHANS */ /* * SSP Serial Port Registers */ - #define SSCR0 __REG(0x41000000) /* SSP Control Register 0 */ #define SSCR1 __REG(0x41000004) /* SSP Control Register 1 */ #define SSSR __REG(0x41000008) /* SSP Status Register */ #define SSITR __REG(0x4100000C) /* SSP Interrupt Test Register */ #define SSDR __REG(0x41000010) /* (Write / Read) SSP Data Write Register/SSP Data Read Register */ -#define SSCR0_DSS (0x0000000f) /* Data Size Select (mask) */ -#define SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..16] */ -#define SSCR0_FRF (0x00000030) /* FRame Format (mask) */ -#define SSCR0_Motorola (0x0 << 4) /* Motorola's Serial Peripheral Interface (SPI) */ -#define SSCR0_TI (0x1 << 4) /* Texas Instruments' Synchronous Serial Protocol (SSP) */ -#define SSCR0_National (0x2 << 4) /* National Microwire */ -#define SSCR0_ECS (1 << 6) /* External clock select */ -#define SSCR0_SSE (1 << 7) /* Synchronous Serial Port Enable */ -#define SSCR0_SCR (0x0000ff00) /* Serial Clock Rate (mask) */ -#define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */ - -#define SSCR1_RIE (1 << 0) /* Receive FIFO Interrupt Enable */ -#define SSCR1_TIE (1 << 1) /* Transmit FIFO Interrupt Enable */ -#define SSCR1_LBM (1 << 2) /* Loop-Back Mode */ -#define SSCR1_SPO (1 << 3) /* Motorola SPI SSPSCLK polarity setting */ -#define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ -#define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ -#define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */ -#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ -#define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ -#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ - -#define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ -#define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ -#define SSSR_BSY (1 << 4) /* SSP Busy */ -#define SSSR_TFS (1 << 5) /* Transmit FIFO Service Request */ -#define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ -#define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ - - /* * MultiMediaCard (MMC) controller */ - #define MMC_STRPCL __REG(0x41100000) /* Control to start and stop MMC clock */ #define MMC_STAT __REG(0x41100004) /* MMC Status Register (read only) */ #define MMC_CLKRT __REG(0x41100008) /* MMC clock rate */ @@ -1776,102 +1256,19 @@ typedef void (*ExcpHndlr) (void) ; #define MMC_RXFIFO __REG(0x41100040) /* Receive FIFO (read only) */ #define MMC_TXFIFO __REG(0x41100044) /* Transmit FIFO (write only) */ -/* - * MultiMediaCard (MMC2) controller - */ - -#define MMC2_STRPCL __REG_2(0x42000000) /* Control to start and stop MMC clock */ -#define MMC2_STAT __REG_2(0x42000004) /* MMC Status Register (read only) */ -#define MMC2_CLKRT __REG_2(0x42000008) /* MMC clock rate */ -#define MMC2_SPI __REG_2(0x4200000c) /* SPI mode control bits */ -#define MMC2_CMDAT __REG_2(0x42000010) /* Command/response/data sequence control */ -#define MMC2_RESTO __REG_2(0x42000014) /* Expected response time out */ -#define MMC2_RDTO __REG_2(0x42000018) /* Expected data read time out */ -#define MMC2_BLKLEN __REG_2(0x4200001c) /* Block length of data transaction */ -#define MMC2_NOB __REG_2(0x42000020) /* Number of blocks, for block mode */ -#define MMC2_PRTBUF __REG_2(0x42000024) /* Partial MMC_TXFIFO FIFO written */ -#define MMC2_I_MASK __REG_2(0x42000028) /* Interrupt Mask */ -#define MMC2_I_REG __REG_2(0x4200002c) /* Interrupt Register (read only) */ -#define MMC2_CMD __REG_2(0x42000030) /* Index of current command */ -#define MMC2_ARGH __REG_2(0x42000034) /* MSW part of the current command argument */ -#define MMC2_ARGL __REG_2(0x42000038) /* LSW part of the current command argument */ -#define MMC2_RES __REG_2(0x4200003c) /* Response FIFO (read only) */ -#define MMC2_RXFIFO __REG_2(0x42000040) /* Receive FIFO (read only) */ -#define MMC2_TXFIFO __REG_2(0x42000044) /* Transmit FIFO (write only) */ - /* * Core Clock */ -#if defined(CONFIG_CPU_MONAHANS) -#define ACCR __REG(0x41340000) /* Application Subsystem Clock Configuration Register */ -#define ACSR __REG(0x41340004) /* Application Subsystem Clock Status Register */ -#define AICSR __REG(0x41340008) /* Application Subsystem Interrupt Control/Status Register */ -#define CKENA __REG(0x4134000C) /* A Clock Enable Register */ -#define CKENB __REG(0x41340010) /* B Clock Enable Register */ -#define AC97_DIV __REG(0x41340014) /* AC97 clock divisor value register */ - -#define ACCR_SMC_MASK 0x03800000 /* Static Memory Controller Frequency Select */ -#define ACCR_SRAM_MASK 0x000c0000 /* SRAM Controller Frequency Select */ -#define ACCR_FC_MASK 0x00030000 /* Frequency Change Frequency Select */ -#define ACCR_HSIO_MASK 0x0000c000 /* High Speed IO Frequency Select */ -#define ACCR_DDR_MASK 0x00003000 /* DDR Memory Controller Frequency Select */ -#define ACCR_XN_MASK 0x00000700 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ -#define ACCR_XL_MASK 0x0000001f /* Crystal Frequency to Memory Frequency Multiplier */ -#define ACCR_XPDIS (1 << 31) -#define ACCR_SPDIS (1 << 30) -#define ACCR_13MEND1 (1 << 27) -#define ACCR_D0CS (1 << 26) -#define ACCR_13MEND2 (1 << 21) -#define ACCR_PCCE (1 << 11) - -#define CKENA_30_MSL0 (1 << 30) /* MSL0 Interface Unit Clock Enable */ -#define CKENA_29_SSP4 (1 << 29) /* SSP3 Unit Clock Enable */ -#define CKENA_28_SSP3 (1 << 28) /* SSP2 Unit Clock Enable */ -#define CKENA_27_SSP2 (1 << 27) /* SSP1 Unit Clock Enable */ -#define CKENA_26_SSP1 (1 << 26) /* SSP0 Unit Clock Enable */ -#define CKENA_25_TSI (1 << 25) /* TSI Clock Enable */ -#define CKENA_24_AC97 (1 << 24) /* AC97 Unit Clock Enable */ -#define CKENA_23_STUART (1 << 23) /* STUART Unit Clock Enable */ -#define CKENA_22_FFUART (1 << 22) /* FFUART Unit Clock Enable */ -#define CKENA_21_BTUART (1 << 21) /* BTUART Unit Clock Enable */ -#define CKENA_20_UDC (1 << 20) /* UDC Clock Enable */ -#define CKENA_19_TPM (1 << 19) /* TPM Unit Clock Enable */ -#define CKENA_18_USIM1 (1 << 18) /* USIM1 Unit Clock Enable */ -#define CKENA_17_USIM0 (1 << 17) /* USIM0 Unit Clock Enable */ -#define CKENA_15_CIR (1 << 15) /* Consumer IR Clock Enable */ -#define CKENA_14_KEY (1 << 14) /* Keypad Controller Clock Enable */ -#define CKENA_13_MMC1 (1 << 13) /* MMC1 Clock Enable */ -#define CKENA_12_MMC0 (1 << 12) /* MMC0 Clock Enable */ -#define CKENA_11_FLASH (1 << 11) /* Boot ROM Clock Enable */ -#define CKENA_10_SRAM (1 << 10) /* SRAM Controller Clock Enable */ -#define CKENA_9_SMC (1 << 9) /* Static Memory Controller */ -#define CKENA_8_DMC (1 << 8) /* Dynamic Memory Controller */ -#define CKENA_7_GRAPHICS (1 << 7) /* 2D Graphics Clock Enable */ -#define CKENA_6_USBCLI (1 << 6) /* USB Client Unit Clock Enable */ -#define CKENA_4_NAND (1 << 4) /* NAND Flash Controller Clock Enable */ -#define CKENA_3_CAMERA (1 << 3) /* Camera Interface Clock Enable */ -#define CKENA_2_USBHOST (1 << 2) /* USB Host Unit Clock Enable */ -#define CKENA_1_LCD (1 << 1) /* LCD Unit Clock Enable */ - -#define CKENB_8_1WIRE ((1 << 8) + 32) /* One Wire Interface Unit Clock Enable */ -#define CKENB_7_GPIO ((1 << 7) + 32) /* GPIO Clock Enable */ -#define CKENB_6_IRQ ((1 << 6) + 32) /* Interrupt Controller Clock Enable */ -#define CKENB_4_I2C ((1 << 4) + 32) /* I2C Unit Clock Enable */ -#define CKENB_1_PWM1 ((1 << 1) + 32) /* PWM2 & PWM3 Clock Enable */ -#define CKENB_0_PWM0 ((1 << 0) + 32) /* PWM0 & PWM1 Clock Enable */ - -#else /* if defined CONFIG_CPU_MONAHANS */ - #define CCCR __REG(0x41300000) /* Core Clock Configuration Register */ #define CKEN __REG(0x41300004) /* Clock Enable Register */ #define OSCC __REG(0x41300008) /* Oscillator Configuration Register */ -#define CCSR __REG(0x4130000C) /* Core Clock Status Register */ #define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ +#if !defined(CONFIG_PXA27X) #define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */ +#endif #define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */ -#define CKEN31_AC97 (1 << 31) #define CKEN24_CAMERA (1 << 24) /* Camera Interface Clock Enable */ #define CKEN23_SSP1 (1 << 23) /* SSP1 Unit Clock Enable */ #define CKEN22_MEMC (1 << 22) /* Memory Controller Clock Enable */ @@ -1886,15 +1283,15 @@ typedef void (*ExcpHndlr) (void) ; #define CKEN13_FICP (1 << 13) /* FICP Unit Clock Enable */ #define CKEN12_MMC (1 << 12) /* MMC Unit Clock Enable */ #define CKEN11_USB (1 << 11) /* USB Unit Clock Enable */ +#if defined(CONFIG_PXA27X) #define CKEN10_USBHOST (1 << 10) /* USB Host Unit Clock Enable */ -#define CKEN9_OSTIMER (1 << 9) /* OS Timer Unit Clock Enable */ +#define CKEN24_CAMERA (1 << 24) /* Camera Unit Clock Enable */ +#endif #define CKEN8_I2S (1 << 8) /* I2S Unit Clock Enable */ #define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */ #define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */ #define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */ -#define CKEN4_SSP3 (1 << 4) /* SSP3 Unit Clock Enable */ #define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */ -#define CKEN3_SSP2 (1 << 3) /* SSP2 Unit Clock Enable */ #define CKEN2_AC97 (1 << 2) /* AC97 Unit Clock Enable */ #define CKEN1_PWM1 (1 << 1) /* PWM1 Clock Enable */ #define CKEN0_PWM0 (1 << 0) /* PWM0 Clock Enable */ @@ -1903,54 +1300,39 @@ typedef void (*ExcpHndlr) (void) ; #define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */ #if !defined(CONFIG_PXA27X) -#define CCCR_L09 (0x1F) -#define CCCR_L27 (0x1) -#define CCCR_L32 (0x2) -#define CCCR_L36 (0x3) -#define CCCR_L40 (0x4) -#define CCCR_L45 (0x5) +#define CCCR_L09 (0x1F) +#define CCCR_L27 (0x1) +#define CCCR_L32 (0x2) +#define CCCR_L36 (0x3) +#define CCCR_L40 (0x4) +#define CCCR_L45 (0x5) -#define CCCR_M1 (0x1 << 5) -#define CCCR_M2 (0x2 << 5) -#define CCCR_M4 (0x3 << 5) +#define CCCR_M1 (0x1 << 5) +#define CCCR_M2 (0x2 << 5) +#define CCCR_M4 (0x3 << 5) -#define CCCR_N10 (0x2 << 7) -#define CCCR_N15 (0x3 << 7) -#define CCCR_N20 (0x4 << 7) -#define CCCR_N25 (0x5 << 7) -#define CCCR_N30 (0x6 << 7) +#define CCCR_N10 (0x2 << 7) +#define CCCR_N15 (0x3 << 7) +#define CCCR_N20 (0x4 << 7) +#define CCCR_N25 (0x5 << 7) +#define CCCR_N30 (0x6 << 7) #endif -#endif /* CONFIG_CPU_MONAHANS */ - /* * LCD */ -#ifndef CONFIG_CPU_MONAHANS - #define LCCR0 __REG(0x44000000) /* LCD Controller Control Register 0 */ #define LCCR1 __REG(0x44000004) /* LCD Controller Control Register 1 */ #define LCCR2 __REG(0x44000008) /* LCD Controller Control Register 2 */ #define LCCR3 __REG(0x4400000C) /* LCD Controller Control Register 3 */ #define DFBR0 __REG(0x44000020) /* DMA Channel 0 Frame Branch Register */ #define DFBR1 __REG(0x44000024) /* DMA Channel 1 Frame Branch Register */ -#define LCSR __REG(0x44000038) /* LCD Controller Status Register */ #define LCSR0 __REG(0x44000038) /* LCD Controller Status Register */ #define LCSR1 __REG(0x44000034) /* LCD Controller Status Register */ #define LIIDR __REG(0x4400003C) /* LCD Controller Interrupt ID Register */ #define TMEDRGBR __REG(0x44000040) /* TMED RGB Seed Register */ #define TMEDCR __REG(0x44000044) /* TMED Control Register */ -#define LCCR3_1BPP (0 << 24) -#define LCCR3_2BPP (1 << 24) -#define LCCR3_4BPP (2 << 24) -#define LCCR3_8BPP (3 << 24) -#define LCCR3_16BPP (4 << 24) -#define LCCR3_18BPP (6 << 24) /* packed pixel format */ -#define LCCR3_19BPP (8 << 24) /* packed pixel format */ -#define LCCR3_24BPP (9 << 24) -#define LCCR3_25BPP (10<< 24) - #define FDADR0 __REG(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */ #define FSADR0 __REG(0x44000204) /* DMA Channel 0 Frame Source Address Register */ #define FIDR0 __REG(0x44000208) /* DMA Channel 0 Frame ID Register */ @@ -1960,116 +1342,71 @@ typedef void (*ExcpHndlr) (void) ; #define FIDR1 __REG(0x44000218) /* DMA Channel 1 Frame ID Register */ #define LDCMD1 __REG(0x4400021C) /* DMA Channel 1 Command Register */ -#else - -#define LCCR0 __REG_2(0x44000000) /* LCD Controller Control Register 0 */ -#define LCCR1 __REG_2(0x44000004) /* LCD Controller Control Register 1 */ -#define LCCR2 __REG_2(0x44000008) /* LCD Controller Control Register 2 */ -#define LCCR3 __REG_2(0x4400000C) /* LCD Controller Control Register 3 */ -#define DFBR0 __REG_2(0x44000020) /* DMA Channel 0 Frame Branch Register */ -#define DFBR1 __REG_2(0x44000024) /* DMA Channel 1 Frame Branch Register */ -#define LCSR __REG_2(0x44000038) /* LCD Controller Status Register */ -#define LCSR1 __REG_2(0x44000034) /* LCD Controller Status Register */ -#define LIIDR __REG_2(0x4400003C) /* LCD Controller Interrupt ID Register */ -#define TMEDRGBR __REG_2(0x44000040) /* TMED RGB Seed Register */ -#define TMEDCR __REG_2(0x44000044) /* TMED Control Register */ - -#define LCCR3_1BPP (0 << 24) -#define LCCR3_2BPP (1 << 24) -#define LCCR3_4BPP (2 << 24) -#define LCCR3_8BPP (3 << 24) -#define LCCR3_16BPP (4 << 24) -#define LCCR3_18BPP (6 << 24) /* packed pixel format */ -#define LCCR3_19BPP (8 << 24) /* packed pixel format */ -#define LCCR3_24BPP (9 << 24) -#define LCCR3_25BPP (10<< 24) - -#define FDADR0 __REG_2(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */ -#define FSADR0 __REG_2(0x44000204) /* DMA Channel 0 Frame Source Address Register */ -#define FIDR0 __REG_2(0x44000208) /* DMA Channel 0 Frame ID Register */ -#define LDCMD0 __REG_2(0x4400020C) /* DMA Channel 0 Command Register */ -#define FDADR1 __REG_2(0x44000210) /* DMA Channel 1 Frame Descriptor Address Register */ -#define FSADR1 __REG_2(0x44000214) /* DMA Channel 1 Frame Source Address Register */ -#define FIDR1 __REG_2(0x44000218) /* DMA Channel 1 Frame ID Register */ -#define LDCMD1 __REG_2(0x4400021C) /* DMA Channel 1 Command Register */ - -#endif - #define LCCR0_ENB (1 << 0) /* LCD Controller enable */ -#define LCCR0_CMS (1 << 1) /* Color/Monochrome Display Select */ -#define LCCR0_Color (LCCR0_CMS*0) /* Color display */ -#define LCCR0_Mono (LCCR0_CMS*1) /* Monochrome display */ -#define LCCR0_SDS (1 << 2) /* Single/Dual Panel Display */ - /* Select */ -#define LCCR0_Sngl (LCCR0_SDS*0) /* Single panel display */ -#define LCCR0_Dual (LCCR0_SDS*1) /* Dual panel display */ - +#define LCCR0_CMS (1 << 1) /* Color = 0, Monochrome = 1 */ +#define LCCR0_SDS (1 << 2) /* Single Panel = 0, Dual Panel = 1 */ #define LCCR0_LDM (1 << 3) /* LCD Disable Done Mask */ #define LCCR0_SFM (1 << 4) /* Start of frame mask */ #define LCCR0_IUM (1 << 5) /* Input FIFO underrun mask */ #define LCCR0_EFM (1 << 6) /* End of Frame mask */ -#define LCCR0_PAS (1 << 7) /* Passive/Active display Select */ -#define LCCR0_Pas (LCCR0_PAS*0) /* Passive display (STN) */ -#define LCCR0_Act (LCCR0_PAS*1) /* Active display (TFT) */ -#define LCCR0_DPD (1 << 9) /* Double Pixel Data (monochrome */ - /* display mode) */ -#define LCCR0_4PixMono (LCCR0_DPD*0) /* 4-Pixel/clock Monochrome */ - /* display */ -#define LCCR0_8PixMono (LCCR0_DPD*1) /* 8-Pixel/clock Monochrome */ - /* display */ +#define LCCR0_PAS (1 << 7) /* Passive = 0, Active = 1 */ +#define LCCR0_BLE (1 << 8) /* Little Endian = 0, Big Endian = 1 */ +#define LCCR0_DPD (1 << 9) /* Double Pixel mode, 4 pixel value = 0, 8 pixle values = 1 */ #define LCCR0_DIS (1 << 10) /* LCD Disable */ #define LCCR0_QDM (1 << 11) /* LCD Quick Disable mask */ #define LCCR0_PDD (0xff << 12) /* Palette DMA request delay */ #define LCCR0_PDD_S 12 -#define LCCR0_BM (1 << 20) /* Branch mask */ +#define LCCR0_BM (1 << 20) /* Branch mask */ #define LCCR0_OUM (1 << 21) /* Output FIFO underrun mask */ -#define LCCR0_LCDT (1 << 22) /* LCD Panel Type */ -#define LCCR0_RDSTM (1 << 23) /* Read Status Interrupt Mask */ -#define LCCR0_CMDIM (1 << 24) /* Command Interrupt Mask */ +#if defined(CONFIG_PXA27X) +#define LCCR0_LCDT (1 << 22) /* LCD Panel Type */ +#define LCCR0_RDSTM (1 << 23) /* Read Status Interrupt Mask */ +#define LCCR0_CMDIM (1 << 24) /* Command Interrupt Mask */ +#endif -#define LCCR1_PPL Fld (10, 0) /* Pixels Per Line - 1 */ -#define LCCR1_DisWdth(Pixel) /* Display Width [1..800 pix.] */ \ - (((Pixel) - 1) << FShft (LCCR1_PPL)) +#define LCCR1_PPL Fld (10, 0) /* Pixels Per Line - 1 */ +#define LCCR1_DisWdth(Pixel) /* Display Width [1..800 pix.] */ \ + (((Pixel) - 1) << FShft (LCCR1_PPL)) -#define LCCR1_HSW Fld (6, 10) /* Horizontal Synchronization */ -#define LCCR1_HorSnchWdth(Tpix) /* Horizontal Synchronization */ \ - /* pulse Width [1..64 Tpix] */ \ - (((Tpix) - 1) << FShft (LCCR1_HSW)) +#define LCCR1_HSW Fld (6, 10) /* Horizontal Synchronization */ +#define LCCR1_HorSnchWdth(Tpix) /* Horizontal Synchronization */ \ + /* pulse Width [1..64 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_HSW)) -#define LCCR1_ELW Fld (8, 16) /* End-of-Line pixel clock Wait */ - /* count - 1 [Tpix] */ -#define LCCR1_EndLnDel(Tpix) /* End-of-Line Delay */ \ - /* [1..256 Tpix] */ \ - (((Tpix) - 1) << FShft (LCCR1_ELW)) +#define LCCR1_ELW Fld (8, 16) /* End-of-Line pixel clock Wait */ + /* count - 1 [Tpix] */ +#define LCCR1_EndLnDel(Tpix) /* End-of-Line Delay */ \ + /* [1..256 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_ELW)) -#define LCCR1_BLW Fld (8, 24) /* Beginning-of-Line pixel clock */ - /* Wait count - 1 [Tpix] */ -#define LCCR1_BegLnDel(Tpix) /* Beginning-of-Line Delay */ \ - /* [1..256 Tpix] */ \ - (((Tpix) - 1) << FShft (LCCR1_BLW)) +#define LCCR1_BLW Fld (8, 24) /* Beginning-of-Line pixel clock */ + /* Wait count - 1 [Tpix] */ +#define LCCR1_BegLnDel(Tpix) /* Beginning-of-Line Delay */ \ + /* [1..256 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_BLW)) -#define LCCR2_LPP Fld (10, 0) /* Line Per Panel - 1 */ -#define LCCR2_DisHght(Line) /* Display Height [1..1024 lines] */ \ - (((Line) - 1) << FShft (LCCR2_LPP)) +#define LCCR2_LPP Fld (10, 0) /* Line Per Panel - 1 */ +#define LCCR2_DisHght(Line) /* Display Height [1..1024 lines] */ \ + (((Line) - 1) << FShft (LCCR2_LPP)) -#define LCCR2_VSW Fld (6, 10) /* Vertical Synchronization pulse */ - /* Width - 1 [Tln] (L_FCLK) */ -#define LCCR2_VrtSnchWdth(Tln) /* Vertical Synchronization pulse */ \ - /* Width [1..64 Tln] */ \ - (((Tln) - 1) << FShft (LCCR2_VSW)) +#define LCCR2_VSW Fld (6, 10) /* Vertical Synchronization pulse */ + /* Width - 1 [Tln] (L_FCLK) */ +#define LCCR2_VrtSnchWdth(Tln) /* Vertical Synchronization pulse */ \ + /* Width [1..64 Tln] */ \ + (((Tln) - 1) << FShft (LCCR2_VSW)) -#define LCCR2_EFW Fld (8, 16) /* End-of-Frame line clock Wait */ - /* count [Tln] */ -#define LCCR2_EndFrmDel(Tln) /* End-of-Frame Delay */ \ - /* [0..255 Tln] */ \ - ((Tln) << FShft (LCCR2_EFW)) +#define LCCR2_EFW Fld (8, 16) /* End-of-Frame line clock Wait */ + /* count [Tln] */ +#define LCCR2_EndFrmDel(Tln) /* End-of-Frame Delay */ \ + /* [0..255 Tln] */ \ + ((Tln) << FShft (LCCR2_EFW)) -#define LCCR2_BFW Fld (8, 24) /* Beginning-of-Frame line clock */ - /* Wait count [Tln] */ -#define LCCR2_BegFrmDel(Tln) /* Beginning-of-Frame Delay */ \ - /* [0..255 Tln] */ \ - ((Tln) << FShft (LCCR2_BFW)) +#define LCCR2_BFW Fld (8, 24) /* Beginning-of-Frame line clock */ + /* Wait count [Tln] */ +#define LCCR2_BegFrmDel(Tln) /* Beginning-of-Frame Delay */ \ + /* [0..255 Tln] */ \ + ((Tln) << FShft (LCCR2_BFW)) #if 0 #define LCCR3_PCD (0xff) /* Pixel clock divisor */ @@ -2081,73 +1418,54 @@ typedef void (*ExcpHndlr) (void) ; #define LCCR3_API_S 16 #define LCCR3_VSP (1 << 20) /* vertical sync polarity */ #define LCCR3_HSP (1 << 21) /* horizontal sync polarity */ -#define LCCR3_PCP (1 << 22) /* Pixel Clock Polarity (L_PCLK) */ -#define LCCR3_PixRsEdg (LCCR3_PCP*0) /* Pixel clock Rising-Edge */ -#define LCCR3_PixFlEdg (LCCR3_PCP*1) /* Pixel clock Falling-Edge */ - -#define LCCR3_OEP (1 << 23) /* Output Enable Polarity (L_BIAS, */ - /* active display mode) */ -#define LCCR3_OutEnH (LCCR3_OEP*0) /* Output Enable active High */ -#define LCCR3_OutEnL (LCCR3_OEP*1) /* Output Enable active Low */ - +#define LCCR3_PCP (1 << 22) /* pixel clock polarity */ +#define LCCR3_OEP (1 << 23) /* output enable polarity */ #if 0 #define LCCR3_BPP (7 << 24) /* bits per pixel */ #define LCCR3_BPP_S 24 #endif #define LCCR3_DPC (1 << 27) /* double pixel clock mode */ - -#define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor */ -#define LCCR3_PixClkDiv(Div) /* Pixel Clock Divisor */ \ - (((Div) << FShft (LCCR3_PCD))) +#define LCCR3_PDFOR_0 (0 << 30) +#define LCCR3_PDFOR_1 (1 << 30) +#define LCCR3_PDFOR_2 (2 << 30) +#define LCCR3_PDFOR_3 (3 << 30) -#define LCCR3_BPP Fld (3, 24) /* Bit Per Pixel */ -#define LCCR3_Bpp(Bpp) /* Bit Per Pixel */ \ - (((Bpp) << FShft (LCCR3_BPP))) +#define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor */ +#define LCCR3_PixClkDiv(Div) /* Pixel Clock Divisor */ \ + (((Div) << FShft (LCCR3_PCD))) -#define LCCR3_ACB Fld (8, 8) /* AC Bias */ -#define LCCR3_Acb(Acb) /* BAC Bias */ \ - (((Acb) << FShft (LCCR3_ACB))) -#define LCCR3_HorSnchH (LCCR3_HSP*0) /* Horizontal Synchronization */ - /* pulse active High */ -#define LCCR3_HorSnchL (LCCR3_HSP*1) /* Horizontal Synchronization */ +#define LCCR3_BPP Fld (3, 24) /* Bit Per Pixel */ +#define LCCR3_Bpp(Bpp) /* Bit Per Pixel */ \ + ((((Bpp&0x7) << FShft (LCCR3_BPP)))|(((Bpp&0x8)<<26))) -#define LCCR3_VrtSnchH (LCCR3_VSP*0) /* Vertical Synchronization pulse */ - /* active High */ -#define LCCR3_VrtSnchL (LCCR3_VSP*1) /* Vertical Synchronization pulse */ - /* active Low */ +#define LCCR3_ACB Fld (8, 8) /* AC Bias */ +#define LCCR3_Acb(Acb) /* BAC Bias */ \ + (((Acb) << FShft (LCCR3_ACB))) -#define LCSR_LDD (1 << 0) /* LCD Disable Done */ -#define LCSR_SOF (1 << 1) /* Start of frame */ -#define LCSR_BER (1 << 2) /* Bus error */ -#define LCSR_ABC (1 << 3) /* AC Bias count */ -#define LCSR_IUL (1 << 4) /* input FIFO underrun Lower panel */ -#define LCSR_IUU (1 << 5) /* input FIFO underrun Upper panel */ -#define LCSR_OU (1 << 6) /* output FIFO underrun */ -#define LCSR_QD (1 << 7) /* quick disable */ -#define LCSR_EOF (1 << 8) /* end of frame */ -#define LCSR_BS (1 << 9) /* branch status */ -#define LCSR_SINT (1 << 10) /* subsequent interrupt */ +#define LCCR3_HorSnchH (LCCR3_HSP*0) /* Horizontal Synchronization */ + /* pulse active High */ +#define LCCR3_HorSnchL (LCCR3_HSP*1) /* Horizontal Synchronization */ -#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */ +#define LCCR3_VrtSnchH (LCCR3_VSP*0) /* Vertical Synchronization pulse */ + /* active High */ +#define LCCR3_VrtSnchL (LCCR3_VSP*1) /* Vertical Synchronization pulse */ + /* active Low */ -#define LCSR_LDD (1 << 0) /* LCD Disable Done */ -#define LCSR_SOF (1 << 1) /* Start of frame */ -#define LCSR_BER (1 << 2) /* Bus error */ -#define LCSR_ABC (1 << 3) /* AC Bias count */ -#define LCSR_IUL (1 << 4) /* input FIFO underrun Lower panel */ -#define LCSR_IUU (1 << 5) /* input FIFO underrun Upper panel */ -#define LCSR_OU (1 << 6) /* output FIFO underrun */ -#define LCSR_QD (1 << 7) /* quick disable */ -#define LCSR_EOF (1 << 8) /* end of frame */ -#define LCSR_BS (1 << 9) /* branch status */ -#define LCSR_SINT (1 << 10) /* subsequent interrupt */ +#define LCSR0_LDD (1 << 0) /* LCD Disable Done */ +#define LCSR0_SOF (1 << 1) /* Start of frame */ +#define LCSR0_BER (1 << 2) /* Bus error */ +#define LCSR0_ABC (1 << 3) /* AC Bias count */ +#define LCSR0_IUL (1 << 4) /* input FIFO underrun Lower panel */ +#define LCSR0_IUU (1 << 5) /* input FIFO underrun Upper panel */ +#define LCSR0_OU (1 << 6) /* output FIFO underrun */ +#define LCSR0_QD (1 << 7) /* quick disable */ +#define LCSR0_EOF0 (1 << 8) /* end of frame */ +#define LCSR0_BS (1 << 9) /* branch status */ +#define LCSR0_SINT (1 << 10) /* subsequent interrupt */ -#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */ - -/* Overlay1 & Overlay2 & Hardware Cursor */ #define LCSR1_SOF1 (1 << 0) #define LCSR1_SOF2 (1 << 1) #define LCSR1_SOF3 (1 << 2) @@ -2175,43 +1493,124 @@ typedef void (*ExcpHndlr) (void) ; #define LCSR1_IU5 (1 << 28) #define LCSR1_IU6 (1 << 29) +#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */ +#if defined(CONFIG_PXA27X) #define LDCMD_SOFINT (1 << 22) #define LDCMD_EOFINT (1 << 21) +#endif -#define LCCR0_LDDALT (1<<26) /* LDD Alternate mapping bit when base pixel is RGBT16 */ -#define LCCR0_OUC (1<<25) /* Overlay Underlay Control Bit */ +/* + * Memory controller + */ +#define MEMC_BASE __REG(0x48000000) /* Base of Memory Controller */ +#define MDCNFG_OFFSET 0x0 +#define MDREFR_OFFSET 0x4 +#define MSC0_OFFSET 0x8 +#define MSC1_OFFSET 0xC +#define MSC2_OFFSET 0x10 +#define MECR_OFFSET 0x14 +#define SXLCR_OFFSET 0x18 +#define SXCNFG_OFFSET 0x1C +#define FLYCNFG_OFFSET 0x20 +#define SXMRS_OFFSET 0x24 +#define MCMEM0_OFFSET 0x28 +#define MCMEM1_OFFSET 0x2C +#define MCATT0_OFFSET 0x30 +#define MCATT1_OFFSET 0x34 +#define MCIO0_OFFSET 0x38 +#define MCIO1_OFFSET 0x3C +#define MDMRS_OFFSET 0x40 -#define LCCR5_SOFM1 (1<<0) /* Start Of Frame Mask for Overlay 1 (channel 1) */ -#define LCCR5_SOFM2 (1<<1) /* Start Of Frame Mask for Overlay 2 (channel 2) */ -#define LCCR5_SOFM3 (1<<2) /* Start Of Frame Mask for Overlay 2 (channel 3) */ -#define LCCR5_SOFM4 (1<<3) /* Start Of Frame Mask for Overlay 2 (channel 4) */ -#define LCCR5_SOFM5 (1<<4) /* Start Of Frame Mask for cursor (channel 5) */ -#define LCCR5_SOFM6 (1<<5) /* Start Of Frame Mask for command data (channel 6) */ +#define MDCNFG __REG(0x48000000) /* SDRAM Configuration Register 0 */ +#define MDCNFG_DE0 0x00000001 +#define MDCNFG_DE1 0x00000002 +#define MDCNFG_DE2 0x00010000 +#define MDCNFG_DE3 0x00020000 +#define MDCNFG_DWID0 0x00000004 -#define LCCR5_EOFM1 (1<<8) /* End Of Frame Mask for Overlay 1 (channel 1) */ -#define LCCR5_EOFM2 (1<<9) /* End Of Frame Mask for Overlay 2 (channel 2) */ -#define LCCR5_EOFM3 (1<<10) /* End Of Frame Mask for Overlay 2 (channel 3) */ -#define LCCR5_EOFM4 (1<<11) /* End Of Frame Mask for Overlay 2 (channel 4) */ -#define LCCR5_EOFM5 (1<<12) /* End Of Frame Mask for cursor (channel 5) */ -#define LCCR5_EOFM6 (1<<13) /* End Of Frame Mask for command data (channel 6) */ +#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */ +#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */ +#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */ +#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */ +#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */ +#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */ +#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */ +#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */ +#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */ +#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */ +#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */ +#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */ +#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */ +#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */ +#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */ +#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */ -#define LCCR5_BSM1 (1<<16) /* Branch mask for Overlay 1 (channel 1) */ -#define LCCR5_BSM2 (1<<17) /* Branch mask for Overlay 2 (channel 2) */ -#define LCCR5_BSM3 (1<<18) /* Branch mask for Overlay 2 (channel 3) */ -#define LCCR5_BSM4 (1<<19) /* Branch mask for Overlay 2 (channel 4) */ -#define LCCR5_BSM5 (1<<20) /* Branch mask for cursor (channel 5) */ -#define LCCR5_BSM6 (1<<21) /* Branch mask for data command (channel 6) */ +#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */ +#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */ +#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */ +#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */ +#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */ +#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */ +#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */ +#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */ +#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */ +#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */ +#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */ +#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */ +#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */ -#define LCCR5_IUM1 (1<<24) /* Input FIFO Underrun Mask for Overlay 1 */ -#define LCCR5_IUM2 (1<<25) /* Input FIFO Underrun Mask for Overlay 2 */ -#define LCCR5_IUM3 (1<<26) /* Input FIFO Underrun Mask for Overlay 2 */ -#define LCCR5_IUM4 (1<<27) /* Input FIFO Underrun Mask for Overlay 2 */ -#define LCCR5_IUM5 (1<<28) /* Input FIFO Underrun Mask for cursor */ -#define LCCR5_IUM6 (1<<29) /* Input FIFO Underrun Mask for data command */ +#if defined(CONFIG_PXA27X) -#define OVL1C1_O1EN (1<<31) /* Enable bit for Overlay 1 */ -#define OVL2C1_O2EN (1<<31) /* Enable bit for Overlay 2 */ -#define CCR_CEN (1<<31) /* Enable bit for Cursor */ +#define ARB_CNTRL __REG(0x48000048) /* Arbiter Control Register */ + +#define ARB_DMA_SLV_PARK (1<<31) /* Be parked with DMA slave when idle */ +#define ARB_CI_PARK (1<<30) /* Be parked with Camera Interface when idle */ +#define ARB_EX_MEM_PARK (1<<29) /* Be parked with external MEMC when idle */ +#define ARB_INT_MEM_PARK (1<<28) /* Be parked with internal MEMC when idle */ +#define ARB_USB_PARK (1<<27) /* Be parked with USB when idle */ +#define ARB_LCD_PARK (1<<26) /* Be parked with LCD when idle */ +#define ARB_DMA_PARK (1<<25) /* Be parked with DMA when idle */ +#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ +#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ + +/* Interrupt Controller */ + +#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */ +#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */ +#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */ +#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */ +#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */ + +/* General Purpose I/O */ + +#define GAFR3_L __REG(0x40E0006C) /* GPIO Alternate Function Select Register GPIO<111:96> */ +#define GAFR3_U __REG(0x40E00070) /* GPIO Alternate Function Select Register GPIO<127:112> */ +#define GPLR3 __REG(0x40E00100) /* GPIO Pin-Level Register GPIO<127:96> */ +#define GPDR3 __REG(0x40E0010C) /* GPIO Pin Direction Register GPIO<127:96> */ +#define GPSR3 __REG(0x40E00118) /* GPIO Pin Output Set Register GPIO<127:96> */ +#define GPCR3 __REG(0x40E00124) /* GPIO Pin Output Clear Register GPIO <127:96> */ +#define GRER3 __REG(0x40E00130) /* GPIO Rising-Edge Detect Register GPIO<127:96> */ +#define GFER3 __REG(0x40E0013C) /* GPIO Falling-Edge Detect Register GPIO<31:0> */ +#define GEDR3 __REG(0x40E00148) /* GPIO Edge Detect Status Register GPIO<127:96> */ + +/* Core Clock */ + +#define CCSR __REG(0x4130000C) /* Core Clock Status Register */ + +#define CKEN23_SSP1 (1 << 23) /* SSP1 Unit Clock Enable */ +#define CKEN22_MEMC (1 << 22) /* Memory Controler */ +#define CKEN21_MSHC (1 << 21) /* Memery Stick Host Controller */ +#define CKEN20_IM (1 << 20) /* Internal Memory Clock Enable */ +#define CKEN19_KEYPAD (1 << 19) /* Keypad Interface Clock Enable */ +#define CKEN18_USIM (1 << 18) /* USIM Unit Clock Enable */ +#define CKEN17_MSL (1 << 17) /* MSL Interface Unit Clock Enable */ +#define CKEN15_PWR_I2C (1 << 15) /* PWR_I2C Unit Clock Enable */ +#define CKEN9_OST (1 << 9) /* OS Timer Unit Clock Enable */ +#define CKEN4_SSP3 (1 << 4) /* SSP3 Unit Clock Enable */ + +/* Memory controller */ + +#define MDREFR_K0DB4 (1 << 29) /* SDCLK[0] divide by 4 */ /* LCD registers */ #define LCCR4 __REG(0x44000010) /* LCD Controller Control Register 4 */ @@ -2247,1071 +1646,104 @@ typedef void (*ExcpHndlr) (void) ; #define FBR5 __REG(0x44000110) /* DMA Channel 5 Frame Branch Register */ #define FBR6 __REG(0x44000114) /* DMA Channel 6 Frame Branch Register */ -/* -* Touch screen interface -*/ -#ifdef CONFIG_CPU_MONAHANS -#define ADCD __REG(0x41c00000) /*Analog-to-Digital Converter Data register*/ -#define ADCS __REG(0x41c00004) /*Analog-to-Digital Converter Setup register*/ -#define ADCE __REG(0x41c00008) /*Analog-to-Digital Converter Enable register*/ -#endif - - -/* - * Memory controller - */ -#ifndef CONFIG_CPU_MONAHANS -#define MEMC_BASE __REG(0x48000000) /* Base of Memory Controller */ -#define MDCNFG_OFFSET 0x0 -#define MDREFR_OFFSET 0x4 -#define MSC0_OFFSET 0x8 -#define MSC1_OFFSET 0xC -#define MSC2_OFFSET 0x10 -#define MECR_OFFSET 0x14 -#define SXLCR_OFFSET 0x18 -#define SXCNFG_OFFSET 0x1C -#define FLYCNFG_OFFSET 0x20 -#define SXMRS_OFFSET 0x24 -#define MCMEM0_OFFSET 0x28 -#define MCMEM1_OFFSET 0x2C -#define MCATT0_OFFSET 0x30 -#define MCATT1_OFFSET 0x34 -#define MCIO0_OFFSET 0x38 -#define MCIO1_OFFSET 0x3C -#define MDMRS_OFFSET 0x40 - -#define MDCNFG __REG((0x48000000) /* SDRAM Configuration Register 0 */ -#define MDCNFG_DE0 0x00000001 -#define MDCNFG_DE1 0x00000002 -#define MDCNFG_DE2 0x00010000 -#define MDCNFG_DE3 0x00020000 -#define MDCNFG_DWID0 0x00000004 -#endif - -#ifdef CONFIG_CPU_MONAHANS -/* Static Memory Controller Registers */ -#define MSC0 __REG_2(0x4A000008) /* Static Memory Control Register 0 */ -#define MSC1 __REG_2(0x4A00000C) /* Static Memory Control Register 1 */ -#define MECR __REG_2(0x4A000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */ -#define SXCNFG __REG_2(0x4A00001C) /* Synchronous Static Memory Control Register */ -#define MCMEM0 __REG_2(0x4A000028) /* Card interface Common Memory Space Socket 0 Timing */ -#define MCATT0 __REG_2(0x4A000030) /* Card interface Attribute Space Socket 0 Timing Configuration */ -#define MCIO0 __REG_2(0x4A000038) /* Card interface I/O Space Socket 0 Timing Configuration */ -#define MEMCLKCFG __REG_2(0x4A000068) /* SCLK speed configuration */ -#define CSADRCFG0 __REG_2(0x4A000080) /* Address Configuration for chip select 0 */ -#define CSADRCFG1 __REG_2(0x4A000084) /* Address Configuration for chip select 1 */ -#define CSADRCFG2 __REG_2(0x4A000088) /* Address Configuration for chip select 2 */ -#define CSADRCFG3 __REG_2(0x4A00008C) /* Address Configuration for chip select 3 */ -#define CSADRCFG_P __REG_2(0x4A000090) /* Address Configuration for pcmcia card interface */ -#define CSMSADRCFG __REG_2(0x4A0000A0) /* Master Address Configuration Register */ - -/* Dynamic Memory Controller Registers */ -#define MDCNFG __REG_2(0x48100000) /* SDRAM Configuration Register 0 */ -#define MDREFR __REG_2(0x48100004) /* SDRAM Refresh Control Register */ -#define FLYCNFG __REG_2(0x48100020) /* Fly-by DMA DVAL[1:0] polarities */ -#define MDMRS __REG_2(0x48100040) /* MRS value to be written to SDRAM */ -#define DDR_SCAL __REG_2(0x48100050) /* Software Delay Line Calibration/Configuration for external DDR memory. */ -#define DDR_HCAL __REG_2(0x48100060) /* Hardware Delay Line Calibration/Configuration for external DDR memory. */ -#define DMCIER __REG_2(0x48100070) /* Dynamic MC Interrupt Enable Register. */ -#define DMCISR __REG_2(0x48100078) /* Dynamic MC Interrupt Status Register. */ -#define DDR_DLS __REG_2(0x48100080) /* DDR Delay Line Value Status register for external DDR memory. */ -#define EMPI __REG_2(0x48100090) /* EMPI Control Register */ -#define RCOMP __REG_2(0x48100100) -#define PAD_MA __REG_2(0x48100110) -#define PAD_MDMSB __REG_2(0x48100114) -#define PAD_MDLSB __REG_2(0x48100118) -#define PAD_DMEM __REG_2(0x4810011c) -#define PAD_SDCLK __REG_2(0x48100120) -#define PAD_SDCS __REG_2(0x48100124) -#define PAD_SMEM __REG_2(0x48100128) -#define PAD_SCLK __REG_2(0x4810012C) - - -/* Data Flash Controller Registers */ - -#define NDCR __REG_2(0x43100000) /* Data Flash Control register */ -#define NDTR0CS0 __REG_2(0x43100004) /* Data Controller Timing Parameter 0 Register for ND_nCS0 */ -#define NDTR0CS1 __REG_2(0x43100008) /* Data Controller Timing Parameter 0 Register for ND_nCS1 */ -#define NDTR1CS0 __REG_2(0x4310000C) /* Data Controller Timing Parameter 1 Register for ND_nCS0 */ -#define NDTR1CS1 __REG_2(0x43100010) /* Data Controller Timing Parameter 1 Register for ND_nCS1 */ -#define NDSR __REG_2(0x43100014) /* Data Controller Status Register */ -#define NDPCR __REG_2(0x43100018) /* Data Controller Page Count Register */ -#define NDBDR0 __REG_2(0x4310001C) /* Data Controller Bad Block Register 0 */ -#define NDBDR1 __REG_2(0x43100020) /* Data Controller Bad Block Register 1 */ -#define NDDB __REG_2(0x43100040) /* Data Controller Data Buffer */ -#define NDCB0 __REG_2(0x43100048) /* Data Controller Command Buffer0 */ -#define NDCB1 __REG_2(0x4310004C) /* Data Controller Command Buffer1 */ -#define NDCB2 __REG_2(0x43100050) /* Data Controller Command Buffer2 */ - -#define NDCR_SPARE_EN (0x1<<31) -#define NDCR_ECC_EN (0x1<<30) -#define NDCR_DMA_EN (0x1<<29) -#define NDCR_ND_RUN (0x1<<28) -#define NDCR_DWIDTH_C (0x1<<27) -#define NDCR_DWIDTH_M (0x1<<26) -#define NDCR_PAGE_SZ (0x3<<24) -#define NDCR_NCSX (0x1<<23) -#define NDCR_ND_MODE (0x3<<21) -#define NDCR_NAND_MODE 0x0 -#define NDCR_CLR_PG_CNT (0x1<<20) -#define NDCR_CLR_ECC (0x1<<19) -#define NDCR_RD_ID_CNT (0x7<<16) -#define NDCR_RA_START (0x1<<15) -#define NDCR_PG_PER_BLK (0x1<<14) -#define NDCR_ND_ARB_EN (0x1<<12) - -#define NDSR_RDY (0x1<<11) -#define NDSR_CS0_PAGED (0x1<<10) -#define NDSR_CS1_PAGED (0x1<<9) -#define NDSR_CS0_CMDD (0x1<<8) -#define NDSR_CS1_CMDD (0x1<<7) -#define NDSR_CS0_BBD (0x1<<6) -#define NDSR_CS1_BBD (0x1<<5) -#define NDSR_BDERR (0x1<<4) -#define NDSR_SBERR (0x1<<3) -#define NDSR_WRDREQ (0x1<<2) -#define NDSR_RDDREQ (0x1<<1) -#define NDSR_WRCMDREQ (0x1) - -#define NDCB0_AUTO_RS (0x1<<25) -#define NDCB0_CSEL (0x1<<24) -#define NDCB0_CMD_TYPE (0x7<<21) -#define NDCB0_NC (0x1<<20) -#define NDCB0_DBC (0x1<<19) -#define NDCB0_ADDR_CYC (0x7<<16) -#define NDCB0_CMD2 (0xff<<8) -#define NDCB0_CMD1 (0xff) -#define MCMEM(s) MCMEM0 -#define MCATT(s) MCATT0 -#define MCIO(s) MCIO0 -#define MECR_CIT (1 << 1)/* Card Is There: 0 -> no card, 1 -> card inserted */ -#else /* CONFIG_CPU_MONAHANS */ - -/* mk: defined @2253 #define MDCNFG __REG(0x48000000) /\* SDRAM Configuration Register 0 *\/ */ -#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */ -#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */ -#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */ -#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */ -#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */ -#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */ -#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */ -#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */ -#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */ -#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */ -#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */ -#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */ -#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */ -#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */ -#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */ -#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */ - -/* - * More handy macros for PCMCIA - * - * Arg is socket number - */ -#define MCMEM(s) __REG2(0x48000028, (s)<<2 ) /* Card interface Common Memory Space Socket s Timing */ -#define MCATT(s) __REG2(0x48000030, (s)<<2 ) /* Card interface Attribute Space Socket s Timing Configuration */ -#define MCIO(s) __REG2(0x48000038, (s)<<2 ) /* Card interface I/O Space Socket s Timing Configuration */ - -/* MECR register defines */ -#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */ -#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */ - -#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */ -#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */ -#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */ -#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */ -#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */ -#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */ -#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */ -#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */ -#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */ -#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */ -#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */ -#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */ -#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */ -#endif - -#ifdef CONFIG_PXA27X - -#define ARB_CNTRL __REG(0x48000048) /* Arbiter Control Register */ - -#define ARB_DMA_SLV_PARK (1<<31) /* Be parked with DMA slave when idle */ -#define ARB_CI_PARK (1<<30) /* Be parked with Camera Interface when idle */ -#define ARB_EX_MEM_PARK (1<<29) /* Be parked with external MEMC when idle */ -#define ARB_INT_MEM_PARK (1<<28) /* Be parked with internal MEMC when idle */ -#define ARB_USB_PARK (1<<27) /* Be parked with USB when idle */ -#define ARB_LCD_PARK (1<<26) /* Be parked with LCD when idle */ -#define ARB_DMA_PARK (1<<25) /* Be parked with DMA when idle */ -#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ -#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ - -/* - * Keypad - */ -#define KPC __REG(0x41500000) /* Keypad Interface Control register */ -#define KPDK __REG(0x41500008) /* Keypad Interface Direct Key register */ -#define KPREC __REG(0x41500010) /* Keypad Interface Rotary Encoder register */ -#define KPMK __REG(0x41500018) /* Keypad Interface Matrix Key register */ -#define KPAS __REG(0x41500020) /* Keypad Interface Automatic Scan register */ -#define KPASMKP0 __REG(0x41500028) /* Keypad Interface Automatic Scan Multiple Key Presser register 0 */ -#define KPASMKP1 __REG(0x41500030) /* Keypad Interface Automatic Scan Multiple Key Presser register 1 */ -#define KPASMKP2 __REG(0x41500038) /* Keypad Interface Automatic Scan Multiple Key Presser register 2 */ -#define KPASMKP3 __REG(0x41500040) /* Keypad Interface Automatic Scan Multiple Key Presser register 3 */ -#define KPKDI __REG(0x41500048) /* Keypad Interface Key Debounce Interval register */ - -#define KPC_AS (0x1 << 30) /* Automatic Scan bit */ -#define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */ -#define KPC_MI (0x1 << 22) /* Matrix interrupt bit */ -#define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */ -#define KPC_MS7 (0x1 << 20) /* Matrix scan line 7 */ -#define KPC_MS6 (0x1 << 19) /* Matrix scan line 6 */ -#define KPC_MS5 (0x1 << 18) /* Matrix scan line 5 */ -#define KPC_MS4 (0x1 << 17) /* Matrix scan line 4 */ -#define KPC_MS3 (0x1 << 16) /* Matrix scan line 3 */ -#define KPC_MS2 (0x1 << 15) /* Matrix scan line 2 */ -#define KPC_MS1 (0x1 << 14) /* Matrix scan line 1 */ -#define KPC_MS0 (0x1 << 13) /* Matrix scan line 0 */ -#define KPC_MS_ALL (KPC_MS0 | KPC_MS1 | KPC_MS2 | KPC_MS3 | KPC_MS4 | KPC_MS5 | KPC_MS6 | KPC_MS7) -#define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */ -#define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */ -#define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Keypad Debounce Select */ -#define KPC_DI (0x1 << 5) /* Direct key interrupt bit */ -#define KPC_RE_ZERO_DEB (0x1 << 4) /* Rotary Encoder Zero Debounce */ -#define KPC_REE1 (0x1 << 3) /* Rotary Encoder1 Enable */ -#define KPC_REE0 (0x1 << 2) /* Rotary Encoder0 Enable */ -#define KPC_DE (0x1 << 1) /* Direct Keypad Enable */ -#define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */ - -#define KPDK_DKP (0x1 << 31) -#define KPDK_DK7 (0x1 << 7) -#define KPDK_DK6 (0x1 << 6) -#define KPDK_DK5 (0x1 << 5) -#define KPDK_DK4 (0x1 << 4) -#define KPDK_DK3 (0x1 << 3) -#define KPDK_DK2 (0x1 << 2) -#define KPDK_DK1 (0x1 << 1) -#define KPDK_DK0 (0x1 << 0) - -#define KPREC_OF1 (0x1 << 31) -#define kPREC_UF1 (0x1 << 30) -#define KPREC_OF0 (0x1 << 15) -#define KPREC_UF0 (0x1 << 14) - -#define KPMK_MKP (0x1 << 31) -#define KPAS_SO (0x1 << 31) -#define KPASMKPx_SO (0x1 << 31) - -/* - * UHC: USB Host Controller (OHCI-like) register definitions - */ -#define UHC_BASE_PHYS (0x4C000000) -#define UHCREV __REG(0x4C000000) /* UHC HCI Spec Revision */ -#define UHCHCON __REG(0x4C000004) /* UHC Host Control Register */ -#define UHCCOMS __REG(0x4C000008) /* UHC Command Status Register */ -#define UHCINTS __REG(0x4C00000C) /* UHC Interrupt Status Register */ -#define UHCINTE __REG(0x4C000010) /* UHC Interrupt Enable */ -#define UHCINTD __REG(0x4C000014) /* UHC Interrupt Disable */ -#define UHCHCCA __REG(0x4C000018) /* UHC Host Controller Comm. Area */ -#define UHCPCED __REG(0x4C00001C) /* UHC Period Current Endpt Descr */ -#define UHCCHED __REG(0x4C000020) /* UHC Control Head Endpt Descr */ -#define UHCCCED __REG(0x4C000024) /* UHC Control Current Endpt Descr */ -#define UHCBHED __REG(0x4C000028) /* UHC Bulk Head Endpt Descr */ -#define UHCBCED __REG(0x4C00002C) /* UHC Bulk Current Endpt Descr */ -#define UHCDHEAD __REG(0x4C000030) /* UHC Done Head */ -#define UHCFMI __REG(0x4C000034) /* UHC Frame Interval */ -#define UHCFMR __REG(0x4C000038) /* UHC Frame Remaining */ -#define UHCFMN __REG(0x4C00003C) /* UHC Frame Number */ -#define UHCPERS __REG(0x4C000040) /* UHC Periodic Start */ -#define UHCLS __REG(0x4C000044) /* UHC Low Speed Threshold */ -#define UHCRHDA __REG(0x4C000048) /* UHC Root Hub Descriptor A */ -#define UHCRHDB __REG(0x4C00004C) /* UHC Root Hub Descriptor B */ -#define UHCRHS __REG(0x4C000050) /* UHC Root Hub Status */ -#define UHCRHPS1 __REG(0x4C000054) /* UHC Root Hub Port 1 Status */ -#define UHCRHPS2 __REG(0x4C000058) /* UHC Root Hub Port 2 Status */ -#define UHCRHPS3 __REG(0x4C00005C) /* UHC Root Hub Port 3 Status */ -#define UHCRHPS(x) __REG2(0x4C000050, (x)<<2) - -#define UHCSTAT __REG(0x4C000060) /* UHC Status Register */ -#define UHCSTAT_UPS3 (1 << 16) /* USB Power Sense Port3 */ -#define UHCSTAT_SBMAI (1 << 15) /* System Bus Master Abort Interrupt*/ -#define UHCSTAT_SBTAI (1 << 14) /* System Bus Target Abort Interrupt*/ -#define UHCSTAT_UPRI (1 << 13) /* USB Port Resume Interrupt */ -#define UHCSTAT_UPS2 (1 << 12) /* USB Power Sense Port 2 */ -#define UHCSTAT_UPS1 (1 << 11) /* USB Power Sense Port 1 */ -#define UHCSTAT_HTA (1 << 10) /* HCI Target Abort */ -#define UHCSTAT_HBA (1 << 8) /* HCI Buffer Active */ -#define UHCSTAT_RWUE (1 << 7) /* HCI Remote Wake Up Event */ - -#define UHCHR __REG(0x4C000064) /* UHC Reset Register */ -#define UHCHR_SSEP3 (1 << 11) /* Sleep Standby Enable for Port3 */ -#define UHCHR_SSEP2 (1 << 10) /* Sleep Standby Enable for Port2 */ -#define UHCHR_SSEP1 (1 << 9) /* Sleep Standby Enable for Port1 */ -#define UHCHR_PCPL (1 << 7) /* Power control polarity low */ -#define UHCHR_PSPL (1 << 6) /* Power sense polarity low */ -#define UHCHR_SSE (1 << 5) /* Sleep Standby Enable */ -#define UHCHR_UIT (1 << 4) /* USB Interrupt Test */ -#define UHCHR_SSDC (1 << 3) /* Simulation Scale Down Clock */ -#define UHCHR_CGR (1 << 2) /* Clock Generation Reset */ -#define UHCHR_FHR (1 << 1) /* Force Host Controller Reset */ -#define UHCHR_FSBIR (1 << 0) /* Force System Bus Iface Reset */ - -#define UHCHIE __REG(0x4C000068) /* UHC Interrupt Enable Register*/ -#define UHCHIE_UPS3IE (1 << 14) /* Power Sense Port3 IntEn */ -#define UHCHIE_UPRIE (1 << 13) /* Port Resume IntEn */ -#define UHCHIE_UPS2IE (1 << 12) /* Power Sense Port2 IntEn */ -#define UHCHIE_UPS1IE (1 << 11) /* Power Sense Port1 IntEn */ -#define UHCHIE_TAIE (1 << 10) /* HCI Interface Transfer Abort - Interrupt Enable*/ -#define UHCHIE_HBAIE (1 << 8) /* HCI Buffer Active IntEn */ -#define UHCHIE_RWIE (1 << 7) /* Remote Wake-up IntEn */ - -#define UHCHIT __REG(0x4C00006C) /* UHC Interrupt Test register */ - -/* Camera Interface */ -#define CICR0 __REG(0x50000000) -#define CICR1 __REG(0x50000004) -#define CICR2 __REG(0x50000008) -#define CICR3 __REG(0x5000000C) -#define CICR4 __REG(0x50000010) -#define CISR __REG(0x50000014) -#define CIFR __REG(0x50000018) -#define CITOR __REG(0x5000001C) -#define CIBR0 __REG(0x50000028) -#define CIBR1 __REG(0x50000030) -#define CIBR2 __REG(0x50000038) - -#define CICR0_DMAEN (1 << 31) /* DMA request enable */ -#define CICR0_PAR_EN (1 << 30) /* Parity enable */ -#define CICR0_SL_CAP_EN (1 << 29) /* Capture enable for slave mode */ -#define CICR0_ENB (1 << 28) /* Camera interface enable */ -#define CICR0_DIS (1 << 27) /* Camera interface disable */ -#define CICR0_SIM (0x7 << 24) /* Sensor interface mode mask */ -#define CICR0_TOM (1 << 9) /* Time-out mask */ -#define CICR0_RDAVM (1 << 8) /* Receive-data-available mask */ -#define CICR0_FEM (1 << 7) /* FIFO-empty mask */ -#define CICR0_EOLM (1 << 6) /* End-of-line mask */ -#define CICR0_PERRM (1 << 5) /* Parity-error mask */ -#define CICR0_QDM (1 << 4) /* Quick-disable mask */ -#define CICR0_CDM (1 << 3) /* Disable-done mask */ -#define CICR0_SOFM (1 << 2) /* Start-of-frame mask */ -#define CICR0_EOFM (1 << 1) /* End-of-frame mask */ -#define CICR0_FOM (1 << 0) /* FIFO-overrun mask */ - -#define CICR1_TBIT (1 << 31) /* Transparency bit */ -#define CICR1_RGBT_CONV (0x3 << 30) /* RGBT conversion mask */ -#define CICR1_PPL (0x3f << 15) /* Pixels per line mask */ -#define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */ -#define CICR1_RGB_F (1 << 11) /* RGB format */ -#define CICR1_YCBCR_F (1 << 10) /* YCbCr format */ -#define CICR1_RGB_BPP (0x7 << 7) /* RGB bis per pixel mask */ -#define CICR1_RAW_BPP (0x3 << 5) /* Raw bis per pixel mask */ -#define CICR1_COLOR_SP (0x3 << 3) /* Color space mask */ -#define CICR1_DW (0x7 << 0) /* Data width mask */ - -#define CICR2_BLW (0xff << 24) /* Beginning-of-line pixel clock - wait count mask */ -#define CICR2_ELW (0xff << 16) /* End-of-line pixel clock - wait count mask */ -#define CICR2_HSW (0x3f << 10) /* Horizontal sync pulse width mask */ -#define CICR2_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock - wait count mask */ -#define CICR2_FSW (0x7 << 0) /* Frame stabilization - wait count mask */ - -#define CICR3_BFW (0xff << 24) /* Beginning-of-frame line clock - wait count mask */ -#define CICR3_EFW (0xff << 16) /* End-of-frame line clock - wait count mask */ -#define CICR3_VSW (0x3f << 10) /* Vertical sync pulse width mask */ -#define CICR3_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock - wait count mask */ -#define CICR3_LPF (0x3ff << 0) /* Lines per frame mask */ - -#define CICR4_MCLK_DLY (0x3 << 24) /* MCLK Data Capture Delay mask */ -#define CICR4_PCLK_EN (1 << 23) /* Pixel clock enable */ -#define CICR4_PCP (1 << 22) /* Pixel clock polarity */ -#define CICR4_HSP (1 << 21) /* Horizontal sync polarity */ -#define CICR4_VSP (1 << 20) /* Vertical sync polarity */ -#define CICR4_MCLK_EN (1 << 19) /* MCLK enable */ -#define CICR4_FR_RATE (0x7 << 8) /* Frame rate mask */ -#define CICR4_DIV (0xff << 0) /* Clock divisor mask */ - -#define CISR_FTO (1 << 15) /* FIFO time-out */ -#define CISR_RDAV_2 (1 << 14) /* Channel 2 receive data available */ -#define CISR_RDAV_1 (1 << 13) /* Channel 1 receive data available */ -#define CISR_RDAV_0 (1 << 12) /* Channel 0 receive data available */ -#define CISR_FEMPTY_2 (1 << 11) /* Channel 2 FIFO empty */ -#define CISR_FEMPTY_1 (1 << 10) /* Channel 1 FIFO empty */ -#define CISR_FEMPTY_0 (1 << 9) /* Channel 0 FIFO empty */ -#define CISR_EOL (1 << 8) /* End of line */ -#define CISR_PAR_ERR (1 << 7) /* Parity error */ -#define CISR_CQD (1 << 6) /* Camera interface quick disable */ -#define CISR_SOF (1 << 5) /* Start of frame */ -#define CISR_CDD (1 << 4) /* Camera interface disable done */ -#define CISR_EOF (1 << 3) /* End of frame */ -#define CISR_IFO_2 (1 << 2) /* FIFO overrun for Channel 2 */ -#define CISR_IFO_1 (1 << 1) /* FIFO overrun for Channel 1 */ -#define CISR_IFO_0 (1 << 0) /* FIFO overrun for Channel 0 */ - -#define CIFR_FLVL2 (0x7f << 23) /* FIFO 2 level mask */ -#define CIFR_FLVL1 (0x7f << 16) /* FIFO 1 level mask */ -#define CIFR_FLVL0 (0xff << 8) /* FIFO 0 level mask */ -#define CIFR_THL_0 (0x3 << 4) /* Threshold Level for Channel 0 FIFO */ -#define CIFR_RESET_F (1 << 3) /* Reset input FIFOs */ -#define CIFR_FEN2 (1 << 2) /* FIFO enable for channel 2 */ -#define CIFR_FEN1 (1 << 1) /* FIFO enable for channel 1 */ -#define CIFR_FEN0 (1 << 0) /* FIFO enable for channel 0 */ - -#define SRAM_SIZE 0x40000 /* 4x64K */ - -#define SRAM_MEM_PHYS 0x5C000000 - -#define IMPMCR __REG(0x58000000) /* IM Power Management Control Reg */ -#define IMPMSR __REG(0x58000008) /* IM Power Management Status Reg */ - -#define IMPMCR_PC3 (0x3 << 22) /* Bank 3 Power Control */ -#define IMPMCR_PC3_RUN_MODE (0x0 << 22) /* Run mode */ -#define IMPMCR_PC3_STANDBY_MODE (0x1 << 22) /* Standby mode */ -#define IMPMCR_PC3_AUTO_MODE (0x3 << 22) /* Automatically controlled */ - -#define IMPMCR_PC2 (0x3 << 20) /* Bank 2 Power Control */ -#define IMPMCR_PC2_RUN_MODE (0x0 << 20) /* Run mode */ -#define IMPMCR_PC2_STANDBY_MODE (0x1 << 20) /* Standby mode */ -#define IMPMCR_PC2_AUTO_MODE (0x3 << 20) /* Automatically controlled */ - -#define IMPMCR_PC1 (0x3 << 18) /* Bank 1 Power Control */ -#define IMPMCR_PC1_RUN_MODE (0x0 << 18) /* Run mode */ -#define IMPMCR_PC1_STANDBY_MODE (0x1 << 18) /* Standby mode */ -#define IMPMCR_PC1_AUTO_MODE (0x3 << 18) /* Automatically controlled */ - -#define IMPMCR_PC0 (0x3 << 16) /* Bank 0 Power Control */ -#define IMPMCR_PC0_RUN_MODE (0x0 << 16) /* Run mode */ -#define IMPMCR_PC0_STANDBY_MODE (0x1 << 16) /* Standby mode */ -#define IMPMCR_PC0_AUTO_MODE (0x3 << 16) /* Automatically controlled */ - -#define IMPMCR_AW3 (1 << 11) /* Bank 3 Automatic Wake-up enable */ -#define IMPMCR_AW2 (1 << 10) /* Bank 2 Automatic Wake-up enable */ -#define IMPMCR_AW1 (1 << 9) /* Bank 1 Automatic Wake-up enable */ -#define IMPMCR_AW0 (1 << 8) /* Bank 0 Automatic Wake-up enable */ - -#define IMPMCR_DST (0xFF << 0) /* Delay Standby Time, ms */ - -#define IMPMSR_PS3 (0x3 << 6) /* Bank 3 Power Status: */ -#define IMPMSR_PS3_RUN_MODE (0x0 << 6) /* Run mode */ -#define IMPMSR_PS3_STANDBY_MODE (0x1 << 6) /* Standby mode */ - -#define IMPMSR_PS2 (0x3 << 4) /* Bank 2 Power Status: */ -#define IMPMSR_PS2_RUN_MODE (0x0 << 4) /* Run mode */ -#define IMPMSR_PS2_STANDBY_MODE (0x1 << 4) /* Standby mode */ - -#define IMPMSR_PS1 (0x3 << 2) /* Bank 1 Power Status: */ -#define IMPMSR_PS1_RUN_MODE (0x0 << 2) /* Run mode */ -#define IMPMSR_PS1_STANDBY_MODE (0x1 << 2) /* Standby mode */ - -#define IMPMSR_PS0 (0x3 << 0) /* Bank 0 Power Status: */ -#define IMPMSR_PS0_RUN_MODE (0x0 << 0) /* Run mode */ -#define IMPMSR_PS0_STANDBY_MODE (0x1 << 0) /* Standby mode */ - -#endif - -/* MFPR */ -#ifdef CONFIG_CPU_MONAHANS - -#define SRAM_SIZE 0xC0000 /* 4x64K */ -#define SRAM_MEM_PHYS 0x5C000000 - -/* GPIO alternate function assignments */ -#define APPS_PAD_BASE 0x40E10000 - -/* MFPR regsiter locations for each pin */ -#define GPIO0_MFPR (APPS_PAD_BASE + 0x0124) -#define GPIO1_MFPR (APPS_PAD_BASE + 0x0128) -#define GPIO2_MFPR (APPS_PAD_BASE + 0x012C) -#define GPIO3_MFPR (APPS_PAD_BASE + 0x0130) -#define GPIO4_MFPR (APPS_PAD_BASE + 0x0134) -#define GPIO5_MFPR (APPS_PAD_BASE + 0x028C) -#define GPIO6_MFPR (APPS_PAD_BASE + 0x0290) -#define GPIO7_MFPR (APPS_PAD_BASE + 0x0294) -#define GPIO8_MFPR (APPS_PAD_BASE + 0x0298) -#define GPIO9_MFPR (APPS_PAD_BASE + 0x029C) -#define GPIO10_MFPR (APPS_PAD_BASE + 0x0458) -#define GPIO11_MFPR (APPS_PAD_BASE + 0x02A0) -#define GPIO12_MFPR (APPS_PAD_BASE + 0x02A4) -#define GPIO13_MFPR (APPS_PAD_BASE + 0x02A8) -#define GPIO14_MFPR (APPS_PAD_BASE + 0x02AC) -#define GPIO15_MFPR (APPS_PAD_BASE + 0x02B0) -#define GPIO16_MFPR (APPS_PAD_BASE + 0x02B4) -#define GPIO17_MFPR (APPS_PAD_BASE + 0x02B8) -#define GPIO18_MFPR (APPS_PAD_BASE + 0x02BC) -#define GPIO19_MFPR (APPS_PAD_BASE + 0x02C0) -#define GPIO20_MFPR (APPS_PAD_BASE + 0x02C4) -#define GPIO21_MFPR (APPS_PAD_BASE + 0x02C8) -#define GPIO22_MFPR (APPS_PAD_BASE + 0x02CC) -#define GPIO23_MFPR (APPS_PAD_BASE + 0x02D0) -#define GPIO24_MFPR (APPS_PAD_BASE + 0x02D4) -#define GPIO25_MFPR (APPS_PAD_BASE + 0x02D8) -#define GPIO26_MFPR (APPS_PAD_BASE + 0x02DC) -#define GPIO27_MFPR (APPS_PAD_BASE + 0x0400) -#define GPIO28_MFPR (APPS_PAD_BASE + 0x0404) -#define GPIO29_MFPR (APPS_PAD_BASE + 0x0408) -#define GPIO30_MFPR (APPS_PAD_BASE + 0x040C) -#define GPIO31_MFPR (APPS_PAD_BASE + 0x0410) -#define GPIO32_MFPR (APPS_PAD_BASE + 0x0414) -#define GPIO33_MFPR (APPS_PAD_BASE + 0x0418) -#define GPIO34_MFPR (APPS_PAD_BASE + 0x041C) -#define GPIO35_MFPR (APPS_PAD_BASE + 0x0420) -#define GPIO36_MFPR (APPS_PAD_BASE + 0x0424) -#define GPIO37_MFPR (APPS_PAD_BASE + 0x0428) -#define GPIO38_MFPR (APPS_PAD_BASE + 0x042C) -#define GPIO39_MFPR (APPS_PAD_BASE + 0x0430) -#define GPIO40_MFPR (APPS_PAD_BASE + 0x0434) -#define GPIO41_MFPR (APPS_PAD_BASE + 0x0438) -#define GPIO42_MFPR (APPS_PAD_BASE + 0x043C) -#define GPIO43_MFPR (APPS_PAD_BASE + 0x0440) -#define GPIO44_MFPR (APPS_PAD_BASE + 0x0444) -#define GPIO45_MFPR (APPS_PAD_BASE + 0x0448) -#define GPIO46_MFPR (APPS_PAD_BASE + 0x044C) -#define GPIO47_MFPR (APPS_PAD_BASE + 0x0450) -#define GPIO48_MFPR (APPS_PAD_BASE + 0x0454) -#define GPIO49_MFPR (APPS_PAD_BASE + 0x045C) -#define GPIO50_MFPR (APPS_PAD_BASE + 0x0460) -#define GPIO51_MFPR (APPS_PAD_BASE + 0x0464) -#define GPIO52_MFPR (APPS_PAD_BASE + 0x0468) -#define GPIO53_MFPR (APPS_PAD_BASE + 0x046C) -#define GPIO54_MFPR (APPS_PAD_BASE + 0x0470) -#define GPIO55_MFPR (APPS_PAD_BASE + 0x0474) -#define GPIO56_MFPR (APPS_PAD_BASE + 0x0478) -#define GPIO57_MFPR (APPS_PAD_BASE + 0x047C) -#define GPIO58_MFPR (APPS_PAD_BASE + 0x0480) -#define GPIO59_MFPR (APPS_PAD_BASE + 0x0484) -#define GPIO60_MFPR (APPS_PAD_BASE + 0x0488) -#define GPIO61_MFPR (APPS_PAD_BASE + 0x048C) -#define GPIO62_MFPR (APPS_PAD_BASE + 0x0490) -#define GPIO63_MFPR (APPS_PAD_BASE + 0x04B4) -#define GPIO64_MFPR (APPS_PAD_BASE + 0x04B8) -#define GPIO65_MFPR (APPS_PAD_BASE + 0x04BC) -#define GPIO66_MFPR (APPS_PAD_BASE + 0x04C0) -#define GPIO67_MFPR (APPS_PAD_BASE + 0x04C4) -#define GPIO68_MFPR (APPS_PAD_BASE + 0x04C8) -#define GPIO69_MFPR (APPS_PAD_BASE + 0x04CC) -#define GPIO70_MFPR (APPS_PAD_BASE + 0x04D0) -#define GPIO71_MFPR (APPS_PAD_BASE + 0x04D4) -#define GPIO72_MFPR (APPS_PAD_BASE + 0x04D8) -#define GPIO73_MFPR (APPS_PAD_BASE + 0x04DC) -#define GPIO74_MFPR (APPS_PAD_BASE + 0x04F0) -#define GPIO75_MFPR (APPS_PAD_BASE + 0x04F4) -#define GPIO76_MFPR (APPS_PAD_BASE + 0x04F8) -#define GPIO77_MFPR (APPS_PAD_BASE + 0x04FC) -#define GPIO78_MFPR (APPS_PAD_BASE + 0x0500) -#define GPIO79_MFPR (APPS_PAD_BASE + 0x0504) -#define GPIO80_MFPR (APPS_PAD_BASE + 0x0508) -#define GPIO81_MFPR (APPS_PAD_BASE + 0x050C) -#define GPIO82_MFPR (APPS_PAD_BASE + 0x0510) -#define GPIO83_MFPR (APPS_PAD_BASE + 0x0514) -#define GPIO84_MFPR (APPS_PAD_BASE + 0x0518) -#define GPIO85_MFPR (APPS_PAD_BASE + 0x051C) -#define GPIO86_MFPR (APPS_PAD_BASE + 0x0520) -#define GPIO87_MFPR (APPS_PAD_BASE + 0x0524) -#define GPIO88_MFPR (APPS_PAD_BASE + 0x0528) -#define GPIO89_MFPR (APPS_PAD_BASE + 0x052C) -#define GPIO90_MFPR (APPS_PAD_BASE + 0x0530) -#define GPIO91_MFPR (APPS_PAD_BASE + 0x0534) -#define GPIO92_MFPR (APPS_PAD_BASE + 0x0538) -#define GPIO93_MFPR (APPS_PAD_BASE + 0x053C) -#define GPIO94_MFPR (APPS_PAD_BASE + 0x0540) -#define GPIO95_MFPR (APPS_PAD_BASE + 0x0544) -#define GPIO96_MFPR (APPS_PAD_BASE + 0x0548) -#define GPIO97_MFPR (APPS_PAD_BASE + 0x054C) -#define GPIO98_MFPR (APPS_PAD_BASE + 0x0550) -#define GPIO99_MFPR (APPS_PAD_BASE + 0x0600) -#define GPIO100_MFPR (APPS_PAD_BASE + 0x0604) -#define GPIO101_MFPR (APPS_PAD_BASE + 0x0608) -#define GPIO102_MFPR (APPS_PAD_BASE + 0x060C) -#define GPIO103_MFPR (APPS_PAD_BASE + 0x0610) -#define GPIO104_MFPR (APPS_PAD_BASE + 0x0614) -#define GPIO105_MFPR (APPS_PAD_BASE + 0x0618) -#define GPIO106_MFPR (APPS_PAD_BASE + 0x061C) -#define GPIO107_MFPR (APPS_PAD_BASE + 0x0620) -#define GPIO108_MFPR (APPS_PAD_BASE + 0x0624) -#define GPIO109_MFPR (APPS_PAD_BASE + 0x0628) -#define GPIO110_MFPR (APPS_PAD_BASE + 0x062C) -#define GPIO111_MFPR (APPS_PAD_BASE + 0x0630) -#define GPIO112_MFPR (APPS_PAD_BASE + 0x0634) -#define GPIO113_MFPR (APPS_PAD_BASE + 0x0638) -#define GPIO114_MFPR (APPS_PAD_BASE + 0x063C) -#define GPIO115_MFPR (APPS_PAD_BASE + 0x0640) -#define GPIO116_MFPR (APPS_PAD_BASE + 0x0644) -#define GPIO117_MFPR (APPS_PAD_BASE + 0x0648) -#define GPIO118_MFPR (APPS_PAD_BASE + 0x064C) -#define GPIO119_MFPR (APPS_PAD_BASE + 0x0650) -#define GPIO120_MFPR (APPS_PAD_BASE + 0x0654) -#define GPIO121_MFPR (APPS_PAD_BASE + 0x0658) -#define GPIO122_MFPR (APPS_PAD_BASE + 0x065C) -#define GPIO123_MFPR (APPS_PAD_BASE + 0x0660) -#define GPIO124_MFPR (APPS_PAD_BASE + 0x0664) -#define GPIO125_MFPR (APPS_PAD_BASE + 0x0668) -#define GPIO126_MFPR (APPS_PAD_BASE + 0x066C) -#define GPIO127_MFPR (APPS_PAD_BASE + 0x0670) -#define GPIO0_2_MFPR (APPS_PAD_BASE + 0x0674) /* MFPR for GPIO0_2 */ -#define GPIO1_2_MFPR (APPS_PAD_BASE + 0x0678) /* MFPR for GPIO1_2 */ -#define GPIO2_2_MFPR (APPS_PAD_BASE + 0x067C) /* MFPR for GPIO2_2 */ -#define GPIO3_2_MFPR (APPS_PAD_BASE + 0x0680) /* MFPR for GPIO3_2 */ -#define GPIO4_2_MFPR (APPS_PAD_BASE + 0x0684) /* MFPR for GPIO4_2 */ -#define GPIO5_2_MFPR (APPS_PAD_BASE + 0x0688) /* MFPR for GPIO5_2 */ -#define GPIO6_2_MFPR (APPS_PAD_BASE + 0x0494) /* MFPR for GPIO6_2 */ -#define GPIO7_2_MFPR (APPS_PAD_BASE + 0x0498) /* MFPR for GPIO7_2 */ -#define GPIO8_2_MFPR (APPS_PAD_BASE + 0x049C) /* MFPR for GPIO8_2 */ -#define GPIO9_2_MFPR (APPS_PAD_BASE + 0x04A0) /* MFPR for GPIO9_2 */ -#define GPIO10_2_MFPR (APPS_PAD_BASE + 0x04A4) /* MFPR for GPIO10_2 */ -#define GPIO11_2_MFPR (APPS_PAD_BASE + 0x04A8) /* MFPR for GPIO11_2 */ -#define GPIO12_2_MFPR (APPS_PAD_BASE + 0x04AC) /* MFPR for GPIO12_2 */ -#define GPIO13_2_MFPR (APPS_PAD_BASE + 0x04B0) /* MFPR for GPIO13_2 */ -#define GPIO14_2_MFPR (APPS_PAD_BASE + 0x04E0) /* MFPR for GPIO14_2 */ -#define GPIO15_2_MFPR (APPS_PAD_BASE + 0x04E4) /* MFPR for GPIO15_2 */ -#define GPIO16_2_MFPR (APPS_PAD_BASE + 0x04E8) /* MFPR for GPIO16_2 */ -#define GPIO17_2_MFPR (APPS_PAD_BASE + 0x04EC) /* MFPR for GPIO17_2 */ - -#define PIN_nXCVREN_MFPR (APPS_PAD_BASE + 0x0138) -#define PIN_ND_CLE_MFPR (APPS_PAD_BASE + 0x0204) -#define PIN_DF_nADV1_ALE_MFPR (APPS_PAD_BASE + 0x0208) -#define PIN_DF_SCLK_S_MFPR (APPS_PAD_BASE + 0x020C) -#define PIN_DF_SCLK_E_MFPR (APPS_PAD_BASE + 0x0210) -#define PIN_nBE0_MFPR (APPS_PAD_BASE + 0x0214) -#define PIN_nBE1_MFPR (APPS_PAD_BASE + 0x0218) -#define PIN_DF_nADV2_ALE_MFPR (APPS_PAD_BASE + 0x021C) -#define PIN_DF_INT_RnB_MFPR (APPS_PAD_BASE + 0x0220) -#define PIN_DF_nCS0_MFPR (APPS_PAD_BASE + 0x0224) -#define PIN_DF_nCS1_MFPR (APPS_PAD_BASE + 0x0228) -#define PIN_DF_nWE_MFPR (APPS_PAD_BASE + 0x022C) -#define PIN_DF_nRE_nOE_MFPR (APPS_PAD_BASE + 0x0230) -#define PIN_nLUA_MFPR (APPS_PAD_BASE + 0x0234) -#define PIN_nLLA_MFPR (APPS_PAD_BASE + 0x0238) -#define PIN_DF_ADDR0_MFPR (APPS_PAD_BASE + 0x023C) -#define PIN_DF_ADDR1_MFPR (APPS_PAD_BASE + 0x0240) -#define PIN_DF_ADDR2_MFPR (APPS_PAD_BASE + 0x0244) -#define PIN_DF_ADDR3_MFPR (APPS_PAD_BASE + 0x0248) -#define PIN_DF_IO0_MFPR (APPS_PAD_BASE + 0x024C) -#define PIN_DF_IO1_MFPR (APPS_PAD_BASE + 0x0254) -#define PIN_DF_IO2_MFPR (APPS_PAD_BASE + 0x025C) -#define PIN_DF_IO3_MFPR (APPS_PAD_BASE + 0x0264) -#define PIN_DF_IO4_MFPR (APPS_PAD_BASE + 0x026C) -#define PIN_DF_IO5_MFPR (APPS_PAD_BASE + 0x0274) -#define PIN_DF_IO6_MFPR (APPS_PAD_BASE + 0x027C) -#define PIN_DF_IO7_MFPR (APPS_PAD_BASE + 0x0294) -#define PIN_DF_IO8_MFPR (APPS_PAD_BASE + 0x0298) -#define PIN_DF_IO9_MFPR (APPS_PAD_BASE + 0x029C) -#define PIN_DF_IO10_MFPR (APPS_PAD_BASE + 0x0260) -#define PIN_DF_IO11_MFPR (APPS_PAD_BASE + 0x0268) -#define PIN_DF_IO12_MFPR (APPS_PAD_BASE + 0x0270) -#define PIN_DF_IO13_MFPR (APPS_PAD_BASE + 0x0278) -#define PIN_DF_IO14_MFPR (APPS_PAD_BASE + 0x0280) -#define PIN_DF_IO15_MFPR (APPS_PAD_BASE + 0x0288) - -/* GPIO mode encodings: Direction, Number, MFPR value */ - -#define MFPR_PS 0x80000000 /* MFPR bit 15: pull_sel */ -#define MFPR_PUE 0x40000000 /* MFPR bit 14: pullup_en */ -#define MFPR_PDE 0x20000000 /* MFPR bit 13: pulldown_en */ -#define MFPR_DF1 0x00000000 /* MFPR bit 12-10: drive, fast 1ma */ -#define MFPR_DF2 0x04000000 /* MFPR bit 12-10: drive, fast 2ma */ -#define MFPR_DF3 0x08000000 /* MFPR bit 12-10: drive, fast 3ma */ -#define MFPR_DF4 0x0c000000 /* MFPR bit 12-10: drive, fast 4ma */ -#define MFPR_DS6 0x10000000 /* MFPR bit 12-10: drive, slow 6ma */ -#define MFPR_DF6 0x14000000 /* MFPR bit 12-10: drive, fast 6ma */ -#define MFPR_DS10 0x18000000 /* MFPR bit 12-10: drive, slow 10ma */ -#define MFPR_DF10 0x1c000000 /* MFPR bit 12-10: drive, fast 10ma */ -#define MFPR_SS 0x02000000 /* MFPR bit 9: sleep_sel */ -#define MFPR_SD 0x01000000 /* MFPR bit 8: sleep_data */ -#define MFPR_SE 0x00800000 /* MFPR bit 7: sleep_oe */ -#define MFPR_EC 0x00400000 /* MFPR bit 6: edge_clear */ -#define MFPR_EF 0x00200000 /* MFPR bit 5: edge_fall_en */ -#define MFPR_ER 0x00100000 /* MFPR bit 4: edge_rise_en */ -#define MFPR_ALT0 0x00000000 /* MFPR bit 2-0: alternate function 0 */ -#define MFPR_ALT1 0x00010000 /* MFPR bit 2-0: alternate function 1 */ -#define MFPR_ALT2 0x00020000 /* MFPR bit 2-0: alternate function 2 */ -#define MFPR_ALT3 0x00030000 /* MFPR bit 2-0: alternate function 3 */ -#define MFPR_ALT4 0x00040000 /* MFPR bit 2-0: alternate function 4 */ -#define MFPR_ALT5 0x00050000 /* MFPR bit 2-0: alternate function 5 */ -#define MFPR_ALT6 0x00060000 /* MFPR bit 2-0: alternate function 6 */ -#define MFPR_ALT7 0x00070000 /* MFPR bit 2-0: alternate function 7 */ -#define GPIO_MD_MASK_NR 0x0000ffff -#define GPIO_MD_MASK_MFPR 0xffff0000 -#define GPIO_MD_SHIFT_MFPR 16 - -#define GPIO3_NCS_2 (3|MFPR_DS6|MFPR_ALT1) -#define GPIO11_PWM0 (11|MFPR_DS6|MFPR_ALT1) -#define GPIO12_PWM1 (12|MFPR_DS6|MFPR_ALT1) -#define GPIO14_LCD_BACKLIGHT_PWM3 (14|MFPR_DS6|MFPR_ALT1) - -#define GPIO18_MMC_DAT_0 (18|MFPR_DS6|MFPR_ALT4) -#define GPIO19_MMC_DAT_1 (19|MFPR_DS6|MFPR_ALT4) -#define GPIO20_MMC_DAT_2 (20|MFPR_DS6|MFPR_ALT4) -#define GPIO21_MMC_DAT_3 (21|MFPR_DS6|MFPR_ALT4) -#define GPIO22_CLK_MMC (22|MFPR_DS6|MFPR_ALT4) -#define GPIO23_MMC_CMD (23|MFPR_DS6|MFPR_ALT4) -#define GPIO24_MMC2_DAT_0 (24|MFPR_DS6|MFPR_ALT4) -#define GPIO25_MMC2_DAT_1 (25|MFPR_DS6|MFPR_ALT4) -#define GPIO26_MMC2_DAT_2 (26|MFPR_DS6|MFPR_ALT4) -#define GPIO27_MMC2_DAT_3 (27|MFPR_DS6|MFPR_ALT4) -#define GPIO28_CLK_MMC2 (28|MFPR_DS6|MFPR_ALT4) -#define GPIO29_MMC2_CMD (29|MFPR_DS6|MFPR_ALT4) -#define GPIO30_CLK_MMC (30|MFPR_DS6|MFPR_ALT4) -#define GPIO31_MMC_CMD (31|MFPR_DS6|MFPR_ALT4) -#define GPIO34_AC97_SYSCLK (34|MFPR_DF6|MFPR_ALT1) -#define GPIO35_AC97_SDATA_IN0 (35|MFPR_DF6|MFPR_ALT1) -#define GPIO36_AC97_SDATA_IN1 (36|MFPR_DF6|MFPR_ALT1) -#define GPIO37_AC97_SDATA_OUT (37|MFPR_DF6|MFPR_ALT1) -#define GPIO38_AC97_SYNC (38|MFPR_DF6|MFPR_ALT1) -#define GPIO39_AC97_BITCLK (39|MFPR_DF6|MFPR_ALT1) -#define GPIO40_AC97_RESET_N (40|MFPR_DF6|MFPR_ALT1) -#define GPIO41_FF_UART1_RXD (41|MFPR_DS6|MFPR_ALT2) -#define GPIO42_FF_UART1_TXD (42|MFPR_DS6|MFPR_ALT2) -#define GPIO43_FF_UART1_CTS (43|MFPR_DS6|MFPR_ALT2) -#define GPIO44_FF_UART1_DCD (44|MFPR_DF10|MFPR_SD|MFPR_ALT2) -#define GPIO45_FF_UART1_DSR (45|MFPR_DS6|MFPR_ALT2) -#define GPIO46_FF_UART1_RI (46|MFPR_DS6|MFPR_ALT2) -#define GPIO47_FF_UART1_DTR (47|MFPR_DS6|MFPR_ALT2) -#define GPIO48_FF_UART1_RTS (48|MFPR_DS6|MFPR_ALT2) -#define GPIO49_CIF_DD0 (49|MFPR_DF6|MFPR_ALT1) -#define GPIO50_CIF_DD1 (50|MFPR_DF6|MFPR_ALT1) -#define GPIO51_CIF_DD2 (51|MFPR_DF6|MFPR_ALT1) -#define GPIO52_CIF_DD3 (52|MFPR_DF6|MFPR_ALT1) -#define GPIO53_CIF_DD4 (53|MFPR_DF6|MFPR_ALT1) -#define GPIO54_CIF_DD5 (54|MFPR_DF6|MFPR_ALT1) -#define GPIO55_CIF_DD6 (55|MFPR_DF6|MFPR_ALT1) -#define GPIO56_CIF_DD7 (56|MFPR_DF6|MFPR_ALT1) -#define GPIO57_CIF_DD8 (57|MFPR_DF6|MFPR_ALT1) -#define GPIO58_CIF_DD9 (58|MFPR_DF6|MFPR_ALT1) -#define GPIO59_CIF_MCLK (59|MFPR_DF6|MFPR_ALT1) -#define GPIO60_CIF_PCLK (60|MFPR_DF6|MFPR_ALT1) -#define GPIO61_CIF_LV (61|MFPR_DF6|MFPR_ALT1) -#define GPIO62_CIF_FV (62|MFPR_DF6|MFPR_ALT1) -#define GPIO63_LCD_LDD_8 (63|MFPR_DF6|MFPR_ALT1) -#define GPIO64_LCD_LDD_9 (64|MFPR_DF6|MFPR_ALT1) -#define GPIO65_LCD_LDD_10 (65|MFPR_DF6|MFPR_ALT1) -#define GPIO66_LCD_LDD_11 (66|MFPR_DF6|MFPR_ALT1) -#define GPIO67_LCD_LDD_12 (67|MFPR_DF6|MFPR_ALT1) -#define GPIO68_LCD_LDD_13 (68|MFPR_DF6|MFPR_ALT1) -#define GPIO69_LCD_LDD_14 (69|MFPR_DF6|MFPR_ALT1) -#define GPIO70_LCD_LDD_15 (70|MFPR_DF6|MFPR_ALT1) -#define GPIO71_LCD_LDD_16 (71|MFPR_DF6|MFPR_ALT1) -#define GPIO72_LCD_LDD_17 (72|MFPR_DF6|MFPR_ALT1) -#define GPIO73_LCD_CS (73|MFPR_DF6|MFPR_ALT2) -#define GPIO74_LCD_VSYNC (74|MFPR_DF6|MFPR_ALT2) -#define GPIO89_SSP3_SCLK (89|MFPR_DS6|MFPR_ALT1) -#define GPIO90_SSP3_SFRM (90|MFPR_DS6|MFPR_ALT1) -#define GPIO91_SSP3_TXD (91|MFPR_DS6|MFPR_ALT1) -#define GPIO92_SSP3_RXD (92|MFPR_DS6|MFPR_ALT1) -#define GPIO93_SSP4_SCLK (93|MFPR_DS6|MFPR_ALT1) -#define GPIO94_SSP4_SFRM (94|MFPR_DS6|MFPR_ALT1) -#define GPIO95_SSP4_TXD (95|MFPR_DS6|MFPR_ALT1) -#define GPIO96_SSP4_RXD (96|MFPR_DS6|MFPR_ALT1) -#define GPIO100_USB_P2_4 (100|MFPR_DS6|MFPR_ALT2) -#define GPIO101_USB_P2_8 (101|MFPR_DS6|MFPR_ALT2) -#define GPIO102_USB_P2_3 (102|MFPR_DS6|MFPR_ALT2) -#define GPIO103_USB_P2_5 (103|MFPR_DS6|MFPR_ALT2) -#define GPIO104_USB_P2_7 (104|MFPR_DS6|MFPR_ALT2) -#define GPIO105_KP_DKIN_0 (105|MFPR_DS6|MFPR_ALT2) -#define GPIO106_KP_DKIN_1 (106|MFPR_DS6|MFPR_ALT2) -#define GPIO107_STD_UART3_TXD (107|MFPR_DS6|MFPR_ALT1) -#define GPIO108_STD_UART3_RXD (108|MFPR_DS6|MFPR_ALT1) -#define GPIO109_BT_UART2_RTS (109|MFPR_DS6|MFPR_ALT1) -#define GPIO110_BT_UART2_RXD (110|MFPR_DS6|MFPR_ALT1) -#define GPIO111_BT_UART2_TXD (111|MFPR_DS6|MFPR_ALT1) -#define GPIO112_BT_UART2_CTS (112|MFPR_DS6|MFPR_ALT1) -#define GPIO113_KP_MKIN_0 (113|MFPR_DS6|MFPR_ALT1) -#define GPIO114_KP_MKIN_1 (114|MFPR_DS6|MFPR_ALT1) -#define GPIO115_KP_MKIN_2 (115|MFPR_DS6|MFPR_ALT1) -#define GPIO116_KP_MKIN_3 (116|MFPR_DS6|MFPR_ALT1) -#define GPIO117_KP_MKIN_4 (117|MFPR_DS6|MFPR_ALT1) -#define GPIO118_KP_MKIN_5 (118|MFPR_DS6|MFPR_ALT1) -#define GPIO119_KP_MKIN_6 (119|MFPR_DS6|MFPR_ALT1) -#define GPIO120_KP_MKIN_7 (120|MFPR_DS6|MFPR_ALT1) -#define GPIO121_KP_MKOUT_0 (121|MFPR_DS6|MFPR_ALT1) -#define GPIO122_KP_MKOUT_1 (122|MFPR_DS6|MFPR_ALT1) -#define GPIO123_KP_MKOUT_2 (123|MFPR_DS6|MFPR_ALT1) -#define GPIO124_KP_MKOUT_3 (124|MFPR_DS6|MFPR_ALT1) -#define GPIO125_KP_MKOUT_4 (125|MFPR_DS6|MFPR_ALT1) -#define GPIO126_KP_MKOUT_5 (126|MFPR_DS6|MFPR_ALT1) -#define GPIO127_KP_MKOUT_6 (127|MFPR_DS6|MFPR_ALT1) -#define GPIO5_2_KP_MKOUT_7 (133|MFPR_DS6|MFPR_ALT1) -#define GPIO6_2_LCD_LDD_0 (134|MFPR_DS6|MFPR_ALT1) -#define GPIO7_2_LCD_LDD_1 (135|MFPR_DS6|MFPR_ALT1) -#define GPIO8_2_LCD_LDD_2 (136|MFPR_DS6|MFPR_ALT1) -#define GPIO9_2_LCD_LDD_3 (137|MFPR_DS6|MFPR_ALT1) -#define GPIO10_2_LCD_LDD_4 (138|MFPR_DS6|MFPR_ALT1) -#define GPIO11_2_LCD_LDD_5 (139|MFPR_DS6|MFPR_ALT1) -#define GPIO12_2_LCD_LDD_6 (140|MFPR_DS6|MFPR_ALT1) -#define GPIO13_2_LCD_LDD_7 (141|MFPR_DS6|MFPR_ALT1) -#define GPIO14_2_LCD_FCLK (142|MFPR_DS6|MFPR_ALT1) -#define GPIO15_2_LCD_LCLK (143|MFPR_DS6|MFPR_ALT1) -#define GPIO16_2_LCD_PCLK (144|MFPR_DS6|MFPR_ALT1) -#define GPIO17_2_LCD_BIAS (145|MFPR_DS6|MFPR_ALT1) - -/* Internal System Bus Arbiter */ -#define ARB_CNTRL1 __REG_2(0x4600FE00) /* PX1 Bus Arbiter Control Register */ -#define ARB_CNTRL2 __REG_2(0x4600FE80) /* PX2 Bus Arbiter Control Register */ - -/* - * Keypad - */ -#define KPC __REG(0x41500000) /* Keypad Interface Control register */ -#define KPDK __REG(0x41500008) /* Keypad Interface Direct Key register */ -#define KPREC __REG(0x41500010) /* Keypad Interface Rotary Encoder register */ -#define KPMK __REG(0x41500018) /* Keypad Interface Matrix Key register */ -#define KPAS __REG(0x41500020) /* Keypad Interface Automatic Scan register */ -#define KPASMKP0 __REG(0x41500028) /* Keypad Interface Automatic Scan Multiple Key Presser register 0 */ -#define KPASMKP1 __REG(0x41500030) /* Keypad Interface Automatic Scan Multiple Key Presser register 1 */ -#define KPASMKP2 __REG(0x41500038) /* Keypad Interface Automatic Scan Multiple Key Presser register 2 */ -#define KPASMKP3 __REG(0x41500040) /* Keypad Interface Automatic Scan Multiple Key Presser register 3 */ -#define KPKDI __REG(0x41500048) /* Keypad Interface Key Debounce Interval register */ - -#define KPC_AS (0x1 << 30) /* Automatic Scan bit */ -#define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */ -#define KPC_MI (0x1 << 22) /* Matrix interrupt bit */ -#define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */ -#define KPC_MS7 (0x1 << 20) /* Matrix scan line 7 */ -#define KPC_MS6 (0x1 << 19) /* Matrix scan line 6 */ -#define KPC_MS5 (0x1 << 18) /* Matrix scan line 5 */ -#define KPC_MS4 (0x1 << 17) /* Matrix scan line 4 */ -#define KPC_MS3 (0x1 << 16) /* Matrix scan line 3 */ -#define KPC_MS2 (0x1 << 15) /* Matrix scan line 2 */ -#define KPC_MS1 (0x1 << 14) /* Matrix scan line 1 */ -#define KPC_MS0 (0x1 << 13) /* Matrix scan line 0 */ -#define KPC_MS_ALL (KPC_MS0 | KPC_MS1 | KPC_MS2 | KPC_MS3 | KPC_MS4 | KPC_MS5 | KPC_MS6 | KPC_MS7) -#define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */ -#define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */ -#define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Keypad Debounce Select */ -#define KPC_DI (0x1 << 5) /* Direct key interrupt bit */ -#define KPC_RE_ZERO_DEB (0x1 << 4) /* Rotary Encoder Zero Debounce */ -#define KPC_REE1 (0x1 << 3) /* Rotary Encoder1 Enable */ -#define KPC_REE0 (0x1 << 2) /* Rotary Encoder0 Enable */ -#define KPC_DE (0x1 << 1) /* Direct Keypad Enable */ -#define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */ - -#define KPDK_DKP (0x1 << 31) -#define KPDK_DK7 (0x1 << 7) -#define KPDK_DK6 (0x1 << 6) -#define KPDK_DK5 (0x1 << 5) -#define KPDK_DK4 (0x1 << 4) -#define KPDK_DK3 (0x1 << 3) -#define KPDK_DK2 (0x1 << 2) -#define KPDK_DK1 (0x1 << 1) -#define KPDK_DK0 (0x1 << 0) - -#define KPREC_OF1 (0x1 << 31) -#define kPREC_UF1 (0x1 << 30) -#define KPREC_OF0 (0x1 << 15) -#define KPREC_UF0 (0x1 << 14) - -#define KPMK_MKP (0x1 << 31) -#define KPAS_SO (0x1 << 31) -#define KPASMKPx_SO (0x1 << 31) - -/* - * UHC: USB Host Controller (OHCI-like) register definitions - */ -#define UHC_BASE_PHYS (0x4C000000) -#define UHCREV __REG_2(0x4C000000) /* UHC HCI Spec Revision */ -#define UHCHCON __REG_2(0x4C000004) /* UHC Host Control Register */ -#define UHCCOMS __REG_2(0x4C000008) /* UHC Command Status Register */ -#define UHCINTS __REG_2(0x4C00000C) /* UHC Interrupt Status Register */ -#define UHCINTE __REG_2(0x4C000010) /* UHC Interrupt Enable */ -#define UHCINTD __REG_2(0x4C000014) /* UHC Interrupt Disable */ -#define UHCHCCA __REG_2(0x4C000018) /* UHC Host Controller Comm. Area */ -#define UHCPCED __REG_2(0x4C00001C) /* UHC Period Current Endpt Descr */ -#define UHCCHED __REG_2(0x4C000020) /* UHC Control Head Endpt Descr */ -#define UHCCCED __REG_2(0x4C000024) /* UHC Control Current Endpt Descr */ -#define UHCBHED __REG_2(0x4C000028) /* UHC Bulk Head Endpt Descr */ -#define UHCBCED __REG_2(0x4C00002C) /* UHC Bulk Current Endpt Descr */ -#define UHCDHEAD __REG_2(0x4C000030) /* UHC Done Head */ -#define UHCFMI __REG_2(0x4C000034) /* UHC Frame Interval */ -#define UHCFMR __REG_2(0x4C000038) /* UHC Frame Remaining */ -#define UHCFMN __REG_2(0x4C00003C) /* UHC Frame Number */ -#define UHCPERS __REG_2(0x4C000040) /* UHC Periodic Start */ -#define UHCLS __REG_2(0x4C000044) /* UHC Low Speed Threshold */ -#define UHCRHDA __REG_2(0x4C000048) /* UHC Root Hub Descriptor A */ -#define UHCRHDB __REG_2(0x4C00004C) /* UHC Root Hub Descriptor B */ -#define UHCRHS __REG_2(0x4C000050) /* UHC Root Hub Status */ -#define UHCRHPS1 __REG_2(0x4C000054) /* UHC Root Hub Port 1 Status */ -#define UHCRHPS2 __REG_2(0x4C000058) /* UHC Root Hub Port 2 Status */ -#define UHCRHPS3 __REG_2(0x4C00005C) /* UHC Root Hub Port 3 Status */ -#define UHCRHPS(x) __REG2_2(0x4C000050, (x)<<2) - -#define UHCSTAT __REG_2(0x4C000060) /* UHC Status Register */ -#define UHCSTAT_UPS3 (1 << 16) /* USB Power Sense Port3 */ -#define UHCSTAT_SBMAI (1 << 15) /* System Bus Master Abort Interrupt*/ -#define UHCSTAT_SBTAI (1 << 14) /* System Bus Target Abort Interrupt*/ -#define UHCSTAT_UPRI (1 << 13) /* USB Port Resume Interrupt */ -#define UHCSTAT_UPS2 (1 << 12) /* USB Power Sense Port 2 */ -#define UHCSTAT_UPS1 (1 << 11) /* USB Power Sense Port 1 */ -#define UHCSTAT_HTA (1 << 10) /* HCI Target Abort */ -#define UHCSTAT_HBA (1 << 8) /* HCI Buffer Active */ -#define UHCSTAT_RWUE (1 << 7) /* HCI Remote Wake Up Event */ - -#define UHCHR __REG_2(0x4C000064) /* UHC Reset Register */ -#define UHCHR_SSEP3 (1 << 11) /* Sleep Standby Enable for Port3 */ -#define UHCHR_SSEP2 (1 << 10) /* Sleep Standby Enable for Port2 */ -#define UHCHR_SSEP1 (1 << 9) /* Sleep Standby Enable for Port1 */ -#define UHCHR_PCPL (1 << 7) /* Power control polarity low */ -#define UHCHR_PSPL (1 << 6) /* Power sense polarity low */ -#define UHCHR_SSE (1 << 5) /* Sleep Standby Enable */ -#define UHCHR_UIT (1 << 4) /* USB Interrupt Test */ -#define UHCHR_SSDC (1 << 3) /* Simulation Scale Down Clock */ -#define UHCHR_CGR (1 << 2) /* Clock Generation Reset */ -#define UHCHR_FHR (1 << 1) /* Force Host Controller Reset */ -#define UHCHR_FSBIR (1 << 0) /* Force System Bus Iface Reset */ - -#define UHCHIE __REG_2(0x4C000068) /* UHC Interrupt Enable Register*/ -#define UHCHIE_UPS3IE (1 << 14) /* Power Sense Port3 IntEn */ -#define UHCHIE_UPRIE (1 << 13) /* Port Resume IntEn */ -#define UHCHIE_UPS2IE (1 << 12) /* Power Sense Port2 IntEn */ -#define UHCHIE_UPS1IE (1 << 11) /* Power Sense Port1 IntEn */ -#define UHCHIE_TAIE (1 << 10) /* HCI Interface Transfer Abort - Interrupt Enable*/ -#define UHCHIE_HBAIE (1 << 8) /* HCI Buffer Active IntEn */ -#define UHCHIE_RWIE (1 << 7) /* Remote Wake-up IntEn */ - -#define UHCHIT __REG_2(0x4C00006C) /* UHC Interrupt Test register */ - -/* Camera Interface / Quick Capture Interface */ -#define CICR0 __REG_3(0x50000000) /* Control register 0 */ -#define CICR1 __REG_3(0x50000004) /* Control register 1 */ -#define CICR2 __REG_3(0x50000008) /* Control register 2 */ -#define CICR3 __REG_3(0x5000000C) /* Control register 3 */ -#define CICR4 __REG_3(0x50000010) /* Control register 4 */ -#define CISR __REG_3(0x50000014) /* Status register */ -#define CITOR __REG_3(0x5000001C) /* Time-Out register */ -#define CIBR0 __REG_3(0x50000028) /* Channel 0 Receive Buffer */ -#define CIBR1 __REG_3(0x50000030) /* Channel 1 Receive Buffer */ -#define CIBR2 __REG_3(0x50000038) /* Channel 2 Receive Buffer */ -#define CIBR3 __REG_3(0x50000040) /* Channel 3 Receive Buffer */ - -#define CIPSS __REG_3(0x50000064) /* Pixel Substitution Status register */ -#define CIPBUF __REG_3(0x50000068) /* Pixel Substitution Buffer */ -#define CIHST __REG_3(0x5000006C) /* Histogram Configuration */ -#define CISUM __REG_3(0x50000070) /* Histogram Summation register */ -#define CICCR __REG_3(0x50000074) /* Compander Configuration */ -#define CISSC __REG_3(0x5000007C) /* Spatial Scaling Configuration */ - -#define CICMR __REG_3(0x50000090) /* Color Management register */ -#define CICMC0 __REG_3(0x50000094) /* Color Management Coefficients 0 */ -#define CICMC1 __REG_3(0x50000098) /* Color Management Coefficients 1 */ -#define CICMC2 __REG_3(0x5000009C) /* Color Management Coefficients 2 */ - -#define CIFR0 __REG_3(0x500000B0) /* FIFO Control register 0 */ -#define CIFR1 __REG_3(0x500000B4) /* FIFO Control register 1 */ -#define CIFSR __REG_3(0x500000C0) /* FIFO Status register */ - -#define CIDADR0 __REG_3(0x50000240) /* DMA Descriptor Address Channel 0 register */ -#define CIDADR1 __REG_3(0x50000250) /* DMA Descriptor Address Channel 1 register */ -#define CIDADR2 __REG_3(0x50000260) /* DMA Descriptor Address Channel 2 register */ -#define CIDADR3 __REG_3(0x50000270) /* DMA Descriptor Address Channel 3 register */ -#define CITADR0 __REG_3(0x50000244) /* DMA Target Address Channel 0 register */ -#define CITADR1 __REG_3(0x50000254) /* DMA Target Address Channel 1 register */ -#define CITADR2 __REG_3(0x50000264) /* DMA Target Address Channel 2 register */ -#define CITADR3 __REG_3(0x50000274) /* DMA Target Address Channel 3 register */ -#define CISADR0 __REG_3(0x50000248) /* DMA Source Address Channel 0 register */ -#define CISADR1 __REG_3(0x50000258) /* DMA Source Address Channel 1 register */ -#define CISADR2 __REG_3(0x50000268) /* DMA Source Address Channel 2 register */ -#define CISADR3 __REG_3(0x50000278) /* DMA Source Address Channel 3 register */ -#define CICMD0 __REG_3(0x5000024C) /* DMA Command Channel 0 register*/ -#define CICMD1 __REG_3(0x5000025C) /* DMA Command Channel 1 register*/ -#define CICMD2 __REG_3(0x5000026C) /* DMA Command Channel 2 register*/ -#define CICMD3 __REG_3(0x5000027C) /* DMA Command Channel 3 register*/ -#define CIDBR0 __REG_3(0x50000220) /* DMA Branch Channel 0 register*/ -#define CIDBR1 __REG_3(0x50000224) /* DMA Branch Channel 1 register*/ -#define CIDBR2 __REG_3(0x50000228) /* DMA Branch Channel 2 register*/ -#define CIDBR3 __REG_3(0x5000022C) /* DMA Branch Channel 3 register*/ -#define CIDCSR0 __REG_3(0x50000200) /* DMA Ctrl/Status Channel 0 register*/ -#define CIDCSR1 __REG_3(0x50000204) /* DMA Ctrl/Status Channel 1 register*/ -#define CIDCSR2 __REG_3(0x50000208) /* DMA Ctrl/Status Channel 2 register*/ -#define CIDCSR3 __REG_3(0x5000020C) /* DMA Ctrl/Status Channel 3 register*/ - -#define CICR0_DMAEN (1 << 31) /* DMA request enable */ -#define CICR0_PAR_EN (1 << 30) /* Parity enable */ -#define CICR0_SL_CAP_EN (1 << 29) /* Capture enable for slave mode */ -#define CICR0_ENB (1 << 28) /* Camera interface enable */ -#define CICR0_DIS (1 << 27) /* Camera interface disable */ -#define CICR0_SIM (0x7 << 24) /* Sensor interface mode mask */ -#define CICR0_TOM (1 << 9) /* Time-out mask */ -#define CICR0_RDAVM (1 << 8) /* Receive-data-available mask */ -#define CICR0_FEM (1 << 7) /* FIFO-empty mask */ -#define CICR0_EOLM (1 << 6) /* End-of-line mask */ -#define CICR0_PERRM (1 << 5) /* Parity-error mask */ -#define CICR0_QDM (1 << 4) /* Quick-disable mask */ -#define CICR0_CDM (1 << 3) /* Disable-done mask */ -#define CICR0_SOFM (1 << 2) /* Start-of-frame mask */ -#define CICR0_EOFM (1 << 1) /* End-of-frame mask */ -#define CICR0_FOM (1 << 0) /* FIFO-overrun mask */ - -#define CICR1_TBIT (1 << 31) /* Transparency bit */ -#define CICR1_RGBT_CONV (0x3 << 30) /* RGBT conversion mask */ -#define CICR1_PPL (0x3f << 15) /* Pixels per line mask */ -#define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */ -#define CICR1_RGB_F (1 << 11) /* RGB format */ -#define CICR1_YCBCR_F (1 << 10) /* YCbCr format */ -#define CICR1_RGB_BPP (0x7 << 7) /* RGB bis per pixel mask */ -#define CICR1_RAW_BPP (0x3 << 5) /* Raw bis per pixel mask */ -#define CICR1_COLOR_SP (0x3 << 3) /* Color space mask */ -#define CICR1_DW (0x7 << 0) /* Data width mask */ - -#define CICR2_BLW (0xff << 24) /* Beginning-of-line pixel clock - wait count mask */ -#define CICR2_ELW (0xff << 16) /* End-of-line pixel clock - wait count mask */ -#define CICR2_HSW (0x3f << 10) /* Horizontal sync pulse width mask */ -#define CICR2_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock - wait count mask */ -#define CICR2_FSW (0x7 << 0) /* Frame stabilization - wait count mask */ - -#define CICR3_BFW (0xff << 24) /* Beginning-of-frame line clock - wait count mask */ -#define CICR3_EFW (0xff << 16) /* End-of-frame line clock - wait count mask */ -#define CICR3_VSW (0x3f << 10) /* Vertical sync pulse width mask */ -#define CICR3_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock - wait count mask */ -#define CICR3_LPF (0x3ff << 0) /* Lines per frame mask */ - -#define CICR4_MCLK_DLY (0x3 << 24) /* MCLK Data Capture Delay mask */ -#define CICR4_PCLK_EN (1 << 23) /* Pixel clock enable */ -#define CICR4_PCP (1 << 22) /* Pixel clock polarity */ -#define CICR4_HSP (1 << 21) /* Horizontal sync polarity */ -#define CICR4_VSP (1 << 20) /* Vertical sync polarity */ -#define CICR4_MCLK_EN (1 << 19) /* MCLK enable */ -#define CICR4_FR_RATE (0x7 << 8) /* Frame rate mask */ -#define CICR4_DIV (0xff << 0) /* Clock divisor mask */ - -#define CISR_FTO (1 << 15) /* FIFO time-out */ -#define CISR_RDAV_2 (1 << 14) /* Channel 2 receive data available */ -#define CISR_RDAV_1 (1 << 13) /* Channel 1 receive data available */ -#define CISR_RDAV_0 (1 << 12) /* Channel 0 receive data available */ -#define CISR_FEMPTY_2 (1 << 11) /* Channel 2 FIFO empty */ -#define CISR_FEMPTY_1 (1 << 10) /* Channel 1 FIFO empty */ -#define CISR_FEMPTY_0 (1 << 9) /* Channel 0 FIFO empty */ -#define CISR_EOL (1 << 8) /* End of line */ -#define CISR_PAR_ERR (1 << 7) /* Parity error */ -#define CISR_CQD (1 << 6) /* Camera interface quick disable */ -#define CISR_SOF (1 << 5) /* Start of frame */ -#define CISR_CDD (1 << 4) /* Camera interface disable done */ -#define CISR_EOF (1 << 3) /* End of frame */ -#define CISR_IFO_2 (1 << 2) /* FIFO overrun for Channel 2 */ -#define CISR_IFO_1 (1 << 1) /* FIFO overrun for Channel 1 */ -#define CISR_IFO_0 (1 << 0) /* FIFO overrun for Channel 0 */ - -#define CIFR_FLVL2 (0x7f << 23) /* FIFO 2 level mask */ -#define CIFR_FLVL1 (0x7f << 16) /* FIFO 1 level mask */ -#define CIFR_FLVL0 (0xff << 8) /* FIFO 0 level mask */ -#define CIFR_THL_0 (0x3 << 4) /* Threshold Level for Channel 0 FIFO */ -#define CIFR_RESET_F (1 << 3) /* Reset input FIFOs */ -#define CIFR_FEN2 (1 << 2) /* FIFO enable for channel 2 */ -#define CIFR_FEN1 (1 << 1) /* FIFO enable for channel 1 */ -#define CIFR_FEN0 (1 << 0) /* FIFO enable for channel 0 */ - -#endif /* CONFIG_CPU_MONAHANS */ - -#endif +#define LCCR0_LDDALT (1<<26) /* LDD Alternate mapping bit when base pixel is RGBT16 */ +#define LCCR0_OUC (1<<25) /* Overlay Underlay Control Bit */ + +#define LCCR5_SOFM1 (1<<0) /* Start Of Frame Mask for Overlay 1 (channel 1) */ +#define LCCR5_SOFM2 (1<<1) /* Start Of Frame Mask for Overlay 2 (channel 2) */ +#define LCCR5_SOFM3 (1<<2) /* Start Of Frame Mask for Overlay 2 (channel 3) */ +#define LCCR5_SOFM4 (1<<3) /* Start Of Frame Mask for Overlay 2 (channel 4) */ +#define LCCR5_SOFM5 (1<<4) /* Start Of Frame Mask for cursor (channel 5) */ +#define LCCR5_SOFM6 (1<<5) /* Start Of Frame Mask for command data (channel 6) */ + +#define LCCR5_EOFM1 (1<<8) /* End Of Frame Mask for Overlay 1 (channel 1) */ +#define LCCR5_EOFM2 (1<<9) /* End Of Frame Mask for Overlay 2 (channel 2) */ +#define LCCR5_EOFM3 (1<<10) /* End Of Frame Mask for Overlay 2 (channel 3) */ +#define LCCR5_EOFM4 (1<<11) /* End Of Frame Mask for Overlay 2 (channel 4) */ +#define LCCR5_EOFM5 (1<<12) /* End Of Frame Mask for cursor (channel 5) */ +#define LCCR5_EOFM6 (1<<13) /* End Of Frame Mask for command data (channel 6) */ + +#define LCCR5_BSM1 (1<<16) /* Branch mask for Overlay 1 (channel 1) */ +#define LCCR5_BSM2 (1<<17) /* Branch mask for Overlay 2 (channel 2) */ +#define LCCR5_BSM3 (1<<18) /* Branch mask for Overlay 2 (channel 3) */ +#define LCCR5_BSM4 (1<<19) /* Branch mask for Overlay 2 (channel 4) */ +#define LCCR5_BSM5 (1<<20) /* Branch mask for cursor (channel 5) */ +#define LCCR5_BSM6 (1<<21) /* Branch mask for data command (channel 6) */ + +#define LCCR5_IUM1 (1<<24) /* Input FIFO Underrun Mask for Overlay 1 */ +#define LCCR5_IUM2 (1<<25) /* Input FIFO Underrun Mask for Overlay 2 */ +#define LCCR5_IUM3 (1<<26) /* Input FIFO Underrun Mask for Overlay 2 */ +#define LCCR5_IUM4 (1<<27) /* Input FIFO Underrun Mask for Overlay 2 */ +#define LCCR5_IUM5 (1<<28) /* Input FIFO Underrun Mask for cursor */ +#define LCCR5_IUM6 (1<<29) /* Input FIFO Underrun Mask for data command */ + +#define OVL1C1_O1EN (1<<31) /* Enable bit for Overlay 1 */ +#define OVL2C1_O2EN (1<<31) /* Enable bit for Overlay 2 */ +#define CCR_CEN (1<<31) /* Enable bit for Cursor */ + +/* Keypad controller */ + +#define KPC __REG(0x41500000) /* Keypad Interface Control register */ +#define KPDK __REG(0x41500008) /* Keypad Interface Direct Key register */ +#define KPREC __REG(0x41500010) /* Keypad Intefcace Rotary Encoder register */ +#define KPMK __REG(0x41500018) /* Keypad Intefcace Matrix Key register */ +#define KPAS __REG(0x41500020) /* Keypad Interface Automatic Scan register */ +#define KPASMKP0 __REG(0x41500028) /* Keypad Interface Automatic Scan Multiple Key Presser register 0 */ +#define KPASMKP1 __REG(0x41500030) /* Keypad Interface Automatic Scan Multiple Key Presser register 1 */ +#define KPASMKP2 __REG(0x41500038) /* Keypad Interface Automatic Scan Multiple Key Presser register 2 */ +#define KPASMKP3 __REG(0x41500040) /* Keypad Interface Automatic Scan Multiple Key Presser register 3 */ +#define KPKDI __REG(0x41500048) /* Keypad Interface Key Debounce Interval register */ + +#define KPC_AS (0x1 << 30) /* Automatic Scan bit */ +#define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */ +#define KPC_MI (0x1 << 22) /* Matrix interrupt bit */ +#define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */ +#define KPC_MS7 (0x1 << 20) /* Matrix scan line 7 */ +#define KPC_MS6 (0x1 << 19) /* Matrix scan line 6 */ +#define KPC_MS5 (0x1 << 18) /* Matrix scan line 5 */ +#define KPC_MS4 (0x1 << 17) /* Matrix scan line 4 */ +#define KPC_MS3 (0x1 << 16) /* Matrix scan line 3 */ +#define KPC_MS2 (0x1 << 15) /* Matrix scan line 2 */ +#define KPC_MS1 (0x1 << 14) /* Matrix scan line 1 */ +#define KPC_MS0 (0x1 << 13) /* Matrix scan line 0 */ +#define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */ +#define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */ +#define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Key Debounce select */ +#define KPC_DI (0x1 << 5) /* Direct key interrupt bit */ +#define KPC_DEE0 (0x1 << 2) /* Rotary Encoder 0 Enable */ +#define KPC_DE (0x1 << 1) /* Direct Keypad Enable */ +#define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */ + +#define KPDK_DKP (0x1 << 31) +#define KPDK_DK7 (0x1 << 7) +#define KPDK_DK6 (0x1 << 6) +#define KPDK_DK5 (0x1 << 5) +#define KPDK_DK4 (0x1 << 4) +#define KPDK_DK3 (0x1 << 3) +#define KPDK_DK2 (0x1 << 2) +#define KPDK_DK1 (0x1 << 1) +#define KPDK_DK0 (0x1 << 0) + +#define KPREC_OF1 (0x1 << 31) +#define kPREC_UF1 (0x1 << 30) +#define KPREC_OF0 (0x1 << 15) +#define KPREC_UF0 (0x1 << 14) + +#define KPMK_MKP (0x1 << 31) +#define KPAS_SO (0x1 << 31) +#define KPASMKPx_SO (0x1 << 31) + +#define GPIO113_BIT (1 << 17)/* GPIO113 in GPSR, GPCR, bit 17 */ +#define PSLR __REG(0x40F00034) +#define PSTR __REG(0x40F00038) /* Power Manager Standby Configuration Reg */ +#define PSNR __REG(0x40F0003C) /* Power Manager Sense Configuration Reg */ +#define PVCR __REG(0x40F00040) /* Power Manager Voltage Change Control Reg */ +#define PKWR __REG(0x40F00050) /* Power Manager KB Wake-Up Enable Reg */ +#define PKSR __REG(0x40F00054) /* Power Manager KB Level-Detect Status Reg */ +#define OSMR4 __REG(0x40A00080) /* */ +#define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register */ +#define OMCR4 __REG(0x40A000C0) /* */ + +#endif /* CONFIG_PXA27X */ + +#endif /* _PXA_REGS_H_ */ From 57dc57f14d307952ed3d49d864c7efa27e14e464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Sun, 19 Feb 2006 16:03:49 +0100 Subject: [PATCH 011/102] Merged sufficient changes to pxa-regs.h in order to make u-boot compile. It doesn't run yet. --- include/asm-arm/arch-pxa/pxa-regs.h | 330 +++++++++++++++++++++++++++- include/configs/zylonite.h | 4 +- 2 files changed, 328 insertions(+), 6 deletions(-) diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 41d37d791a..20ab8c1d4c 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -33,12 +33,21 @@ typedef void (*ExcpHndlr) (void) ; /* * PXA Chip selects */ +#ifdef CONFIG_CPU_MONAHANS +#define PXA_CS0_PHYS 0x00000000 /* for both small and large same start */ +#define PXA_CS1_PHYS 0x04000000 /* Small partition start address (64MB) */ +#define PXA_CS1_LPHYS 0x30000000 /* Large partition start address (256MB) */ +#define PXA_CS2_PHYS 0x10000000 /* (64MB) */ +#define PXA_CS3_PHYS 0x14000000 /* (64MB) */ +#define PXA_PCMCIA_PHYS 0x20000000 /* (256MB) */ +#else #define PXA_CS0_PHYS 0x00000000 #define PXA_CS1_PHYS 0x04000000 #define PXA_CS2_PHYS 0x08000000 #define PXA_CS3_PHYS 0x0C000000 #define PXA_CS4_PHYS 0x10000000 #define PXA_CS5_PHYS 0x14000000 +#endif /* CONFIG_CPU_MONAHANS */ /* * Personal Computer Memory Card International Association (PCMCIA) sockets @@ -49,10 +58,12 @@ typedef void (*ExcpHndlr) (void) ; #define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */ #define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */ +#ifndef CONFIG_CPU_MONAHANS /* Monahans supports only one slot */ #define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */ #define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */ #define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */ #define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */ +#endif #define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */ #define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */ @@ -72,10 +83,12 @@ typedef void (*ExcpHndlr) (void) ; #define _PCMCIA0Attr _PCMCIAAttr (0) /* PCMCIA 0 Attribute */ #define _PCMCIA0Mem _PCMCIAMem (0) /* PCMCIA 0 Memory */ +#ifndef CONFIG_CPU_MONAHANS /* Monahans supports only one slot */ #define _PCMCIA1 _PCMCIA (1) /* PCMCIA 1 */ #define _PCMCIA1IO _PCMCIAIO (1) /* PCMCIA 1 I/O */ #define _PCMCIA1Attr _PCMCIAAttr (1) /* PCMCIA 1 Attribute */ #define _PCMCIA1Mem _PCMCIAMem (1) /* PCMCIA 1 Memory */ +#endif /* * DMA Controller @@ -96,6 +109,24 @@ typedef void (*ExcpHndlr) (void) ; #define DCSR13 __REG(0x40000034) /* DMA Control / Status Register for Channel 13 */ #define DCSR14 __REG(0x40000038) /* DMA Control / Status Register for Channel 14 */ #define DCSR15 __REG(0x4000003c) /* DMA Control / Status Register for Channel 15 */ +#ifdef CONFIG_CPU_MONAHANS +#define DCSR16 __REG(0x40000040) /* DMA Control / Status Register for Channel 16 */ +#define DCSR17 __REG(0x40000044) /* DMA Control / Status Register for Channel 17 */ +#define DCSR18 __REG(0x40000048) /* DMA Control / Status Register for Channel 18 */ +#define DCSR19 __REG(0x4000004c) /* DMA Control / Status Register for Channel 19 */ +#define DCSR20 __REG(0x40000050) /* DMA Control / Status Register for Channel 20 */ +#define DCSR21 __REG(0x40000054) /* DMA Control / Status Register for Channel 21 */ +#define DCSR22 __REG(0x40000058) /* DMA Control / Status Register for Channel 22 */ +#define DCSR23 __REG(0x4000005c) /* DMA Control / Status Register for Channel 23 */ +#define DCSR24 __REG(0x40000060) /* DMA Control / Status Register for Channel 24 */ +#define DCSR25 __REG(0x40000064) /* DMA Control / Status Register for Channel 25 */ +#define DCSR26 __REG(0x40000068) /* DMA Control / Status Register for Channel 26 */ +#define DCSR27 __REG(0x4000006c) /* DMA Control / Status Register for Channel 27 */ +#define DCSR28 __REG(0x40000070) /* DMA Control / Status Register for Channel 28 */ +#define DCSR29 __REG(0x40000074) /* DMA Control / Status Register for Channel 29 */ +#define DCSR30 __REG(0x40000078) /* DMA Control / Status Register for Channel 30 */ +#define DCSR31 __REG(0x4000007c) /* DMA Control / Status Register for Channel 31 */ +#endif /* CONFIG_CPU_MONAHANS */ #define DCSR(x) __REG2(0x40000000, (x) << 2) @@ -103,7 +134,7 @@ typedef void (*ExcpHndlr) (void) ; #define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */ #define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */ -#if defined(CONFIG_PXA27X) +#if defined(CONFIG_PXA27X) || defined (CONFIG_CPU_MONAHANS) #define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */ #define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */ #define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */ @@ -813,15 +844,45 @@ typedef void (*ExcpHndlr) (void) ; /* * OS Timer & Match Registers */ -#define OSMR0 __REG(0x40A00000) /* */ -#define OSMR1 __REG(0x40A00004) /* */ -#define OSMR2 __REG(0x40A00008) /* */ -#define OSMR3 __REG(0x40A0000C) /* */ +#define OSMR0 __REG(0x40A00000) /* OS Timer Match Register 0 */ +#define OSMR1 __REG(0x40A00004) /* OS Timer Match Register 1 */ +#define OSMR2 __REG(0x40A00008) /* OS Timer Match Register 2 */ +#define OSMR3 __REG(0x40A0000C) /* OS Timer Match Register 3 */ #define OSCR __REG(0x40A00010) /* OS Timer Counter Register */ #define OSSR __REG(0x40A00014) /* OS Timer Status Register */ #define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */ #define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */ +#ifdef CONFIG_CPU_MONAHANS +#define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register 4 */ +#define OSCR5 __REG(0x40A00044) /* OS Timer Counter Register 5 */ +#define OSCR6 __REG(0x40A00048) /* OS Timer Counter Register 6 */ +#define OSCR7 __REG(0x40A0004C) /* OS Timer Counter Register 7 */ +#define OSCR8 __REG(0x40A00050) /* OS Timer Counter Register 8 */ +#define OSCR9 __REG(0x40A00054) /* OS Timer Counter Register 9 */ +#define OSCR10 __REG(0x40A00058) /* OS Timer Counter Register 10 */ +#define OSCR11 __REG(0x40A0005C) /* OS Timer Counter Register 11 */ + +#define OSMR4 __REG(0x40A00080) /* OS Timer Match Register 4 */ +#define OSMR5 __REG(0x40A00084) /* OS Timer Match Register 5 */ +#define OSMR6 __REG(0x40A00088) /* OS Timer Match Register 6 */ +#define OSMR7 __REG(0x40A0008C) /* OS Timer Match Register 7 */ +#define OSMR8 __REG(0x40A00090) /* OS Timer Match Register 8 */ +#define OSMR9 __REG(0x40A00094) /* OS Timer Match Register 9 */ +#define OSMR10 __REG(0x40A00098) /* OS Timer Match Register 10 */ +#define OSMR11 __REG(0x40A0009C) /* OS Timer Match Register 11 */ + +#define OMCR4 __REG(0x40A000C0) /* OS Match Control Register 4 */ +#define OMCR5 __REG(0x40A000C4) /* OS Match Control Register 5 */ +#define OMCR6 __REG(0x40A000C8) /* OS Match Control Register 6 */ +#define OMCR7 __REG(0x40A000CC) /* OS Match Control Register 7 */ +#define OMCR8 __REG(0x40A000D0) /* OS Match Control Register 8 */ +#define OMCR9 __REG(0x40A000D4) /* OS Match Control Register 9 */ +#define OMCR10 __REG(0x40A000D8) /* OS Match Control Register 10 */ +#define OMCR11 __REG(0x40A000DC) /* OS Match Control Register 11 */ +#endif /* CONFIG_CPU_MONAHANS */ + +#define OSSR_M4 (1 << 4) /* Match status channel 4 */ #define OSSR_M3 (1 << 3) /* Match status channel 3 */ #define OSSR_M2 (1 << 2) /* Match status channel 2 */ #define OSSR_M1 (1 << 1) /* Match status channel 1 */ @@ -829,6 +890,7 @@ typedef void (*ExcpHndlr) (void) ; #define OWER_WME (1 << 0) /* Watchdog Match Enable */ +#define OIER_E4 (1 << 4) /* Interrupt enable channel 4 */ #define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */ #define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */ #define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */ @@ -855,6 +917,19 @@ typedef void (*ExcpHndlr) (void) ; #define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */ #define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */ +#ifdef CONFIG_CPU_MONAHANS +#define ICHP __REG(0x40D00018) /* Interrupt Controller Highest Priority Register */ +/* Missing: 32 Interrupt priority registers */ +/* mk@tbd: These are the same as beneath for PXA27x: maybe can be + * merged if GPIO Stuff is same too. */ +#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */ +#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */ +#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */ +#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */ +#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */ +/* Missing: 2 Interrupt priority registers */ +#endif /* CONFIG_CPU_MONAHANS */ + /* * General Purpose I/O */ @@ -1142,6 +1217,79 @@ typedef void (*ExcpHndlr) (void) ; /* * Power Manager */ +#ifdef CONFIG_CPU_MONAHANS + +#define ASCR __REG(0x40F40000) /* Application Subsystem Power Status/Control Register */ +#define ARSR __REG(0x40F40004) /* Application Subsystem Reset Status Register */ +#define AD3ER __REG(0x40F40008) /* Application Subsystem D3 state Wakeup Enable Register */ +#define AD3SR __REG(0x40F4000C) /* Application Subsystem D3 state Wakeup Status Register */ +#define AD2D0ER __REG(0x40F40010) /* Application Subsystem D2 to D0 state Wakeup Enable Register */ +#define AD2D0SR __REG(0x40F40014) /* Application Subsystem D2 to D0 state Wakeup Status Register */ +#define AD2D1ER __REG(0x40F40018) /* Application Subsystem D2 to D1 state Wakeup Enable Register */ +#define AD2D1SR __REG(0x40F4001C) /* Application Subsystem D2 to D1 state Wakeup Status Register */ +#define AD1D0ER __REG(0x40F40020) /* Application Subsystem D1 to D0 state Wakeup Enable Register */ +#define AD1D0SR __REG(0x40F40024) /* Application Subsystem D1 to D0 state Wakeup Status Register */ +#define ASDCNT __REG(0x40F40028) /* Application Subsystem SRAM Drowsy Count Register */ +#define AD3R __REG(0x40F40030) /* Application Subsystem D3 State Configuration Register */ +#define AD2R __REG(0x40F40034) /* Application Subsystem D2 State Configuration Register */ +#define AD1R __REG(0x40F40038) /* Application Subsystem D1 State Configuration Register */ + +#define PMCR __REG(0x40F50000) /* Power Manager Control Register */ +#define PSR __REG(0x40F50004) /* Power Manager S2 Status Register */ +#define PSPR __REG(0x40F50008) /* Power Manager Scratch Pad Register */ +#define PCFR __REG(0x40F5000C) /* Power Manager General Configuration Register */ +#define PWER __REG(0x40F50010) /* Power Manager Wake-up Enable Register */ +#define PWSR __REG(0x40F50014) /* Power Manager Wake-up Status Register */ +#define PECR __REG(0x40F50018) /* Power Manager EXT_WAKEUP[1:0] Control Register */ +#define DCDCSR __REG(0x40F50080) /* DC-DC Controller Status Register */ +#define PVCR __REG(0x40F50100) /* Power Manager Voltage Change Control Register */ +#define PCMD(x) __REG(0x40F50110 + x*4) +#define PCMD0 __REG(0x40F50110 + 0 * 4) +#define PCMD1 __REG(0x40F50110 + 1 * 4) +#define PCMD2 __REG(0x40F50110 + 2 * 4) +#define PCMD3 __REG(0x40F50110 + 3 * 4) +#define PCMD4 __REG(0x40F50110 + 4 * 4) +#define PCMD5 __REG(0x40F50110 + 5 * 4) +#define PCMD6 __REG(0x40F50110 + 6 * 4) +#define PCMD7 __REG(0x40F50110 + 7 * 4) +#define PCMD8 __REG(0x40F50110 + 8 * 4) +#define PCMD9 __REG(0x40F50110 + 9 * 4) +#define PCMD10 __REG(0x40F50110 + 10 * 4) +#define PCMD11 __REG(0x40F50110 + 11 * 4) +#define PCMD12 __REG(0x40F50110 + 12 * 4) +#define PCMD13 __REG(0x40F50110 + 13 * 4) +#define PCMD14 __REG(0x40F50110 + 14 * 4) +#define PCMD15 __REG(0x40F50110 + 15 * 4) +#define PCMD16 __REG(0x40F50110 + 16 * 4) +#define PCMD17 __REG(0x40F50110 + 17 * 4) +#define PCMD18 __REG(0x40F50110 + 18 * 4) +#define PCMD19 __REG(0x40F50110 + 19 * 4) +#define PCMD20 __REG(0x40F50110 + 20 * 4) +#define PCMD21 __REG(0x40F50110 + 21 * 4) +#define PCMD22 __REG(0x40F50110 + 22 * 4) +#define PCMD23 __REG(0x40F50110 + 23 * 4) +#define PCMD24 __REG(0x40F50110 + 24 * 4) +#define PCMD25 __REG(0x40F50110 + 25 * 4) +#define PCMD26 __REG(0x40F50110 + 26 * 4) +#define PCMD27 __REG(0x40F50110 + 27 * 4) +#define PCMD28 __REG(0x40F50110 + 28 * 4) +#define PCMD29 __REG(0x40F50110 + 29 * 4) +#define PCMD30 __REG(0x40F50110 + 30 * 4) +#define PCMD31 __REG(0x40F50110 + 31 * 4) + +#define PCMD_MBC (1<<12) +#define PCMD_DCE (1<<11) +#define PCMD_LC (1<<10) +#define PCMD_SQC (3<<8) /* only 00 and 01 are valid */ + +#define PVCR_FVC (0x1 << 28) +#define PVCR_VCSA (0x1<<14) +#define PVCR_CommandDelay (0xf80) +#define PVCR_ReadPointer (0x01f00000) +#define PVCR_SlaveAddress (0x7f) + +#else /* ifdef CONFIG_CPU_MONAHANS */ + #define PMCR __REG(0x40F00000) /* Power Manager Control Register */ #define PSSR __REG(0x40F00004) /* Power Manager Sleep Status Register */ #define PSPR __REG(0x40F00008) /* Power Manager Scratch Pad Register */ @@ -1225,6 +1373,8 @@ typedef void (*ExcpHndlr) (void) ; #define RCSR_WDR (1 << 1) /* Watchdog Reset */ #define RCSR_HWR (1 << 0) /* Hardware Reset */ +#endif /* CONFIG_CPU_MONAHANS */ + /* * SSP Serial Port Registers */ @@ -1259,6 +1409,67 @@ typedef void (*ExcpHndlr) (void) ; /* * Core Clock */ + +#if defined(CONFIG_CPU_MONAHANS) +#define ACCR __REG(0x41340000) /* Application Subsystem Clock Configuration Register */ +#define ACSR __REG(0x41340004) /* Application Subsystem Clock Status Register */ +#define AICSR __REG(0x41340008) /* Application Subsystem Interrupt Control/Status Register */ +#define CKENA __REG(0x4134000C) /* A Clock Enable Register */ +#define CKENB __REG(0x41340010) /* B Clock Enable Register */ +#define AC97_DIV __REG(0x41340014) /* AC97 clock divisor value register */ + +#define ACCR_SMC_MASK 0x03800000 /* Static Memory Controller Frequency Select */ +#define ACCR_SRAM_MASK 0x000c0000 /* SRAM Controller Frequency Select */ +#define ACCR_FC_MASK 0x00030000 /* Frequency Change Frequency Select */ +#define ACCR_HSIO_MASK 0x0000c000 /* High Speed IO Frequency Select */ +#define ACCR_DDR_MASK 0x00003000 /* DDR Memory Controller Frequency Select */ +#define ACCR_XN_MASK 0x00000700 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ +#define ACCR_XL_MASK 0x0000001f /* Crystal Frequency to Memory Frequency Multiplier */ +#define ACCR_XPDIS (1 << 31) +#define ACCR_SPDIS (1 << 30) +#define ACCR_13MEND1 (1 << 27) +#define ACCR_D0CS (1 << 26) +#define ACCR_13MEND2 (1 << 21) +#define ACCR_PCCE (1 << 11) + +#define CKENA_30_MSL0 (1 << 30) /* MSL0 Interface Unit Clock Enable */ +#define CKENA_29_SSP4 (1 << 29) /* SSP3 Unit Clock Enable */ +#define CKENA_28_SSP3 (1 << 28) /* SSP2 Unit Clock Enable */ +#define CKENA_27_SSP2 (1 << 27) /* SSP1 Unit Clock Enable */ +#define CKENA_26_SSP1 (1 << 26) /* SSP0 Unit Clock Enable */ +#define CKENA_25_TSI (1 << 25) /* TSI Clock Enable */ +#define CKENA_24_AC97 (1 << 24) /* AC97 Unit Clock Enable */ +#define CKENA_23_STUART (1 << 23) /* STUART Unit Clock Enable */ +#define CKENA_22_FFUART (1 << 22) /* FFUART Unit Clock Enable */ +#define CKENA_21_BTUART (1 << 21) /* BTUART Unit Clock Enable */ +#define CKENA_20_UDC (1 << 20) /* UDC Clock Enable */ +#define CKENA_19_TPM (1 << 19) /* TPM Unit Clock Enable */ +#define CKENA_18_USIM1 (1 << 18) /* USIM1 Unit Clock Enable */ +#define CKENA_17_USIM0 (1 << 17) /* USIM0 Unit Clock Enable */ +#define CKENA_15_CIR (1 << 15) /* Consumer IR Clock Enable */ +#define CKENA_14_KEY (1 << 14) /* Keypad Controller Clock Enable */ +#define CKENA_13_MMC1 (1 << 13) /* MMC1 Clock Enable */ +#define CKENA_12_MMC0 (1 << 12) /* MMC0 Clock Enable */ +#define CKENA_11_FLASH (1 << 11) /* Boot ROM Clock Enable */ +#define CKENA_10_SRAM (1 << 10) /* SRAM Controller Clock Enable */ +#define CKENA_9_SMC (1 << 9) /* Static Memory Controller */ +#define CKENA_8_DMC (1 << 8) /* Dynamic Memory Controller */ +#define CKENA_7_GRAPHICS (1 << 7) /* 2D Graphics Clock Enable */ +#define CKENA_6_USBCLI (1 << 6) /* USB Client Unit Clock Enable */ +#define CKENA_4_NAND (1 << 4) /* NAND Flash Controller Clock Enable */ +#define CKENA_3_CAMERA (1 << 3) /* Camera Interface Clock Enable */ +#define CKENA_2_USBHOST (1 << 2) /* USB Host Unit Clock Enable */ +#define CKENA_1_LCD (1 << 1) /* LCD Unit Clock Enable */ + +#define CKENB_8_1WIRE ((1 << 8) + 32) /* One Wire Interface Unit Clock Enable */ +#define CKENB_7_GPIO ((1 << 7) + 32) /* GPIO Clock Enable */ +#define CKENB_6_IRQ ((1 << 6) + 32) /* Interrupt Controller Clock Enable */ +#define CKENB_4_I2C ((1 << 4) + 32) /* I2C Unit Clock Enable */ +#define CKENB_1_PWM1 ((1 << 1) + 32) /* PWM2 & PWM3 Clock Enable */ +#define CKENB_0_PWM0 ((1 << 0) + 32) /* PWM0 & PWM1 Clock Enable */ + +#else /* if defined CONFIG_CPU_MONAHANS */ + #define CCCR __REG(0x41300000) /* Core Clock Configuration Register */ #define CKEN __REG(0x41300004) /* Clock Enable Register */ #define OSCC __REG(0x41300008) /* Oscillator Configuration Register */ @@ -1318,6 +1529,8 @@ typedef void (*ExcpHndlr) (void) ; #define CCCR_N30 (0x6 << 7) #endif +#endif /* CONFIG_CPU_MONAHANS */ + /* * LCD */ @@ -1502,6 +1715,111 @@ typedef void (*ExcpHndlr) (void) ; /* * Memory controller */ + +#ifdef CONFIG_CPU_MONAHANS +/* Static Memory Controller Registers */ +#define MSC0 __REG_2(0x4A000008) /* Static Memory Control Register 0 */ +#define MSC1 __REG_2(0x4A00000C) /* Static Memory Control Register 1 */ +#define MECR __REG_2(0x4A000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */ +#define SXCNFG __REG_2(0x4A00001C) /* Synchronous Static Memory Control Register */ +#define MCMEM0 __REG_2(0x4A000028) /* Card interface Common Memory Space Socket 0 Timing */ +#define MCATT0 __REG_2(0x4A000030) /* Card interface Attribute Space Socket 0 Timing Configuration */ +#define MCIO0 __REG_2(0x4A000038) /* Card interface I/O Space Socket 0 Timing Configuration */ +#define MEMCLKCFG __REG_2(0x4A000068) /* SCLK speed configuration */ +#define CSADRCFG0 __REG_2(0x4A000080) /* Address Configuration for chip select 0 */ +#define CSADRCFG1 __REG_2(0x4A000084) /* Address Configuration for chip select 1 */ +#define CSADRCFG2 __REG_2(0x4A000088) /* Address Configuration for chip select 2 */ +#define CSADRCFG3 __REG_2(0x4A00008C) /* Address Configuration for chip select 3 */ +#define CSADRCFG_P __REG_2(0x4A000090) /* Address Configuration for pcmcia card interface */ +#define CSMSADRCFG __REG_2(0x4A0000A0) /* Master Address Configuration Register */ +#define CLK_RET_DEL __REG_2(0x4A0000B0) /* Delay line and mux selects for return data latching for sync. flash */ +#define ADV_RET_DEL __REG_2(0x4A0000B4) /* Delay line and mux selects for return data latching for sync. flash */ + +/* Dynamic Memory Controller Registers */ +#define MDCNFG __REG_2(0x48100000) /* SDRAM Configuration Register 0 */ +#define MDREFR __REG_2(0x48100004) /* SDRAM Refresh Control Register */ +#define FLYCNFG __REG_2(0x48100020) /* Fly-by DMA DVAL[1:0] polarities */ +#define MDMRS __REG_2(0x48100040) /* MRS value to be written to SDRAM */ +#define DDR_SCAL __REG_2(0x48100050) /* Software Delay Line Calibration/Configuration for external DDR memory. */ +#define DDR_HCAL __REG_2(0x48100060) /* Hardware Delay Line Calibration/Configuration for external DDR memory. */ +#define DDR_WCAL __REG_2(0x48100068) /* DDR Write Strobe Calibration Register */ +#define DMCIER __REG_2(0x48100070) /* Dynamic MC Interrupt Enable Register. */ +#define DMCISR __REG_2(0x48100078) /* Dynamic MC Interrupt Status Register. */ +#define DDR_DLS __REG_2(0x48100080) /* DDR Delay Line Value Status register for external DDR memory. */ +#define EMPI __REG_2(0x48100090) /* EMPI Control Register */ +#define RCOMP __REG_2(0x48100100) +#define PAD_MA __REG_2(0x48100110) +#define PAD_MDMSB __REG_2(0x48100114) +#define PAD_MDLSB __REG_2(0x48100118) +#define PAD_DMEM __REG_2(0x4810011c) +#define PAD_SDCLK __REG_2(0x48100120) +#define PAD_SDCS __REG_2(0x48100124) +#define PAD_SMEM __REG_2(0x48100128) +#define PAD_SCLK __REG_2(0x4810012C) +#define TAI __REG_2(0x48100F00) /* TAI Tavor Address Isolation Register */ + + +/* Data Flash Controller Registers */ + +#define NDCR __REG_2(0x43100000) /* Data Flash Control register */ +#define NDTR0CS0 __REG_2(0x43100004) /* Data Controller Timing Parameter 0 Register for ND_nCS0 */ +#define NDTR0CS1 __REG_2(0x43100008) /* Data Controller Timing Parameter 0 Register for ND_nCS1 */ +#define NDTR1CS0 __REG_2(0x4310000C) /* Data Controller Timing Parameter 1 Register for ND_nCS0 */ +#define NDTR1CS1 __REG_2(0x43100010) /* Data Controller Timing Parameter 1 Register for ND_nCS1 */ +#define NDSR __REG_2(0x43100014) /* Data Controller Status Register */ +#define NDPCR __REG_2(0x43100018) /* Data Controller Page Count Register */ +#define NDBDR0 __REG_2(0x4310001C) /* Data Controller Bad Block Register 0 */ +#define NDBDR1 __REG_2(0x43100020) /* Data Controller Bad Block Register 1 */ +#define NDDB __REG_2(0x43100040) /* Data Controller Data Buffer */ +#define NDCB0 __REG_2(0x43100048) /* Data Controller Command Buffer0 */ +#define NDCB1 __REG_2(0x4310004C) /* Data Controller Command Buffer1 */ +#define NDCB2 __REG_2(0x43100050) /* Data Controller Command Buffer2 */ + +#define NDCR_SPARE_EN (0x1<<31) +#define NDCR_ECC_EN (0x1<<30) +#define NDCR_DMA_EN (0x1<<29) +#define NDCR_ND_RUN (0x1<<28) +#define NDCR_DWIDTH_C (0x1<<27) +#define NDCR_DWIDTH_M (0x1<<26) +#define NDCR_PAGE_SZ (0x3<<24) +#define NDCR_NCSX (0x1<<23) +#define NDCR_ND_MODE (0x3<<21) +#define NDCR_NAND_MODE 0x0 +#define NDCR_CLR_PG_CNT (0x1<<20) +#define NDCR_CLR_ECC (0x1<<19) +#define NDCR_RD_ID_CNT (0x7<<16) +#define NDCR_RA_START (0x1<<15) +#define NDCR_PG_PER_BLK (0x1<<14) +#define NDCR_ND_ARB_EN (0x1<<12) + +#define NDSR_RDY (0x1<<11) +#define NDSR_CS0_PAGED (0x1<<10) +#define NDSR_CS1_PAGED (0x1<<9) +#define NDSR_CS0_CMDD (0x1<<8) +#define NDSR_CS1_CMDD (0x1<<7) +#define NDSR_CS0_BBD (0x1<<6) +#define NDSR_CS1_BBD (0x1<<5) +#define NDSR_BDERR (0x1<<4) +#define NDSR_SBERR (0x1<<3) +#define NDSR_WRDREQ (0x1<<2) +#define NDSR_RDDREQ (0x1<<1) +#define NDSR_WRCMDREQ (0x1) + +#define NDCB0_AUTO_RS (0x1<<25) +#define NDCB0_CSEL (0x1<<24) +#define NDCB0_CMD_TYPE (0x7<<21) +#define NDCB0_NC (0x1<<20) +#define NDCB0_DBC (0x1<<19) +#define NDCB0_ADDR_CYC (0x7<<16) +#define NDCB0_CMD2 (0xff<<8) +#define NDCB0_CMD1 (0xff) +#define MCMEM(s) MCMEM0 +#define MCATT(s) MCATT0 +#define MCIO(s) MCIO0 +#define MECR_CIT (1 << 1)/* Card Is There: 0 -> no card, 1 -> card inserted */ + +#else /* CONFIG_CPU_MONAHANS */ + #define MEMC_BASE __REG(0x48000000) /* Base of Memory Controller */ #define MDCNFG_OFFSET 0x0 #define MDREFR_OFFSET 0x4 @@ -1573,6 +1891,8 @@ typedef void (*ExcpHndlr) (void) ; #define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ #define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ +#endif /* CONFIG_CPU_MONAHANS */ + /* Interrupt Controller */ #define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */ diff --git a/include/configs/zylonite.h b/include/configs/zylonite.h index f23300d004..3968c93388 100644 --- a/include/configs/zylonite.h +++ b/include/configs/zylonite.h @@ -36,6 +36,7 @@ */ #define CONFIG_CPU_MONAHANS 1 /* Intel Monahan CPU */ #define CONFIG_ZYLONITE 1 /* Zylonite board */ + /* #define CONFIG_LCD 1 */ #ifdef CONFIG_LCD #define CONFIG_SHARP_LM8V31 @@ -230,7 +231,8 @@ * second sector, not an environment. You have been warned! */ #define CFG_MONITOR_LEN PHYS_FLASH_SECT_SIZE -#undef CFG_ENV_IS_IN_FLASH + +#define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_ADDR (PHYS_FLASH_1 + PHYS_FLASH_SECT_SIZE) #define CFG_ENV_SECT_SIZE PHYS_FLASH_SECT_SIZE #define CFG_ENV_SIZE (PHYS_FLASH_SECT_SIZE / 16) From 8fb1857b40aa47219ca4bf792b3daad3c1fcbbc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Mon, 20 Feb 2006 15:59:07 +0100 Subject: [PATCH 012/102] Merged and added more pxa-regs.h stuff, especially the GPIO Control Register Definitions. --- drivers/smc91111.c | 2 +- include/asm-arm/arch-pxa/pxa-regs.h | 205 ++++++++++++++++++++++++++++ include/configs/zylonite.h | 6 +- 3 files changed, 209 insertions(+), 4 deletions(-) diff --git a/drivers/smc91111.c b/drivers/smc91111.c index 060da8ff2a..7941244f17 100644 --- a/drivers/smc91111.c +++ b/drivers/smc91111.c @@ -72,7 +72,7 @@ #define NO_AUTOPROBE -#define SMC_DEBUG 0 +#define SMC_DEBUG 3 #if SMC_DEBUG > 1 static const char version[] = diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 20ab8c1d4c..a8477cf60d 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -961,12 +961,217 @@ typedef void (*ExcpHndlr) (void) ; #define GEDR1 __REG(0x40E0004C) /* GPIO Edge Detect Status Register GPIO<63:32> */ #define GEDR2 __REG(0x40E00050) /* GPIO Edge Detect Status Register GPIO<80:64> */ +#ifdef CONFIG_CPU_MONAHANS +#define GPLR3 __REG(0x40E00100) /* GPIO Pin-Level Register GPIO<127:96> */ +#define GPDR3 __REG(0x40E0010C) /* GPIO Pin Direction Register GPIO<127:96> */ +#define GPSR3 __REG(0x40E00118) /* GPIO Pin Output Set Register GPIO<127:96> */ +#define GPCR3 __REG(0x40E00124) /* GPIO Pin Output Clear Register GPIO<127:96> */ +#define GRER3 __REG(0x40E00130) /* GPIO Rising-Edge Detect Register GPIO<127:96> */ +#define GFER3 __REG(0x40E0013C) /* GPIO Falling-Edge Detect Register GPIO<127:96> */ +#define GEDR3 __REG(0x40E00148) /* GPIO Edge Detect Status Register GPIO<127:96> */ + +#define GSDR0 __REG(0x40E00400) /* Bit-wise Set of GPDR[31:0] */ +#define GSDR1 __REG(0x40E00404) /* Bit-wise Set of GPDR[63:32] */ +#define GSDR2 __REG(0x40E00408) /* Bit-wise Set of GPDR[95:64] */ +#define GSDR3 __REG(0x40E0040C) /* Bit-wise Set of GPDR[127:96] */ + +#define GCDR0 __REG(0x40E00420) /* Bit-wise Clear of GPDR[31:0] */ +#define GCDR1 __REG(0x40E00424) /* Bit-wise Clear of GPDR[63:32] */ +#define GCDR2 __REG(0x40E00428) /* Bit-wise Clear of GPDR[95:64] */ +#define GCDR3 __REG(0x40E0042C) /* Bit-wise Clear of GPDR[127:96] */ + +#define GSRER0 __REG(0x40E00440) /* Set Rising Edge Det. Enable [31:0] */ +#define GSRER1 __REG(0x40E00444) /* Set Rising Edge Det. Enable [63:32] */ +#define GSRER2 __REG(0x40E00448) /* Set Rising Edge Det. Enable [95:64] */ +#define GSRER3 __REG(0x40E0044C) /* Set Rising Edge Det. Enable [127:96] */ + +#define GCRER0 __REG(0x40E00460) /* Clear Rising Edge Det. Enable [31:0] */ +#define GCRER1 __REG(0x40E00464) /* Clear Rising Edge Det. Enable [63:32] */ +#define GCRER2 __REG(0x40E00468) /* Clear Rising Edge Det. Enable [95:64] */ +#define GCRER3 __REG(0x40E0046C) /* Clear Rising Edge Det. Enable[127:96] */ + +#define GSFER0 __REG(0x40E00480) /* Set Falling Edge Det. Enable [31:0] */ +#define GSFER1 __REG(0x40E00484) /* Set Falling Edge Det. Enable [63:32] */ +#define GSFER2 __REG(0x40E00488) /* Set Falling Edge Det. Enable [95:64] */ +#define GSFER3 __REG(0x40E0048C) /* Set Falling Edge Det. Enable[127:96] */ + +#define GCFER0 __REG(0x40E004A0) /* Clr Falling Edge Det. Enable [31:0] */ +#define GCFER1 __REG(0x40E004A4) /* Clr Falling Edge Det. Enable [63:32] */ +#define GCFER2 __REG(0x40E004A8) /* Clr Falling Edge Det. Enable [95:64] */ +#define GCFER3 __REG(0x40E004AC) /* Clr Falling Edge Det. Enable[127:96] */ + +#define GSDR(x) __REG2(0x40E00400, ((x) & 0x60) >> 3) +#define GCDR(x) __REG2(0x40300420, ((x) & 0x60) >> 3) + +/* Multi-funktion Pin Registers, uncomplete, only GPIO relevant pins for now */ +#define GPIO0 __REG(0x40e10124) +#define GPIO1 __REG(0x40e10128) +#define GPIO2 __REG(0x40e1012c) +#define GPIO3 __REG(0x40e10130) +#define GPIO4 __REG(0x40e10134) + +#define GPIO5 __REG(0x40e1028c) +#define GPIO6 __REG(0x40e10290) +#define GPIO7 __REG(0x40e10294) +#define GPIO8 __REG(0x40e10298) +#define GPIO9 __REG(0x40e1029c) + +#define GPIO11 __REG(0x40e102a0) +#define GPIO12 __REG(0x40e102a4) +#define GPIO13 __REG(0x40e102a8) +#define GPIO14 __REG(0x40e102ac) +#define GPIO15 __REG(0x40e102b0) +#define GPIO16 __REG(0x40e102b4) +#define GPIO17 __REG(0x40e102b8) +#define GPIO18 __REG(0x40e102bc) +#define GPIO19 __REG(0x40e102c0) +#define GPIO20 __REG(0x40e102c4) +#define GPIO21 __REG(0x40e102c8) +#define GPIO22 __REG(0x40e102cc) +#define GPIO23 __REG(0x40e102d0) +#define GPIO24 __REG(0x40e102d4) +#define GPIO25 __REG(0x40e102d8) +#define GPIO26 __REG(0x40e102dc) + +#define GPIO27 __REG(0x40e10400) +#define GPIO28 __REG(0x40e10404) +#define GPIO29 __REG(0x40e10408) +#define GPIO30 __REG(0x40e1040c) +#define GPIO31 __REG(0x40e10410) +#define GPIO32 __REG(0x40e10414) +#define GPIO33 __REG(0x40e10418) +#define GPIO34 __REG(0x40e1041c) +#define GPIO35 __REG(0x40e10420) +#define GPIO36 __REG(0x40e10424) +#define GPIO37 __REG(0x40e10428) +#define GPIO38 __REG(0x40e1042c) +#define GPIO39 __REG(0x40e10430) +#define GPIO40 __REG(0x40e10434) +#define GPIO41 __REG(0x40e10438) +#define GPIO42 __REG(0x40e1043c) +#define GPIO43 __REG(0x40e10440) +#define GPIO44 __REG(0x40e10444) +#define GPIO45 __REG(0x40e10448) +#define GPIO46 __REG(0x40e1044c) +#define GPIO47 __REG(0x40e10450) +#define GPIO48 __REG(0x40e10454) + +#define GPIO10 __REG(0x40e10458) + +#define GPIO49 __REG(0x40e1045c) +#define GPIO50 __REG(0x40e10460) +#define GPIO51 __REG(0x40e10464) +#define GPIO52 __REG(0x40e10468) +#define GPIO53 __REG(0x40e1046c) +#define GPIO54 __REG(0x40e10470) +#define GPIO55 __REG(0x40e10474) +#define GPIO56 __REG(0x40e10478) +#define GPIO57 __REG(0x40e1047c) +#define GPIO58 __REG(0x40e10480) +#define GPIO59 __REG(0x40e10484) +#define GPIO60 __REG(0x40e10488) +#define GPIO61 __REG(0x40e1048c) +#define GPIO62 __REG(0x40e10490) + +#define GPIO6_2 __REG(0x40e10494) +#define GPIO7_2 __REG(0x40e10498) +#define GPIO8_2 __REG(0x40e1049c) +#define GPIO9_2 __REG(0x40e104a0) +#define GPIO10_2 __REG(0x40e104a4) +#define GPIO11_2 __REG(0x40e104a8) +#define GPIO12_2 __REG(0x40e104ac) +#define GPIO13_2 __REG(0x40e104b0) + +#define GPIO63 __REG(0x40e104b4) +#define GPIO64 __REG(0x40e104b8) +#define GPIO65 __REG(0x40e104bc) +#define GPIO66 __REG(0x40e104c0) +#define GPIO67 __REG(0x40e104c4) +#define GPIO68 __REG(0x40e104c8) +#define GPIO69 __REG(0x40e104cc) +#define GPIO70 __REG(0x40e104d0) +#define GPIO71 __REG(0x40e104d4) +#define GPIO72 __REG(0x40e104d8) +#define GPIO73 __REG(0x40e104dc) + +#define GPIO14_2 __REG(0x40e104e0) +#define GPIO15_2 __REG(0x40e104e4) +#define GPIO16_2 __REG(0x40e104e8) +#define GPIO17_2 __REG(0x40e104ec) + +#define GPIO74 __REG(0x40e104f0) +#define GPIO75 __REG(0x40e104f4) +#define GPIO76 __REG(0x40e104f8) +#define GPIO77 __REG(0x40e104fc) +#define GPIO78 __REG(0x40e10500) +#define GPIO79 __REG(0x40e10504) +#define GPIO80 __REG(0x40e10508) +#define GPIO81 __REG(0x40e1050c) +#define GPIO82 __REG(0x40e10510) +#define GPIO83 __REG(0x40e10514) +#define GPIO84 __REG(0x40e10518) +#define GPIO85 __REG(0x40e1051c) +#define GPIO86 __REG(0x40e10520) +#define GPIO87 __REG(0x40e10524) +#define GPIO88 __REG(0x40e10528) +#define GPIO89 __REG(0x40e1052c) +#define GPIO90 __REG(0x40e10530) +#define GPIO91 __REG(0x40e10534) +#define GPIO92 __REG(0x40e10538) +#define GPIO93 __REG(0x40e1053c) +#define GPIO94 __REG(0x40e10540) +#define GPIO95 __REG(0x40e10544) +#define GPIO96 __REG(0x40e10548) +#define GPIO97 __REG(0x40e1054c) +#define GPIO98 __REG(0x40e10550) + +#define GPIO99 __REG(0x40e10600) +#define GPIO100 __REG(0x40e10604) +#define GPIO101 __REG(0x40e10608) +#define GPIO102 __REG(0x40e1060c) +#define GPIO103 __REG(0x40e10610) +#define GPIO104 __REG(0x40e10614) +#define GPIO105 __REG(0x40e10618) +#define GPIO106 __REG(0x40e1061c) +#define GPIO107 __REG(0x40e10620) +#define GPIO108 __REG(0x40e10624) +#define GPIO109 __REG(0x40e10628) +#define GPIO110 __REG(0x40e1062c) +#define GPIO111 __REG(0x40e10630) +#define GPIO112 __REG(0x40e10634) + +#define GPIO113 __REG(0x40e10638) +#define GPIO114 __REG(0x40e1063c) +#define GPIO115 __REG(0x40e10640) +#define GPIO116 __REG(0x40e10644) +#define GPIO117 __REG(0x40e10648) +#define GPIO118 __REG(0x40e1064c) +#define GPIO119 __REG(0x40e10650) +#define GPIO120 __REG(0x40e10654) +#define GPIO121 __REG(0x40e10658) +#define GPIO122 __REG(0x40e1065c) +#define GPIO123 __REG(0x40e10660) +#define GPIO124 __REG(0x40e10664) +#define GPIO125 __REG(0x40e10668) +#define GPIO126 __REG(0x40e1066c) +#define GPIO127 __REG(0x40e10670) + +#define GPIO0_2 __REG(0x40e10674) +#define GPIO1_2 __REG(0x40e10678) +#define GPIO2_2 __REG(0x40e1067c) +#define GPIO3_2 __REG(0x40e10680) +#define GPIO4_2 __REG(0x40e10684) +#define GPIO5_2 __REG(0x40e10688) + +#else /* CONFIG_CPU_MONAHANS */ + #define GAFR0_L __REG(0x40E00054) /* GPIO Alternate Function Select Register GPIO<15:0> */ #define GAFR0_U __REG(0x40E00058) /* GPIO Alternate Function Select Register GPIO<31:16> */ #define GAFR1_L __REG(0x40E0005C) /* GPIO Alternate Function Select Register GPIO<47:32> */ #define GAFR1_U __REG(0x40E00060) /* GPIO Alternate Function Select Register GPIO<63:48> */ #define GAFR2_L __REG(0x40E00064) /* GPIO Alternate Function Select Register GPIO<79:64> */ #define GAFR2_U __REG(0x40E00068) /* GPIO Alternate Function Select Register GPIO 80 */ +#endif /* CONFIG_CPU_MONAHANS */ /* More handy macros. The argument is a literal GPIO number. */ diff --git a/include/configs/zylonite.h b/include/configs/zylonite.h index 3968c93388..a8ff9fdf4d 100644 --- a/include/configs/zylonite.h +++ b/include/configs/zylonite.h @@ -63,7 +63,7 @@ # define CONFIG_SMC91111_BASE 0x14000300 # define CONFIG_SMC91111_EXT_PHY # define CONFIG_SMC_USE_32_BIT -# undef CONFIG_SMC_USE_IOFUNCS +# undef CONFIG_SMC_USE_IOFUNCS /* just for use with the kernel */ #endif /* @@ -78,7 +78,7 @@ /* #define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_MMC | CFG_CMD_FAT) */ #ifdef TURN_ON_ETHERNET -# define CONFIG_COMMANDS (CONFIG_CMD_DFL) +# define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_PING) #else # define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_NET) #endif @@ -87,7 +87,7 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include -#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTDELAY -1 #define CONFIG_ETHADDR 08:00:3e:26:0a:5b #define CONFIG_NETMASK 255.255.0.0 #define CONFIG_IPADDR 192.168.0.21 From 4f7a0e36713d93591812bfd424002c3aa5337c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Mon, 20 Feb 2006 16:37:37 +0100 Subject: [PATCH 013/102] New board directory and config for the benq delta board (copied from zylonite). Minor pxa-regs.h update. --- MAKEALL | 1 + Makefile | 3 + board/delta/Makefile | 48 +++ board/delta/config.mk | 4 + board/delta/delta.c | 75 +++++ board/delta/flash.c | 434 ++++++++++++++++++++++++++++ board/delta/lowlevel_init.S | 375 ++++++++++++++++++++++++ board/delta/u-boot.lds | 56 ++++ include/asm-arm/arch-pxa/pxa-regs.h | 31 ++ include/configs/delta.h | 249 ++++++++++++++++ 10 files changed, 1276 insertions(+) create mode 100644 board/delta/Makefile create mode 100644 board/delta/config.mk create mode 100644 board/delta/delta.c create mode 100644 board/delta/flash.c create mode 100644 board/delta/lowlevel_init.S create mode 100644 board/delta/u-boot.lds create mode 100644 include/configs/delta.h diff --git a/MAKEALL b/MAKEALL index 2587741ee7..f9a0abba2b 100755 --- a/MAKEALL +++ b/MAKEALL @@ -205,6 +205,7 @@ LIST_pxa=" \ adsvix cerf250 cradle csb226 \ innokom lubbock pxa255_idp wepep250 \ xaeniax xm250 xsengine zylonite \ + delta " LIST_ixp="ixdp425" diff --git a/Makefile b/Makefile index 63e0a20662..736ffb6a03 100644 --- a/Makefile +++ b/Makefile @@ -1603,6 +1603,9 @@ cerf250_config : unconfig cradle_config : unconfig @./mkconfig $(@:_config=) arm pxa cradle +delta_config : + @./mkconfig $(@:_config=) arm pxa delta + csb226_config : unconfig @./mkconfig $(@:_config=) arm pxa csb226 diff --git a/board/delta/Makefile b/board/delta/Makefile new file mode 100644 index 0000000000..d968efbf81 --- /dev/null +++ b/board/delta/Makefile @@ -0,0 +1,48 @@ + +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := delta.o flash.o +SOBJS := lowlevel_init.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) $(SOBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/delta/config.mk b/board/delta/config.mk new file mode 100644 index 0000000000..09b0f71557 --- /dev/null +++ b/board/delta/config.mk @@ -0,0 +1,4 @@ +#TEXT_BASE = 0x0 +#TEXT_BASE = 0xa1700000 +#TEXT_BASE = 0xa3080000 +TEXT_BASE = 0xa3008000 diff --git a/board/delta/delta.c b/board/delta/delta.c new file mode 100644 index 0000000000..e618ab96a1 --- /dev/null +++ b/board/delta/delta.c @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2002 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +/* ------------------------------------------------------------------------- */ + + +/* + * Miscelaneous platform dependent initialisations + */ + +int board_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + /* memory and cpu-speed are setup before relocation */ + /* so we do _nothing_ here */ + + /* arch number of Lubbock-Board */ + gd->bd->bi_arch_number = MACH_TYPE_LUBBOCK; + + /* adress of boot parameters */ + gd->bd->bi_boot_params = 0xa0000100; + + return 0; +} + +int board_late_init(void) +{ + setenv("stdout", "serial"); + setenv("stderr", "serial"); + return 0; +} + + +int dram_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; + gd->bd->bi_dram[2].start = PHYS_SDRAM_3; + gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE; + gd->bd->bi_dram[3].start = PHYS_SDRAM_4; + gd->bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE; + + return 0; +} diff --git a/board/delta/flash.c b/board/delta/flash.c new file mode 100644 index 0000000000..883c1ba3b3 --- /dev/null +++ b/board/delta/flash.c @@ -0,0 +1,434 @@ +/* + * (C) Copyright 2001 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/* Board support for 1 or 2 flash devices */ +#define FLASH_PORT_WIDTH32 +#undef FLASH_PORT_WIDTH16 + +#ifdef FLASH_PORT_WIDTH16 +#define FLASH_PORT_WIDTH ushort +#define FLASH_PORT_WIDTHV vu_short +#define SWAP(x) __swab16(x) +#else +#define FLASH_PORT_WIDTH ulong +#define FLASH_PORT_WIDTHV vu_long +#define SWAP(x) __swab32(x) +#endif + +#define FPW FLASH_PORT_WIDTH +#define FPWV FLASH_PORT_WIDTHV + +#define mb() __asm__ __volatile__ ("" : : : "memory") + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (FPW *addr, flash_info_t *info); +static int write_data (flash_info_t *info, ulong dest, FPW data); +static void flash_get_offsets (ulong base, flash_info_t *info); +void inline spin_wheel (void); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ +#if 0 + int i; + ulong size = 0; + + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { + switch (i) { + case 0: + flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]); + flash_get_offsets (PHYS_FLASH_1, &flash_info[i]); + break; + case 1: + flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]); + flash_get_offsets (PHYS_FLASH_2, &flash_info[i]); + break; + default: + panic ("configured too many flash banks!\n"); + break; + } + size += flash_info[i].size; + } + + /* Protect monitor and environment sectors + */ + flash_protect ( FLAG_PROTECT_SET, + CFG_FLASH_BASE, + CFG_FLASH_BASE + monitor_flash_len - 1, + &flash_info[0] ); + + flash_protect ( FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] ); + + return size; +#endif + return 0; +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + return; + } + + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { + for (i = 0; i < info->sector_count; i++) { + info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE); + info->protect[i] = 0; + } + } +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: + printf ("INTEL "); + break; + default: + printf ("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F128J3A: + printf ("28F128J3A\n"); + break; + default: + printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " "); + } + printf ("\n"); + return; +} + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (FPW *addr, flash_info_t *info) +{ + volatile FPW value; + + /* Write auto select command: read Manufacturer ID */ + addr[0x5555] = (FPW) 0x00AA00AA; + addr[0x2AAA] = (FPW) 0x00550055; + addr[0x5555] = (FPW) 0x00900090; + + mb (); + value = addr[0]; + + switch (value) { + + case (FPW) INTEL_MANUFACT: + info->flash_id = FLASH_MAN_INTEL; + break; + + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ + return (0); /* no or unknown flash */ + } + + mb (); + value = addr[1]; /* device ID */ + + switch (value) { + + case (FPW) INTEL_ID_28F128J3A: + info->flash_id += FLASH_28F128J3A; + info->sector_count = 128; + info->size = 0x02000000; + break; /* => 16 MB */ + + default: + info->flash_id = FLASH_UNKNOWN; + break; + } + + if (info->sector_count > CFG_MAX_FLASH_SECT) { + printf ("** ERROR: sector count %d > max (%d) **\n", + info->sector_count, CFG_MAX_FLASH_SECT); + info->sector_count = CFG_MAX_FLASH_SECT; + } + + addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ + + return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + int flag, prot, sect; + ulong type, start, last; + int rcode = 0; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + type = (info->flash_id & FLASH_VENDMASK); + if ((type != FLASH_MAN_INTEL)) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + start = get_timer (0); + last = start; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + FPWV *addr = (FPWV *) (info->start[sect]); + FPW status; + + printf ("Erasing sector %2d ... ", sect); + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked (); + + *addr = (FPW) 0x00500050; /* clear status register */ + *addr = (FPW) 0x00200020; /* erase setup */ + *addr = (FPW) 0x00D000D0; /* erase confirm */ + + while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { + if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + *addr = (FPW) 0x00B000B0; /* suspend erase */ + *addr = (FPW) 0x00FF00FF; /* reset to read mode */ + rcode = 1; + break; + } + } + + *addr = 0x00500050; /* clear status register cmd. */ + *addr = 0x00FF00FF; /* resest to read mode */ + + printf (" done\n"); + } + } + return rcode; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - Flash not identified + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp; + FPW data; + int count, i, l, rc, port_width; + + if (info->flash_id == FLASH_UNKNOWN) { + return 4; + } +/* get lower word aligned address */ +#ifdef FLASH_PORT_WIDTH16 + wp = (addr & ~1); + port_width = 2; +#else + wp = (addr & ~3); + port_width = 4; +#endif + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + for (; i < port_width && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt == 0 && i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + if ((rc = write_data (info, wp, SWAP (data))) != 0) { + return (rc); + } + wp += port_width; + } + + /* + * handle word aligned part + */ + count = 0; + while (cnt >= port_width) { + data = 0; + for (i = 0; i < port_width; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_data (info, wp, SWAP (data))) != 0) { + return (rc); + } + wp += port_width; + cnt -= port_width; + if (count++ > 0x800) { + spin_wheel (); + count = 0; + } + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + return (write_data (info, wp, SWAP (data))); +} + +/*----------------------------------------------------------------------- + * Write a word or halfword to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_data (flash_info_t *info, ulong dest, FPW data) +{ + FPWV *addr = (FPWV *) dest; + ulong status; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & data) != data) { + printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr); + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + *addr = (FPW) 0x00400040; /* write setup */ + *addr = data; + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked (); + + /* wait while polling the status register */ + while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { + if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) { + *addr = (FPW) 0x00FF00FF; /* restore read mode */ + return (1); + } + } + + *addr = (FPW) 0x00FF00FF; /* restore read mode */ + + return (0); +} + +void inline spin_wheel (void) +{ + static int p = 0; + static char w[] = "\\/-"; + + printf ("\010%c", w[p]); + (++p == 3) ? (p = 0) : 0; +} diff --git a/board/delta/lowlevel_init.S b/board/delta/lowlevel_init.S new file mode 100644 index 0000000000..4d62be5d5e --- /dev/null +++ b/board/delta/lowlevel_init.S @@ -0,0 +1,375 @@ +/* + * Most of this taken from Redboot hal_platform_setup.h with cleanup + * + * NOTE: I haven't clean this up considerably, just enough to get it + * running. See hal_platform_setup.h for the source. See + * board/cradle/lowlevel_init.S for another PXA250 setup that is + * much cleaner. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +DRAM_SIZE: .long CFG_DRAM_SIZE + +/* wait for coprocessor write complete */ + .macro CPWAIT reg + mrc p15,0,\reg,c2,c0,0 + mov \reg,\reg + sub pc,pc,#4 + .endm + + +.macro wait time + ldr r2, =OSCR + mov r3, #0 + str r3, [r2] +0: + ldr r3, [r2] + cmp r3, \time + bls 0b +.endm + +/* + * Memory setup + */ + +.globl lowlevel_init +lowlevel_init: + /* Set up GPIO pins first ----------------------------------------- */ + mov r10, lr + + /* Configure GPIO Pins 41 - 48 as UART1 / altern. Fkt. 2 */ + ldr r0, =0x40E10438 @ GPIO41 FFRXD + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E1043C @ GPIO42 FFTXD + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E10440 @ GPIO43 FFCTS + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E10444 @ GPIO 44 FFDCD + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E10448 @ GPIO 45 FFDSR + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E1044C @ GPIO 46 FFRI + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E10450 @ GPIO 47 FFDTR + ldr r1, =0x802 + str r1, [r0] + + ldr r0, =0x40E10454 @ GPIO 48 + ldr r1, =0x802 + str r1, [r0] + + /* tebrandt - ASCR, clear the RDH bit */ + ldr r0, =ASCR + ldr r1, [r0] + bic r1, r1, #0x80000000 + str r1, [r0] + + /* ---------------------------------------------------------------- */ + /* Enable memory interface */ + /* */ + /* The sequence below is based on the recommended init steps */ + /* detailed in the Intel PXA250 Operating Systems Developers Guide, */ + /* Chapter 10. */ + /* ---------------------------------------------------------------- */ + + /* ---------------------------------------------------------------- */ + /* Step 1: Wait for at least 200 microsedonds to allow internal */ + /* clocks to settle. Only necessary after hard reset... */ + /* FIXME: can be optimized later */ + /* ---------------------------------------------------------------- */ + + /* mk: replaced with wait macro */ +/* ldr r3, =OSCR /\* reset the OS Timer Count to zero *\/ */ +/* mov r2, #0 */ +/* str r2, [r3] */ +/* ldr r4, =0x300 /\* really 0x2E1 is about 200usec, *\/ */ +/* /\* so 0x300 should be plenty *\/ */ +/* 1: */ +/* ldr r2, [r3] */ +/* cmp r4, r2 */ +/* bgt 1b */ + wait #300 + +mem_init: + + /* configure the MEMCLKCFG register */ + ldr r1, =MEMCLKCFG + ldr r2, =0x00010001 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set CSADRCFG[0] to data flash SRAM mode */ + ldr r1, =CSADRCFG0 + ldr r2, =0x00320809 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set CSADRCFG[1] to data flash SRAM mode */ + ldr r1, =CSADRCFG1 + ldr r2, =0x00320809 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set MSC 0 register for SRAM memory */ + ldr r1, =MSC0 + ldr r2, =0x11191119 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set CSADRCFG[2] to data flash SRAM mode */ + ldr r1, =CSADRCFG2 + ldr r2, =0x00320809 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set CSADRCFG[3] to VLIO mode */ + ldr r1, =CSADRCFG3 + ldr r2, =0x0032080B + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + + /* set MSC 1 register for VLIO memory */ + ldr r1, =MSC1 + ldr r2, =0x123C1119 + str r2, [r1] @ WRITE + ldr r2, [r1] @ DELAY UNTIL WRITTEN + +#if 0 + /* This does not work in Zylonite. -SC */ + ldr r0, =0x15fffff0 + ldr r1, =0xb10b + str r1, [r0] + str r1, [r0, #4] +#endif + + /* Configure ACCR Register */ + ldr r0, =ACCR @ ACCR + ldr r1, =0x0180b108 + str r1, [r0] + ldr r1, [r0] + + /* Configure MDCNFG Register */ + ldr r0, =MDCNFG @ MDCNFG + ldr r1, =0x403 + str r1, [r0] + ldr r1, [r0] + + /* Perform Resistive Compensation by configuring RCOMP register */ + ldr r1, =RCOMP @ RCOMP + ldr r2, =0x000000ff + str r2, [r1] + ldr r2, [r1] + + /* Configure MDMRS Register for SDCS0 */ + ldr r1, =MDMRS @ MDMRS + ldr r2, =0x60000023 + ldr r3, [r1] + orr r2, r2, r3 + str r2, [r1] + ldr r2, [r1] + + /* Configure MDMRS Register for SDCS1 */ + ldr r1, =MDMRS @ MDMRS + ldr r2, =0xa0000023 + ldr r3, [r1] + orr r2, r2, r3 + str r2, [r1] + ldr r2, [r1] + + /* Configure MDREFR */ + ldr r1, =MDREFR @ MDREFR + ldr r2, =0x00000006 + str r2, [r1] + ldr r2, [r1] + + /* Configure EMPI */ + ldr r1, =EMPI @ EMPI + ldr r2, =0x80000000 + str r2, [r1] + ldr r2, [r1] + + /* Hardware DDR Read-Strobe Delay Calibration */ + ldr r0, =DDR_HCAL @ DDR_HCAL + ldr r1, =0x803ffc07 @ the offset is correct? -SC + str r1, [r0] + wait #5 + ldr r1, [r0] + + /* Here we assume the hardware calibration alwasy be successful. -SC */ + /* Set DMCEN bit in MDCNFG Register */ + ldr r0, =MDCNFG @ MDCNFG + ldr r1, [r0] + orr r1, r1, #0x40000000 @ enable SDRAM for Normal Access + str r1, [r0] + + /* scrub/init SDRAM if enabled/present */ +/* ldr r11, =0xa0000000 /\* base address of SDRAM (CFG_DRAM_BASE) *\/ */ +/* ldr r12, =0x04000000 /\* size of memory to scrub (CFG_DRAM_SIZE) *\/ */ +/* mov r8,r12 /\* save DRAM size (mk: why???) *\/ */ + ldr r8, =0xa0000000 /* base address of SDRAM (CFG_DRAM_BASE) */ + ldr r9, =0x04000000 /* size of memory to scrub (CFG_DRAM_SIZE) */ + mov r0, #0 /* scrub with 0x0000:0000 */ + mov r1, #0 + mov r2, #0 + mov r3, #0 + mov r4, #0 + mov r5, #0 + mov r6, #0 + mov r7, #0 +10: /* fastScrubLoop */ + subs r9, r9, #32 // 32 bytes/line + stmia r8!, {r0-r7} + beq 15f + b 10b + +15: + /* Mask all interrupts */ + mov r1, #0 + mcr p6, 0, r1, c1, c0, 0 @ ICMR + + /* Disable software and data breakpoints */ + mov r0, #0 + mcr p15,0,r0,c14,c8,0 // ibcr0 + mcr p15,0,r0,c14,c9,0 // ibcr1 + mcr p15,0,r0,c14,c4,0 // dbcon + + /* Enable all debug functionality */ + mov r0,#0x80000000 + mcr p14,0,r0,c10,c0,0 // dcsr + + + + /* We are finished with Intel's memory controller initialisation */ + + + /* ---------------------------------------------------------------- */ + /* End lowlevel_init */ + /* ---------------------------------------------------------------- */ + +endlowlevel_init: + + mov pc, lr + + +/* +@******************************************************************************** +@ DDR calibration +@ +@ This function is used to calibrate DQS delay lines. +@ Monahans supports three ways to do it. One is software +@ calibration. Two is hardware calibration. Three is hybrid +@ calibration. +@ +@ TBD +@ -SC +ddr_calibration: + + @ Case 1: Write the correct delay value once + @ Configure DDR_SCAL Register + ldr r0, =DDR_SCAL @ DDR_SCAL +q ldr r1, =0xaf2f2f2f + str r1, [r0] + ldr r1, [r0] +*/ +/* @ Case 2: Software Calibration + @ Write test pattern to memory + ldr r5, =0x0faf0faf @ Data Pattern + ldr r4, =0xa0000000 @ DDR ram + str r5, [r4] + + mov r1, =0x0 @ delay count + mov r6, =0x0 + mov r7, =0x0 +ddr_loop1: + add r1, r1, =0x1 + cmp r1, =0xf + ble end_loop + mov r3, r1 + mov r0, r1, lsl #30 + orr r3, r3, r0 + mov r0, r1, lsl #22 + orr r3, r3, r0 + mov r0, r1, lsl #14 + orr r3, r3, r0 + orr r3, r3, =0x80000000 + ldr r2, =DDR_SCAL + str r3, [r2] + + ldr r2, [r4] + cmp r2, r5 + bne ddr_loop1 + mov r6, r1 +ddr_loop2: + add r1, r1, =0x1 + cmp r1, =0xf + ble end_loop + mov r3, r1 + mov r0, r1, lsl #30 + orr r3, r3, r0 + mov r0, r1, lsl #22 + orr r3, r3, r0 + mov r0, r1, lsl #14 + orr r3, r3, r0 + orr r3, r3, =0x80000000 + ldr r2, =DDR_SCAL + str r3, [r2] + + ldr r2, [r4] + cmp r2, r5 + be ddr_loop2 + mov r7, r2 + + add r3, r6, r7 + lsr r3, r3, =0x1 + mov r0, r1, lsl #30 + orr r3, r3, r0 + mov r0, r1, lsl #22 + orr r3, r3, r0 + mov r0, r1, lsl #14 + orr r3, r3, r0 + orr r3, r3, =0x80000000 + ldr r2, =DDR_SCAL + +end_loop: + + @ Case 3: Hardware Calibratoin + ldr r0, =DDR_HCAL @ DDR_HCAL + ldr r1, =0x803ffc07 @ the offset is correct? -SC + str r1, [r0] + wait #5 + ldr r1, [r0] + mov pc, lr +*/ diff --git a/board/delta/u-boot.lds b/board/delta/u-boot.lds new file mode 100644 index 0000000000..f0102391b3 --- /dev/null +++ b/board/delta/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/pxa/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index a8477cf60d..235a365495 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1163,6 +1163,37 @@ typedef void (*ExcpHndlr) (void) ; #define GPIO4_2 __REG(0x40e10684) #define GPIO5_2 __REG(0x40e10688) +/* MFPR Bit Definitions, see 4-10, Vol. 1 */ +#define PULL_SEL 0x8000 +#define PULLUP_EN 0x4000 +#define PULLDOWN_EN 0x2000 + +#define DRIVE_FAST_1mA 0x0 +#define DRIVE_FAST_2mA 0x400 +#define DRIVE_FAST_3mA 0x800 +#define DRIVE_FAST_4mA 0xC00 +#define DRIVE_SLOW_6mA 0x1000 +#define DRIVE_FAST_6mA 0x1400 +#define DRIVE_SLOW_10mA 0x1800 +#define DRIVE_FAST_10mA 0x1C00 + +#define SLEEP_SEL 0x200 +#define SLEEP_DATA 0x100 +#define SLEEP_OE_N 0x80 +#define EDGE_CLEAR 0x40 +#define EDGE_FALL_EN 0x20 +#define EDGE_RISE_EN 0x10 + +#define AF_SEL_0 0x0 /* Alternate function 0 (reset state) */ +#define AF_SEL_1 0x1 /* Alternate function 1 */ +#define AF_SEL_2 0x2 /* Alternate function 2 */ +#define AF_SEL_3 0x3 /* Alternate function 3 */ +#define AF_SEL_4 0x4 /* Alternate function 4 */ +#define AF_SEL_5 0x5 /* Alternate function 5 */ +#define AF_SEL_6 0x6 /* Alternate function 6 */ +#define AF_SEL_7 0x7 /* Alternate function 7 */ + + #else /* CONFIG_CPU_MONAHANS */ #define GAFR0_L __REG(0x40E00054) /* GPIO Alternate Function Select Register GPIO<15:0> */ diff --git a/include/configs/delta.h b/include/configs/delta.h new file mode 100644 index 0000000000..7b923c22e9 --- /dev/null +++ b/include/configs/delta.h @@ -0,0 +1,249 @@ +/* + * Configuation settings for the Delta board. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ +#define CONFIG_CPU_MONAHANS 1 /* Intel Monahan CPU */ +#define CONFIG_DELTA 1 /* Delta board */ + +/* #define CONFIG_LCD 1 */ +#ifdef CONFIG_LCD +#define CONFIG_SHARP_LM8V31 +#endif +/* #define CONFIG_MMC 1 */ +#define BOARD_LATE_INIT 1 + +#undef CONFIG_SKIP_RELOCATE_UBOOT +#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ + +/* + * Size of malloc() pool + */ +#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ + +/* + * Hardware drivers + */ + +#undef TURN_ON_ETHERNET +#ifdef TURN_ON_ETHERNET +# define CONFIG_DRIVER_SMC91111 1 +# define CONFIG_SMC91111_BASE 0x14000300 +# define CONFIG_SMC91111_EXT_PHY +# define CONFIG_SMC_USE_32_BIT +# undef CONFIG_SMC_USE_IOFUNCS /* just for use with the kernel */ +#endif + +/* + * select serial console configuration + */ +#define CONFIG_FFUART 1 + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_BAUDRATE 115200 + +/* #define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_MMC | CFG_CMD_FAT) */ +#ifdef TURN_ON_ETHERNET +# define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_PING) +#else +# define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_NET) +#endif + + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +#define CONFIG_BOOTDELAY -1 +#define CONFIG_ETHADDR 08:00:3e:26:0a:5b +#define CONFIG_NETMASK 255.255.0.0 +#define CONFIG_IPADDR 192.168.0.21 +#define CONFIG_SERVERIP 192.168.0.250 +#define CONFIG_BOOTCOMMAND "bootm 80000" +#define CONFIG_BOOTARGS "root=/dev/mtdblock2 rootfstype=cramfs console=ttyS0,115200" +#define CONFIG_CMDLINE_TAG +#define CONFIG_TIMESTAMP + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + +/* + * Miscellaneous configurable options + */ +#define CFG_HUSH_PARSER 1 +#define CFG_PROMPT_HUSH_PS2 "> " + +#define CFG_LONGHELP /* undef to save memory */ +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT "$ " /* Monitor Command Prompt */ +#else +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#endif +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_DEVICE_NULLDEV 1 + +#define CFG_MEMTEST_START 0xa0400000 /* memtest works on */ +#define CFG_MEMTEST_END 0xa0800000 /* 4 ... 8 MB in DRAM */ + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +#define CFG_LOAD_ADDR (CFG_DRAM_BASE + 0x8000) /* default load address */ + +#define CFG_HZ 3686400 /* incrementer freq: 3.6864 MHz */ +#define CFG_CPUSPEED 0x161 /* set core clock to 400/200/100 MHz */ + + /* valid baudrates */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* #define CFG_MMC_BASE 0xF0000000 */ + +/* + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ +#endif + +/* + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 4 /* we have 2 banks of DRAM */ +#define PHYS_SDRAM_1 0xa0000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */ +#define PHYS_SDRAM_2 0xa4000000 /* SDRAM Bank #2 */ +#define PHYS_SDRAM_2_SIZE 0x00000000 /* 0 MB */ +#define PHYS_SDRAM_3 0xa8000000 /* SDRAM Bank #3 */ +#define PHYS_SDRAM_3_SIZE 0x00000000 /* 0 MB */ +#define PHYS_SDRAM_4 0xac000000 /* SDRAM Bank #4 */ +#define PHYS_SDRAM_4_SIZE 0x00000000 /* 0 MB */ + +#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ +#define PHYS_FLASH_2 0x04000000 /* Flash Bank #2 */ +#define PHYS_FLASH_SIZE 0x02000000 /* 32 MB */ +#define PHYS_FLASH_BANK_SIZE 0x02000000 /* 32 MB Banks */ +#define PHYS_FLASH_SECT_SIZE 0x00040000 /* 256 KB sectors (x2) */ + +#define CFG_DRAM_BASE 0xa0000000 +#define CFG_DRAM_SIZE 0x04000000 + +#define CFG_FLASH_BASE PHYS_FLASH_1 + +#define FPGA_REGS_BASE_PHYSICAL 0x08000000 + +/* + * GPIO settings + */ +#define CFG_GPSR0_VAL 0x00008000 +#define CFG_GPSR1_VAL 0x00FC0382 +#define CFG_GPSR2_VAL 0x0001FFFF +#define CFG_GPCR0_VAL 0x00000000 +#define CFG_GPCR1_VAL 0x00000000 +#define CFG_GPCR2_VAL 0x00000000 +#define CFG_GPDR0_VAL 0x0060A800 +#define CFG_GPDR1_VAL 0x00FF0382 +#define CFG_GPDR2_VAL 0x0001C000 +#define CFG_GAFR0_L_VAL 0x98400000 +#define CFG_GAFR0_U_VAL 0x00002950 +#define CFG_GAFR1_L_VAL 0x000A9558 +#define CFG_GAFR1_U_VAL 0x0005AAAA +#define CFG_GAFR2_L_VAL 0xA0000000 +#define CFG_GAFR2_U_VAL 0x00000002 + +#define CFG_PSSR_VAL 0x20 + +/* + * Memory settings + */ +#define CFG_MSC0_VAL 0x23F223F2 +#define CFG_MSC1_VAL 0x3FF1A441 +#define CFG_MSC2_VAL 0x7FF97FF1 +#define CFG_MDCNFG_VAL 0x00001AC9 +#define CFG_MDREFR_VAL 0x00018018 +#define CFG_MDMRS_VAL 0x00000000 + +/* + * PCMCIA and CF Interfaces + */ +#define CFG_MECR_VAL 0x00000000 +#define CFG_MCMEM0_VAL 0x00010504 +#define CFG_MCMEM1_VAL 0x00010504 +#define CFG_MCATT0_VAL 0x00010504 +#define CFG_MCATT1_VAL 0x00010504 +#define CFG_MCIO0_VAL 0x00004715 +#define CFG_MCIO1_VAL 0x00004715 + +#define _LED 0x08000010 +#define LED_BLANK 0x08000040 + +/* + * FLASH and environment organization + */ +#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ + +/* timeout values are in ticks */ +#define CFG_FLASH_ERASE_TOUT (25*CFG_HZ) /* Timeout for Flash Erase */ +#define CFG_FLASH_WRITE_TOUT (25*CFG_HZ) /* Timeout for Flash Write */ + +/* NOTE: many default partitioning schemes assume the kernel starts at the + * second sector, not an environment. You have been warned! + */ +#define CFG_MONITOR_LEN PHYS_FLASH_SECT_SIZE + +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_ENV_ADDR (PHYS_FLASH_1 + PHYS_FLASH_SECT_SIZE) +#define CFG_ENV_SECT_SIZE PHYS_FLASH_SECT_SIZE +#define CFG_ENV_SIZE (PHYS_FLASH_SECT_SIZE / 16) + + +/* + * FPGA Offsets + */ +#define WHOAMI_OFFSET 0x00 +#define HEXLED_OFFSET 0x10 +#define BLANKLED_OFFSET 0x40 +#define DISCRETELED_OFFSET 0x40 +#define CNFG_SWITCHES_OFFSET 0x50 +#define USER_SWITCHES_OFFSET 0x60 +#define MISC_WR_OFFSET 0x80 +#define MISC_RD_OFFSET 0x90 +#define INT_MASK_OFFSET 0xC0 +#define INT_CLEAR_OFFSET 0xD0 +#define GP_OFFSET 0x100 + +#endif /* __CONFIG_H */ From 48b6242aa1a5c8ef5f08abf30ebf9a49e3d95bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Wed, 22 Feb 2006 00:06:01 +0100 Subject: [PATCH 014/102] SDRAM seems to be working on delta board, though u-boot doesn't start yet. --- board/delta/lowlevel_init.S | 141 ++++++++++++++++------------ include/asm-arm/arch-pxa/pxa-regs.h | 25 +++++ 2 files changed, 108 insertions(+), 58 deletions(-) diff --git a/board/delta/lowlevel_init.S b/board/delta/lowlevel_init.S index 4d62be5d5e..35716f245e 100644 --- a/board/delta/lowlevel_init.S +++ b/board/delta/lowlevel_init.S @@ -48,7 +48,21 @@ DRAM_SIZE: .long CFG_DRAM_SIZE cmp r3, \time bls 0b .endm - + + +#define SDRAM_CMD_NOP 0x40000000 + +.macro do_nop_cmd num + ldr r2, =MDMRS + ldr r3, =SDRAM_CMD_NOP + ldr r4, =0x0 +loop: + str r3, [r2] + add r4, r4, #1 + cmp r4, \num + bls loop +.endm + /* * Memory setup */ @@ -58,39 +72,15 @@ lowlevel_init: /* Set up GPIO pins first ----------------------------------------- */ mov r10, lr - /* Configure GPIO Pins 41 - 48 as UART1 / altern. Fkt. 2 */ - ldr r0, =0x40E10438 @ GPIO41 FFRXD - ldr r1, =0x802 - str r1, [r0] - - ldr r0, =0x40E1043C @ GPIO42 FFTXD - ldr r1, =0x802 - str r1, [r0] - - ldr r0, =0x40E10440 @ GPIO43 FFCTS - ldr r1, =0x802 - str r1, [r0] - - ldr r0, =0x40E10444 @ GPIO 44 FFDCD - ldr r1, =0x802 - str r1, [r0] - - ldr r0, =0x40E10448 @ GPIO 45 FFDSR - ldr r1, =0x802 - str r1, [r0] - - ldr r0, =0x40E1044C @ GPIO 46 FFRI - ldr r1, =0x802 - str r1, [r0] - - ldr r0, =0x40E10450 @ GPIO 47 FFDTR - ldr r1, =0x802 - str r1, [r0] - - ldr r0, =0x40E10454 @ GPIO 48 - ldr r1, =0x802 - str r1, [r0] + /* Configure GPIO Pins 97, 98 UART1 / altern. Fkt. 1 */ + ldr r0, =GPIO97 + ldr r1, =0x801 + str r1, [r0] + ldr r0, =GPIO98 + ldr r1, =0x801 + str r1, [r0] + /* tebrandt - ASCR, clear the RDH bit */ ldr r0, =ASCR ldr r1, [r0] @@ -99,10 +89,6 @@ lowlevel_init: /* ---------------------------------------------------------------- */ /* Enable memory interface */ - /* */ - /* The sequence below is based on the recommended init steps */ - /* detailed in the Intel PXA250 Operating Systems Developers Guide, */ - /* Chapter 10. */ /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */ @@ -110,21 +96,67 @@ lowlevel_init: /* clocks to settle. Only necessary after hard reset... */ /* FIXME: can be optimized later */ /* ---------------------------------------------------------------- */ - - /* mk: replaced with wait macro */ -/* ldr r3, =OSCR /\* reset the OS Timer Count to zero *\/ */ -/* mov r2, #0 */ -/* str r2, [r3] */ -/* ldr r4, =0x300 /\* really 0x2E1 is about 200usec, *\/ */ -/* /\* so 0x300 should be plenty *\/ */ -/* 1: */ -/* ldr r2, [r3] */ -/* cmp r4, r2 */ -/* bgt 1b */ wait #300 mem_init: +#define NEW_SDRAM_INIT 1 +#ifdef NEW_SDRAM_INIT + + /* Configure ACCR Register - enable DMEMC Clock at 260 / 2 MHz */ + ldr r0, =ACCR + ldr r1, [r0] + orr r1, r1, #0x3000 + str r1, [r0] + ldr r1, [r0] + + /* 2. Programm MDCNFG, leaving DMCEN de-asserted */ + ldr r0, =MDCNFG + ldr r1, =(MDCNFG_DMAP | MDCNFG_DTYPE | MDCNFG_DTC_2 | MDCNFG_DCSE0 | MDCNFG_DRAC_13) + /* ldr r1, =0x80000403 */ + str r1, [r0] + ldr r1, [r0] /* delay until written */ + + /* 3. wait nop power up waiting period (200ms) + * optimization: Steps 4+6 can be done during this + */ + wait #300 + + /* 4. Perform an initial Rcomp-calibration cycle */ + ldr r0, =RCOMP + ldr r1, =0x80000000 + str r1, [r0] + ldr r1, [r0] /* delay until written */ + /* missing: program for automatic rcomp evaluation cycles */ + + /* 5. DDR DRAM strobe delay calibration */ + ldr r0, =DDR_HCAL + ldr r1, =0x88000007 + str r1, [r0] + wait #5 + ldr r1, [r0] /* delay until written */ + + /* Set MDMRS */ + ldr r0, =MDMRS + ldr r1, =0x60000023 + str r1, [r0] + wait #300 + + /* Configure MDREFR */ + ldr r0, =MDREFR + ldr r1, =0x00000006 + str r1, [r0] + ldr r1, [r0] + + /* Enable the dynamic memory controller */ + ldr r0, =MDCNFG + ldr r1, [r0] + orr r1, r1, #MDCNFG_DMCEN + str r1, [r0] + + +#else /* NEW_SDRAM_INIT */ + /* configure the MEMCLKCFG register */ ldr r1, =MEMCLKCFG ldr r2, =0x00010001 @@ -235,6 +267,8 @@ mem_init: orr r1, r1, #0x40000000 @ enable SDRAM for Normal Access str r1, [r0] +#endif /* NEW_SDRAM_INIT */ + /* scrub/init SDRAM if enabled/present */ /* ldr r11, =0xa0000000 /\* base address of SDRAM (CFG_DRAM_BASE) *\/ */ /* ldr r12, =0x04000000 /\* size of memory to scrub (CFG_DRAM_SIZE) *\/ */ @@ -270,18 +304,9 @@ mem_init: mov r0,#0x80000000 mcr p14,0,r0,c10,c0,0 // dcsr - - - /* We are finished with Intel's memory controller initialisation */ - - - /* ---------------------------------------------------------------- */ - /* End lowlevel_init */ - /* ---------------------------------------------------------------- */ - endlowlevel_init: - mov pc, lr + mov pc, lr /* diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 235a365495..44532c9c16 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1994,6 +1994,31 @@ typedef void (*ExcpHndlr) (void) ; #define PAD_SCLK __REG_2(0x4810012C) #define TAI __REG_2(0x48100F00) /* TAI Tavor Address Isolation Register */ +/* Some frequently used bits */ +#define MDCNFG_DMAP 0x80000000 /* SDRAM 1GB Memory Map Enable */ +#define MDCNFG_DMCEN 0x40000000 /* Enable Dynamic Memory Controller */ +#define MDCNFG_HWFREQ 0x20000000 /* Hardware Frequency Change Calibration */ +#define MDCNFG_DTYPE 0x400 /* SDRAM Type: 1=DDR SDRAM */ + +#define MDCNFG_DTC_0 0x0 /* Timing Category of SDRAM */ +#define MDCNFG_DTC_1 0x100 +#define MDCNFG_DTC_2 0x200 +#define MDCNFG_DTC_3 0x300 + +#define MDCNFG_DRAC_12 0x0 /* Number of Row Access Bits */ +#define MDCNFG_DRAC_13 0x20 +#define MDCNFG_DRAC_14 0x40 + +#define MDCNFG_DCAC_9 0x0 /* Number of Column Acess Bits */ +#define MDCNFG_DCAC_10 0x08 +#define MDCNFG_DCAC_11 0x10 + +#define MDCNFG_DBW_16 0x4 /* SDRAM Data Bus width 16bit */ +#define MDCNFG_DCSE1 0x2 /* SDRAM CS 1 Enable */ +#define MDCNFG_DCSE0 0x1 /* SDRAM CS 0 Enable */ + + + /* Data Flash Controller Registers */ From 86ea5f93d7d18871edfc8e7eadcf93d8951d3909 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 22 Feb 2006 00:43:16 +0100 Subject: [PATCH 015/102] Initial port to MCC200 board (work in progress) Minimally modified patch by Bluetechnix, Vienna --- Makefile | 9 +- board/mcc200/Makefile | 46 ++ board/mcc200/config.mk | 31 ++ board/mcc200/flash.c | 738 ++++++++++++++++++++++++++++++++ board/mcc200/flash.h | 437 +++++++++++++++++++ board/mcc200/mcc200.c | 328 ++++++++++++++ board/mcc200/mt46v16m16-75.h | 37 ++ board/mcc200/mt48lc16m16a2-75.h | 43 ++ board/mcc200/mt48lc8m32b2-6-7.h | 30 ++ board/mcc200/u-boot.lds | 125 ++++++ cpu/mpc5xxx/fec.c | 3 +- include/configs/mcc200.h | 402 +++++++++++++++++ 12 files changed, 2225 insertions(+), 4 deletions(-) create mode 100644 board/mcc200/Makefile create mode 100644 board/mcc200/config.mk create mode 100644 board/mcc200/flash.c create mode 100644 board/mcc200/flash.h create mode 100644 board/mcc200/mcc200.c create mode 100644 board/mcc200/mt46v16m16-75.h create mode 100644 board/mcc200/mt48lc16m16a2-75.h create mode 100644 board/mcc200/mt48lc8m32b2-6-7.h create mode 100644 board/mcc200/u-boot.lds create mode 100644 include/configs/mcc200.h diff --git a/Makefile b/Makefile index 08a8e46708..dabe2d2405 100644 --- a/Makefile +++ b/Makefile @@ -291,14 +291,17 @@ icecube_5100_config: unconfig } @./mkconfig -a IceCube ppc mpc5xxx icecube -inka4x0_config: unconfig +inka4x0_config: unconfig @./mkconfig inka4x0 ppc mpc5xxx inka4x0 +mcc200_config: unconfig + @./mkconfig mcc200 ppc mpc5xxx mcc200 + o2dnt_config: - @./mkconfig -a o2dnt ppc mpc5xxx o2dnt + @./mkconfig o2dnt ppc mpc5xxx o2dnt pf5200_config: unconfig - @./mkconfig -a pf5200 ppc mpc5xxx pf5200 esd + @./mkconfig pf5200 ppc mpc5xxx pf5200 esd PM520_config \ PM520_DDR_config \ diff --git a/board/mcc200/Makefile b/board/mcc200/Makefile new file mode 100644 index 0000000000..162734bb83 --- /dev/null +++ b/board/mcc200/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2003-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := $(BOARD).o flash.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/mcc200/config.mk b/board/mcc200/config.mk new file mode 100644 index 0000000000..0a278b16bf --- /dev/null +++ b/board/mcc200/config.mk @@ -0,0 +1,31 @@ +# +# (C) Copyright 2003-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# MCC200 board +# + +TEXT_BASE = 0xfff00000 +# TEXT_BASE = 0x00100000 + +PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board diff --git a/board/mcc200/flash.c b/board/mcc200/flash.c new file mode 100644 index 0000000000..8e1757acd4 --- /dev/null +++ b/board/mcc200/flash.c @@ -0,0 +1,738 @@ +/* + * (C) Copyright 2001 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2001-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +//###CHD: gehört wieder raus ist vom PXA271 file! +#define FLASH_28F256L18T 0x00B0 /* Intel 28F256L18T ( 32M = 128K x 255 + 32k x 4) */ +#define FLASH_28F256L18B 0x00B1 /* Intel 28F256L18B ( 32M = 32k x 4 + 128K x 255) */ +#define FLASH_28F256P30B 0x001C /* Intel 28F256P30B ( 32M = 32k x 4 + 128K x 255) */ +#define FLASH_28F256P30T 0x0019 /* Intel 28F256P30T ( 128K x 255 + 32M = 32k x 4 + */ + +#define INTEL_ID_28F016S 0x66a066a0 /* 28F016S[VS] ID (16M = 512k x 16) */ +#define INTEL_ID_28F800B3T 0x88928892 /* 8M = 512K x 16 top boot sector */ +#define INTEL_ID_28F800B3B 0x88938893 /* 8M = 512K x 16 bottom boot sector */ +#define INTEL_ID_28F160B3T 0x88908890 /* 16M = 1M x 16 top boot sector */ +#define INTEL_ID_28F160B3B 0x88918891 /* 16M = 1M x 16 bottom boot sector */ +#define INTEL_ID_28F320B3T 0x88968896 /* 32M = 2M x 16 top boot sector */ +#define INTEL_ID_28F320B3B 0x88978897 /* 32M = 2M x 16 bottom boot sector */ +#define INTEL_ID_28F640B3T 0x88988898 /* 64M = 4M x 16 top boot sector */ +#define INTEL_ID_28F640B3B 0x88998899 /* 64M = 4M x 16 bottom boot sector */ +#define INTEL_ID_28F160F3B 0x88F488F4 /* 16M = 1M x 16 bottom boot sector */ + +#define INTEL_ID_28F800C3T 0x88C088C0 /* 8M = 512K x 16 top boot sector */ +#define INTEL_ID_28F800C3B 0x88C188C1 /* 8M = 512K x 16 bottom boot sector */ +#define INTEL_ID_28F160C3T 0x88C288C2 /* 16M = 1M x 16 top boot sector */ +#define INTEL_ID_28F160C3B 0x88C388C3 /* 16M = 1M x 16 bottom boot sector */ +#define INTEL_ID_28F320C3T 0x88C488C4 /* 32M = 2M x 16 top boot sector */ +#define INTEL_ID_28F320C3B 0x88C588C5 /* 32M = 2M x 16 bottom boot sector */ +#define INTEL_ID_28F640C3T 0x88CC88CC /* 64M = 4M x 16 top boot sector */ +#define INTEL_ID_28F640C3B 0x88CD88CD /* 64M = 4M x 16 bottom boot sector */ + +#define INTEL_ID_28F128J3 0x89188918 /* 16M = 8M x 16 x 128 */ +#define INTEL_ID_28F320J5 0x00140014 /* 32M = 128K x 32 */ +#define INTEL_ID_28F640J5 0x00150015 /* 64M = 128K x 64 */ +#define INTEL_ID_28F320J3A 0x00160016 /* 32M = 128K x 32 */ +#define INTEL_ID_28F640J3A 0x00170017 /* 64M = 128K x 64 */ +#define INTEL_ID_28F256L18 0x88108810 /* 32M = 128K x 255 */ +#define INTEL_ID_28F128J3A 0x00180018 /* 128M = 128K x 128 */ +#define INTEL_ID_28F256L18T 0x880D880D /* 256M = 128K x 255 + 32k x 4 */ +#define INTEL_ID_28F256L18B 0x88108810 /* 256M = 32k x 4 + 128K x 255 */ +#define INTEL_ID_28F256P30B 0x891C891C /* 256M = 32k x 4 + 128K x 255 */ +#define INTEL_ID_28F256P30T 0x89198919 /* 256M = 128K x 255 + 32k x 4 */ +#define INTEL_ID_28F64K3 0x88018801 /* 64M = 32K x 255 + 32k x 4 */ +#define INTEL_ID_28F128K3 0x88028802 /* 128M = 64K x 255 + 32k x 4 */ +#define INTEL_ID_28F256K3 0x88038803 /* 256M = 128K x 255 + 32k x 4 */ + +#define INTEL_ID_28F160S3 0x00D000D0 /* 16M = 512K x 32 (64kB x 32) */ +#define INTEL_ID_28F320S3 0x00D400D4 /* 32M = 512K x 64 (64kB x 64) */ + + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/* Board support for 1 or 2 flash devices */ +#define FLASH_PORT_WIDTH32 +#undef FLASH_PORT_WIDTH16 + +#ifdef FLASH_PORT_WIDTH16 +#define FLASH_PORT_WIDTH ushort +#define FLASH_PORT_WIDTHV vu_short +#define SWAP(x) (x) +#else +#define FLASH_PORT_WIDTH ulong +#define FLASH_PORT_WIDTHV vu_long +#define SWAP(x) (x) +#endif + +/* Intel-compatible flash ID */ +#define INTEL_COMPAT 0x00890089 +#define INTEL_ALT 0x00B000B0 + + + +/* Intel-compatible flash commands */ +#define INTEL_PROGRAM 0x00100010 +#define INTEL_ERASE 0x00200020 +#define INTEL_CLEAR 0x00500050 +#define INTEL_LOCKBIT 0x00600060 +#define INTEL_PROTECT 0x00010001 +#define INTEL_STATUS 0x00700070 +#define INTEL_READID 0x00900090 +#define INTEL_CONFIRM 0x00D000D0 +#define INTEL_RESET 0xFFFFFFFF + +/* Intel-compatible flash status bits */ +#define INTEL_FINISHED 0x00800080 +#define INTEL_OK 0x00800080 + +#define FPW FLASH_PORT_WIDTH +#define FPWV FLASH_PORT_WIDTHV + +#define mb() __asm__ __volatile__ ("" : : : "memory") + +///###CHD: auch wieder raus! + switch anweisung für den P30iger! +/* Flash Organization Structure */ +typedef struct OrgDef { + unsigned int sector_number; + unsigned int sector_size; +} OrgDef; + +/* Flash Organizations */ +OrgDef OrgIntel_28F256L18B[] = { + {4, 0x8000}, /* 4 * 32kBytes sectors */ + {255, 0x20000}, /* 255 * 128kBytes sectors */ +}; + +OrgDef OrgIntel_28F256L18T[] = { + {255, 0x20000}, /* 255 * 128kBytes sectors */ + {4, 0x8000} /* 4 * 32kBytes sectors */ +}; + +OrgDef OrgIntel_28F128J3A[] = { + {128, 0x20000}, /* 128 * 128kBytes sectors */ +}; +static unsigned int OrgSectTypeNum_28F256L18 = 2; +static unsigned int OrgSectTypeNum_28F256J3 = 1; + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (FPW *addr, flash_info_t *info); +static int write_data (flash_info_t *info, ulong dest, FPW data); +static void flash_get_offsets (ulong base, flash_info_t *info); +void inline spin_wheel (void); +static void flash_sync_real_protect (flash_info_t * info); +static unsigned char intel_sector_protected (flash_info_t *info, ushort sector); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + int i; + ulong size = 0; + extern void flash_preinit(void); + extern void flash_afterinit(ulong, ulong); + ulong flashbase = CFG_FLASH_BASE; + + flash_preinit(); + + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { + switch (i) { + case 0: + memset(&flash_info[i], 0, sizeof(flash_info_t)); + flash_get_size ((FPW *) flashbase, &flash_info[i]); + flash_get_offsets (flash_info[i].start[0], &flash_info[i]); + break; + default: + panic ("configured to many flash banks!\n"); + break; + } + size += flash_info[i].size; + + /* get the h/w and s/w protection status in sync */ + flash_sync_real_protect(&flash_info[i]); + } + + /* Protect monitor and environment sectors + */ +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE +#ifndef CONFIG_BOOT_ROM + flash_protect ( FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE + monitor_flash_len - 1, + &flash_info[0] ); +#endif +#endif + +#ifdef CFG_ENV_IS_IN_FLASH + flash_protect ( FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] ); +#endif + + flash_afterinit(flash_info[0].start[0], flash_info[0].size); + + return size; +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + return; + } + + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { + for (i = 0; i < info->sector_count; i++) { + info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE); + } + } +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: + printf ("INTEL "); + break; + default: + printf ("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F128J3A: + printf ("28F128J3A\n"); + break; + + case FLASH_28F640J3A: + printf ("28F640J3A\n"); + break; + + case FLASH_28F320J3A: + printf ("28F320J3A\n"); + break; + + case FLASH_28F256P30T: + printf ("FLASH_28F256P30T\n"); + break; + + default: + printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " "); + } + printf ("\n"); + return; +} + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (FPW *addr, flash_info_t *info) +{ + volatile FPW value; + + /* Write auto select command: read Manufacturer ID */ + addr[0x5555] = (FPW) 0x00AA00AA; + addr[0x2AAA] = (FPW) 0x00550055; + addr[0x5555] = (FPW) 0x00900090; + + mb (); + udelay(100); + + value = addr[0]; + + switch (value) { + + case (FPW) INTEL_MANUFACT: + info->flash_id = FLASH_MAN_INTEL; + break; + + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ + return (0); /* no or unknown flash */ + } + + mb (); + value = addr[1]; /* device ID */ + + switch (value) { + + case (FPW) INTEL_ID_28F128J3A: + info->flash_id += FLASH_28F128J3A; + info->sector_count = 128; + info->size = 0x02000000; + info->start[0] = CFG_FLASH_BASE; + break; /* => 32 MB */ + + case (FPW) INTEL_ID_28F640J3A: + info->flash_id += FLASH_28F640J3A; + info->sector_count = 64; + info->size = 0x01000000; + info->start[0] = CFG_FLASH_BASE + 0x01000000; + break; /* => 16 MB */ + + case (FPW) (INTEL_ID_28F256P30T): + info->flash_id += FLASH_28F256L18B; + info->sector_count = 128;//falsch!!! + info->size = 0x02000000; + info->start[0] = CFG_FLASH_BASE; + debug ("Intel StrataFlash 28F256P30T device initialized\n"); + break; /* => 32 MB */ + + case (FPW) INTEL_ID_28F320J3A: + info->flash_id += FLASH_28F320J3A; + info->sector_count = 32; + info->size = 0x800000; + info->start[0] = CFG_FLASH_BASE + 0x01800000; + break; /* => 8 MB */ + + default: + info->flash_id = FLASH_UNKNOWN; + break; + } + + if (info->sector_count > CFG_MAX_FLASH_SECT) { + printf ("** ERROR: sector count %d > max (%d) **\n", + info->sector_count, CFG_MAX_FLASH_SECT); + info->sector_count = CFG_MAX_FLASH_SECT; + } + + addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ + + return (info->size); +} + + +/* + * This function gets the u-boot flash sector protection status + * (flash_info_t.protect[]) in sync with the sector protection + * status stored in hardware. + */ +static void flash_sync_real_protect (flash_info_t * info) +{ + int i; + + switch (info->flash_id & FLASH_TYPEMASK) { + + case FLASH_28F128J3A: + case FLASH_28F640J3A: + case FLASH_28F320J3A: + for (i = 0; i < info->sector_count; ++i) { + info->protect[i] = intel_sector_protected(info, i); + } + break; + default: + /* no h/w protect support */ + break; + } +} + + +/* + * checks if "sector" in bank "info" is protected. Should work on intel + * strata flash chips 28FxxxJ3x in 8-bit mode. + * Returns 1 if sector is protected (or timed-out while trying to read + * protection status), 0 if it is not. + */ +static unsigned char intel_sector_protected (flash_info_t *info, ushort sector) +{ + FPWV *addr; + FPWV *lock_conf_addr; + ulong start; + unsigned char ret; + + /* + * first, wait for the WSM to be finished. The rationale for + * waiting for the WSM to become idle for at most + * CFG_FLASH_ERASE_TOUT is as follows. The WSM can be busy + * because of: (1) erase, (2) program or (3) lock bit + * configuration. So we just wait for the longest timeout of + * the (1)-(3), i.e. the erase timeout. + */ + + /* wait at least 35ns (W12) before issuing Read Status Register */ + udelay(1); + addr = (FPWV *) info->start[sector]; + *addr = (FPW) INTEL_STATUS; + + start = get_timer (0); + while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) { + if (get_timer (start) > CFG_FLASH_ERASE_TOUT) { + *addr = (FPW) INTEL_RESET; /* restore read mode */ + printf("WSM busy too long, can't get prot status\n"); + return 1; + } + } + + /* issue the Read Identifier Codes command */ + *addr = (FPW) INTEL_READID; + + /* wait at least 35ns (W12) before reading */ + udelay(1); + + /* Intel example code uses offset of 2 for 16 bit flash */ + lock_conf_addr = (FPWV *) info->start[sector] + 2; + ret = (*lock_conf_addr & (FPW) INTEL_PROTECT) ? 1 : 0; + + /* put flash back in read mode */ + *addr = (FPW) INTEL_RESET; + + return ret; +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + int flag, prot, sect; + ulong type, start, last; + int rcode = 0; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + type = (info->flash_id & FLASH_VENDMASK); + if ((type != FLASH_MAN_INTEL)) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + start = get_timer (0); + last = start; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + FPWV *addr = (FPWV *) (info->start[sect]); + FPW status; + + printf ("Erasing sector %2d ... ", sect); + + /* arm simple, non interrupt dependent timer */ + start = get_timer(0); + + *addr = (FPW) 0x00500050; /* clear status register */ + *addr = (FPW) 0x00200020; /* erase setup */ + *addr = (FPW) 0x00D000D0; /* erase confirm */ + + while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { + if (get_timer(start) > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + *addr = (FPW) 0x00B000B0; /* suspend erase */ + *addr = (FPW) 0x00FF00FF; /* reset to read mode */ + rcode = 1; + break; + } + } + + *addr = 0x00500050; /* clear status register cmd. */ + *addr = 0x00FF00FF; /* resest to read mode */ + + printf (" done\n"); + } + } + return rcode; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - Flash not identified + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp; + FPW data; + int count, i, l, rc, port_width; + + if (info->flash_id == FLASH_UNKNOWN) { + return 4; + } +/* get lower word aligned address */ +#ifdef FLASH_PORT_WIDTH16 + wp = (addr & ~1); + port_width = 2; +#else + wp = (addr & ~3); + port_width = 4; +#endif + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + for (; i < port_width && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt == 0 && i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + if ((rc = write_data (info, wp, SWAP (data))) != 0) { + return (rc); + } + wp += port_width; + } + + /* + * handle word aligned part + */ + count = 0; + while (cnt >= port_width) { + data = 0; + for (i = 0; i < port_width; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_data (info, wp, SWAP (data))) != 0) { + return (rc); + } + wp += port_width; + cnt -= port_width; + if (count++ > 0x800) { + spin_wheel (); + count = 0; + } + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + return (write_data (info, wp, SWAP (data))); +} + +/*----------------------------------------------------------------------- + * Write a word or halfword to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_data (flash_info_t *info, ulong dest, FPW data) +{ + FPWV *addr = (FPWV *) dest; + ulong status; + ulong start; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & data) != data) { + printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr); + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + *addr = (FPW) 0x00400040; /* write setup */ + *addr = data; + + /* arm simple, non interrupt dependent timer */ + start = get_timer(0); + + /* wait while polling the status register */ + while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + *addr = (FPW) 0x00FF00FF; /* restore read mode */ + return (1); + } + } + + *addr = (FPW) 0x00FF00FF; /* restore read mode */ + + return (0); +} + +void inline spin_wheel (void) +{ + static int p = 0; + static char w[] = "\\/-"; + + printf ("\010%c", w[p]); + (++p == 3) ? (p = 0) : 0; +} + +/*----------------------------------------------------------------------- + * Set/Clear sector's lock bit, returns: + * 0 - OK + * 1 - Error (timeout, voltage problems, etc.) + */ +int flash_real_protect (flash_info_t *info, long sector, int prot) +{ + ulong start; + int i; + int rc = 0; + vu_long *addr = (vu_long *)(info->start[sector]); + int flag = disable_interrupts(); + + *addr = INTEL_CLEAR; /* Clear status register */ + if (prot) { /* Set sector lock bit */ + *addr = INTEL_LOCKBIT; /* Sector lock bit */ + *addr = INTEL_PROTECT; /* set */ + } + else { /* Clear sector lock bit */ + *addr = INTEL_LOCKBIT; /* All sectors lock bits */ + *addr = INTEL_CONFIRM; /* clear */ + } + + start = get_timer(0); + + while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) { + if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT) { + printf("Flash lock bit operation timed out\n"); + rc = 1; + break; + } + } + + if (*addr != INTEL_OK) { + printf("Flash lock bit operation failed at %08X, CSR=%08X\n", + (uint)addr, (uint)*addr); + rc = 1; + } + + if (!rc) + info->protect[sector] = prot; + + /* + * Clear lock bit command clears all sectors lock bits, so + * we have to restore lock bits of protected sectors. + * WARNING: code below re-locks sectors only for one bank (info). + * This causes problems on boards where several banks share + * the same chip, as sectors in othere banks will be unlocked + * but not re-locked. It works fine on pm520 though, as there + * is only one chip and one bank. + */ + if (!prot) + { + for (i = 0; i < info->sector_count; i++) + { + if (info->protect[i]) + { + start = get_timer(0); + addr = (vu_long *)(info->start[i]); + *addr = INTEL_LOCKBIT; /* Sector lock bit */ + *addr = INTEL_PROTECT; /* set */ + while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) + { + if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT) + { + printf("Flash lock bit operation timed out\n"); + rc = 1; + break; + } + } + } + } + /* + * get the s/w sector protection status in sync with the h/w, + * in case something went wrong during the re-locking. + */ + flash_sync_real_protect(info); /* resets flash to read mode */ + } + + if (flag) + enable_interrupts(); + + *addr = INTEL_RESET; /* Reset to read array mode */ + + return rc; +} diff --git a/board/mcc200/flash.h b/board/mcc200/flash.h new file mode 100644 index 0000000000..9dc5d04ff2 --- /dev/null +++ b/board/mcc200/flash.h @@ -0,0 +1,437 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, +8 * MA 02111-1307 USA + */ + +#ifndef _FLASH_H_ +#define _FLASH_H_ + +#ifndef CFG_NO_FLASH +/*----------------------------------------------------------------------- + * FLASH Info: contains chip specific data, per FLASH bank + */ + +typedef struct { + ulong size; /* total bank size in bytes */ + ushort sector_count; /* number of erase units */ + ulong flash_id; /* combined device & manufacturer code */ + ulong start[CFG_MAX_FLASH_SECT]; /* physical sector start addresses */ + uchar protect[CFG_MAX_FLASH_SECT]; /* sector protection status */ +#ifdef CFG_FLASH_CFI + uchar portwidth; /* the width of the port */ + uchar chipwidth; /* the width of the chip */ + ushort buffer_size; /* # of bytes in write buffer */ + ulong erase_blk_tout; /* maximum block erase timeout */ + ulong write_tout; /* maximum write timeout */ + ulong buffer_write_tout; /* maximum buffer write timeout */ + ushort vendor; /* the primary vendor id */ + ushort cmd_reset; /* Vendor specific reset command */ + ushort interface; /* used for x8/x16 adjustments */ +#endif +} flash_info_t; + +/* + * Values for the width of the port + */ +#define FLASH_CFI_8BIT 0x01 +#define FLASH_CFI_16BIT 0x02 +#define FLASH_CFI_32BIT 0x04 +#define FLASH_CFI_64BIT 0x08 +/* + * Values for the width of the chip + */ +#define FLASH_CFI_BY8 0x01 +#define FLASH_CFI_BY16 0x02 +#define FLASH_CFI_BY32 0x04 +#define FLASH_CFI_BY64 0x08 +/* convert between bit value and numeric value */ +#define CFI_FLASH_SHIFT_WIDTH 3 +/* + * Values for the flash device interface + */ +#define FLASH_CFI_X8 0x00 +#define FLASH_CFI_X16 0x01 +#define FLASH_CFI_X8X16 0x02 + +/* convert between bit value and numeric value */ +#define CFI_FLASH_SHIFT_WIDTH 3 +/* Prototypes */ + +extern unsigned long flash_init (void); +extern void flash_print_info (flash_info_t *); +extern int flash_erase (flash_info_t *, int, int); +extern int flash_sect_erase (ulong addr_first, ulong addr_last); +extern int flash_sect_protect (int flag, ulong addr_first, ulong addr_last); + +/* common/flash.c */ +extern void flash_protect (int flag, ulong from, ulong to, flash_info_t *info); +extern int flash_write (uchar *, ulong, ulong); +extern flash_info_t *addr2info (ulong); +extern int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt); + +/* board/?/flash.c */ +#if defined(CFG_FLASH_PROTECTION) +extern int flash_real_protect(flash_info_t *info, long sector, int prot); +extern void flash_read_user_serial(flash_info_t * info, void * buffer, int offset, int len); +extern void flash_read_factory_serial(flash_info_t * info, void * buffer, int offset, int len); +#endif /* CFG_FLASH_PROTECTION */ + +/*----------------------------------------------------------------------- + * return codes from flash_write(): + */ +#define ERR_OK 0 +#define ERR_TIMOUT 1 +#define ERR_NOT_ERASED 2 +#define ERR_PROTECTED 4 +#define ERR_INVAL 8 +#define ERR_ALIGN 16 +#define ERR_UNKNOWN_FLASH_VENDOR 32 +#define ERR_UNKNOWN_FLASH_TYPE 64 +#define ERR_PROG_ERROR 128 + +/*----------------------------------------------------------------------- + * Protection Flags for flash_protect(): + */ +#define FLAG_PROTECT_SET 0x01 +#define FLAG_PROTECT_CLEAR 0x02 + +/*----------------------------------------------------------------------- + * Device IDs + */ + +#define AMD_MANUFACT 0x00010001 /* AMD manuf. ID in D23..D16, D7..D0 */ +#define FUJ_MANUFACT 0x00040004 /* FUJITSU manuf. ID in D23..D16, D7..D0 */ +#define ATM_MANUFACT 0x001F001F /* ATMEL */ +#define STM_MANUFACT 0x00200020 /* STM (Thomson) manuf. ID in D23.. -"- */ +#define SST_MANUFACT 0x00BF00BF /* SST manuf. ID in D23..D16, D7..D0 */ +#define MT_MANUFACT 0x00890089 /* MT manuf. ID in D23..D16, D7..D0 */ +#define INTEL_MANUFACT 0x00890089 /* INTEL manuf. ID in D23..D16, D7..D0 */ +#define INTEL_ALT_MANU 0x00B000B0 /* alternate INTEL namufacturer ID */ +#define MX_MANUFACT 0x00C200C2 /* MXIC manuf. ID in D23..D16, D7..D0 */ +#define TOSH_MANUFACT 0x00980098 /* TOSHIBA manuf. ID in D23..D16, D7..D0 */ +#define MT2_MANUFACT 0x002C002C /* alternate MICRON manufacturer ID*/ +#define EXCEL_MANUFACT 0x004A004A /* Excel Semiconductor */ + + /* Micron Technologies (INTEL compat.) */ +#define MT_ID_28F400_T 0x44704470 /* 28F400B3 ID ( 4 M, top boot sector) */ +#define MT_ID_28F400_B 0x44714471 /* 28F400B3 ID ( 4 M, bottom boot sect) */ + +#define AMD_ID_LV040B 0x4F /* 29LV040B ID */ + /* 4 Mbit, 512K x 8, */ + /* 8 64K x 8 uniform sectors */ + +#define AMD_ID_F040B 0xA4 /* 29F040B ID */ + /* 4 Mbit, 512K x 8, */ + /* 8 64K x 8 uniform sectors */ +#define STM_ID_M29W040B 0xE3 /* M29W040B ID */ + /* 4 Mbit, 512K x 8, */ + /* 8 64K x 8 uniform sectors */ +#define AMD_ID_F080B 0xD5 /* 29F080 ID ( 1 M) */ + /* 8 Mbit, 512K x 16, */ + /* 8 64K x 16 uniform sectors */ +#define AMD_ID_F016D 0xAD /* 29F016 ID ( 2 M x 8) */ +#define AMD_ID_F032B 0x41 /* 29F032 ID ( 4 M x 8) */ +#define AMD_ID_LV116DT 0xC7 /* 29LV116DT ( 2 M x 8, top boot sect) */ +#define AMD_ID_LV116DB 0x4C /* 29LV116DB ( 2 M x 8, bottom boot sect) */ +#define AMD_ID_LV016B 0xc8 /* 29LV016 ID ( 2 M x 8) */ + +#define AMD_ID_PL160CB 0x22452245 /* 29PL160CB ID (16 M, bottom boot sect */ + +#define AMD_ID_LV400T 0x22B922B9 /* 29LV400T ID ( 4 M, top boot sector) */ +#define AMD_ID_LV400B 0x22BA22BA /* 29LV400B ID ( 4 M, bottom boot sect) */ + +#define AMD_ID_LV033C 0xA3 /* 29LV033C ID ( 4 M x 8) */ +#define AMD_ID_LV065D 0x93 /* 29LV065D ID ( 8 M x 8) */ + +#define AMD_ID_LV800T 0x22DA22DA /* 29LV800T ID ( 8 M, top boot sector) */ +#define AMD_ID_LV800B 0x225B225B /* 29LV800B ID ( 8 M, bottom boot sect) */ + +#define AMD_ID_LV160T 0x22C422C4 /* 29LV160T ID (16 M, top boot sector) */ +#define AMD_ID_LV160B 0x22492249 /* 29LV160B ID (16 M, bottom boot sect) */ + +#define AMD_ID_DL163T 0x22282228 /* 29DL163T ID (16 M, top boot sector) */ +#define AMD_ID_DL163B 0x222B222B /* 29DL163B ID (16 M, bottom boot sect) */ + +#define AMD_ID_LV320T 0x22F622F6 /* 29LV320T ID (32 M, top boot sector) */ +#define MX_ID_LV320T 0x22A722A7 /* 29LV320T by Macronix, AMD compatible */ +#define AMD_ID_LV320B 0x22F922F9 /* 29LV320B ID (32 M, bottom boot sect) */ +#define MX_ID_LV320B 0x22A822A8 /* 29LV320B by Macronix, AMD compatible */ + +#define AMD_ID_DL322T 0x22552255 /* 29DL322T ID (32 M, top boot sector) */ +#define AMD_ID_DL322B 0x22562256 /* 29DL322B ID (32 M, bottom boot sect) */ +#define AMD_ID_DL323T 0x22502250 /* 29DL323T ID (32 M, top boot sector) */ +#define AMD_ID_DL323B 0x22532253 /* 29DL323B ID (32 M, bottom boot sect) */ +#define AMD_ID_DL324T 0x225C225C /* 29DL324T ID (32 M, top boot sector) */ +#define AMD_ID_DL324B 0x225F225F /* 29DL324B ID (32 M, bottom boot sect) */ + +#define AMD_ID_DL640 0x227E227E /* 29DL640D ID (64 M, dual boot sectors)*/ +#define AMD_ID_MIRROR 0x227E227E /* 1st ID word for MirrorBit family */ +#define AMD_ID_DL640G_2 0x22022202 /* 2nd ID word for AM29DL640G at 0x38 */ +#define AMD_ID_DL640G_3 0x22012201 /* 3rd ID word for AM29DL640G at 0x3c */ +#define AMD_ID_LV640U_2 0x220C220C /* 2nd ID word for AM29LV640M at 0x38 */ +#define AMD_ID_LV640U_3 0x22012201 /* 3rd ID word for AM29LV640M at 0x3c */ +#define AMD_ID_LV640MT_2 0x22102210 /* 2nd ID word for AM29LV640MT at 0x38 */ +#define AMD_ID_LV640MT_3 0x22012201 /* 3rd ID word for AM29LV640MT at 0x3c */ +#define AMD_ID_LV640MB_2 0x22102210 /* 2nd ID word for AM29LV640MB at 0x38 */ +#define AMD_ID_LV640MB_3 0x22002200 /* 3rd ID word for AM29LV640MB at 0x3c */ +#define AMD_ID_LV128U_2 0x22122212 /* 2nd ID word for AM29LV128M at 0x38 */ +#define AMD_ID_LV128U_3 0x22002200 /* 3rd ID word for AM29LV128M at 0x3c */ +#define AMD_ID_LV256U_2 0x22122212 /* 2nd ID word for AM29LV256M at 0x38 */ +#define AMD_ID_LV256U_3 0x22012201 /* 3rd ID word for AM29LV256M at 0x3c */ +#define AMD_ID_GL064M_2 0x22132213 /* 2nd ID word for S29GL064M-R6 */ +#define AMD_ID_GL064M_3 0x22012201 /* 3rd ID word for S29GL064M-R6 */ + +#define AMD_ID_LV320B_2 0x221A221A /* 2d ID word for AM29LV320MB at 0x38 */ +#define AMD_ID_LV320B_3 0x22002200 /* 3d ID word for AM29LV320MB at 0x3c */ + +#define AMD_ID_LV640U 0x22D722D7 /* 29LV640U ID (64 M, uniform sectors) */ + +#define ATM_ID_BV1614 0x000000C0 /* 49BV1614 ID */ +#define ATM_ID_BV1614A 0x000000C8 /* 49BV1614A ID */ +#define ATM_ID_BV6416 0x000000D6 /* 49BV6416 ID */ + +#define FUJI_ID_29F800BA 0x22582258 /* MBM29F800BA ID (8M) */ +#define FUJI_ID_29F800TA 0x22D622D6 /* MBM29F800TA ID (8M) */ +#define FUJI_ID_29LV650UE 0x22d722d7 /* MBM29LV650UE/651UE ID (8M = 128 x 32kWord) */ + +#define SST_ID_xF200A 0x27892789 /* 39xF200A ID ( 2M = 128K x 16 ) */ +#define SST_ID_xF400A 0x27802780 /* 39xF400A ID ( 4M = 256K x 16 ) */ +#define SST_ID_xF800A 0x27812781 /* 39xF800A ID ( 8M = 512K x 16 ) */ +#define SST_ID_xF160A 0x27822782 /* 39xF800A ID (16M = 1M x 16 ) */ +#define SST_ID_xF1601 0x234B234B /* 39xF1601 ID (16M = 1M x 16 ) */ +#define SST_ID_xF1602 0x234A234A /* 39xF1602 ID (16M = 1M x 16 ) */ +#define SST_ID_xF3201 0x235B235B /* 39xF3201 ID (32M = 2M x 16 ) */ +#define SST_ID_xF3202 0x235A235A /* 39xF3202 ID (32M = 2M x 16 ) */ +#define SST_ID_xF6401 0x236B236B /* 39xF6401 ID (64M = 4M x 16 ) */ +#define SST_ID_xF6402 0x236A236A /* 39xF6402 ID (64M = 4M x 16 ) */ +#define SST_ID_xF040 0xBFD7BFD7 /* 39xF040 ID (512KB = 4Mbit x 8) */ + +#define STM_ID_F040B 0xE2 /* M29F040B ID ( 4M = 512K x 8 ) */ + /* 8 64K x 8 uniform sectors */ + +#define STM_ID_x800AB 0x005B005B /* M29W800AB ID (8M = 512K x 16 ) */ +#define STM_ID_29W320DT 0x22CA22CA /* M29W320DT ID (32 M, top boot sector) */ +#define STM_ID_29W320DB 0x22CB22CB /* M29W320DB ID (32 M, bottom boot sect) */ +#define STM_ID_29W040B 0x00E300E3 /* M29W040B ID (4M = 512K x 8) */ + +#define INTEL_ID_28F016S 0x66a066a0 /* 28F016S[VS] ID (16M = 512k x 16) */ +#define INTEL_ID_28F800B3T 0x88928892 /* 8M = 512K x 16 top boot sector */ +#define INTEL_ID_28F800B3B 0x88938893 /* 8M = 512K x 16 bottom boot sector */ +#define INTEL_ID_28F160B3T 0x88908890 /* 16M = 1M x 16 top boot sector */ +#define INTEL_ID_28F160B3B 0x88918891 /* 16M = 1M x 16 bottom boot sector */ +#define INTEL_ID_28F320B3T 0x88968896 /* 32M = 2M x 16 top boot sector */ +#define INTEL_ID_28F320B3B 0x88978897 /* 32M = 2M x 16 bottom boot sector */ +#define INTEL_ID_28F640B3T 0x88988898 /* 64M = 4M x 16 top boot sector */ +#define INTEL_ID_28F640B3B 0x88998899 /* 64M = 4M x 16 bottom boot sector */ +#define INTEL_ID_28F160F3B 0x88F488F4 /* 16M = 1M x 16 bottom boot sector */ + +#define INTEL_ID_28F800C3T 0x88C088C0 /* 8M = 512K x 16 top boot sector */ +#define INTEL_ID_28F800C3B 0x88C188C1 /* 8M = 512K x 16 bottom boot sector */ +#define INTEL_ID_28F160C3T 0x88C288C2 /* 16M = 1M x 16 top boot sector */ +#define INTEL_ID_28F160C3B 0x88C388C3 /* 16M = 1M x 16 bottom boot sector */ +#define INTEL_ID_28F320C3T 0x88C488C4 /* 32M = 2M x 16 top boot sector */ +#define INTEL_ID_28F320C3B 0x88C588C5 /* 32M = 2M x 16 bottom boot sector */ +#define INTEL_ID_28F640C3T 0x88CC88CC /* 64M = 4M x 16 top boot sector */ +#define INTEL_ID_28F640C3B 0x88CD88CD /* 64M = 4M x 16 bottom boot sector */ + +#define INTEL_ID_28F128J3 0x89188918 /* 16M = 8M x 16 x 128 */ +#define INTEL_ID_28F320J5 0x00140014 /* 32M = 128K x 32 */ +#define INTEL_ID_28F640J5 0x00150015 /* 64M = 128K x 64 */ +#define INTEL_ID_28F320J3A 0x00160016 /* 32M = 128K x 32 */ +#define INTEL_ID_28F640J3A 0x00170017 /* 64M = 128K x 64 */ +#define INTEL_ID_28F256L18 0x88108810 /* 32M = 128K x 255 */ +#define INTEL_ID_28F128J3A 0x00180018 /* 128M = 128K x 128 */ +#define INTEL_ID_28F256L18T 0x880D880D /* 256M = 128K x 255 + 32k x 4 */ +#define INTEL_ID_28F256L18B 0x88108810 /* 256M = 32k x 4 + 128K x 255 */ +#define INTEL_ID_28F256P30B 0x891C891C /* 256M = 32k x 4 + 128K x 255 */ +#define INTEL_ID_28F256P30T 0x89198919 /* 256M = 128K x 255 + 32k x 4 */ +#define INTEL_ID_28F64K3 0x88018801 /* 64M = 32K x 255 + 32k x 4 */ +#define INTEL_ID_28F128K3 0x88028802 /* 128M = 64K x 255 + 32k x 4 */ +#define INTEL_ID_28F256K3 0x88038803 /* 256M = 128K x 255 + 32k x 4 */ + +#define INTEL_ID_28F160S3 0x00D000D0 /* 16M = 512K x 32 (64kB x 32) */ +#define INTEL_ID_28F320S3 0x00D400D4 /* 32M = 512K x 64 (64kB x 64) */ + +/* Note that the Sharp 28F016SC is compatible with the Intel E28F016SC */ +#define SHARP_ID_28F016SCL 0xAAAAAAAA /* LH28F016SCT-L95 2Mx8, 32 64k blocks */ +#define SHARP_ID_28F016SCZ 0xA0A0A0A0 /* LH28F016SCT-Z4 2Mx8, 32 64k blocks */ +#define SHARP_ID_28F008SC 0xA6A6A6A6 /* LH28F008SCT-L12 1Mx8, 16 64k blocks */ + /* LH28F008SCR-L85 1Mx8, 16 64k blocks */ + +#define TOSH_ID_FVT160 0xC2 /* TC58FVT160 ID (16 M, top ) */ +#define TOSH_ID_FVB160 0x43 /* TC58FVT160 ID (16 M, bottom ) */ + +/*----------------------------------------------------------------------- + * Internal FLASH identification codes + * + * Be careful when adding new type! Odd numbers are "bottom boot sector" types! + */ + +#define FLASH_AM040 0x0001 /* AMD Am29F040B, Am29LV040B */ + /* Bright Micro BM29F040 */ + /* Fujitsu MBM29F040A */ + /* STM M29W040B */ + /* SGS Thomson M29F040B */ + /* 8 64K x 8 uniform sectors */ +#define FLASH_AM400T 0x0002 /* AMD AM29LV400 */ +#define FLASH_AM400B 0x0003 +#define FLASH_AM800T 0x0004 /* AMD AM29LV800 */ +#define FLASH_AM800B 0x0005 +#define FLASH_AM116DT 0x0026 /* AMD AM29LV116DT (2Mx8bit) */ +#define FLASH_AM116DB 0x0027 /* AMD AM29LV116DB (2Mx8bit) */ +#define FLASH_AM160T 0x0006 /* AMD AM29LV160 */ +#define FLASH_AM160LV 0x0046 /* AMD29LV160DB (2M = 2Mx8bit ) */ +#define FLASH_AM160B 0x0007 +#define FLASH_AM320T 0x0008 /* AMD AM29LV320 */ +#define FLASH_AM320B 0x0009 + +#define FLASH_AM080 0x000A /* AMD Am29F080B */ + /* 16 64K x 8 uniform sectors */ + +#define FLASH_AMDL322T 0x0010 /* AMD AM29DL322 */ +#define FLASH_AMDL322B 0x0011 +#define FLASH_AMDL323T 0x0012 /* AMD AM29DL323 */ +#define FLASH_AMDL323B 0x0013 +#define FLASH_AMDL324T 0x0014 /* AMD AM29DL324 */ +#define FLASH_AMDL324B 0x0015 + +#define FLASH_AMDLV033C 0x0018 +#define FLASH_AMDLV065D 0x001A + +#define FLASH_AMDL640 0x0016 /* AMD AM29DL640D */ +#define FLASH_AMD016 0x0018 /* AMD AM29F016D */ +#define FLASH_AMDL640MB 0x0019 /* AMD AM29LV640MB (64M, bottom boot sect)*/ +#define FLASH_AMDL640MT 0x001A /* AMD AM29LV640MT (64M, top boot sect) */ + +#define FLASH_SST200A 0x0040 /* SST 39xF200A ID ( 2M = 128K x 16 ) */ +#define FLASH_SST400A 0x0042 /* SST 39xF400A ID ( 4M = 256K x 16 ) */ +#define FLASH_SST800A 0x0044 /* SST 39xF800A ID ( 8M = 512K x 16 ) */ +#define FLASH_SST160A 0x0046 /* SST 39xF160A ID ( 16M = 1M x 16 ) */ +#define FLASH_SST320 0x0048 /* SST 39xF160A ID ( 16M = 1M x 16 ) */ +#define FLASH_SST640 0x004A /* SST 39xF160A ID ( 16M = 1M x 16 ) */ +#define FLASH_SST040 0x000E /* SST 39xF040 ID (512KB = 4Mbit x 8 ) */ + +#define FLASH_STM800AB 0x0051 /* STM M29WF800AB ( 8M = 512K x 16 ) */ +#define FLASH_STMW320DT 0x0052 /* STM M29W320DT (32 M, top boot sector) */ +#define FLASH_STMW320DB 0x0053 /* STM M29W320DB (32 M, bottom boot sect)*/ +#define FLASH_STM320DB 0x00CB /* STM M29W320DB (4M = 64K x 64, bottom)*/ +#define FLASH_STM800DT 0x00D7 /* STM M29W800DT (1M = 64K x 16, top) */ +#define FLASH_STM800DB 0x005B /* STM M29W800DB (1M = 64K x 16, bottom)*/ + +#define FLASH_28F400_T 0x0062 /* MT 28F400B3 ID ( 4M = 256K x 16 ) */ +#define FLASH_28F400_B 0x0063 /* MT 28F400B3 ID ( 4M = 256K x 16 ) */ + +#define FLASH_INTEL800T 0x0074 /* INTEL 28F800B3T ( 8M = 512K x 16 ) */ +#define FLASH_INTEL800B 0x0075 /* INTEL 28F800B3B ( 8M = 512K x 16 ) */ +#define FLASH_INTEL160T 0x0076 /* INTEL 28F160B3T ( 16M = 1 M x 16 ) */ +#define FLASH_INTEL160B 0x0077 /* INTEL 28F160B3B ( 16M = 1 M x 16 ) */ +#define FLASH_INTEL320T 0x0078 /* INTEL 28F320B3T ( 32M = 2 M x 16 ) */ +#define FLASH_INTEL320B 0x0079 /* INTEL 28F320B3B ( 32M = 2 M x 16 ) */ +#define FLASH_INTEL640T 0x007A /* INTEL 28F320B3T ( 64M = 4 M x 16 ) */ +#define FLASH_INTEL640B 0x007B /* INTEL 28F320B3B ( 64M = 4 M x 16 ) */ + +#define FLASH_28F008S5 0x0080 /* Intel 28F008S5 ( 1M = 64K x 16 ) */ +#define FLASH_28F016SV 0x0081 /* Intel 28F016SV ( 16M = 512k x 32 ) */ +#define FLASH_28F800_B 0x0083 /* Intel E28F800B ( 1M = ? ) */ +#define FLASH_AM29F800B 0x0084 /* AMD Am29F800BB ( 1M = ? ) */ +#define FLASH_28F320J5 0x0085 /* Intel 28F320J5 ( 4M = 128K x 32 ) */ +#define FLASH_28F160S3 0x0086 /* Intel 28F160S3 ( 16M = 512K x 32 ) */ +#define FLASH_28F320S3 0x0088 /* Intel 28F320S3 ( 32M = 512K x 64 ) */ +#define FLASH_AM640U 0x0090 /* AMD Am29LV640U ( 64M = 4M x 16 ) */ +#define FLASH_AM033C 0x0091 /* AMD AM29LV033 ( 32M = 4M x 8 ) */ +#define FLASH_LH28F016SCT 0x0092 /* Sharp 28F016SCT ( 8 Meg Flash SIMM ) */ +#define FLASH_28F160F3B 0x0093 /* Intel 28F160F3B ( 16M = 1M x 16 ) */ + +#define FLASH_28F640J5 0x0099 /* INTEL 28F640J5 ( 64M = 128K x 64) */ + +#define FLASH_28F800C3T 0x009A /* Intel 28F800C3T ( 8M = 512K x 16 ) */ +#define FLASH_28F800C3B 0x009B /* Intel 28F800C3B ( 8M = 512K x 16 ) */ +#define FLASH_28F160C3T 0x009C /* Intel 28F160C3T ( 16M = 1M x 16 ) */ +#define FLASH_28F160C3B 0x009D /* Intel 28F160C3B ( 16M = 1M x 16 ) */ +#define FLASH_28F320C3T 0x009E /* Intel 28F320C3T ( 32M = 2M x 16 ) */ +#define FLASH_28F320C3B 0x009F /* Intel 28F320C3B ( 32M = 2M x 16 ) */ +#define FLASH_28F640C3T 0x00A0 /* Intel 28F640C3T ( 64M = 4M x 16 ) */ +#define FLASH_28F640C3B 0x00A1 /* Intel 28F640C3B ( 64M = 4M x 16 ) */ +#define FLASH_AMLV320U 0x00A2 /* AMD 29LV320M ( 32M = 2M x 16 ) */ +#define FLASH_AMLV640U 0x00A4 /* AMD 29LV640M ( 64M = 4M x 16 ) */ +#define FLASH_AMLV128U 0x00A6 /* AMD 29LV128M ( 128M = 8M x 16 ) */ +#define FLASH_AMLV320B 0x00A7 /* AMD 29LV320MB ( 32M = 2M x 16 ) */ +#define FLASH_AMLV320T 0x00A8 /* AMD 29LV320MT ( 32M = 2M x 16 ) */ +#define FLASH_AMLV256U 0x00AA /* AMD 29LV256M ( 256M = 16M x 16 ) */ +#define FLASH_MXLV320B 0x00AB /* MX 29LV320MB ( 32M = 2M x 16 ) */ +#define FLASH_MXLV320T 0x00AC /* MX 29LV320MT ( 32M = 2M x 16 ) */ +#define FLASH_28F256L18T 0x00B0 /* Intel 28F256L18T ( 32M = 128K x 255 + 32k x 4) */ +#define FLASH_28F256L18B 0x00B1 /* Intel 28F256L18B ( 32M = 32k x 4 + 128K x 255) */ +#define FLASH_28F256P30B 0x001C /* Intel 28F256P30B ( 32M = 32k x 4 + 128K x 255) */ +#define FLASH_28F256P30T 0x0019 /* Intel 28F256P30T ( 128K x 255 + 32M = 32k x 4 + */ +#define FLASH_AMDL163T 0x00B2 /* AMD AM29DL163T (2M x 16 ) */ +#define FLASH_AMDL163B 0x00B3 +#define FLASH_28F64K3 0x00B4 /* Intel 28F64K3 ( 64M) */ +#define FLASH_28F128K3 0x00B6 /* Intel 28F128K3 ( 128M = 8M x 16 ) */ +#define FLASH_28F256K3 0x00B8 /* Intel 28F256K3 ( 256M = 16M x 16 ) */ + +#define FLASH_28F320J3A 0x00C0 /* INTEL 28F320J3A ( 32M = 128K x 32) */ +#define FLASH_28F640J3A 0x00C2 /* INTEL 28F640J3A ( 64M = 128K x 64) */ +#define FLASH_28F128J3A 0x00C4 /* INTEL 28F128J3A (128M = 128K x 128) */ + +#define FLASH_FUJLV650 0x00D0 /* Fujitsu MBM 29LV650UE/651UE */ +#define FLASH_MT28S4M16LC 0x00E1 /* Micron MT28S4M16LC */ +#define FLASH_S29GL064M 0x00F0 /* Spansion S29GL064M-R6 */ + +#define FLASH_UNKNOWN 0xFFFF /* unknown flash type */ + + +/* manufacturer offsets + */ +#define FLASH_MAN_AMD 0x00000000 /* AMD */ +#define FLASH_MAN_FUJ 0x00010000 /* Fujitsu */ +#define FLASH_MAN_BM 0x00020000 /* Bright Microelectronics */ +#define FLASH_MAN_MX 0x00030000 /* MXIC */ +#define FLASH_MAN_STM 0x00040000 +#define FLASH_MAN_TOSH 0x00050000 /* Toshiba */ +#define FLASH_MAN_EXCEL 0x00060000 /* Excel Semiconductor */ +#define FLASH_MAN_SST 0x00100000 +#define FLASH_MAN_INTEL 0x00300000 +#define FLASH_MAN_MT 0x00400000 +#define FLASH_MAN_SHARP 0x00500000 + + +#define FLASH_TYPEMASK 0x0000FFFF /* extract FLASH type information */ +#define FLASH_VENDMASK 0xFFFF0000 /* extract FLASH vendor information */ + +#define FLASH_AMD_COMP 0x000FFFFF /* Up to this ID, FLASH is compatible */ + /* with AMD, Fujitsu and SST */ + /* (JEDEC standard commands ?) */ + +#define FLASH_BTYPE 0x0001 /* mask for bottom boot sector type */ + +/*----------------------------------------------------------------------- + * Timeout constants: + * + * We can't find any specifications for maximum chip erase times, + * so these values are guestimates. + */ +#define FLASH_ERASE_TIMEOUT 120000 /* timeout for erasing in ms */ +#define FLASH_WRITE_TIMEOUT 500 /* timeout for writes in ms */ + +#endif /* !CFG_NO_FLASH */ + +#endif /* _FLASH_H_ */ diff --git a/board/mcc200/mcc200.c b/board/mcc200/mcc200.c new file mode 100644 index 0000000000..dd2e1916e0 --- /dev/null +++ b/board/mcc200/mcc200.c @@ -0,0 +1,328 @@ +/* + * (C) Copyright 2003-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2004 + * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +//###CHD: es gibt eigentlich kein DDR bei uns -> weg damit!; dto. PCI! +#if defined(CONFIG_MPC5200_DDR) +#include "mt46v16m16-75.h" +#else +//#include "mt48lc16m16a2-75.h" +#include "mt48lc8m32b2-6-7.h" +#endif + +//###CHD: wenn RAMBOOT gehen wuerde, .... +#ifndef CFG_RAMBOOT +static void sdram_start (int hi_addr) +{ + long hi_addr_bit = hi_addr ? 0x01000000 : 0; + + /* unlock mode register */ + *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit; + __asm__ volatile ("sync"); + + /* precharge all banks */ + *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit; + __asm__ volatile ("sync"); + +#if SDRAM_DDR + /* set mode register: extended mode */ + *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE; + __asm__ volatile ("sync"); + + /* set mode register: reset DLL */ + *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000; + __asm__ volatile ("sync"); +#endif + + /* precharge all banks */ + *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit; + __asm__ volatile ("sync"); + + /* auto refresh */ + *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit; + __asm__ volatile ("sync"); + + /* set mode register */ + *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE; + __asm__ volatile ("sync"); + + /* normal operation */ + *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit; + __asm__ volatile ("sync"); +} +#endif + +/* + * ATTENTION: Although partially referenced initdram does NOT make real use + * use of CFG_SDRAM_BASE. The code does not work if CFG_SDRAM_BASE + * is something else than 0x00000000. + */ + +#if defined(CONFIG_MPC5200) +long int initdram (int board_type) +{ + ulong dramsize = 0; + ulong dramsize2 = 0; +#ifndef CFG_RAMBOOT + ulong test1, test2; + + /* setup SDRAM chip selects */ + *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */ + *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */ + __asm__ volatile ("sync"); + + /* setup config registers */ + *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1; + *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2; + __asm__ volatile ("sync"); + +#if SDRAM_DDR + /* set tap delay */ + *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY; + __asm__ volatile ("sync"); +#endif + + /* find RAM size using SDRAM CS0 only */ + sdram_start(0); + test1 = get_ram_size((long *)CFG_SDRAM_BASE, 0x80000000); + sdram_start(1); + test2 = get_ram_size((long *)CFG_SDRAM_BASE, 0x80000000); + if (test1 > test2) { + sdram_start(0); + dramsize = test1; + } else { + dramsize = test2; + } + + /* memory smaller than 1MB is impossible */ + if (dramsize < (1 << 20)) { + dramsize = 0; + } + + /* set SDRAM CS0 size according to the amount of RAM found */ + if (dramsize > 0) { + *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 + __builtin_ffs(dramsize >> 20) - 1; + } else { + *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */ + } + + /* let SDRAM CS1 start right after CS0 */ + *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */ + + /* find RAM size using SDRAM CS1 only */ + if (!dramsize) + sdram_start(0); + test2 = test1 = get_ram_size((long *)(CFG_SDRAM_BASE + dramsize), 0x80000000); + if (!dramsize) { + sdram_start(1); + test2 = get_ram_size((long *)(CFG_SDRAM_BASE + dramsize), 0x80000000); + } + if (test1 > test2) { + sdram_start(0); + dramsize2 = test1; + } else { + dramsize2 = test2; + } + + /* memory smaller than 1MB is impossible */ + if (dramsize2 < (1 << 20)) { + dramsize2 = 0; + } + + /* set SDRAM CS1 size according to the amount of RAM found */ + if (dramsize2 > 0) { + *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1); + } else { + *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */ + } + +#else /* CFG_RAMBOOT */ + + /* retrieve size of memory connected to SDRAM CS0 */ + dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF; + if (dramsize >= 0x13) { + dramsize = (1 << (dramsize - 0x13)) << 20; + } else { + dramsize = 0; + } + + /* retrieve size of memory connected to SDRAM CS1 */ + dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF; + if (dramsize2 >= 0x13) { + dramsize2 = (1 << (dramsize2 - 0x13)) << 20; + } else { + dramsize2 = 0; + } + +#endif /* CFG_RAMBOOT */ + + return dramsize + dramsize2; +} + +//###CHD: sowas gibt es bei usn nicht! +#elif defined(CONFIG_MGT5100) + +long int initdram (int board_type) +{ + ulong dramsize = 0; +#ifndef CFG_RAMBOOT + ulong test1, test2; + + /* setup and enable SDRAM chip selects */ + *(vu_long *)MPC5XXX_SDRAM_START = 0x00000000; + *(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */ + *(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */ + __asm__ volatile ("sync"); + + /* setup config registers */ + *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1; + *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2; + + /* address select register */ + *(vu_long *)MPC5XXX_SDRAM_XLBSEL = SDRAM_ADDRSEL; + __asm__ volatile ("sync"); + + /* find RAM size */ + sdram_start(0); + test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x80000000); + sdram_start(1); + test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x80000000); + if (test1 > test2) { + sdram_start(0); + dramsize = test1; + } else { + dramsize = test2; + } + + /* set SDRAM end address according to size */ + *(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15); + +#else /* CFG_RAMBOOT */ + + /* Retrieve amount of SDRAM available */ + dramsize = ((*(vu_long *)MPC5XXX_SDRAM_STOP + 1) << 15); + +#endif /* CFG_RAMBOOT */ + + return dramsize; +} + +#else +#error Neither CONFIG_MPC5200 or CONFIG_MGT5100 defined +#endif + +int checkboard (void) +{ + puts("Board: Bluetechnix DevMPC5200Leica \n"); +/* +#if defined(CONFIG_MPC5200) + puts ("Board: MicroSys PM520 \n"); +#elif defined(CONFIG_MGT5100) + puts ("Board: MicroSys PM510 \n"); +#endif*/ + return 0; +} + +void flash_preinit(void) +{ + /* + * Now, when we are in RAM, enable flash write + * access for detection process. + * Note that CS_BOOT cannot be cleared when + * executing in flash. + */ +#if defined(CONFIG_MGT5100) + *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */ + *(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */ +#endif + *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */ +} + +void flash_afterinit(ulong start, ulong size) +{ +#if defined(CONFIG_BOOT_ROM) + /* adjust mapping */ + *(vu_long *)MPC5XXX_CS1_START = + START_REG(start); + *(vu_long *)MPC5XXX_CS1_STOP = + STOP_REG(start, size); +#else + /* adjust mapping */ + *(vu_long *)MPC5XXX_BOOTCS_START = *(vu_long *)MPC5XXX_CS0_START = + START_REG(start); + *(vu_long *)MPC5XXX_BOOTCS_STOP = *(vu_long *)MPC5XXX_CS0_STOP = + STOP_REG(start, size); +#endif +} + + +extern flash_info_t flash_info[]; /* info for FLASH chips */ + +int misc_init_r (void) +{ + DECLARE_GLOBAL_DATA_PTR; + /* adjust flash start */ + gd->bd->bi_flashstart = flash_info[0].start[0]; + return (0); +} + +#ifdef CONFIG_PCI +static struct pci_controller hose; + +extern void pci_mpc5xxx_init(struct pci_controller *); + +void pci_init_board(void) +{ + pci_mpc5xxx_init(&hose); +} +#endif + +#if defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) + +void init_ide_reset (void) +{ + debug ("init_ide_reset\n"); + +} + +void ide_set_reset (int idereset) +{ + debug ("ide_reset(%d)\n", idereset); + +} +#endif /* defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) */ + +#if (CONFIG_COMMANDS & CFG_CMD_DOC) +extern void doc_probe (ulong physadr); +void doc_init (void) +{ + doc_probe (CFG_DOC_BASE); +} +#endif diff --git a/board/mcc200/mt46v16m16-75.h b/board/mcc200/mt46v16m16-75.h new file mode 100644 index 0000000000..f650faaa10 --- /dev/null +++ b/board/mcc200/mt46v16m16-75.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2004 + * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#define SDRAM_DDR 1 /* is DDR */ + +#if defined(CONFIG_MPC5200) +/* Settings for XLB = 132 MHz */ +#define SDRAM_MODE 0x018D0000 +#define SDRAM_EMODE 0x40090000 +#define SDRAM_CONTROL 0x714f0f00 +#define SDRAM_CONFIG1 0x73722930 +#define SDRAM_CONFIG2 0x47770000 +#define SDRAM_TAPDELAY 0x10000000 + +#else +#error CONFIG_MPC5200 not defined +#endif diff --git a/board/mcc200/mt48lc16m16a2-75.h b/board/mcc200/mt48lc16m16a2-75.h new file mode 100644 index 0000000000..ffdf0396a5 --- /dev/null +++ b/board/mcc200/mt48lc16m16a2-75.h @@ -0,0 +1,43 @@ +/* + * (C) Copyright 2004 + * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#define SDRAM_DDR 0 /* is SDR */ + +#if defined(CONFIG_MPC5200) +/* Settings for XLB = 132 MHz */ +#define SDRAM_MODE 0x00CD0000 +#define SDRAM_CONTROL 0x504F0000 +#define SDRAM_CONFIG1 0xD2322800 +#define SDRAM_CONFIG2 0x8AD70000 + +#elif defined(CONFIG_MGT5100) +/* Settings for XLB = 66 MHz */ +#define SDRAM_MODE 0x008D0000 +#define SDRAM_CONTROL 0x504F0000 +#define SDRAM_CONFIG1 0xC2222600 +#define SDRAM_CONFIG2 0x88B70004 +#define SDRAM_ADDRSEL 0x02000000 + +#else +#error Neither CONFIG_MPC5200 or CONFIG_MGT5100 defined +#endif diff --git a/board/mcc200/mt48lc8m32b2-6-7.h b/board/mcc200/mt48lc8m32b2-6-7.h new file mode 100644 index 0000000000..6c2b2b3b36 --- /dev/null +++ b/board/mcc200/mt48lc8m32b2-6-7.h @@ -0,0 +1,30 @@ +/* + * Configuration Registers for the MT48LC8M32B2 SDRAM on the MPC5200 platform + */ + +#define SDRAM_DDR 0 /* is SDR */ + +#if defined(CONFIG_MPC5200) +/* Settings for XLB = 132 MHz */ +//#define SDRAM_MODE 0x00cc0000 // CL-3 BURST-8 -> Mode Register—MBAR + 0x0100 +//#define SDRAM_CONTROL 0x501f0000 // Control Register—MBAR + 0x0104 +//#define SDRAM_CONFIG1 0xe2329000 // Delays between commands -> Configuration Register 1—MBAR + 0x0108 +//#define SDRAM_CONFIG2 0x46e70000 // Delays between commands -> Configuration Register 2—MBAR + 0x010C + +//Christian +//#define SDRAM_MODE 0x00cd0000 // CL-3 BURST-8 -> Mode Register—MBAR + 0x0100 +//#define SDRAM_CONTROL 0x501f0000 // Control Register—MBAR + 0x0104 +//#define SDRAM_CONFIG1 0xd2322900 // Delays between commands -> Configuration Register 1—MBAR + 0x0108 +//#define SDRAM_CONFIG2 0x8ad70000 // Delays between commands -> Configuration Register 2—MBAR + 0x010C + +//###CHD: ordentliche Doku dazu! CAS=2, etc. +//STefan +#define SDRAM_MODE 0x008d0000 // CL-3 BURST-8 -> Mode Register—MBAR + 0x0100 +#define SDRAM_CONTROL 0x504f0000 // Control Register—MBAR + 0x0104 +#define SDRAM_CONFIG1 0xc2222900 // Delays between commands -> Configuration Register 1—MBAR + 0x0108 +#define SDRAM_CONFIG2 0x88c70000 // Delays between commands -> Configuration Register 2—MBAR + 0x010C + + +#else +#error CONFIG_MPC5200 not defined, please set parameters for your sdram controller in mt48lc8m32b2.h +#endif diff --git a/board/mcc200/u-boot.lds b/board/mcc200/u-boot.lds new file mode 100644 index 0000000000..4fdea6b783 --- /dev/null +++ b/board/mcc200/u-boot.lds @@ -0,0 +1,125 @@ +/* + * (C) Copyright 2003-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + cpu/mpc5xxx/start.o (.text) + *(.text) + *(.fixup) + *(.got1) + . = ALIGN(16); + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c index 86c8ce6879..2e8e54958f 100644 --- a/cpu/mpc5xxx/fec.c +++ b/cpu/mpc5xxx/fec.c @@ -880,8 +880,9 @@ int mpc5xxx_fec_initialize(bd_t * bis) fec->rbdBase = (FEC_RBD *)(FEC_BD_BASE + FEC_TBD_NUM * sizeof(FEC_TBD)); #if defined(CONFIG_CANMB) || defined(CONFIG_HMI1001) || \ defined(CONFIG_ICECUBE) || defined(CONFIG_INKA4X0) || \ + defined(CONFIG_MCC200) || defined(CONFIG_O2DNT) || \ defined(CONFIG_PM520) || defined(CONFIG_TOP5200) || \ - defined(CONFIG_TQM5200) || defined(CONFIG_O2DNT) + defined(CONFIG_TQM5200) # ifndef CONFIG_FEC_10MBIT fec->xcv_type = MII100; # else diff --git a/include/configs/mcc200.h b/include/configs/mcc200.h new file mode 100644 index 0000000000..5f1fd8895a --- /dev/null +++ b/include/configs/mcc200.h @@ -0,0 +1,402 @@ +/* + * (C) Copyright 2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ + +#define CONFIG_MPC5200 +#define CONFIG_MPC5xxx 1 /* This is an MPC5xxx CPU */ +#define CONFIG_MCC200 1 /* ... on MCC200 board */ + +#define CFG_MPC5XXX_CLKIN 33000000 /* ... running at 33MHz */ + +#define CONFIG_MISC_INIT_R + +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#define CFG_CACHELINE_SIZE 32 /* For MPC5xxx CPUs */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ +#endif + +/* + * Serial console configuration + */ +#define CONFIG_PSC_CONSOLE 1 /* console is on PSC1 */ +#define CONFIG_BAUDRATE 115200 +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 230400 } + + +//###CHD: MPC5100 gibt es nicht -> weg damit! +#ifdef CONFIG_MPC5200 /* MPC5100 PCI is not supported yet. */ +/* + * PCI Mapping: + * 0x40000000 - 0x4fffffff - PCI Memory + * 0x50000000 - 0x50ffffff - PCI IO Space + */ +//Wenn geht PCI raus! +#define CONFIG_PCI 1 +#define CONFIG_PCI_PNP 1 +#define CONFIG_PCI_SCAN_SHOW 1 +#undef CONFIG_PCI_SCAN_SHOW + +#define CONFIG_PCI_MEM_BUS 0x40000000 +#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS +#define CONFIG_PCI_MEM_SIZE 0x10000000 + +#define CONFIG_PCI_IO_BUS 0x50000000 +#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS +#define CONFIG_PCI_IO_SIZE 0x01000000 + +#define CONFIG_NET_MULTI 1 +#define CONFIG_MII 1 +#define CONFIG_EEPRO100 1 +#define CFG_RX_ETH_BUFFER 8 /* use 8 rx buffer on eepro100 */ +#undef CONFIG_NS8382X + +#define ADD_PCI_CMD CFG_CMD_PCI + +#else /* MPC5100 */ + +#define ADD_PCI_CMD 0 /* no CFG_CMD_PCI */ + +#endif + +/* Partitions */ +#define CONFIG_DOS_PARTITION + +/* USB */ +#if 1 +#define CONFIG_USB_OHCI +#define ADD_USB_CMD CFG_CMD_USB | CFG_CMD_FAT +#define CONFIG_USB_STORAGE +#else +#define ADD_USB_CMD 0 +#endif + +//###CHD: BOOTROm raus! +#if defined(CONFIG_BOOT_ROM) +#define ADD_DOC_CMD 0 +#else +#define ADD_DOC_CMD CFG_CMD_DOC +#endif + +/* + * Supported commands + */ +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ + ADD_DOC_CMD | \ + ADD_PCI_CMD | \ + ADD_USB_CMD | \ + CFG_CMD_BEDBUG | \ + CFG_CMD_DATE | \ + CFG_CMD_DHCP | \ + CFG_CMD_EEPROM | \ + CFG_CMD_FAT | \ + CFG_CMD_I2C | \ + CFG_CMD_IDE | \ + CFG_CMD_NFS | \ + CFG_CMD_SNTP ) + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +/* + * Autobooting + */ +#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ + +#define CONFIG_PREBOOT "echo;" \ + "echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \ + "echo" + +#undef CONFIG_BOOTARGS + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "netdev=eth0\0" \ + "hostname=lmpc\0" \ + "nfsargs=setenv bootargs root=/dev/nfs rw " \ + "nfsroot=${serverip}:${rootpath}\0" \ + "ramargs=setenv bootargs root=/dev/ram rw\0" \ + "addip=setenv bootargs ${bootargs} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \ + ":${hostname}:${netdev}:off panic=1\0" \ + "flash_nfs=run nfsargs addip;" \ + "bootm ${kernel_addr}\0" \ + "flash_self=run ramargs addip;" \ + "bootm ${kernel_addr} ${ramdisk_addr}\0" \ + "net_nfs=tftp 200000 ${bootfile};run nfsargs addip;bootm\0" \ + "rootpath=/opt/eldk30/ppc_82xx\0" \ + "bootfile=/tftpboot/LMPC/uImage\0" \ + "baudrate=115200\0" \ + "serverip=192.168.0.1\0" \ + "ipaddr=192.168.0.2\0" \ + "ethaddr=00:02:44:7d:73:3b\0" \ + "" + +#define CONFIG_BOOTCOMMAND "run flash_self" + +#if defined(CONFIG_MPC5200) +/* + * IPB Bus clocking configuration. + */ +#undef CFG_IPBSPEED_133 /* define for 133MHz speed */ +#endif + +//###CHD: EEProm config RTC config sollte raus, gibt es nciht bei uns auf I2C! +/* + * I2C configuration + */ +#define CONFIG_HARD_I2C 1 /* I2C with hardware support */ +#define CFG_I2C_MODULE 2 /* Select I2C module #1 or #2 */ + +#define CFG_I2C_SPEED 100000 /* 100 kHz */ +#define CFG_I2C_SLAVE 0x7F + +/* + * EEPROM configuration + */ +#define CFG_I2C_EEPROM_ADDR 0x58 +#define CFG_I2C_EEPROM_ADDR_LEN 1 +#define CFG_EEPROM_PAGE_WRITE_BITS 4 +#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 + +/* + * RTC configuration + */ +#define CONFIG_RTC_PCF8563 +#define CFG_I2C_RTC_ADDR 0x51 + +//###CHD: meiner Ansicht nach auch raus! +/* + * Disk-On-Chip configuration + */ + +#define CFG_DOC_SHORT_TIMEOUT +#define CFG_MAX_DOC_DEVICE 1 /* Max number of DOC devices */ + +#define CFG_DOC_SUPPORT_2000 +#define CFG_DOC_SUPPORT_MILLENNIUM +#define CFG_DOC_BASE 0xE0000000 +#define CFG_DOC_SIZE 0x00100000 + +//###CHD: BOOTROm raus! +#if defined(CONFIG_BOOT_ROM) +/* + * Flash configuration (8,16 or 32 MB) + * TEXT base always at 0xFFF00000 + * ENV_ADDR always at 0xFFF40000 + * FLASH_BASE at 0xFC000000 for 32 MB + * 0xFD000000 for 16 MB + * 0xFD800000 for 8 MB + */ +#define CFG_FLASH_BASE 0xfc000000 +#define CFG_FLASH_SIZE 0x02000000 +#define CFG_BOOTROM_BASE 0xFFF00000 +#define CFG_BOOTROM_SIZE 0x00080000 +#define CFG_ENV_ADDR (0xFDF00000 + 0x40000) +#else +/* + * Flash configuration (8,16 or 32 MB) + * TEXT base always at 0xFFF00000 + * ENV_ADDR always at 0xFFF40000 + * FLASH_BASE at 0xFE000000 for 32 MB + * 0xFF000000 for 16 MB + * 0xFF800000 for 8 MB + */ +#define CFG_FLASH_BASE 0xfe000000 +#define CFG_FLASH_SIZE 0x02000000 +#define CFG_ENV_ADDR (0xFFF00000 + 0x40000) +#endif +#define CFG_MAX_FLASH_BANKS 1 /* max num of memory banks */ + +#define CFG_MAX_FLASH_SECT 128 /* max num of sects on one chip */ + +#define CFG_FLASH_ERASE_TOUT 240000 /* Flash Erase Timeout (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (in ms) */ +#define CFG_FLASH_LOCK_TOUT 5 /* Timeout for Flash Set Lock Bit (in ms) */ +#define CFG_FLASH_UNLOCK_TOUT 10000 /* Timeout for Flash Clear Lock Bits (in ms) */ +#define CFG_FLASH_PROTECTION /* "Real" (hardware) sectors protection */ + +#define PHYS_FLASH_SECT_SIZE 0x00040000 /* 256 KB sectors (x2) */ + +#undef CONFIG_FLASH_16BIT /* Flash is 32-bit */ + + +/* + * Environment settings + */ +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_ENV_SIZE 0x10000 +#define CFG_ENV_SECT_SIZE 0x40000 +#define CONFIG_ENV_OVERWRITE 1 + +/* + * Memory map + */ +#define CFG_MBAR 0xf0000000 +#define CFG_SDRAM_BASE 0x00000000 +#define CFG_DEFAULT_MBAR 0x80000000 + +/* Use SRAM until RAM will be available */ +#define CFG_INIT_RAM_ADDR MPC5XXX_SRAM +#define CFG_INIT_RAM_END MPC5XXX_SRAM_SIZE /* End of used area in DPRAM */ + + +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +#define CFG_MONITOR_BASE TEXT_BASE +#if (CFG_MONITOR_BASE < CFG_FLASH_BASE) +# define CFG_RAMBOOT 1 +#endif + +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ + +/* + * Ethernet configuration + */ +#define CONFIG_MPC5xxx_FEC 1 +/* + * Define CONFIG_FEC_10MBIT to force FEC at 10Mb + */ +/* #define CONFIG_FEC_10MBIT 1 */ +#define CONFIG_PHY_ADDR 0x00 + +/* + * GPIO configuration + */ +//###CHD: MSB = 1 -> 64MB: funktioniert nicht: ERRATA - BUG? +//###CHD: 0x10000004 = 32MB SDRAM +//###CHD: 0x90000004 = 64MB SDRAM +#define CFG_GPS_PORT_CONFIG 0x10000004 + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x00100000 /* memtest works on */ +#define CFG_MEMTEST_END 0x00f00000 /* 1 ... 15 MB in DRAM */ + +#define CFG_LOAD_ADDR 0x100000 /* default load address */ + +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + +/* + * Various low-level settings + */ +#if defined(CONFIG_MPC5200) +#define CFG_HID0_INIT HID0_ICE | HID0_ICFI +#define CFG_HID0_FINAL HID0_ICE +#else +#define CFG_HID0_INIT 0 +#define CFG_HID0_FINAL 0 +#endif + +//###CHD: hier sollte das BOOT_ROM raus! +#if defined(CONFIG_BOOT_ROM) +#define CFG_BOOTCS_START CFG_BOOTROM_BASE +#define CFG_BOOTCS_SIZE CFG_BOOTROM_SIZE +#define CFG_BOOTCS_CFG 0x00047800 +#define CFG_CS0_START CFG_BOOTROM_BASE +#define CFG_CS0_SIZE CFG_BOOTROM_SIZE +#define CFG_CS1_START CFG_FLASH_BASE +#define CFG_CS1_SIZE CFG_FLASH_SIZE +#define CFG_CS1_CFG 0x0004fb00 +#else +#define CFG_BOOTCS_START CFG_FLASH_BASE +#define CFG_BOOTCS_SIZE CFG_FLASH_SIZE +#define CFG_BOOTCS_CFG 0x0004fb00 +#define CFG_CS0_START CFG_FLASH_BASE +#define CFG_CS0_SIZE CFG_FLASH_SIZE +#define CFG_CS1_START CFG_DOC_BASE +#define CFG_CS1_SIZE CFG_DOC_SIZE +#define CFG_CS1_CFG 0x00047800 +#endif + +#define CFG_CS_BURST 0x00000000 +#define CFG_CS_DEADCYCLE 0x33333333 + +#define CFG_RESET_ADDRESS 0xff000000 + +/*----------------------------------------------------------------------- + * USB stuff + *----------------------------------------------------------------------- + */ +#define CONFIG_USB_CLOCK 0x0001BBBB +#define CONFIG_USB_CONFIG 0x00005000 + +/*----------------------------------------------------------------------- + * IDE/ATA stuff Supports IDE harddisk + *----------------------------------------------------------------------- + */ + +//###CHD: eigentlich das ganze IDE zeugs raus (IDE wird derzeit nciht mehr gescannt!) +#undef CONFIG_IDE_8xx_PCCARD /* Use IDE with PC Card Adapter */ + +#undef CONFIG_IDE_8xx_DIRECT /* Direct IDE not supported */ +#undef CONFIG_IDE_LED /* LED for ide not supported */ + +#undef CONFIG_IDE_RESET /* reset for ide supported */ +#define CONFIG_IDE_PREINIT +#undef CONFIG_IDE_PREINIT + +#define CFG_IDE_MAXBUS 0 /* max. 1 IDE bus */ +#define CFG_IDE_MAXDEVICE 2 /* max. 2 drive per IDE bus */ + +#define CFG_ATA_IDE0_OFFSET 0x0000 + +#define CFG_ATA_BASE_ADDR MPC5XXX_ATA + +/* Offset for data I/O */ +#define CFG_ATA_DATA_OFFSET (0x0060) + +/* Offset for normal register accesses */ +#define CFG_ATA_REG_OFFSET (CFG_ATA_DATA_OFFSET) + +/* Offset for alternate registers */ +#define CFG_ATA_ALT_OFFSET (0x005C) + +/* Interval between registers */ +#define CFG_ATA_STRIDE 4 + +#endif /* __CONFIG_H */ From ff3c2a947889a9d60fc1c869565aa88b2e44b37b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Wed, 22 Feb 2006 14:05:44 +0100 Subject: [PATCH 016/102] SDRAM now working for delta board, but there are still aliasing problems, we only see 64MB. --- Makefile | 1 + board/delta/config.mk | 3 ++- board/delta/lowlevel_init.S | 31 ++++++++----------------------- include/configs/delta.h | 22 ++++++++++++---------- include/configs/zylonite.h | 4 ++-- 5 files changed, 25 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index 736ffb6a03..229f5760a1 100644 --- a/Makefile +++ b/Makefile @@ -1838,6 +1838,7 @@ clean: rm -f board/cray/L1/bootscript.c board/cray/L1/bootscript.image rm -f board/trab/trab_fkt board/voiceblue/eeprom rm -f board/integratorap/u-boot.lds board/integratorcp/u-boot.lds + rm -f u-boot.objdump-* clobber: clean find . -type f \( -name .depend \ diff --git a/board/delta/config.mk b/board/delta/config.mk index 09b0f71557..4b0fa679ee 100644 --- a/board/delta/config.mk +++ b/board/delta/config.mk @@ -1,4 +1,5 @@ #TEXT_BASE = 0x0 #TEXT_BASE = 0xa1700000 #TEXT_BASE = 0xa3080000 -TEXT_BASE = 0xa3008000 +#TEXT_BASE = 0xa3008000 +TEXT_BASE = 0x9ffe0000 diff --git a/board/delta/lowlevel_init.S b/board/delta/lowlevel_init.S index 35716f245e..66e75750bd 100644 --- a/board/delta/lowlevel_init.S +++ b/board/delta/lowlevel_init.S @@ -49,20 +49,6 @@ DRAM_SIZE: .long CFG_DRAM_SIZE bls 0b .endm - -#define SDRAM_CMD_NOP 0x40000000 - -.macro do_nop_cmd num - ldr r2, =MDMRS - ldr r3, =SDRAM_CMD_NOP - ldr r4, =0x0 -loop: - str r3, [r2] - add r4, r4, #1 - cmp r4, \num - bls loop -.endm - /* * Memory setup */ @@ -96,7 +82,7 @@ lowlevel_init: /* clocks to settle. Only necessary after hard reset... */ /* FIXME: can be optimized later */ /* ---------------------------------------------------------------- */ - wait #300 +; wait #300 mem_init: @@ -138,7 +124,7 @@ mem_init: /* Set MDMRS */ ldr r0, =MDMRS - ldr r1, =0x60000023 + ldr r1, =0x60000033 str r1, [r0] wait #300 @@ -269,13 +255,11 @@ mem_init: #endif /* NEW_SDRAM_INIT */ +#ifndef CFG_SKIP_DRAM_SCRUB /* scrub/init SDRAM if enabled/present */ -/* ldr r11, =0xa0000000 /\* base address of SDRAM (CFG_DRAM_BASE) *\/ */ -/* ldr r12, =0x04000000 /\* size of memory to scrub (CFG_DRAM_SIZE) *\/ */ -/* mov r8,r12 /\* save DRAM size (mk: why???) *\/ */ - ldr r8, =0xa0000000 /* base address of SDRAM (CFG_DRAM_BASE) */ - ldr r9, =0x04000000 /* size of memory to scrub (CFG_DRAM_SIZE) */ - mov r0, #0 /* scrub with 0x0000:0000 */ + ldr r8, =CFG_DRAM_BASE /* base address of SDRAM (CFG_DRAM_BASE) */ + ldr r9, =CFG_DRAM_SIZE /* size of memory to scrub (CFG_DRAM_SIZE) */ + mov r0, #0 /* scrub with 0x0000:0000 */ mov r1, #0 mov r2, #0 mov r3, #0 @@ -284,10 +268,11 @@ mem_init: mov r6, #0 mov r7, #0 10: /* fastScrubLoop */ - subs r9, r9, #32 // 32 bytes/line + subs r9, r9, #32 /* 8 words/line */ stmia r8!, {r0-r7} beq 15f b 10b +#endif /* CFG_SKIP_DRAM_SCRUB */ 15: /* Mask all interrupts */ diff --git a/include/configs/delta.h b/include/configs/delta.h index 7b923c22e9..786ed9a815 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -143,14 +143,14 @@ * Physical Memory Map */ #define CONFIG_NR_DRAM_BANKS 4 /* we have 2 banks of DRAM */ -#define PHYS_SDRAM_1 0xa0000000 /* SDRAM Bank #1 */ -#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */ -#define PHYS_SDRAM_2 0xa4000000 /* SDRAM Bank #2 */ -#define PHYS_SDRAM_2_SIZE 0x00000000 /* 0 MB */ -#define PHYS_SDRAM_3 0xa8000000 /* SDRAM Bank #3 */ -#define PHYS_SDRAM_3_SIZE 0x00000000 /* 0 MB */ -#define PHYS_SDRAM_4 0xac000000 /* SDRAM Bank #4 */ -#define PHYS_SDRAM_4_SIZE 0x00000000 /* 0 MB */ +#define PHYS_SDRAM_1 0x80000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE 0x8000000 /* 128 MB */ +#define PHYS_SDRAM_2 0x88000000 /* SDRAM Bank #2 */ +#define PHYS_SDRAM_2_SIZE 0x8000000 /* 128 MB */ +#define PHYS_SDRAM_3 0x90000000 /* SDRAM Bank #3 */ +#define PHYS_SDRAM_3_SIZE 0x8000000 /* 128 MB */ +#define PHYS_SDRAM_4 0x98000000 /* SDRAM Bank #4 */ +#define PHYS_SDRAM_4_SIZE 0x8000000 /* 128 MB */ #define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ #define PHYS_FLASH_2 0x04000000 /* Flash Bank #2 */ @@ -158,8 +158,10 @@ #define PHYS_FLASH_BANK_SIZE 0x02000000 /* 32 MB Banks */ #define PHYS_FLASH_SECT_SIZE 0x00040000 /* 256 KB sectors (x2) */ -#define CFG_DRAM_BASE 0xa0000000 -#define CFG_DRAM_SIZE 0x04000000 +#define CFG_DRAM_BASE 0x80000000 /* at CS0 */ +#define CFG_DRAM_SIZE 0x20000000 /* 512 MB Ram */ + +#define CFG_SKIP_DRAM_SCRUB 1 #define CFG_FLASH_BASE PHYS_FLASH_1 diff --git a/include/configs/zylonite.h b/include/configs/zylonite.h index a8ff9fdf4d..4232d504ee 100644 --- a/include/configs/zylonite.h +++ b/include/configs/zylonite.h @@ -120,8 +120,8 @@ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CFG_DEVICE_NULLDEV 1 -#define CFG_MEMTEST_START 0xa0400000 /* memtest works on */ -#define CFG_MEMTEST_END 0xa0800000 /* 4 ... 8 MB in DRAM */ +#define CFG_MEMTEST_START 0x9c000000 /* memtest works on */ +#define CFG_MEMTEST_END 0x9c400000 /* 4 ... 8 MB in DRAM */ #undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ From 599f52253ab38e1b9d3966279ce83e7816f1e5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Wed, 22 Feb 2006 17:48:43 +0100 Subject: [PATCH 017/102] SDRAM now working. --- board/delta/config.mk | 5 +++-- include/configs/delta.h | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/board/delta/config.mk b/board/delta/config.mk index 4b0fa679ee..d48fe054a0 100644 --- a/board/delta/config.mk +++ b/board/delta/config.mk @@ -1,5 +1,6 @@ #TEXT_BASE = 0x0 #TEXT_BASE = 0xa1700000 #TEXT_BASE = 0xa3080000 -#TEXT_BASE = 0xa3008000 -TEXT_BASE = 0x9ffe0000 +#TEXT_BASE = 0x9ffe0000 +TEXT_BASE = 0xa3008000 + diff --git a/include/configs/delta.h b/include/configs/delta.h index 786ed9a815..5b42069694 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -143,14 +143,14 @@ * Physical Memory Map */ #define CONFIG_NR_DRAM_BANKS 4 /* we have 2 banks of DRAM */ -#define PHYS_SDRAM_1 0x80000000 /* SDRAM Bank #1 */ -#define PHYS_SDRAM_1_SIZE 0x8000000 /* 128 MB */ -#define PHYS_SDRAM_2 0x88000000 /* SDRAM Bank #2 */ -#define PHYS_SDRAM_2_SIZE 0x8000000 /* 128 MB */ -#define PHYS_SDRAM_3 0x90000000 /* SDRAM Bank #3 */ -#define PHYS_SDRAM_3_SIZE 0x8000000 /* 128 MB */ -#define PHYS_SDRAM_4 0x98000000 /* SDRAM Bank #4 */ -#define PHYS_SDRAM_4_SIZE 0x8000000 /* 128 MB */ +#define PHYS_SDRAM_1 0xa0000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE 0x1000000 /* 64 MB */ +#define PHYS_SDRAM_2 0xa1000000 /* SDRAM Bank #2 */ +#define PHYS_SDRAM_2_SIZE 0x1000000 /* 64 MB */ +#define PHYS_SDRAM_3 0xa2000000 /* SDRAM Bank #3 */ +#define PHYS_SDRAM_3_SIZE 0x1000000 /* 64 MB */ +#define PHYS_SDRAM_4 0xa3000000 /* SDRAM Bank #4 */ +#define PHYS_SDRAM_4_SIZE 0x1000000 /* 64 MB */ #define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ #define PHYS_FLASH_2 0x04000000 /* Flash Bank #2 */ @@ -158,8 +158,8 @@ #define PHYS_FLASH_BANK_SIZE 0x02000000 /* 32 MB Banks */ #define PHYS_FLASH_SECT_SIZE 0x00040000 /* 256 KB sectors (x2) */ -#define CFG_DRAM_BASE 0x80000000 /* at CS0 */ -#define CFG_DRAM_SIZE 0x20000000 /* 512 MB Ram */ +#define CFG_DRAM_BASE 0xa0000000 /* at CS0 */ +#define CFG_DRAM_SIZE 0x04000000 /* 64 MB Ram */ #define CFG_SKIP_DRAM_SCRUB 1 From c81eb1f5f5510e4fb11e3a76b4595a270f96e191 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Fri, 24 Feb 2006 01:42:40 +0100 Subject: [PATCH 018/102] Cleanup MCC200 board. --- MAKEALL | 4 ++-- board/mcc200/mcc200.c | 8 +------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/MAKEALL b/MAKEALL index fcbab47cab..ca66456cd4 100755 --- a/MAKEALL +++ b/MAKEALL @@ -26,8 +26,8 @@ LIST_5xx=" \ LIST_5xxx=" \ cpci5200 icecube_5100 icecube_5200 EVAL5200 \ - pf5200 PM520 Total5100 Total5200 \ - Total5200_Rev2 TQM5200_auto o2dnt \ + mcc200 o2dnt pf5200 PM520 \ + Total5100 Total5200 Total5200_Rev2 TQM5200_auto \ " ######################################################################### diff --git a/board/mcc200/mcc200.c b/board/mcc200/mcc200.c index dd2e1916e0..d7f95c83d0 100644 --- a/board/mcc200/mcc200.c +++ b/board/mcc200/mcc200.c @@ -240,13 +240,7 @@ long int initdram (int board_type) int checkboard (void) { - puts("Board: Bluetechnix DevMPC5200Leica \n"); -/* -#if defined(CONFIG_MPC5200) - puts ("Board: MicroSys PM520 \n"); -#elif defined(CONFIG_MGT5100) - puts ("Board: MicroSys PM510 \n"); -#endif*/ + puts ("Board: MCC200\n"); return 0; } From 79b4cda076069d04122f0d863bcb822b5e596c93 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 28 Feb 2006 15:29:58 +0100 Subject: [PATCH 019/102] Major CFI-FLASH driver update: * Add env-variable "unlock" to handle initial state of sectors (locked/unlocked). Only the U-Boot image and it's environment is protected, all other sectors are unprotected (unlocked) if flash hardware protection is used (CFG_FLASH_PROTECTION) and the environment variable "unlock" is set to "yes". Patch by Stefan Roese, 28 Feb 2006 * Update drivers/cfi_flash.c: - find_sector() called in both versions of flash_write_cfiword() Patch by Peter Pearse, 27th Feb 2006 * CFI support for a x8/x16 AMD/Spansion flash configured in x8 mode Patch by Jose Maria Lopez, 16 Jan 2006 * Add support for AMD/Spansion Flashes in flash_write_cfibuffer Patch by Alex Bastos and Thomas Schaefer, 2005-08-29 * Changes/fixes for drivers/cfi_flash.c: We *should* check if there are any error bits if the previous call returned ERR_OK (Otherwise we will have output an error message in flash_status_check() already.) The original code would only check for error bits if flash_status_check() returns ERR_TIMEOUT. Patch by Marcus Hall, 23 Aug 2005 * Changes/fixes for drivers/cfi_flash.c: - Add CFG_FLASH_PROTECT_CLEAR on drivers/cfi_flash.c - Prohibit buffer write when buffer_size is 1 on drivers/cfi_flash.c Patch by Sangmoon Kim, 19 Aug 2005 * Fixes for drivers/cfi_flash.c: - Fix wrong timeout value usage in flash_status_check() - Round write_tout up when converting to msec in flash_get_size() - Remove clearing flash status at the end of flash_write_cfibuffer() which sets Intel 28F640J3 flash back to command mode on CSB472 Patch by Tolunay Orkun, 02 July 2005 --- CHANGELOG | 39 +++++++ board/tqm85xx/tqm85xx.c | 3 +- drivers/cfi_flash.c | 225 +++++++++++++++++++++++++++------------- include/flash.h | 7 ++ 4 files changed, 201 insertions(+), 73 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 44989b849d..5e4d0770d2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,45 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add env-variable "unlock" to handle initial state of sectors + (locked/unlocked). + + Only the U-Boot image and it's environment is protected, + all other sectors are unprotected (unlocked) if flash + hardware protection is used (CFG_FLASH_PROTECTION) and + the environment variable "unlock" is set to "yes". + + Patch by Stefan Roese, 28 Feb 2006 + +* Update drivers/cfi_flash.c: + - find_sector() called in both versions of flash_write_cfiword() + Patch by Peter Pearse, 27th Feb 2006 + +* CFI support for a x8/x16 AMD/Spansion flash configured in x8 mode + Patch by Jose Maria Lopez, 16 Jan 2006 + +* Add support for AMD/Spansion Flashes in flash_write_cfibuffer + Patch by Alex Bastos and Thomas Schaefer, 2005-08-29 + +* Changes/fixes for drivers/cfi_flash.c: + We *should* check if there are any error bits if the previous call + returned ERR_OK (Otherwise we will have output an error message in + flash_status_check() already.) The original code would only check for + error bits if flash_status_check() returns ERR_TIMEOUT. + Patch by Marcus Hall, 23 Aug 2005 + +* Changes/fixes for drivers/cfi_flash.c: + - Add CFG_FLASH_PROTECT_CLEAR on drivers/cfi_flash.c + - Prohibit buffer write when buffer_size is 1 on drivers/cfi_flash.c + Patch by Sangmoon Kim, 19 Aug 2005 + +* Fixes for drivers/cfi_flash.c: + - Fix wrong timeout value usage in flash_status_check() + - Round write_tout up when converting to msec in flash_get_size() + - Remove clearing flash status at the end of flash_write_cfibuffer() + which sets Intel 28F640J3 flash back to command mode on CSB472 + Patch by Tolunay Orkun, 02 July 2005 + * Add GIT version information (commid ID) to untagged U-Boot versions As done in the linux kernel, the U-Boot version (U_BOOT_VERSION) diff --git a/board/tqm85xx/tqm85xx.c b/board/tqm85xx/tqm85xx.c index 13ea6f48dd..b36beadea7 100644 --- a/board/tqm85xx/tqm85xx.c +++ b/board/tqm85xx/tqm85xx.c @@ -40,7 +40,6 @@ extern flash_info_t flash_info[]; /* FLASH chips info */ void local_bus_init (void); long int fixed_sdram (void); -ulong flash_get_size (ulong base, int banknum); #ifdef CONFIG_CPM2 /* @@ -296,7 +295,7 @@ int misc_init_r (void) /* Monitor protection ON by default */ flash_protect (FLAG_PROTECT_SET, - CFG_MONITOR_BASE, 0xffffffff, + CFG_MONITOR_BASE, CFG_MONITOR_BASE + monitor_flash_len - 1, &flash_info[CFG_MAX_FLASH_BANKS - 1]); /* Environment protection ON by default */ diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c index 4b7a1107a9..df17da5eaf 100644 --- a/drivers/cfi_flash.c +++ b/drivers/cfi_flash.c @@ -104,12 +104,15 @@ #define AMD_CMD_ERASE_SECTOR 0x30 #define AMD_CMD_UNLOCK_START 0xAA #define AMD_CMD_UNLOCK_ACK 0x55 +#define AMD_CMD_WRITE_TO_BUFFER 0x25 +#define AMD_CMD_WRITE_BUFFER_CONFIRM 0x29 #define AMD_STATUS_TOGGLE 0x40 #define AMD_STATUS_ERROR 0x20 -#define AMD_ADDR_ERASE_START 0x555 -#define AMD_ADDR_START 0x555 -#define AMD_ADDR_ACK 0x2AA + +#define AMD_ADDR_ERASE_START ((info->portwidth == FLASH_CFI_8BIT) ? 0xAAA : 0x555) +#define AMD_ADDR_START ((info->portwidth == FLASH_CFI_8BIT) ? 0xAAA : 0x555) +#define AMD_ADDR_ACK ((info->portwidth == FLASH_CFI_8BIT) ? 0x555 : 0x2AA) #define FLASH_OFFSET_CFI 0x55 #define FLASH_OFFSET_CFI_RESP 0x10 @@ -175,6 +178,13 @@ static ulong bank_base[CFG_MAX_FLASH_BANKS] = CFG_FLASH_BANKS_LIST; flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* FLASH chips info */ #endif +/* + * Check if chip width is defined. If not, start detecting with 8bit. + */ +#ifndef CFG_FLASH_CFI_WIDTH +#define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT +#endif + /*----------------------------------------------------------------------- * Functions @@ -190,7 +200,6 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, u static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd); static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd); static int flash_detect_cfi (flash_info_t * info); -ulong flash_get_size (ulong base, int banknum); static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword); static int flash_full_status_check (flash_info_t * info, flash_sect_t sector, ulong tout, char *prompt); @@ -328,6 +337,7 @@ ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset) return retval; } + /*----------------------------------------------------------------------- */ unsigned long flash_init (void) @@ -345,6 +355,24 @@ unsigned long flash_init (void) i, flash_info[i].size, flash_info[i].size << 20); #endif /* CFG_FLASH_QUIET_TEST */ } +#ifdef CFG_FLASH_PROTECTION + else { + char *s = getenv("unlock"); + + if (((s = getenv("unlock")) != NULL) && (strcmp(s, "yes") == 0)) { + /* + * Only the U-Boot image and it's environment is protected, + * all other sectors are unprotected (unlocked) if flash + * hardware protection is used (CFG_FLASH_PROTECTION) and + * the environment variable "unlock" is set to "yes". + */ + flash_protect (FLAG_PROTECT_CLEAR, + flash_info[i].start[0], + flash_info[i].start[0] + flash_info[i].size - 1, + &flash_info[i]); + } + } +#endif /* CFG_FLASH_PROTECTION */ } /* Monitor protection ON by default */ @@ -565,7 +593,22 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) buffered_size = (info->portwidth / info->chipwidth); buffered_size *= info->buffer_size; while (cnt >= info->portwidth) { - i = buffered_size > cnt ? cnt : buffered_size; + /* prohibit buffer write when buffer_size is 1 */ + if (info->buffer_size == 1) { + cword.l = 0; + for (i = 0; i < info->portwidth; i++) + flash_add_byte (info, &cword, *src++); + if ((rc = flash_write_cfiword (info, wp, cword)) != 0) + return rc; + wp += info->portwidth; + cnt -= info->portwidth; + continue; + } + + /* write buffer until next buffered_size aligned boundary */ + i = buffered_size - (wp % buffered_size); + if (i > cnt) + i = cnt; if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK) return rc; i -= i & (info->portwidth - 1); @@ -705,7 +748,7 @@ static int flash_status_check (flash_info_t * info, flash_sect_t sector, /* Wait for command completion */ start = get_timer (0); while (flash_is_busy (info, sector)) { - if (get_timer (start) > info->erase_blk_tout * CFG_HZ) { + if (get_timer (start) > tout) { printf ("Flash %s timeout at address %lx data %lx\n", prompt, info->start[sector], flash_read_long (info, sector, 0)); @@ -729,7 +772,7 @@ static int flash_full_status_check (flash_info_t * info, flash_sect_t sector, switch (info->vendor) { case CFI_CMDSET_INTEL_EXTENDED: case CFI_CMDSET_INTEL_STANDARD: - if ((retcode != ERR_OK) + if ((retcode == ERR_OK) && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) { retcode = ERR_INVAL; printf ("Flash %s error at address %lx\n", prompt, @@ -985,7 +1028,7 @@ static int flash_detect_cfi (flash_info_t * info) { debug ("flash detect cfi\n"); - for (info->portwidth = FLASH_CFI_8BIT; + for (info->portwidth = CFG_FLASH_CFI_WIDTH; info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) { for (info->chipwidth = FLASH_CFI_BY8; info->chipwidth <= info->portwidth; @@ -1106,8 +1149,9 @@ ulong flash_get_size (ulong base, int banknum) info->erase_blk_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_EMAX_TOUT))); tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_WBTOUT); info->buffer_write_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT))); - tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_WTOUT); - info->write_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_WMAX_TOUT))) / 1000; + tmp = (1 << flash_read_uchar (info, FLASH_OFFSET_WTOUT)) * + (1 << flash_read_uchar (info, FLASH_OFFSET_WMAX_TOUT)); + info->write_tout = tmp / 1000 + (tmp % 1000 ? 1 : 0); /* round up when converting to ms */ info->flash_id = FLASH_MAN_CFI; if ((info->interface == FLASH_CFI_X8X16) && (info->chipwidth == FLASH_CFI_BY8)) { info->portwidth >>= 1; /* XXX - Need to test on x8/x16 in parallel. */ @@ -1118,13 +1162,26 @@ ulong flash_get_size (ulong base, int banknum) return (info->size); } +/* loop through the sectors from the highest address + * when the passed address is greater or equal to the sector address + * we have a match + */ +static flash_sect_t find_sector (flash_info_t * info, ulong addr) +{ + flash_sect_t sector; + + for (sector = info->sector_count - 1; sector >= 0; sector--) { + if (addr >= info->start[sector]) + break; + } + return sector; +} /*----------------------------------------------------------------------- */ static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword) { - cfiptr_t ctladdr; cfiptr_t cptr; int flag; @@ -1188,26 +1245,12 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest, if (flag) enable_interrupts (); - return flash_full_status_check (info, 0, info->write_tout, "write"); + return flash_full_status_check (info, find_sector (info, dest), + info->write_tout, "write"); } #ifdef CFG_FLASH_USE_BUFFER_WRITE -/* loop through the sectors from the highest address - * when the passed address is greater or equal to the sector address - * we have a match - */ -static flash_sect_t find_sector (flash_info_t * info, ulong addr) -{ - flash_sect_t sector; - - for (sector = info->sector_count - 1; sector >= 0; sector--) { - if (addr >= info->start[sector]) - break; - } - return sector; -} - static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int len) { @@ -1216,66 +1259,106 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int retcode; volatile cfiptr_t src; volatile cfiptr_t dst; - /* buffered writes in the AMD chip set is not supported yet */ - if((info->vendor == CFI_CMDSET_AMD_STANDARD) || - (info->vendor == CFI_CMDSET_AMD_EXTENDED)) - return ERR_INVAL; - src.cp = cp; - dst.cp = (uchar *) dest; - sector = find_sector (info, dest); - flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS); - flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER); - if ((retcode = - flash_status_check (info, sector, info->buffer_write_tout, - "write to buffer")) == ERR_OK) { - /* reduce the number of loops by the width of the port */ - switch (info->portwidth) { - case FLASH_CFI_8BIT: - cnt = len; - break; - case FLASH_CFI_16BIT: - cnt = len >> 1; - break; - case FLASH_CFI_32BIT: - cnt = len >> 2; - break; - case FLASH_CFI_64BIT: - cnt = len >> 3; - break; - default: - return ERR_INVAL; - break; - } - flash_write_cmd (info, sector, 0, (uchar) cnt - 1); - while (cnt-- > 0) { + switch (info->vendor) { + case CFI_CMDSET_INTEL_STANDARD: + case CFI_CMDSET_INTEL_EXTENDED: + src.cp = cp; + dst.cp = (uchar *) dest; + sector = find_sector (info, dest); + flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS); + flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER); + if ((retcode = flash_status_check (info, sector, info->buffer_write_tout, + "write to buffer")) == ERR_OK) { + /* reduce the number of loops by the width of the port */ switch (info->portwidth) { case FLASH_CFI_8BIT: - *dst.cp++ = *src.cp++; + cnt = len; break; case FLASH_CFI_16BIT: - *dst.wp++ = *src.wp++; + cnt = len >> 1; break; case FLASH_CFI_32BIT: - *dst.lp++ = *src.lp++; + cnt = len >> 2; break; case FLASH_CFI_64BIT: - *dst.llp++ = *src.llp++; + cnt = len >> 3; break; default: return ERR_INVAL; break; } + flash_write_cmd (info, sector, 0, (uchar) cnt - 1); + while (cnt-- > 0) { + switch (info->portwidth) { + case FLASH_CFI_8BIT: + *dst.cp++ = *src.cp++; + break; + case FLASH_CFI_16BIT: + *dst.wp++ = *src.wp++; + break; + case FLASH_CFI_32BIT: + *dst.lp++ = *src.lp++; + break; + case FLASH_CFI_64BIT: + *dst.llp++ = *src.llp++; + break; + default: + return ERR_INVAL; + break; + } + } + flash_write_cmd (info, sector, 0, + FLASH_CMD_WRITE_BUFFER_CONFIRM); + retcode = flash_full_status_check (info, sector, + info->buffer_write_tout, + "buffer write"); } - flash_write_cmd (info, sector, 0, - FLASH_CMD_WRITE_BUFFER_CONFIRM); - retcode = - flash_full_status_check (info, sector, - info->buffer_write_tout, - "buffer write"); + return retcode; + + case CFI_CMDSET_AMD_STANDARD: + case CFI_CMDSET_AMD_EXTENDED: + src.cp = cp; + dst.cp = (uchar *) dest; + sector = find_sector (info, dest); + + flash_unlock_seq(info,0); + flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_TO_BUFFER); + + switch (info->portwidth) { + case FLASH_CFI_8BIT: + cnt = len; + flash_write_cmd (info, sector, 0, (uchar) cnt - 1); + while (cnt-- > 0) *dst.cp++ = *src.cp++; + break; + case FLASH_CFI_16BIT: + cnt = len >> 1; + flash_write_cmd (info, sector, 0, (uchar) cnt - 1); + while (cnt-- > 0) *dst.wp++ = *src.wp++; + break; + case FLASH_CFI_32BIT: + cnt = len >> 2; + flash_write_cmd (info, sector, 0, (uchar) cnt - 1); + while (cnt-- > 0) *dst.lp++ = *src.lp++; + break; + case FLASH_CFI_64BIT: + cnt = len >> 3; + flash_write_cmd (info, sector, 0, (uchar) cnt - 1); + while (cnt-- > 0) *dst.llp++ = *src.llp++; + break; + default: + return ERR_INVAL; + } + + flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM); + retcode = flash_full_status_check (info, sector, info->buffer_write_tout, + "buffer write"); + return retcode; + + default: + debug ("Unknown Command Set\n"); + return ERR_INVAL; } - flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS); - return retcode; } #endif /* CFG_FLASH_USE_BUFFER_WRITE */ #endif /* CFG_FLASH_CFI */ diff --git a/include/flash.h b/include/flash.h index 069aa63414..9108723366 100644 --- a/include/flash.h +++ b/include/flash.h @@ -80,6 +80,7 @@ extern void flash_print_info (flash_info_t *); extern int flash_erase (flash_info_t *, int, int); extern int flash_sect_erase (ulong addr_first, ulong addr_last); extern int flash_sect_protect (int flag, ulong addr_first, ulong addr_last); +extern ulong flash_get_size (ulong base, int banknum); /* common/flash.c */ extern void flash_protect (int flag, ulong from, ulong to, flash_info_t *info); @@ -274,6 +275,12 @@ extern void flash_read_factory_serial(flash_info_t * info, void * buffer, int of #define INTEL_ID_28F64K3 0x88018801 /* 64M = 32K x 255 + 32k x 4 */ #define INTEL_ID_28F128K3 0x88028802 /* 128M = 64K x 255 + 32k x 4 */ #define INTEL_ID_28F256K3 0x88038803 /* 256M = 128K x 255 + 32k x 4 */ +#define INTEL_ID_28F64P30T 0x88178817 /* 64M = 32K x 255 + 32k x 4 */ +#define INTEL_ID_28F64P30B 0x881A881A /* 64M = 32K x 255 + 32k x 4 */ +#define INTEL_ID_28F128P30T 0x88188818 /* 128M = 64K x 255 + 32k x 4 */ +#define INTEL_ID_28F128P30B 0x881B881B /* 128M = 64K x 255 + 32k x 4 */ +#define INTEL_ID_28F256P30T 0x88198819 /* 256M = 128K x 255 + 32k x 4 */ +#define INTEL_ID_28F256P30B 0x881C881C /* 256M = 128K x 255 + 32k x 4 */ #define INTEL_ID_28F160S3 0x00D000D0 /* 16M = 512K x 32 (64kB x 32) */ #define INTEL_ID_28F320S3 0x00D400D4 /* 32M = 512K x 64 (64kB x 64) */ From 58ad4978330aefd6bdce72906f809bcfb6c94710 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 28 Feb 2006 15:33:28 +0100 Subject: [PATCH 020/102] Convert mcc200 to use common CFI flash driver Patch by Stefan Roese, 28 Feb 2006 --- CHANGELOG | 3 + board/mcc200/Makefile | 2 +- board/mcc200/flash.c | 738 --------------------------------------- board/mcc200/flash.h | 437 ----------------------- board/mcc200/mcc200.c | 86 +++-- include/configs/mcc200.h | 159 +++------ 6 files changed, 95 insertions(+), 1330 deletions(-) delete mode 100644 board/mcc200/flash.c delete mode 100644 board/mcc200/flash.h diff --git a/CHANGELOG b/CHANGELOG index 5e4d0770d2..e7683ecfb8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Convert mcc200 to use common CFI flash driver + Patch by Stefan Roese, 28 Feb 2006 + * Add env-variable "unlock" to handle initial state of sectors (locked/unlocked). diff --git a/board/mcc200/Makefile b/board/mcc200/Makefile index 162734bb83..7fdc088e9c 100644 --- a/board/mcc200/Makefile +++ b/board/mcc200/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = lib$(BOARD).a -OBJS := $(BOARD).o flash.o +OBJS := $(BOARD).o $(LIB): $(OBJS) $(SOBJS) $(AR) crv $@ $(OBJS) diff --git a/board/mcc200/flash.c b/board/mcc200/flash.c deleted file mode 100644 index 8e1757acd4..0000000000 --- a/board/mcc200/flash.c +++ /dev/null @@ -1,738 +0,0 @@ -/* - * (C) Copyright 2001 - * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net - * - * (C) Copyright 2001-2006 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -//###CHD: gehört wieder raus ist vom PXA271 file! -#define FLASH_28F256L18T 0x00B0 /* Intel 28F256L18T ( 32M = 128K x 255 + 32k x 4) */ -#define FLASH_28F256L18B 0x00B1 /* Intel 28F256L18B ( 32M = 32k x 4 + 128K x 255) */ -#define FLASH_28F256P30B 0x001C /* Intel 28F256P30B ( 32M = 32k x 4 + 128K x 255) */ -#define FLASH_28F256P30T 0x0019 /* Intel 28F256P30T ( 128K x 255 + 32M = 32k x 4 + */ - -#define INTEL_ID_28F016S 0x66a066a0 /* 28F016S[VS] ID (16M = 512k x 16) */ -#define INTEL_ID_28F800B3T 0x88928892 /* 8M = 512K x 16 top boot sector */ -#define INTEL_ID_28F800B3B 0x88938893 /* 8M = 512K x 16 bottom boot sector */ -#define INTEL_ID_28F160B3T 0x88908890 /* 16M = 1M x 16 top boot sector */ -#define INTEL_ID_28F160B3B 0x88918891 /* 16M = 1M x 16 bottom boot sector */ -#define INTEL_ID_28F320B3T 0x88968896 /* 32M = 2M x 16 top boot sector */ -#define INTEL_ID_28F320B3B 0x88978897 /* 32M = 2M x 16 bottom boot sector */ -#define INTEL_ID_28F640B3T 0x88988898 /* 64M = 4M x 16 top boot sector */ -#define INTEL_ID_28F640B3B 0x88998899 /* 64M = 4M x 16 bottom boot sector */ -#define INTEL_ID_28F160F3B 0x88F488F4 /* 16M = 1M x 16 bottom boot sector */ - -#define INTEL_ID_28F800C3T 0x88C088C0 /* 8M = 512K x 16 top boot sector */ -#define INTEL_ID_28F800C3B 0x88C188C1 /* 8M = 512K x 16 bottom boot sector */ -#define INTEL_ID_28F160C3T 0x88C288C2 /* 16M = 1M x 16 top boot sector */ -#define INTEL_ID_28F160C3B 0x88C388C3 /* 16M = 1M x 16 bottom boot sector */ -#define INTEL_ID_28F320C3T 0x88C488C4 /* 32M = 2M x 16 top boot sector */ -#define INTEL_ID_28F320C3B 0x88C588C5 /* 32M = 2M x 16 bottom boot sector */ -#define INTEL_ID_28F640C3T 0x88CC88CC /* 64M = 4M x 16 top boot sector */ -#define INTEL_ID_28F640C3B 0x88CD88CD /* 64M = 4M x 16 bottom boot sector */ - -#define INTEL_ID_28F128J3 0x89188918 /* 16M = 8M x 16 x 128 */ -#define INTEL_ID_28F320J5 0x00140014 /* 32M = 128K x 32 */ -#define INTEL_ID_28F640J5 0x00150015 /* 64M = 128K x 64 */ -#define INTEL_ID_28F320J3A 0x00160016 /* 32M = 128K x 32 */ -#define INTEL_ID_28F640J3A 0x00170017 /* 64M = 128K x 64 */ -#define INTEL_ID_28F256L18 0x88108810 /* 32M = 128K x 255 */ -#define INTEL_ID_28F128J3A 0x00180018 /* 128M = 128K x 128 */ -#define INTEL_ID_28F256L18T 0x880D880D /* 256M = 128K x 255 + 32k x 4 */ -#define INTEL_ID_28F256L18B 0x88108810 /* 256M = 32k x 4 + 128K x 255 */ -#define INTEL_ID_28F256P30B 0x891C891C /* 256M = 32k x 4 + 128K x 255 */ -#define INTEL_ID_28F256P30T 0x89198919 /* 256M = 128K x 255 + 32k x 4 */ -#define INTEL_ID_28F64K3 0x88018801 /* 64M = 32K x 255 + 32k x 4 */ -#define INTEL_ID_28F128K3 0x88028802 /* 128M = 64K x 255 + 32k x 4 */ -#define INTEL_ID_28F256K3 0x88038803 /* 256M = 128K x 255 + 32k x 4 */ - -#define INTEL_ID_28F160S3 0x00D000D0 /* 16M = 512K x 32 (64kB x 32) */ -#define INTEL_ID_28F320S3 0x00D400D4 /* 32M = 512K x 64 (64kB x 64) */ - - -flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ - -/* Board support for 1 or 2 flash devices */ -#define FLASH_PORT_WIDTH32 -#undef FLASH_PORT_WIDTH16 - -#ifdef FLASH_PORT_WIDTH16 -#define FLASH_PORT_WIDTH ushort -#define FLASH_PORT_WIDTHV vu_short -#define SWAP(x) (x) -#else -#define FLASH_PORT_WIDTH ulong -#define FLASH_PORT_WIDTHV vu_long -#define SWAP(x) (x) -#endif - -/* Intel-compatible flash ID */ -#define INTEL_COMPAT 0x00890089 -#define INTEL_ALT 0x00B000B0 - - - -/* Intel-compatible flash commands */ -#define INTEL_PROGRAM 0x00100010 -#define INTEL_ERASE 0x00200020 -#define INTEL_CLEAR 0x00500050 -#define INTEL_LOCKBIT 0x00600060 -#define INTEL_PROTECT 0x00010001 -#define INTEL_STATUS 0x00700070 -#define INTEL_READID 0x00900090 -#define INTEL_CONFIRM 0x00D000D0 -#define INTEL_RESET 0xFFFFFFFF - -/* Intel-compatible flash status bits */ -#define INTEL_FINISHED 0x00800080 -#define INTEL_OK 0x00800080 - -#define FPW FLASH_PORT_WIDTH -#define FPWV FLASH_PORT_WIDTHV - -#define mb() __asm__ __volatile__ ("" : : : "memory") - -///###CHD: auch wieder raus! + switch anweisung für den P30iger! -/* Flash Organization Structure */ -typedef struct OrgDef { - unsigned int sector_number; - unsigned int sector_size; -} OrgDef; - -/* Flash Organizations */ -OrgDef OrgIntel_28F256L18B[] = { - {4, 0x8000}, /* 4 * 32kBytes sectors */ - {255, 0x20000}, /* 255 * 128kBytes sectors */ -}; - -OrgDef OrgIntel_28F256L18T[] = { - {255, 0x20000}, /* 255 * 128kBytes sectors */ - {4, 0x8000} /* 4 * 32kBytes sectors */ -}; - -OrgDef OrgIntel_28F128J3A[] = { - {128, 0x20000}, /* 128 * 128kBytes sectors */ -}; -static unsigned int OrgSectTypeNum_28F256L18 = 2; -static unsigned int OrgSectTypeNum_28F256J3 = 1; - -/*----------------------------------------------------------------------- - * Functions - */ -static ulong flash_get_size (FPW *addr, flash_info_t *info); -static int write_data (flash_info_t *info, ulong dest, FPW data); -static void flash_get_offsets (ulong base, flash_info_t *info); -void inline spin_wheel (void); -static void flash_sync_real_protect (flash_info_t * info); -static unsigned char intel_sector_protected (flash_info_t *info, ushort sector); - -/*----------------------------------------------------------------------- - */ - -unsigned long flash_init (void) -{ - int i; - ulong size = 0; - extern void flash_preinit(void); - extern void flash_afterinit(ulong, ulong); - ulong flashbase = CFG_FLASH_BASE; - - flash_preinit(); - - for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { - switch (i) { - case 0: - memset(&flash_info[i], 0, sizeof(flash_info_t)); - flash_get_size ((FPW *) flashbase, &flash_info[i]); - flash_get_offsets (flash_info[i].start[0], &flash_info[i]); - break; - default: - panic ("configured to many flash banks!\n"); - break; - } - size += flash_info[i].size; - - /* get the h/w and s/w protection status in sync */ - flash_sync_real_protect(&flash_info[i]); - } - - /* Protect monitor and environment sectors - */ -#if CFG_MONITOR_BASE >= CFG_FLASH_BASE -#ifndef CONFIG_BOOT_ROM - flash_protect ( FLAG_PROTECT_SET, - CFG_MONITOR_BASE, - CFG_MONITOR_BASE + monitor_flash_len - 1, - &flash_info[0] ); -#endif -#endif - -#ifdef CFG_ENV_IS_IN_FLASH - flash_protect ( FLAG_PROTECT_SET, - CFG_ENV_ADDR, - CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] ); -#endif - - flash_afterinit(flash_info[0].start[0], flash_info[0].size); - - return size; -} - -/*----------------------------------------------------------------------- - */ -static void flash_get_offsets (ulong base, flash_info_t *info) -{ - int i; - - if (info->flash_id == FLASH_UNKNOWN) { - return; - } - - if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { - for (i = 0; i < info->sector_count; i++) { - info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE); - } - } -} - -/*----------------------------------------------------------------------- - */ -void flash_print_info (flash_info_t *info) -{ - int i; - - if (info->flash_id == FLASH_UNKNOWN) { - printf ("missing or unknown FLASH type\n"); - return; - } - - switch (info->flash_id & FLASH_VENDMASK) { - case FLASH_MAN_INTEL: - printf ("INTEL "); - break; - default: - printf ("Unknown Vendor "); - break; - } - - switch (info->flash_id & FLASH_TYPEMASK) { - case FLASH_28F128J3A: - printf ("28F128J3A\n"); - break; - - case FLASH_28F640J3A: - printf ("28F640J3A\n"); - break; - - case FLASH_28F320J3A: - printf ("28F320J3A\n"); - break; - - case FLASH_28F256P30T: - printf ("FLASH_28F256P30T\n"); - break; - - default: - printf ("Unknown Chip Type\n"); - break; - } - - printf (" Size: %ld MB in %d Sectors\n", - info->size >> 20, info->sector_count); - - printf (" Sector Start Addresses:"); - for (i = 0; i < info->sector_count; ++i) { - if ((i % 5) == 0) - printf ("\n "); - printf (" %08lX%s", - info->start[i], - info->protect[i] ? " (RO)" : " "); - } - printf ("\n"); - return; -} - -/* - * The following code cannot be run from FLASH! - */ -static ulong flash_get_size (FPW *addr, flash_info_t *info) -{ - volatile FPW value; - - /* Write auto select command: read Manufacturer ID */ - addr[0x5555] = (FPW) 0x00AA00AA; - addr[0x2AAA] = (FPW) 0x00550055; - addr[0x5555] = (FPW) 0x00900090; - - mb (); - udelay(100); - - value = addr[0]; - - switch (value) { - - case (FPW) INTEL_MANUFACT: - info->flash_id = FLASH_MAN_INTEL; - break; - - default: - info->flash_id = FLASH_UNKNOWN; - info->sector_count = 0; - info->size = 0; - addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ - return (0); /* no or unknown flash */ - } - - mb (); - value = addr[1]; /* device ID */ - - switch (value) { - - case (FPW) INTEL_ID_28F128J3A: - info->flash_id += FLASH_28F128J3A; - info->sector_count = 128; - info->size = 0x02000000; - info->start[0] = CFG_FLASH_BASE; - break; /* => 32 MB */ - - case (FPW) INTEL_ID_28F640J3A: - info->flash_id += FLASH_28F640J3A; - info->sector_count = 64; - info->size = 0x01000000; - info->start[0] = CFG_FLASH_BASE + 0x01000000; - break; /* => 16 MB */ - - case (FPW) (INTEL_ID_28F256P30T): - info->flash_id += FLASH_28F256L18B; - info->sector_count = 128;//falsch!!! - info->size = 0x02000000; - info->start[0] = CFG_FLASH_BASE; - debug ("Intel StrataFlash 28F256P30T device initialized\n"); - break; /* => 32 MB */ - - case (FPW) INTEL_ID_28F320J3A: - info->flash_id += FLASH_28F320J3A; - info->sector_count = 32; - info->size = 0x800000; - info->start[0] = CFG_FLASH_BASE + 0x01800000; - break; /* => 8 MB */ - - default: - info->flash_id = FLASH_UNKNOWN; - break; - } - - if (info->sector_count > CFG_MAX_FLASH_SECT) { - printf ("** ERROR: sector count %d > max (%d) **\n", - info->sector_count, CFG_MAX_FLASH_SECT); - info->sector_count = CFG_MAX_FLASH_SECT; - } - - addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ - - return (info->size); -} - - -/* - * This function gets the u-boot flash sector protection status - * (flash_info_t.protect[]) in sync with the sector protection - * status stored in hardware. - */ -static void flash_sync_real_protect (flash_info_t * info) -{ - int i; - - switch (info->flash_id & FLASH_TYPEMASK) { - - case FLASH_28F128J3A: - case FLASH_28F640J3A: - case FLASH_28F320J3A: - for (i = 0; i < info->sector_count; ++i) { - info->protect[i] = intel_sector_protected(info, i); - } - break; - default: - /* no h/w protect support */ - break; - } -} - - -/* - * checks if "sector" in bank "info" is protected. Should work on intel - * strata flash chips 28FxxxJ3x in 8-bit mode. - * Returns 1 if sector is protected (or timed-out while trying to read - * protection status), 0 if it is not. - */ -static unsigned char intel_sector_protected (flash_info_t *info, ushort sector) -{ - FPWV *addr; - FPWV *lock_conf_addr; - ulong start; - unsigned char ret; - - /* - * first, wait for the WSM to be finished. The rationale for - * waiting for the WSM to become idle for at most - * CFG_FLASH_ERASE_TOUT is as follows. The WSM can be busy - * because of: (1) erase, (2) program or (3) lock bit - * configuration. So we just wait for the longest timeout of - * the (1)-(3), i.e. the erase timeout. - */ - - /* wait at least 35ns (W12) before issuing Read Status Register */ - udelay(1); - addr = (FPWV *) info->start[sector]; - *addr = (FPW) INTEL_STATUS; - - start = get_timer (0); - while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) { - if (get_timer (start) > CFG_FLASH_ERASE_TOUT) { - *addr = (FPW) INTEL_RESET; /* restore read mode */ - printf("WSM busy too long, can't get prot status\n"); - return 1; - } - } - - /* issue the Read Identifier Codes command */ - *addr = (FPW) INTEL_READID; - - /* wait at least 35ns (W12) before reading */ - udelay(1); - - /* Intel example code uses offset of 2 for 16 bit flash */ - lock_conf_addr = (FPWV *) info->start[sector] + 2; - ret = (*lock_conf_addr & (FPW) INTEL_PROTECT) ? 1 : 0; - - /* put flash back in read mode */ - *addr = (FPW) INTEL_RESET; - - return ret; -} - -/*----------------------------------------------------------------------- - */ - -int flash_erase (flash_info_t *info, int s_first, int s_last) -{ - int flag, prot, sect; - ulong type, start, last; - int rcode = 0; - - if ((s_first < 0) || (s_first > s_last)) { - if (info->flash_id == FLASH_UNKNOWN) { - printf ("- missing\n"); - } else { - printf ("- no sectors to erase\n"); - } - return 1; - } - - type = (info->flash_id & FLASH_VENDMASK); - if ((type != FLASH_MAN_INTEL)) { - printf ("Can't erase unknown flash type %08lx - aborted\n", - info->flash_id); - return 1; - } - - prot = 0; - for (sect = s_first; sect <= s_last; ++sect) { - if (info->protect[sect]) { - prot++; - } - } - - if (prot) { - printf ("- Warning: %d protected sectors will not be erased!\n", - prot); - } else { - printf ("\n"); - } - - start = get_timer (0); - last = start; - - /* Disable interrupts which might cause a timeout here */ - flag = disable_interrupts (); - - /* Start erase on unprotected sectors */ - for (sect = s_first; sect <= s_last; sect++) { - if (info->protect[sect] == 0) { /* not protected */ - FPWV *addr = (FPWV *) (info->start[sect]); - FPW status; - - printf ("Erasing sector %2d ... ", sect); - - /* arm simple, non interrupt dependent timer */ - start = get_timer(0); - - *addr = (FPW) 0x00500050; /* clear status register */ - *addr = (FPW) 0x00200020; /* erase setup */ - *addr = (FPW) 0x00D000D0; /* erase confirm */ - - while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { - if (get_timer(start) > CFG_FLASH_ERASE_TOUT) { - printf ("Timeout\n"); - *addr = (FPW) 0x00B000B0; /* suspend erase */ - *addr = (FPW) 0x00FF00FF; /* reset to read mode */ - rcode = 1; - break; - } - } - - *addr = 0x00500050; /* clear status register cmd. */ - *addr = 0x00FF00FF; /* resest to read mode */ - - printf (" done\n"); - } - } - return rcode; -} - -/*----------------------------------------------------------------------- - * Copy memory to flash, returns: - * 0 - OK - * 1 - write timeout - * 2 - Flash not erased - * 4 - Flash not identified - */ - -int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) -{ - ulong cp, wp; - FPW data; - int count, i, l, rc, port_width; - - if (info->flash_id == FLASH_UNKNOWN) { - return 4; - } -/* get lower word aligned address */ -#ifdef FLASH_PORT_WIDTH16 - wp = (addr & ~1); - port_width = 2; -#else - wp = (addr & ~3); - port_width = 4; -#endif - - /* - * handle unaligned start bytes - */ - if ((l = addr - wp) != 0) { - data = 0; - for (i = 0, cp = wp; i < l; ++i, ++cp) { - data = (data << 8) | (*(uchar *) cp); - } - for (; i < port_width && cnt > 0; ++i) { - data = (data << 8) | *src++; - --cnt; - ++cp; - } - for (; cnt == 0 && i < port_width; ++i, ++cp) { - data = (data << 8) | (*(uchar *) cp); - } - - if ((rc = write_data (info, wp, SWAP (data))) != 0) { - return (rc); - } - wp += port_width; - } - - /* - * handle word aligned part - */ - count = 0; - while (cnt >= port_width) { - data = 0; - for (i = 0; i < port_width; ++i) { - data = (data << 8) | *src++; - } - if ((rc = write_data (info, wp, SWAP (data))) != 0) { - return (rc); - } - wp += port_width; - cnt -= port_width; - if (count++ > 0x800) { - spin_wheel (); - count = 0; - } - } - - if (cnt == 0) { - return (0); - } - - /* - * handle unaligned tail bytes - */ - data = 0; - for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { - data = (data << 8) | *src++; - --cnt; - } - for (; i < port_width; ++i, ++cp) { - data = (data << 8) | (*(uchar *) cp); - } - - return (write_data (info, wp, SWAP (data))); -} - -/*----------------------------------------------------------------------- - * Write a word or halfword to Flash, returns: - * 0 - OK - * 1 - write timeout - * 2 - Flash not erased - */ -static int write_data (flash_info_t *info, ulong dest, FPW data) -{ - FPWV *addr = (FPWV *) dest; - ulong status; - ulong start; - int flag; - - /* Check if Flash is (sufficiently) erased */ - if ((*addr & data) != data) { - printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr); - return (2); - } - /* Disable interrupts which might cause a timeout here */ - flag = disable_interrupts (); - - *addr = (FPW) 0x00400040; /* write setup */ - *addr = data; - - /* arm simple, non interrupt dependent timer */ - start = get_timer(0); - - /* wait while polling the status register */ - while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { - if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { - *addr = (FPW) 0x00FF00FF; /* restore read mode */ - return (1); - } - } - - *addr = (FPW) 0x00FF00FF; /* restore read mode */ - - return (0); -} - -void inline spin_wheel (void) -{ - static int p = 0; - static char w[] = "\\/-"; - - printf ("\010%c", w[p]); - (++p == 3) ? (p = 0) : 0; -} - -/*----------------------------------------------------------------------- - * Set/Clear sector's lock bit, returns: - * 0 - OK - * 1 - Error (timeout, voltage problems, etc.) - */ -int flash_real_protect (flash_info_t *info, long sector, int prot) -{ - ulong start; - int i; - int rc = 0; - vu_long *addr = (vu_long *)(info->start[sector]); - int flag = disable_interrupts(); - - *addr = INTEL_CLEAR; /* Clear status register */ - if (prot) { /* Set sector lock bit */ - *addr = INTEL_LOCKBIT; /* Sector lock bit */ - *addr = INTEL_PROTECT; /* set */ - } - else { /* Clear sector lock bit */ - *addr = INTEL_LOCKBIT; /* All sectors lock bits */ - *addr = INTEL_CONFIRM; /* clear */ - } - - start = get_timer(0); - - while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) { - if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT) { - printf("Flash lock bit operation timed out\n"); - rc = 1; - break; - } - } - - if (*addr != INTEL_OK) { - printf("Flash lock bit operation failed at %08X, CSR=%08X\n", - (uint)addr, (uint)*addr); - rc = 1; - } - - if (!rc) - info->protect[sector] = prot; - - /* - * Clear lock bit command clears all sectors lock bits, so - * we have to restore lock bits of protected sectors. - * WARNING: code below re-locks sectors only for one bank (info). - * This causes problems on boards where several banks share - * the same chip, as sectors in othere banks will be unlocked - * but not re-locked. It works fine on pm520 though, as there - * is only one chip and one bank. - */ - if (!prot) - { - for (i = 0; i < info->sector_count; i++) - { - if (info->protect[i]) - { - start = get_timer(0); - addr = (vu_long *)(info->start[i]); - *addr = INTEL_LOCKBIT; /* Sector lock bit */ - *addr = INTEL_PROTECT; /* set */ - while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) - { - if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT) - { - printf("Flash lock bit operation timed out\n"); - rc = 1; - break; - } - } - } - } - /* - * get the s/w sector protection status in sync with the h/w, - * in case something went wrong during the re-locking. - */ - flash_sync_real_protect(info); /* resets flash to read mode */ - } - - if (flag) - enable_interrupts(); - - *addr = INTEL_RESET; /* Reset to read array mode */ - - return rc; -} diff --git a/board/mcc200/flash.h b/board/mcc200/flash.h deleted file mode 100644 index 9dc5d04ff2..0000000000 --- a/board/mcc200/flash.h +++ /dev/null @@ -1,437 +0,0 @@ -/* - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -8 * MA 02111-1307 USA - */ - -#ifndef _FLASH_H_ -#define _FLASH_H_ - -#ifndef CFG_NO_FLASH -/*----------------------------------------------------------------------- - * FLASH Info: contains chip specific data, per FLASH bank - */ - -typedef struct { - ulong size; /* total bank size in bytes */ - ushort sector_count; /* number of erase units */ - ulong flash_id; /* combined device & manufacturer code */ - ulong start[CFG_MAX_FLASH_SECT]; /* physical sector start addresses */ - uchar protect[CFG_MAX_FLASH_SECT]; /* sector protection status */ -#ifdef CFG_FLASH_CFI - uchar portwidth; /* the width of the port */ - uchar chipwidth; /* the width of the chip */ - ushort buffer_size; /* # of bytes in write buffer */ - ulong erase_blk_tout; /* maximum block erase timeout */ - ulong write_tout; /* maximum write timeout */ - ulong buffer_write_tout; /* maximum buffer write timeout */ - ushort vendor; /* the primary vendor id */ - ushort cmd_reset; /* Vendor specific reset command */ - ushort interface; /* used for x8/x16 adjustments */ -#endif -} flash_info_t; - -/* - * Values for the width of the port - */ -#define FLASH_CFI_8BIT 0x01 -#define FLASH_CFI_16BIT 0x02 -#define FLASH_CFI_32BIT 0x04 -#define FLASH_CFI_64BIT 0x08 -/* - * Values for the width of the chip - */ -#define FLASH_CFI_BY8 0x01 -#define FLASH_CFI_BY16 0x02 -#define FLASH_CFI_BY32 0x04 -#define FLASH_CFI_BY64 0x08 -/* convert between bit value and numeric value */ -#define CFI_FLASH_SHIFT_WIDTH 3 -/* - * Values for the flash device interface - */ -#define FLASH_CFI_X8 0x00 -#define FLASH_CFI_X16 0x01 -#define FLASH_CFI_X8X16 0x02 - -/* convert between bit value and numeric value */ -#define CFI_FLASH_SHIFT_WIDTH 3 -/* Prototypes */ - -extern unsigned long flash_init (void); -extern void flash_print_info (flash_info_t *); -extern int flash_erase (flash_info_t *, int, int); -extern int flash_sect_erase (ulong addr_first, ulong addr_last); -extern int flash_sect_protect (int flag, ulong addr_first, ulong addr_last); - -/* common/flash.c */ -extern void flash_protect (int flag, ulong from, ulong to, flash_info_t *info); -extern int flash_write (uchar *, ulong, ulong); -extern flash_info_t *addr2info (ulong); -extern int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt); - -/* board/?/flash.c */ -#if defined(CFG_FLASH_PROTECTION) -extern int flash_real_protect(flash_info_t *info, long sector, int prot); -extern void flash_read_user_serial(flash_info_t * info, void * buffer, int offset, int len); -extern void flash_read_factory_serial(flash_info_t * info, void * buffer, int offset, int len); -#endif /* CFG_FLASH_PROTECTION */ - -/*----------------------------------------------------------------------- - * return codes from flash_write(): - */ -#define ERR_OK 0 -#define ERR_TIMOUT 1 -#define ERR_NOT_ERASED 2 -#define ERR_PROTECTED 4 -#define ERR_INVAL 8 -#define ERR_ALIGN 16 -#define ERR_UNKNOWN_FLASH_VENDOR 32 -#define ERR_UNKNOWN_FLASH_TYPE 64 -#define ERR_PROG_ERROR 128 - -/*----------------------------------------------------------------------- - * Protection Flags for flash_protect(): - */ -#define FLAG_PROTECT_SET 0x01 -#define FLAG_PROTECT_CLEAR 0x02 - -/*----------------------------------------------------------------------- - * Device IDs - */ - -#define AMD_MANUFACT 0x00010001 /* AMD manuf. ID in D23..D16, D7..D0 */ -#define FUJ_MANUFACT 0x00040004 /* FUJITSU manuf. ID in D23..D16, D7..D0 */ -#define ATM_MANUFACT 0x001F001F /* ATMEL */ -#define STM_MANUFACT 0x00200020 /* STM (Thomson) manuf. ID in D23.. -"- */ -#define SST_MANUFACT 0x00BF00BF /* SST manuf. ID in D23..D16, D7..D0 */ -#define MT_MANUFACT 0x00890089 /* MT manuf. ID in D23..D16, D7..D0 */ -#define INTEL_MANUFACT 0x00890089 /* INTEL manuf. ID in D23..D16, D7..D0 */ -#define INTEL_ALT_MANU 0x00B000B0 /* alternate INTEL namufacturer ID */ -#define MX_MANUFACT 0x00C200C2 /* MXIC manuf. ID in D23..D16, D7..D0 */ -#define TOSH_MANUFACT 0x00980098 /* TOSHIBA manuf. ID in D23..D16, D7..D0 */ -#define MT2_MANUFACT 0x002C002C /* alternate MICRON manufacturer ID*/ -#define EXCEL_MANUFACT 0x004A004A /* Excel Semiconductor */ - - /* Micron Technologies (INTEL compat.) */ -#define MT_ID_28F400_T 0x44704470 /* 28F400B3 ID ( 4 M, top boot sector) */ -#define MT_ID_28F400_B 0x44714471 /* 28F400B3 ID ( 4 M, bottom boot sect) */ - -#define AMD_ID_LV040B 0x4F /* 29LV040B ID */ - /* 4 Mbit, 512K x 8, */ - /* 8 64K x 8 uniform sectors */ - -#define AMD_ID_F040B 0xA4 /* 29F040B ID */ - /* 4 Mbit, 512K x 8, */ - /* 8 64K x 8 uniform sectors */ -#define STM_ID_M29W040B 0xE3 /* M29W040B ID */ - /* 4 Mbit, 512K x 8, */ - /* 8 64K x 8 uniform sectors */ -#define AMD_ID_F080B 0xD5 /* 29F080 ID ( 1 M) */ - /* 8 Mbit, 512K x 16, */ - /* 8 64K x 16 uniform sectors */ -#define AMD_ID_F016D 0xAD /* 29F016 ID ( 2 M x 8) */ -#define AMD_ID_F032B 0x41 /* 29F032 ID ( 4 M x 8) */ -#define AMD_ID_LV116DT 0xC7 /* 29LV116DT ( 2 M x 8, top boot sect) */ -#define AMD_ID_LV116DB 0x4C /* 29LV116DB ( 2 M x 8, bottom boot sect) */ -#define AMD_ID_LV016B 0xc8 /* 29LV016 ID ( 2 M x 8) */ - -#define AMD_ID_PL160CB 0x22452245 /* 29PL160CB ID (16 M, bottom boot sect */ - -#define AMD_ID_LV400T 0x22B922B9 /* 29LV400T ID ( 4 M, top boot sector) */ -#define AMD_ID_LV400B 0x22BA22BA /* 29LV400B ID ( 4 M, bottom boot sect) */ - -#define AMD_ID_LV033C 0xA3 /* 29LV033C ID ( 4 M x 8) */ -#define AMD_ID_LV065D 0x93 /* 29LV065D ID ( 8 M x 8) */ - -#define AMD_ID_LV800T 0x22DA22DA /* 29LV800T ID ( 8 M, top boot sector) */ -#define AMD_ID_LV800B 0x225B225B /* 29LV800B ID ( 8 M, bottom boot sect) */ - -#define AMD_ID_LV160T 0x22C422C4 /* 29LV160T ID (16 M, top boot sector) */ -#define AMD_ID_LV160B 0x22492249 /* 29LV160B ID (16 M, bottom boot sect) */ - -#define AMD_ID_DL163T 0x22282228 /* 29DL163T ID (16 M, top boot sector) */ -#define AMD_ID_DL163B 0x222B222B /* 29DL163B ID (16 M, bottom boot sect) */ - -#define AMD_ID_LV320T 0x22F622F6 /* 29LV320T ID (32 M, top boot sector) */ -#define MX_ID_LV320T 0x22A722A7 /* 29LV320T by Macronix, AMD compatible */ -#define AMD_ID_LV320B 0x22F922F9 /* 29LV320B ID (32 M, bottom boot sect) */ -#define MX_ID_LV320B 0x22A822A8 /* 29LV320B by Macronix, AMD compatible */ - -#define AMD_ID_DL322T 0x22552255 /* 29DL322T ID (32 M, top boot sector) */ -#define AMD_ID_DL322B 0x22562256 /* 29DL322B ID (32 M, bottom boot sect) */ -#define AMD_ID_DL323T 0x22502250 /* 29DL323T ID (32 M, top boot sector) */ -#define AMD_ID_DL323B 0x22532253 /* 29DL323B ID (32 M, bottom boot sect) */ -#define AMD_ID_DL324T 0x225C225C /* 29DL324T ID (32 M, top boot sector) */ -#define AMD_ID_DL324B 0x225F225F /* 29DL324B ID (32 M, bottom boot sect) */ - -#define AMD_ID_DL640 0x227E227E /* 29DL640D ID (64 M, dual boot sectors)*/ -#define AMD_ID_MIRROR 0x227E227E /* 1st ID word for MirrorBit family */ -#define AMD_ID_DL640G_2 0x22022202 /* 2nd ID word for AM29DL640G at 0x38 */ -#define AMD_ID_DL640G_3 0x22012201 /* 3rd ID word for AM29DL640G at 0x3c */ -#define AMD_ID_LV640U_2 0x220C220C /* 2nd ID word for AM29LV640M at 0x38 */ -#define AMD_ID_LV640U_3 0x22012201 /* 3rd ID word for AM29LV640M at 0x3c */ -#define AMD_ID_LV640MT_2 0x22102210 /* 2nd ID word for AM29LV640MT at 0x38 */ -#define AMD_ID_LV640MT_3 0x22012201 /* 3rd ID word for AM29LV640MT at 0x3c */ -#define AMD_ID_LV640MB_2 0x22102210 /* 2nd ID word for AM29LV640MB at 0x38 */ -#define AMD_ID_LV640MB_3 0x22002200 /* 3rd ID word for AM29LV640MB at 0x3c */ -#define AMD_ID_LV128U_2 0x22122212 /* 2nd ID word for AM29LV128M at 0x38 */ -#define AMD_ID_LV128U_3 0x22002200 /* 3rd ID word for AM29LV128M at 0x3c */ -#define AMD_ID_LV256U_2 0x22122212 /* 2nd ID word for AM29LV256M at 0x38 */ -#define AMD_ID_LV256U_3 0x22012201 /* 3rd ID word for AM29LV256M at 0x3c */ -#define AMD_ID_GL064M_2 0x22132213 /* 2nd ID word for S29GL064M-R6 */ -#define AMD_ID_GL064M_3 0x22012201 /* 3rd ID word for S29GL064M-R6 */ - -#define AMD_ID_LV320B_2 0x221A221A /* 2d ID word for AM29LV320MB at 0x38 */ -#define AMD_ID_LV320B_3 0x22002200 /* 3d ID word for AM29LV320MB at 0x3c */ - -#define AMD_ID_LV640U 0x22D722D7 /* 29LV640U ID (64 M, uniform sectors) */ - -#define ATM_ID_BV1614 0x000000C0 /* 49BV1614 ID */ -#define ATM_ID_BV1614A 0x000000C8 /* 49BV1614A ID */ -#define ATM_ID_BV6416 0x000000D6 /* 49BV6416 ID */ - -#define FUJI_ID_29F800BA 0x22582258 /* MBM29F800BA ID (8M) */ -#define FUJI_ID_29F800TA 0x22D622D6 /* MBM29F800TA ID (8M) */ -#define FUJI_ID_29LV650UE 0x22d722d7 /* MBM29LV650UE/651UE ID (8M = 128 x 32kWord) */ - -#define SST_ID_xF200A 0x27892789 /* 39xF200A ID ( 2M = 128K x 16 ) */ -#define SST_ID_xF400A 0x27802780 /* 39xF400A ID ( 4M = 256K x 16 ) */ -#define SST_ID_xF800A 0x27812781 /* 39xF800A ID ( 8M = 512K x 16 ) */ -#define SST_ID_xF160A 0x27822782 /* 39xF800A ID (16M = 1M x 16 ) */ -#define SST_ID_xF1601 0x234B234B /* 39xF1601 ID (16M = 1M x 16 ) */ -#define SST_ID_xF1602 0x234A234A /* 39xF1602 ID (16M = 1M x 16 ) */ -#define SST_ID_xF3201 0x235B235B /* 39xF3201 ID (32M = 2M x 16 ) */ -#define SST_ID_xF3202 0x235A235A /* 39xF3202 ID (32M = 2M x 16 ) */ -#define SST_ID_xF6401 0x236B236B /* 39xF6401 ID (64M = 4M x 16 ) */ -#define SST_ID_xF6402 0x236A236A /* 39xF6402 ID (64M = 4M x 16 ) */ -#define SST_ID_xF040 0xBFD7BFD7 /* 39xF040 ID (512KB = 4Mbit x 8) */ - -#define STM_ID_F040B 0xE2 /* M29F040B ID ( 4M = 512K x 8 ) */ - /* 8 64K x 8 uniform sectors */ - -#define STM_ID_x800AB 0x005B005B /* M29W800AB ID (8M = 512K x 16 ) */ -#define STM_ID_29W320DT 0x22CA22CA /* M29W320DT ID (32 M, top boot sector) */ -#define STM_ID_29W320DB 0x22CB22CB /* M29W320DB ID (32 M, bottom boot sect) */ -#define STM_ID_29W040B 0x00E300E3 /* M29W040B ID (4M = 512K x 8) */ - -#define INTEL_ID_28F016S 0x66a066a0 /* 28F016S[VS] ID (16M = 512k x 16) */ -#define INTEL_ID_28F800B3T 0x88928892 /* 8M = 512K x 16 top boot sector */ -#define INTEL_ID_28F800B3B 0x88938893 /* 8M = 512K x 16 bottom boot sector */ -#define INTEL_ID_28F160B3T 0x88908890 /* 16M = 1M x 16 top boot sector */ -#define INTEL_ID_28F160B3B 0x88918891 /* 16M = 1M x 16 bottom boot sector */ -#define INTEL_ID_28F320B3T 0x88968896 /* 32M = 2M x 16 top boot sector */ -#define INTEL_ID_28F320B3B 0x88978897 /* 32M = 2M x 16 bottom boot sector */ -#define INTEL_ID_28F640B3T 0x88988898 /* 64M = 4M x 16 top boot sector */ -#define INTEL_ID_28F640B3B 0x88998899 /* 64M = 4M x 16 bottom boot sector */ -#define INTEL_ID_28F160F3B 0x88F488F4 /* 16M = 1M x 16 bottom boot sector */ - -#define INTEL_ID_28F800C3T 0x88C088C0 /* 8M = 512K x 16 top boot sector */ -#define INTEL_ID_28F800C3B 0x88C188C1 /* 8M = 512K x 16 bottom boot sector */ -#define INTEL_ID_28F160C3T 0x88C288C2 /* 16M = 1M x 16 top boot sector */ -#define INTEL_ID_28F160C3B 0x88C388C3 /* 16M = 1M x 16 bottom boot sector */ -#define INTEL_ID_28F320C3T 0x88C488C4 /* 32M = 2M x 16 top boot sector */ -#define INTEL_ID_28F320C3B 0x88C588C5 /* 32M = 2M x 16 bottom boot sector */ -#define INTEL_ID_28F640C3T 0x88CC88CC /* 64M = 4M x 16 top boot sector */ -#define INTEL_ID_28F640C3B 0x88CD88CD /* 64M = 4M x 16 bottom boot sector */ - -#define INTEL_ID_28F128J3 0x89188918 /* 16M = 8M x 16 x 128 */ -#define INTEL_ID_28F320J5 0x00140014 /* 32M = 128K x 32 */ -#define INTEL_ID_28F640J5 0x00150015 /* 64M = 128K x 64 */ -#define INTEL_ID_28F320J3A 0x00160016 /* 32M = 128K x 32 */ -#define INTEL_ID_28F640J3A 0x00170017 /* 64M = 128K x 64 */ -#define INTEL_ID_28F256L18 0x88108810 /* 32M = 128K x 255 */ -#define INTEL_ID_28F128J3A 0x00180018 /* 128M = 128K x 128 */ -#define INTEL_ID_28F256L18T 0x880D880D /* 256M = 128K x 255 + 32k x 4 */ -#define INTEL_ID_28F256L18B 0x88108810 /* 256M = 32k x 4 + 128K x 255 */ -#define INTEL_ID_28F256P30B 0x891C891C /* 256M = 32k x 4 + 128K x 255 */ -#define INTEL_ID_28F256P30T 0x89198919 /* 256M = 128K x 255 + 32k x 4 */ -#define INTEL_ID_28F64K3 0x88018801 /* 64M = 32K x 255 + 32k x 4 */ -#define INTEL_ID_28F128K3 0x88028802 /* 128M = 64K x 255 + 32k x 4 */ -#define INTEL_ID_28F256K3 0x88038803 /* 256M = 128K x 255 + 32k x 4 */ - -#define INTEL_ID_28F160S3 0x00D000D0 /* 16M = 512K x 32 (64kB x 32) */ -#define INTEL_ID_28F320S3 0x00D400D4 /* 32M = 512K x 64 (64kB x 64) */ - -/* Note that the Sharp 28F016SC is compatible with the Intel E28F016SC */ -#define SHARP_ID_28F016SCL 0xAAAAAAAA /* LH28F016SCT-L95 2Mx8, 32 64k blocks */ -#define SHARP_ID_28F016SCZ 0xA0A0A0A0 /* LH28F016SCT-Z4 2Mx8, 32 64k blocks */ -#define SHARP_ID_28F008SC 0xA6A6A6A6 /* LH28F008SCT-L12 1Mx8, 16 64k blocks */ - /* LH28F008SCR-L85 1Mx8, 16 64k blocks */ - -#define TOSH_ID_FVT160 0xC2 /* TC58FVT160 ID (16 M, top ) */ -#define TOSH_ID_FVB160 0x43 /* TC58FVT160 ID (16 M, bottom ) */ - -/*----------------------------------------------------------------------- - * Internal FLASH identification codes - * - * Be careful when adding new type! Odd numbers are "bottom boot sector" types! - */ - -#define FLASH_AM040 0x0001 /* AMD Am29F040B, Am29LV040B */ - /* Bright Micro BM29F040 */ - /* Fujitsu MBM29F040A */ - /* STM M29W040B */ - /* SGS Thomson M29F040B */ - /* 8 64K x 8 uniform sectors */ -#define FLASH_AM400T 0x0002 /* AMD AM29LV400 */ -#define FLASH_AM400B 0x0003 -#define FLASH_AM800T 0x0004 /* AMD AM29LV800 */ -#define FLASH_AM800B 0x0005 -#define FLASH_AM116DT 0x0026 /* AMD AM29LV116DT (2Mx8bit) */ -#define FLASH_AM116DB 0x0027 /* AMD AM29LV116DB (2Mx8bit) */ -#define FLASH_AM160T 0x0006 /* AMD AM29LV160 */ -#define FLASH_AM160LV 0x0046 /* AMD29LV160DB (2M = 2Mx8bit ) */ -#define FLASH_AM160B 0x0007 -#define FLASH_AM320T 0x0008 /* AMD AM29LV320 */ -#define FLASH_AM320B 0x0009 - -#define FLASH_AM080 0x000A /* AMD Am29F080B */ - /* 16 64K x 8 uniform sectors */ - -#define FLASH_AMDL322T 0x0010 /* AMD AM29DL322 */ -#define FLASH_AMDL322B 0x0011 -#define FLASH_AMDL323T 0x0012 /* AMD AM29DL323 */ -#define FLASH_AMDL323B 0x0013 -#define FLASH_AMDL324T 0x0014 /* AMD AM29DL324 */ -#define FLASH_AMDL324B 0x0015 - -#define FLASH_AMDLV033C 0x0018 -#define FLASH_AMDLV065D 0x001A - -#define FLASH_AMDL640 0x0016 /* AMD AM29DL640D */ -#define FLASH_AMD016 0x0018 /* AMD AM29F016D */ -#define FLASH_AMDL640MB 0x0019 /* AMD AM29LV640MB (64M, bottom boot sect)*/ -#define FLASH_AMDL640MT 0x001A /* AMD AM29LV640MT (64M, top boot sect) */ - -#define FLASH_SST200A 0x0040 /* SST 39xF200A ID ( 2M = 128K x 16 ) */ -#define FLASH_SST400A 0x0042 /* SST 39xF400A ID ( 4M = 256K x 16 ) */ -#define FLASH_SST800A 0x0044 /* SST 39xF800A ID ( 8M = 512K x 16 ) */ -#define FLASH_SST160A 0x0046 /* SST 39xF160A ID ( 16M = 1M x 16 ) */ -#define FLASH_SST320 0x0048 /* SST 39xF160A ID ( 16M = 1M x 16 ) */ -#define FLASH_SST640 0x004A /* SST 39xF160A ID ( 16M = 1M x 16 ) */ -#define FLASH_SST040 0x000E /* SST 39xF040 ID (512KB = 4Mbit x 8 ) */ - -#define FLASH_STM800AB 0x0051 /* STM M29WF800AB ( 8M = 512K x 16 ) */ -#define FLASH_STMW320DT 0x0052 /* STM M29W320DT (32 M, top boot sector) */ -#define FLASH_STMW320DB 0x0053 /* STM M29W320DB (32 M, bottom boot sect)*/ -#define FLASH_STM320DB 0x00CB /* STM M29W320DB (4M = 64K x 64, bottom)*/ -#define FLASH_STM800DT 0x00D7 /* STM M29W800DT (1M = 64K x 16, top) */ -#define FLASH_STM800DB 0x005B /* STM M29W800DB (1M = 64K x 16, bottom)*/ - -#define FLASH_28F400_T 0x0062 /* MT 28F400B3 ID ( 4M = 256K x 16 ) */ -#define FLASH_28F400_B 0x0063 /* MT 28F400B3 ID ( 4M = 256K x 16 ) */ - -#define FLASH_INTEL800T 0x0074 /* INTEL 28F800B3T ( 8M = 512K x 16 ) */ -#define FLASH_INTEL800B 0x0075 /* INTEL 28F800B3B ( 8M = 512K x 16 ) */ -#define FLASH_INTEL160T 0x0076 /* INTEL 28F160B3T ( 16M = 1 M x 16 ) */ -#define FLASH_INTEL160B 0x0077 /* INTEL 28F160B3B ( 16M = 1 M x 16 ) */ -#define FLASH_INTEL320T 0x0078 /* INTEL 28F320B3T ( 32M = 2 M x 16 ) */ -#define FLASH_INTEL320B 0x0079 /* INTEL 28F320B3B ( 32M = 2 M x 16 ) */ -#define FLASH_INTEL640T 0x007A /* INTEL 28F320B3T ( 64M = 4 M x 16 ) */ -#define FLASH_INTEL640B 0x007B /* INTEL 28F320B3B ( 64M = 4 M x 16 ) */ - -#define FLASH_28F008S5 0x0080 /* Intel 28F008S5 ( 1M = 64K x 16 ) */ -#define FLASH_28F016SV 0x0081 /* Intel 28F016SV ( 16M = 512k x 32 ) */ -#define FLASH_28F800_B 0x0083 /* Intel E28F800B ( 1M = ? ) */ -#define FLASH_AM29F800B 0x0084 /* AMD Am29F800BB ( 1M = ? ) */ -#define FLASH_28F320J5 0x0085 /* Intel 28F320J5 ( 4M = 128K x 32 ) */ -#define FLASH_28F160S3 0x0086 /* Intel 28F160S3 ( 16M = 512K x 32 ) */ -#define FLASH_28F320S3 0x0088 /* Intel 28F320S3 ( 32M = 512K x 64 ) */ -#define FLASH_AM640U 0x0090 /* AMD Am29LV640U ( 64M = 4M x 16 ) */ -#define FLASH_AM033C 0x0091 /* AMD AM29LV033 ( 32M = 4M x 8 ) */ -#define FLASH_LH28F016SCT 0x0092 /* Sharp 28F016SCT ( 8 Meg Flash SIMM ) */ -#define FLASH_28F160F3B 0x0093 /* Intel 28F160F3B ( 16M = 1M x 16 ) */ - -#define FLASH_28F640J5 0x0099 /* INTEL 28F640J5 ( 64M = 128K x 64) */ - -#define FLASH_28F800C3T 0x009A /* Intel 28F800C3T ( 8M = 512K x 16 ) */ -#define FLASH_28F800C3B 0x009B /* Intel 28F800C3B ( 8M = 512K x 16 ) */ -#define FLASH_28F160C3T 0x009C /* Intel 28F160C3T ( 16M = 1M x 16 ) */ -#define FLASH_28F160C3B 0x009D /* Intel 28F160C3B ( 16M = 1M x 16 ) */ -#define FLASH_28F320C3T 0x009E /* Intel 28F320C3T ( 32M = 2M x 16 ) */ -#define FLASH_28F320C3B 0x009F /* Intel 28F320C3B ( 32M = 2M x 16 ) */ -#define FLASH_28F640C3T 0x00A0 /* Intel 28F640C3T ( 64M = 4M x 16 ) */ -#define FLASH_28F640C3B 0x00A1 /* Intel 28F640C3B ( 64M = 4M x 16 ) */ -#define FLASH_AMLV320U 0x00A2 /* AMD 29LV320M ( 32M = 2M x 16 ) */ -#define FLASH_AMLV640U 0x00A4 /* AMD 29LV640M ( 64M = 4M x 16 ) */ -#define FLASH_AMLV128U 0x00A6 /* AMD 29LV128M ( 128M = 8M x 16 ) */ -#define FLASH_AMLV320B 0x00A7 /* AMD 29LV320MB ( 32M = 2M x 16 ) */ -#define FLASH_AMLV320T 0x00A8 /* AMD 29LV320MT ( 32M = 2M x 16 ) */ -#define FLASH_AMLV256U 0x00AA /* AMD 29LV256M ( 256M = 16M x 16 ) */ -#define FLASH_MXLV320B 0x00AB /* MX 29LV320MB ( 32M = 2M x 16 ) */ -#define FLASH_MXLV320T 0x00AC /* MX 29LV320MT ( 32M = 2M x 16 ) */ -#define FLASH_28F256L18T 0x00B0 /* Intel 28F256L18T ( 32M = 128K x 255 + 32k x 4) */ -#define FLASH_28F256L18B 0x00B1 /* Intel 28F256L18B ( 32M = 32k x 4 + 128K x 255) */ -#define FLASH_28F256P30B 0x001C /* Intel 28F256P30B ( 32M = 32k x 4 + 128K x 255) */ -#define FLASH_28F256P30T 0x0019 /* Intel 28F256P30T ( 128K x 255 + 32M = 32k x 4 + */ -#define FLASH_AMDL163T 0x00B2 /* AMD AM29DL163T (2M x 16 ) */ -#define FLASH_AMDL163B 0x00B3 -#define FLASH_28F64K3 0x00B4 /* Intel 28F64K3 ( 64M) */ -#define FLASH_28F128K3 0x00B6 /* Intel 28F128K3 ( 128M = 8M x 16 ) */ -#define FLASH_28F256K3 0x00B8 /* Intel 28F256K3 ( 256M = 16M x 16 ) */ - -#define FLASH_28F320J3A 0x00C0 /* INTEL 28F320J3A ( 32M = 128K x 32) */ -#define FLASH_28F640J3A 0x00C2 /* INTEL 28F640J3A ( 64M = 128K x 64) */ -#define FLASH_28F128J3A 0x00C4 /* INTEL 28F128J3A (128M = 128K x 128) */ - -#define FLASH_FUJLV650 0x00D0 /* Fujitsu MBM 29LV650UE/651UE */ -#define FLASH_MT28S4M16LC 0x00E1 /* Micron MT28S4M16LC */ -#define FLASH_S29GL064M 0x00F0 /* Spansion S29GL064M-R6 */ - -#define FLASH_UNKNOWN 0xFFFF /* unknown flash type */ - - -/* manufacturer offsets - */ -#define FLASH_MAN_AMD 0x00000000 /* AMD */ -#define FLASH_MAN_FUJ 0x00010000 /* Fujitsu */ -#define FLASH_MAN_BM 0x00020000 /* Bright Microelectronics */ -#define FLASH_MAN_MX 0x00030000 /* MXIC */ -#define FLASH_MAN_STM 0x00040000 -#define FLASH_MAN_TOSH 0x00050000 /* Toshiba */ -#define FLASH_MAN_EXCEL 0x00060000 /* Excel Semiconductor */ -#define FLASH_MAN_SST 0x00100000 -#define FLASH_MAN_INTEL 0x00300000 -#define FLASH_MAN_MT 0x00400000 -#define FLASH_MAN_SHARP 0x00500000 - - -#define FLASH_TYPEMASK 0x0000FFFF /* extract FLASH type information */ -#define FLASH_VENDMASK 0xFFFF0000 /* extract FLASH vendor information */ - -#define FLASH_AMD_COMP 0x000FFFFF /* Up to this ID, FLASH is compatible */ - /* with AMD, Fujitsu and SST */ - /* (JEDEC standard commands ?) */ - -#define FLASH_BTYPE 0x0001 /* mask for bottom boot sector type */ - -/*----------------------------------------------------------------------- - * Timeout constants: - * - * We can't find any specifications for maximum chip erase times, - * so these values are guestimates. - */ -#define FLASH_ERASE_TIMEOUT 120000 /* timeout for erasing in ms */ -#define FLASH_WRITE_TIMEOUT 500 /* timeout for writes in ms */ - -#endif /* !CFG_NO_FLASH */ - -#endif /* _FLASH_H_ */ diff --git a/board/mcc200/mcc200.c b/board/mcc200/mcc200.c index d7f95c83d0..47073907e1 100644 --- a/board/mcc200/mcc200.c +++ b/board/mcc200/mcc200.c @@ -36,6 +36,8 @@ #include "mt48lc8m32b2-6-7.h" #endif +extern flash_info_t flash_info[]; /* FLASH chips info */ + //###CHD: wenn RAMBOOT gehen wuerde, .... #ifndef CFG_RAMBOOT static void sdram_start (int hi_addr) @@ -244,46 +246,56 @@ int checkboard (void) return 0; } -void flash_preinit(void) -{ - /* - * Now, when we are in RAM, enable flash write - * access for detection process. - * Note that CS_BOOT cannot be cleared when - * executing in flash. - */ -#if defined(CONFIG_MGT5100) - *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */ - *(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */ -#endif - *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */ -} - -void flash_afterinit(ulong start, ulong size) -{ -#if defined(CONFIG_BOOT_ROM) - /* adjust mapping */ - *(vu_long *)MPC5XXX_CS1_START = - START_REG(start); - *(vu_long *)MPC5XXX_CS1_STOP = - STOP_REG(start, size); -#else - /* adjust mapping */ - *(vu_long *)MPC5XXX_BOOTCS_START = *(vu_long *)MPC5XXX_CS0_START = - START_REG(start); - *(vu_long *)MPC5XXX_BOOTCS_STOP = *(vu_long *)MPC5XXX_CS0_STOP = - STOP_REG(start, size); -#endif -} - - -extern flash_info_t flash_info[]; /* info for FLASH chips */ - int misc_init_r (void) { DECLARE_GLOBAL_DATA_PTR; - /* adjust flash start */ - gd->bd->bi_flashstart = flash_info[0].start[0]; + + /* + * Adjust flash start and offset to detected values + */ + gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize; + gd->bd->bi_flashoffset = 0; + + /* + * Check if boot FLASH isn't max size + */ + if (gd->bd->bi_flashsize < (0 - CFG_FLASH_BASE)) { + /* adjust mapping */ + *(vu_long *)MPC5XXX_BOOTCS_START = *(vu_long *)MPC5XXX_CS0_START = + START_REG(gd->bd->bi_flashstart); + *(vu_long *)MPC5XXX_BOOTCS_STOP = *(vu_long *)MPC5XXX_CS0_STOP = + STOP_REG(gd->bd->bi_flashstart, gd->bd->bi_flashsize); + + /* + * Re-check to get correct base address + */ + flash_get_size(gd->bd->bi_flashstart, CFG_MAX_FLASH_BANKS - 1); + + /* + * Re-do flash protection upon new addresses + */ + flash_protect (FLAG_PROTECT_CLEAR, + gd->bd->bi_flashstart, 0xffffffff, + &flash_info[CFG_MAX_FLASH_BANKS - 1]); + + /* Monitor protection ON by default */ + flash_protect (FLAG_PROTECT_SET, + CFG_MONITOR_BASE, CFG_MONITOR_BASE + monitor_flash_len - 1, + &flash_info[CFG_MAX_FLASH_BANKS - 1]); + + /* Environment protection ON by default */ + flash_protect (FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1, + &flash_info[CFG_MAX_FLASH_BANKS - 1]); + + /* Redundant environment protection ON by default */ + flash_protect (FLAG_PROTECT_SET, + CFG_ENV_ADDR_REDUND, + CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1, + &flash_info[CFG_MAX_FLASH_BANKS - 1]); + } + return (0); } diff --git a/include/configs/mcc200.h b/include/configs/mcc200.h index 5f1fd8895a..a8a8934012 100644 --- a/include/configs/mcc200.h +++ b/include/configs/mcc200.h @@ -52,15 +52,11 @@ #define CONFIG_BAUDRATE 115200 #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 230400 } - -//###CHD: MPC5100 gibt es nicht -> weg damit! -#ifdef CONFIG_MPC5200 /* MPC5100 PCI is not supported yet. */ /* * PCI Mapping: * 0x40000000 - 0x4fffffff - PCI Memory * 0x50000000 - 0x50ffffff - PCI IO Space */ -//Wenn geht PCI raus! #define CONFIG_PCI 1 #define CONFIG_PCI_PNP 1 #define CONFIG_PCI_SCAN_SHOW 1 @@ -82,12 +78,6 @@ #define ADD_PCI_CMD CFG_CMD_PCI -#else /* MPC5100 */ - -#define ADD_PCI_CMD 0 /* no CFG_CMD_PCI */ - -#endif - /* Partitions */ #define CONFIG_DOS_PARTITION @@ -100,12 +90,7 @@ #define ADD_USB_CMD 0 #endif -//###CHD: BOOTROm raus! -#if defined(CONFIG_BOOT_ROM) -#define ADD_DOC_CMD 0 -#else #define ADD_DOC_CMD CFG_CMD_DOC -#endif /* * Supported commands @@ -120,7 +105,6 @@ CFG_CMD_EEPROM | \ CFG_CMD_FAT | \ CFG_CMD_I2C | \ - CFG_CMD_IDE | \ CFG_CMD_NFS | \ CFG_CMD_SNTP ) @@ -140,7 +124,7 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ "netdev=eth0\0" \ - "hostname=lmpc\0" \ + "hostname=mcc200\0" \ "nfsargs=setenv bootargs root=/dev/nfs rw " \ "nfsroot=${serverip}:${rootpath}\0" \ "ramargs=setenv bootargs root=/dev/ram rw\0" \ @@ -152,24 +136,28 @@ "flash_self=run ramargs addip;" \ "bootm ${kernel_addr} ${ramdisk_addr}\0" \ "net_nfs=tftp 200000 ${bootfile};run nfsargs addip;bootm\0" \ - "rootpath=/opt/eldk30/ppc_82xx\0" \ - "bootfile=/tftpboot/LMPC/uImage\0" \ + "rootpath=/opt/eldk/ppc_82xx\0" \ + "bootfile=/tftpboot/mcc200/uImage\0" \ "baudrate=115200\0" \ - "serverip=192.168.0.1\0" \ - "ipaddr=192.168.0.2\0" \ - "ethaddr=00:02:44:7d:73:3b\0" \ + "load=tftp 100000 /tftpboot/mcc200/u-boot.bin\0" \ + "update=protect off fff00000 fff3ffff;era fff00000 fff3ffff;" \ + "cp.b 100000 fff00000 40000;" \ + "setenv filesize;saveenv\0" \ + "upd=run load;run update\0" \ + "serverip=192.168.1.1\0" \ + "ipaddr=192.168.133.144\0" \ + "netmask=255.255.0.0\0" \ + "unlock=yes\0" \ + "ethaddr=00:02:44:7d:73:3b\0" \ "" #define CONFIG_BOOTCOMMAND "run flash_self" -#if defined(CONFIG_MPC5200) /* * IPB Bus clocking configuration. */ #undef CFG_IPBSPEED_133 /* define for 133MHz speed */ -#endif -//###CHD: EEProm config RTC config sollte raus, gibt es nciht bei uns auf I2C! /* * I2C configuration */ @@ -193,11 +181,9 @@ #define CONFIG_RTC_PCF8563 #define CFG_I2C_RTC_ADDR 0x51 -//###CHD: meiner Ansicht nach auch raus! /* * Disk-On-Chip configuration */ - #define CFG_DOC_SHORT_TIMEOUT #define CFG_MAX_DOC_DEVICE 1 /* Max number of DOC devices */ @@ -206,56 +192,46 @@ #define CFG_DOC_BASE 0xE0000000 #define CFG_DOC_SIZE 0x00100000 -//###CHD: BOOTROm raus! -#if defined(CONFIG_BOOT_ROM) /* * Flash configuration (8,16 or 32 MB) * TEXT base always at 0xFFF00000 * ENV_ADDR always at 0xFFF40000 - * FLASH_BASE at 0xFC000000 for 32 MB - * 0xFD000000 for 16 MB - * 0xFD800000 for 8 MB - */ -#define CFG_FLASH_BASE 0xfc000000 -#define CFG_FLASH_SIZE 0x02000000 -#define CFG_BOOTROM_BASE 0xFFF00000 -#define CFG_BOOTROM_SIZE 0x00080000 -#define CFG_ENV_ADDR (0xFDF00000 + 0x40000) -#else -/* - * Flash configuration (8,16 or 32 MB) - * TEXT base always at 0xFFF00000 - * ENV_ADDR always at 0xFFF40000 - * FLASH_BASE at 0xFE000000 for 32 MB + * FLASH_BASE at 0xFC000000 for 64 MB (only 32MB are supported, not enough addr lines!!!) + * 0xFE000000 for 32 MB * 0xFF000000 for 16 MB * 0xFF800000 for 8 MB */ -#define CFG_FLASH_BASE 0xfe000000 -#define CFG_FLASH_SIZE 0x02000000 -#define CFG_ENV_ADDR (0xFFF00000 + 0x40000) -#endif -#define CFG_MAX_FLASH_BANKS 1 /* max num of memory banks */ +#define CFG_FLASH_BASE 0xfc000000 +#define CFG_FLASH_SIZE 0x04000000 -#define CFG_MAX_FLASH_SECT 128 /* max num of sects on one chip */ +#define CFG_FLASH_CFI /* The flash is CFI compatible */ +#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ -#define CFG_FLASH_ERASE_TOUT 240000 /* Flash Erase Timeout (in ms) */ -#define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (in ms) */ -#define CFG_FLASH_LOCK_TOUT 5 /* Timeout for Flash Set Lock Bit (in ms) */ -#define CFG_FLASH_UNLOCK_TOUT 10000 /* Timeout for Flash Clear Lock Bits (in ms) */ -#define CFG_FLASH_PROTECTION /* "Real" (hardware) sectors protection */ +#define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } -#define PHYS_FLASH_SECT_SIZE 0x00040000 /* 256 KB sectors (x2) */ +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 512 /* max number of sectors on one chip */ -#undef CONFIG_FLASH_16BIT /* Flash is 32-bit */ +#define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ +#define CFG_FLASH_PROTECTION 1 /* hardware flash protection */ +#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ -/* - * Environment settings - */ -#define CFG_ENV_IS_IN_FLASH 1 -#define CFG_ENV_SIZE 0x10000 -#define CFG_ENV_SECT_SIZE 0x40000 -#define CONFIG_ENV_OVERWRITE 1 +#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ +#define CFG_FLASH_QUIET_TEST 1 /* don't warn upon unknown flash */ + +#define CFG_ENV_IS_IN_FLASH 1 /* use FLASH for environment vars */ + +#define CFG_ENV_SECT_SIZE 0x40000 /* size of one complete sector */ +#define CFG_ENV_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN) +#define CFG_ENV_SIZE 0x2000 /* Total Size of Environment Sector */ + +/* Address and size of Redundant Environment Sector */ +#define CFG_ENV_ADDR_REDUND (CFG_ENV_ADDR + CFG_ENV_SECT_SIZE) +#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE) + +#define CONFIG_ENV_OVERWRITE 1 /* allow modification of vendor params */ /* * Memory map @@ -279,7 +255,7 @@ #endif #define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ -#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ +#define CFG_MALLOC_LEN (512 << 10) /* Reserve 512 kB for malloc() */ #define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ /* @@ -290,7 +266,7 @@ * Define CONFIG_FEC_10MBIT to force FEC at 10Mb */ /* #define CONFIG_FEC_10MBIT 1 */ -#define CONFIG_PHY_ADDR 0x00 +#define CONFIG_PHY_ADDR 1 /* * GPIO configuration @@ -324,25 +300,9 @@ /* * Various low-level settings */ -#if defined(CONFIG_MPC5200) #define CFG_HID0_INIT HID0_ICE | HID0_ICFI #define CFG_HID0_FINAL HID0_ICE -#else -#define CFG_HID0_INIT 0 -#define CFG_HID0_FINAL 0 -#endif -//###CHD: hier sollte das BOOT_ROM raus! -#if defined(CONFIG_BOOT_ROM) -#define CFG_BOOTCS_START CFG_BOOTROM_BASE -#define CFG_BOOTCS_SIZE CFG_BOOTROM_SIZE -#define CFG_BOOTCS_CFG 0x00047800 -#define CFG_CS0_START CFG_BOOTROM_BASE -#define CFG_CS0_SIZE CFG_BOOTROM_SIZE -#define CFG_CS1_START CFG_FLASH_BASE -#define CFG_CS1_SIZE CFG_FLASH_SIZE -#define CFG_CS1_CFG 0x0004fb00 -#else #define CFG_BOOTCS_START CFG_FLASH_BASE #define CFG_BOOTCS_SIZE CFG_FLASH_SIZE #define CFG_BOOTCS_CFG 0x0004fb00 @@ -351,7 +311,6 @@ #define CFG_CS1_START CFG_DOC_BASE #define CFG_CS1_SIZE CFG_DOC_SIZE #define CFG_CS1_CFG 0x00047800 -#endif #define CFG_CS_BURST 0x00000000 #define CFG_CS_DEADCYCLE 0x33333333 @@ -365,38 +324,4 @@ #define CONFIG_USB_CLOCK 0x0001BBBB #define CONFIG_USB_CONFIG 0x00005000 -/*----------------------------------------------------------------------- - * IDE/ATA stuff Supports IDE harddisk - *----------------------------------------------------------------------- - */ - -//###CHD: eigentlich das ganze IDE zeugs raus (IDE wird derzeit nciht mehr gescannt!) -#undef CONFIG_IDE_8xx_PCCARD /* Use IDE with PC Card Adapter */ - -#undef CONFIG_IDE_8xx_DIRECT /* Direct IDE not supported */ -#undef CONFIG_IDE_LED /* LED for ide not supported */ - -#undef CONFIG_IDE_RESET /* reset for ide supported */ -#define CONFIG_IDE_PREINIT -#undef CONFIG_IDE_PREINIT - -#define CFG_IDE_MAXBUS 0 /* max. 1 IDE bus */ -#define CFG_IDE_MAXDEVICE 2 /* max. 2 drive per IDE bus */ - -#define CFG_ATA_IDE0_OFFSET 0x0000 - -#define CFG_ATA_BASE_ADDR MPC5XXX_ATA - -/* Offset for data I/O */ -#define CFG_ATA_DATA_OFFSET (0x0060) - -/* Offset for normal register accesses */ -#define CFG_ATA_REG_OFFSET (CFG_ATA_DATA_OFFSET) - -/* Offset for alternate registers */ -#define CFG_ATA_ALT_OFFSET (0x005C) - -/* Interval between registers */ -#define CFG_ATA_STRIDE 4 - #endif /* __CONFIG_H */ From 6949328d7df7a98b88a8edc0f7238687a3083a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Tue, 28 Feb 2006 18:05:25 +0100 Subject: [PATCH 021/102] First steps implementing NAND support. Not working, fails to read ID. --- Makefile | 5 +- board/delta/Makefile | 2 +- board/delta/config.mk | 3 + board/delta/delta.c | 2 +- board/delta/flash.c | 434 ---------------------------- board/delta/nand.c | 306 ++++++++++++++++++++ include/asm-arm/arch-pxa/pxa-regs.h | 79 ++++- include/configs/delta.h | 68 +++-- lib_arm/board.c | 4 + 9 files changed, 423 insertions(+), 480 deletions(-) delete mode 100644 board/delta/flash.c create mode 100644 board/delta/nand.c diff --git a/Makefile b/Makefile index 516bf2c192..26f5ae638d 100644 --- a/Makefile +++ b/Makefile @@ -208,6 +208,9 @@ etags: net disk rtc dtt drivers drivers/sk98lin common \ \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)` +ctags: + ctags -Re + System.map: u-boot @$(NM) $< | \ grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ @@ -1874,7 +1877,7 @@ clobber: clean -o -name '*.srec' -o -name '*.bin' -o -name u-boot.img \) \ -print0 \ | xargs -0 rm -f - rm -f $(OBJS) *.bak tags TAGS include/version_autogenerated.h + rm -f $(OBJS) *.bak tags include/version_autogenerated.h rm -fr *.*~ rm -f u-boot u-boot.map u-boot.hex $(ALL) diff --git a/board/delta/Makefile b/board/delta/Makefile index d968efbf81..e744eec2e0 100644 --- a/board/delta/Makefile +++ b/board/delta/Makefile @@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk LIB = lib$(BOARD).a -OBJS := delta.o flash.o +OBJS := delta.o nand.o SOBJS := lowlevel_init.o $(LIB): $(OBJS) $(SOBJS) diff --git a/board/delta/config.mk b/board/delta/config.mk index d48fe054a0..b269b6efa1 100644 --- a/board/delta/config.mk +++ b/board/delta/config.mk @@ -4,3 +4,6 @@ #TEXT_BASE = 0x9ffe0000 TEXT_BASE = 0xa3008000 +# Compile the new NAND code (needed iff #ifdef CONFIG_NEW_NAND_CODE) +BOARDLIBS = drivers/nand/libnand.a + diff --git a/board/delta/delta.c b/board/delta/delta.c index e618ab96a1..3ffcc2af9b 100644 --- a/board/delta/delta.c +++ b/board/delta/delta.c @@ -41,7 +41,7 @@ int board_init (void) /* memory and cpu-speed are setup before relocation */ /* so we do _nothing_ here */ - /* arch number of Lubbock-Board */ + /* arch number of Lubbock-Board mk@tbd: fix this! */ gd->bd->bi_arch_number = MACH_TYPE_LUBBOCK; /* adress of boot parameters */ diff --git a/board/delta/flash.c b/board/delta/flash.c deleted file mode 100644 index 883c1ba3b3..0000000000 --- a/board/delta/flash.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * (C) Copyright 2001 - * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net - * - * (C) Copyright 2001 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - - -flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ - -/* Board support for 1 or 2 flash devices */ -#define FLASH_PORT_WIDTH32 -#undef FLASH_PORT_WIDTH16 - -#ifdef FLASH_PORT_WIDTH16 -#define FLASH_PORT_WIDTH ushort -#define FLASH_PORT_WIDTHV vu_short -#define SWAP(x) __swab16(x) -#else -#define FLASH_PORT_WIDTH ulong -#define FLASH_PORT_WIDTHV vu_long -#define SWAP(x) __swab32(x) -#endif - -#define FPW FLASH_PORT_WIDTH -#define FPWV FLASH_PORT_WIDTHV - -#define mb() __asm__ __volatile__ ("" : : : "memory") - -/*----------------------------------------------------------------------- - * Functions - */ -static ulong flash_get_size (FPW *addr, flash_info_t *info); -static int write_data (flash_info_t *info, ulong dest, FPW data); -static void flash_get_offsets (ulong base, flash_info_t *info); -void inline spin_wheel (void); - -/*----------------------------------------------------------------------- - */ - -unsigned long flash_init (void) -{ -#if 0 - int i; - ulong size = 0; - - for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { - switch (i) { - case 0: - flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]); - flash_get_offsets (PHYS_FLASH_1, &flash_info[i]); - break; - case 1: - flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]); - flash_get_offsets (PHYS_FLASH_2, &flash_info[i]); - break; - default: - panic ("configured too many flash banks!\n"); - break; - } - size += flash_info[i].size; - } - - /* Protect monitor and environment sectors - */ - flash_protect ( FLAG_PROTECT_SET, - CFG_FLASH_BASE, - CFG_FLASH_BASE + monitor_flash_len - 1, - &flash_info[0] ); - - flash_protect ( FLAG_PROTECT_SET, - CFG_ENV_ADDR, - CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] ); - - return size; -#endif - return 0; -} - -/*----------------------------------------------------------------------- - */ -static void flash_get_offsets (ulong base, flash_info_t *info) -{ - int i; - - if (info->flash_id == FLASH_UNKNOWN) { - return; - } - - if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { - for (i = 0; i < info->sector_count; i++) { - info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE); - info->protect[i] = 0; - } - } -} - -/*----------------------------------------------------------------------- - */ -void flash_print_info (flash_info_t *info) -{ - int i; - - if (info->flash_id == FLASH_UNKNOWN) { - printf ("missing or unknown FLASH type\n"); - return; - } - - switch (info->flash_id & FLASH_VENDMASK) { - case FLASH_MAN_INTEL: - printf ("INTEL "); - break; - default: - printf ("Unknown Vendor "); - break; - } - - switch (info->flash_id & FLASH_TYPEMASK) { - case FLASH_28F128J3A: - printf ("28F128J3A\n"); - break; - default: - printf ("Unknown Chip Type\n"); - break; - } - - printf (" Size: %ld MB in %d Sectors\n", - info->size >> 20, info->sector_count); - - printf (" Sector Start Addresses:"); - for (i = 0; i < info->sector_count; ++i) { - if ((i % 5) == 0) - printf ("\n "); - printf (" %08lX%s", - info->start[i], - info->protect[i] ? " (RO)" : " "); - } - printf ("\n"); - return; -} - -/* - * The following code cannot be run from FLASH! - */ -static ulong flash_get_size (FPW *addr, flash_info_t *info) -{ - volatile FPW value; - - /* Write auto select command: read Manufacturer ID */ - addr[0x5555] = (FPW) 0x00AA00AA; - addr[0x2AAA] = (FPW) 0x00550055; - addr[0x5555] = (FPW) 0x00900090; - - mb (); - value = addr[0]; - - switch (value) { - - case (FPW) INTEL_MANUFACT: - info->flash_id = FLASH_MAN_INTEL; - break; - - default: - info->flash_id = FLASH_UNKNOWN; - info->sector_count = 0; - info->size = 0; - addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ - return (0); /* no or unknown flash */ - } - - mb (); - value = addr[1]; /* device ID */ - - switch (value) { - - case (FPW) INTEL_ID_28F128J3A: - info->flash_id += FLASH_28F128J3A; - info->sector_count = 128; - info->size = 0x02000000; - break; /* => 16 MB */ - - default: - info->flash_id = FLASH_UNKNOWN; - break; - } - - if (info->sector_count > CFG_MAX_FLASH_SECT) { - printf ("** ERROR: sector count %d > max (%d) **\n", - info->sector_count, CFG_MAX_FLASH_SECT); - info->sector_count = CFG_MAX_FLASH_SECT; - } - - addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ - - return (info->size); -} - - -/*----------------------------------------------------------------------- - */ - -int flash_erase (flash_info_t *info, int s_first, int s_last) -{ - int flag, prot, sect; - ulong type, start, last; - int rcode = 0; - - if ((s_first < 0) || (s_first > s_last)) { - if (info->flash_id == FLASH_UNKNOWN) { - printf ("- missing\n"); - } else { - printf ("- no sectors to erase\n"); - } - return 1; - } - - type = (info->flash_id & FLASH_VENDMASK); - if ((type != FLASH_MAN_INTEL)) { - printf ("Can't erase unknown flash type %08lx - aborted\n", - info->flash_id); - return 1; - } - - prot = 0; - for (sect = s_first; sect <= s_last; ++sect) { - if (info->protect[sect]) { - prot++; - } - } - - if (prot) { - printf ("- Warning: %d protected sectors will not be erased!\n", - prot); - } else { - printf ("\n"); - } - - start = get_timer (0); - last = start; - - /* Disable interrupts which might cause a timeout here */ - flag = disable_interrupts (); - - /* Start erase on unprotected sectors */ - for (sect = s_first; sect <= s_last; sect++) { - if (info->protect[sect] == 0) { /* not protected */ - FPWV *addr = (FPWV *) (info->start[sect]); - FPW status; - - printf ("Erasing sector %2d ... ", sect); - - /* arm simple, non interrupt dependent timer */ - reset_timer_masked (); - - *addr = (FPW) 0x00500050; /* clear status register */ - *addr = (FPW) 0x00200020; /* erase setup */ - *addr = (FPW) 0x00D000D0; /* erase confirm */ - - while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { - if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { - printf ("Timeout\n"); - *addr = (FPW) 0x00B000B0; /* suspend erase */ - *addr = (FPW) 0x00FF00FF; /* reset to read mode */ - rcode = 1; - break; - } - } - - *addr = 0x00500050; /* clear status register cmd. */ - *addr = 0x00FF00FF; /* resest to read mode */ - - printf (" done\n"); - } - } - return rcode; -} - -/*----------------------------------------------------------------------- - * Copy memory to flash, returns: - * 0 - OK - * 1 - write timeout - * 2 - Flash not erased - * 4 - Flash not identified - */ - -int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) -{ - ulong cp, wp; - FPW data; - int count, i, l, rc, port_width; - - if (info->flash_id == FLASH_UNKNOWN) { - return 4; - } -/* get lower word aligned address */ -#ifdef FLASH_PORT_WIDTH16 - wp = (addr & ~1); - port_width = 2; -#else - wp = (addr & ~3); - port_width = 4; -#endif - - /* - * handle unaligned start bytes - */ - if ((l = addr - wp) != 0) { - data = 0; - for (i = 0, cp = wp; i < l; ++i, ++cp) { - data = (data << 8) | (*(uchar *) cp); - } - for (; i < port_width && cnt > 0; ++i) { - data = (data << 8) | *src++; - --cnt; - ++cp; - } - for (; cnt == 0 && i < port_width; ++i, ++cp) { - data = (data << 8) | (*(uchar *) cp); - } - - if ((rc = write_data (info, wp, SWAP (data))) != 0) { - return (rc); - } - wp += port_width; - } - - /* - * handle word aligned part - */ - count = 0; - while (cnt >= port_width) { - data = 0; - for (i = 0; i < port_width; ++i) { - data = (data << 8) | *src++; - } - if ((rc = write_data (info, wp, SWAP (data))) != 0) { - return (rc); - } - wp += port_width; - cnt -= port_width; - if (count++ > 0x800) { - spin_wheel (); - count = 0; - } - } - - if (cnt == 0) { - return (0); - } - - /* - * handle unaligned tail bytes - */ - data = 0; - for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { - data = (data << 8) | *src++; - --cnt; - } - for (; i < port_width; ++i, ++cp) { - data = (data << 8) | (*(uchar *) cp); - } - - return (write_data (info, wp, SWAP (data))); -} - -/*----------------------------------------------------------------------- - * Write a word or halfword to Flash, returns: - * 0 - OK - * 1 - write timeout - * 2 - Flash not erased - */ -static int write_data (flash_info_t *info, ulong dest, FPW data) -{ - FPWV *addr = (FPWV *) dest; - ulong status; - int flag; - - /* Check if Flash is (sufficiently) erased */ - if ((*addr & data) != data) { - printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr); - return (2); - } - /* Disable interrupts which might cause a timeout here */ - flag = disable_interrupts (); - - *addr = (FPW) 0x00400040; /* write setup */ - *addr = data; - - /* arm simple, non interrupt dependent timer */ - reset_timer_masked (); - - /* wait while polling the status register */ - while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { - if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) { - *addr = (FPW) 0x00FF00FF; /* restore read mode */ - return (1); - } - } - - *addr = (FPW) 0x00FF00FF; /* restore read mode */ - - return (0); -} - -void inline spin_wheel (void) -{ - static int p = 0; - static char w[] = "\\/-"; - - printf ("\010%c", w[p]); - (++p == 3) ? (p = 0) : 0; -} diff --git a/board/delta/nand.c b/board/delta/nand.c new file mode 100644 index 0000000000..9caddba064 --- /dev/null +++ b/board/delta/nand.c @@ -0,0 +1,306 @@ +/* + * (C) Copyright 2006 DENX Software Engineering + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) +#ifdef CONFIG_NEW_NAND_CODE + +#include +#include + +/* + * hardware specific access to control-lines + * function borrowed from Linux 2.6 (drivers/mtd/nand/ppchameleonevb.c) + */ +static void delta_hwcontrol(struct mtd_info *mtdinfo, int cmd) +{ +#if 0 + struct nand_chip *this = mtdinfo->priv; + ulong base = (ulong) this->IO_ADDR_W; + + switch(cmd) { + case NAND_CTL_SETCLE: + MACRO_NAND_CTL_SETCLE((unsigned long)base); + break; + case NAND_CTL_CLRCLE: + MACRO_NAND_CTL_CLRCLE((unsigned long)base); + break; + case NAND_CTL_SETALE: + MACRO_NAND_CTL_SETALE((unsigned long)base); + break; + case NAND_CTL_CLRALE: + MACRO_NAND_CTL_CLRALE((unsigned long)base); + break; + case NAND_CTL_SETNCE: + MACRO_NAND_ENABLE_CE((unsigned long)base); + break; + case NAND_CTL_CLRNCE: + MACRO_NAND_DISABLE_CE((unsigned long)base); + break; + } +#endif +} + + +/* read device ready pin */ +static int delta_device_ready(struct mtd_info *mtdinfo) +{ + if(NDSR & NDSR_RDY) + return 1; + else + return 0; +#if 0 + struct nand_chip *this = mtdinfo->priv; + ulong rb_gpio_pin; + + /* use the base addr to find out which chip are we dealing with */ + switch((ulong) this->IO_ADDR_W) { + case CFG_NAND0_BASE: + rb_gpio_pin = CFG_NAND0_RDY; + break; + case CFG_NAND1_BASE: + rb_gpio_pin = CFG_NAND1_RDY; + break; + default: /* this should never happen */ + return 0; + break; + } + + if (in32(GPIO0_IR) & rb_gpio_pin) + return 1; +#endif + return 0; +} + +static u_char delta_read_byte(struct mtd_info *mtd) +{ +/* struct nand_chip *this = mtd->priv; */ + unsigned long tmp; + + /* wait for read request */ + while(1) { + if(NDSR & NDSR_RDDREQ) { + NDSR |= NDSR_RDDREQ; + break; + } + } + + tmp = NDDB; + printk("delta_read_byte: 0x%x.\n", tmp); + return (u_char) tmp; +} + +/* this is really monahans, not board specific ... */ +static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, + int column, int page_addr) +{ + /* register struct nand_chip *this = mtd->priv; */ + unsigned long ndcb0=0, ndcb1=0, ndcb2=0; + uchar command2; + + /* Clear NDSR */ + NDSR = 0xFFF; + + /* apparently NDCR[NDRUN] needs to be set before writing to NDCBx */ + NDCR |= NDCR_ND_RUN; + + /* wait for write command request + * hmm, might be nice if this could time-out. mk@tbd + */ + while(1) { + if(NDSR & NDSR_WRCMDREQ) { + NDSR |= NDSR_WRCMDREQ; /* Ack */ + break; + } + } + + /* if command is a double byte cmd, we set bit double cmd bit 19 */ + command2 = (command>>8) & 0xFF; + ndcb0 = command | ((command2 ? 1 : 0) << 19); + + switch (command) { + case NAND_CMD_READID: + printk("delta_cmdfunc: NAND_CMD_READID.\n"); + ndcb0 |= ((3 << 21) | (2 << 16)); + break; + case NAND_CMD_PAGEPROG: + case NAND_CMD_ERASE1: + case NAND_CMD_ERASE2: + case NAND_CMD_SEQIN: + case NAND_CMD_STATUS: + return; + case NAND_CMD_RESET: + return; + default: + printk("delta_cmdfunc: error, unkown command issued.\n"); + return; + } + + NDCB0 = ndcb0; + NDCB1 = ndcb1; + NDCB2 = ndcb2; +} + +/* + * Board-specific NAND initialization. The following members of the + * argument are board-specific (per include/linux/mtd/nand_new.h): + * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device + * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device + * - hwcontrol: hardwarespecific function for accesing control-lines + * - dev_ready: hardwarespecific function for accesing device ready/busy line + * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must + * only be provided if a hardware ECC is available + * - eccmode: mode of ecc, see defines + * - chip_delay: chip dependent delay for transfering data from array to + * read regs (tR) + * - options: various chip options. They can partly be set to inform + * nand_scan about special functionality. See the defines for further + * explanation + * Members with a "?" were not set in the merged testing-NAND branch, + * so they are not set here either. + */ +void board_nand_init(struct nand_chip *nand) +{ + unsigned long tCH, tCS, tWH, tWP, tRH, tRP, tRP_high, tR, tWHR, tAR; + + /* set up GPIO Control Registers */ + + /* turn on the NAND Controller Clock (104 MHz @ D0) */ + CKENA |= (CKENA_4_NAND | CKENA_9_SMC); + + /* NAND Timing Parameters (in ns) */ +#define NAND_TIMING_tCH 10 +#define NAND_TIMING_tCS 0 +#define NAND_TIMING_tWH 20 +#define NAND_TIMING_tWP 40 +#define NAND_TIMING_tRH 20 +#define NAND_TIMING_tRP 40 +#define NAND_TIMING_tR 11123 +#define NAND_TIMING_tWHR 110 +#define NAND_TIMING_tAR 10 + +/* Maximum values for NAND Interface Timing Registers in DFC clock + * periods */ +#define DFC_MAX_tCH 7 +#define DFC_MAX_tCS 7 +#define DFC_MAX_tWH 7 +#define DFC_MAX_tWP 7 +#define DFC_MAX_tRH 7 +#define DFC_MAX_tRP 15 +#define DFC_MAX_tR 65535 +#define DFC_MAX_tWHR 15 +#define DFC_MAX_tAR 15 + +#define DFC_CLOCK 104 /* DFC Clock is 104 MHz */ +#define DFC_CLK_PER_US DFC_CLOCK/1000 /* clock period in ns */ +#define MIN(x, y) ((x < y) ? x : y) + + + tCH = MIN(((unsigned long) (NAND_TIMING_tCH * DFC_CLK_PER_US) + 1), + DFC_MAX_tCH); + tCS = MIN(((unsigned long) (NAND_TIMING_tCS * DFC_CLK_PER_US) + 1), + DFC_MAX_tCS); + tWH = MIN(((unsigned long) (NAND_TIMING_tWH * DFC_CLK_PER_US) + 1), + DFC_MAX_tWH); + tWP = MIN(((unsigned long) (NAND_TIMING_tWP * DFC_CLK_PER_US) + 1), + DFC_MAX_tWP); + tRH = MIN(((unsigned long) (NAND_TIMING_tRH * DFC_CLK_PER_US) + 1), + DFC_MAX_tRH); + tRP = MIN(((unsigned long) (NAND_TIMING_tRP * DFC_CLK_PER_US) + 1), + DFC_MAX_tRP); + tR = MIN(((unsigned long) (NAND_TIMING_tR * DFC_CLK_PER_US) + 1), + DFC_MAX_tR); + tWHR = MIN(((unsigned long) (NAND_TIMING_tWHR * DFC_CLK_PER_US) + 1), + DFC_MAX_tWHR); + tAR = MIN(((unsigned long) (NAND_TIMING_tAR * DFC_CLK_PER_US) + 1), + DFC_MAX_tAR); + + + /* tRP value is split in the register */ + if(tRP & (1 << 4)) { + tRP_high = 1; + tRP &= ~(1 << 4); + } else { + tRP_high = 0; + } + + NDTR0CS0 = (tCH << 19) | + (tCS << 16) | + (tWH << 11) | + (tWP << 8) | + (tRP_high << 6) | + (tRH << 3) | + (tRP << 0); + + NDTR1CS0 = (tR << 16) | + (tWHR << 4) | + (tAR << 0); + + + + /* If it doesn't work (unlikely) think about: + * - ecc enable + * - chip select don't care + * - read id byte count + * + * Intentionally enabled by not setting bits: + * - dma (DMA_EN) + * - page size = 512 + * - cs don't care, see if we can enable later! + * - row address start position (after second cycle) + * - pages per block = 32 + */ + NDCR = (NDCR_ND_ARB_EN | /* enable bus arbiter */ + NDCR_SPARE_EN | /* use the spare area */ + NDCR_DWIDTH_C | /* 16bit DFC data bus width */ + NDCR_DWIDTH_M | /* 16 bit Flash device data bus width */ + (2 << 16) | /* read id count = 7 ???? mk@tbd */ + NDCE_RDYM | /* flash device ready ir masked */ + NDCE_CS0_PAGEDM | /* ND_nCSx page done ir masked */ + NDCE_CS1_PAGEDM | + NDCE_CS0_CMDDM | /* ND_CSx command done ir masked */ + NDCE_CS1_CMDDM | + NDCE_CS0_BBDM | /* ND_CSx bad block detect ir masked */ + NDCE_CS1_BBDM | + NDCE_DBERRM | /* double bit error ir masked */ + NDCE_SBERRM | /* single bit error ir masked */ + NDCE_WRDREQM | /* write data request ir masked */ + NDCE_RDDREQM | /* read data request ir masked */ + NDCE_WRCMDREQM); /* write command request ir masked */ + + + + nand->hwcontrol = delta_hwcontrol; + nand->dev_ready = delta_device_ready; + nand->eccmode = NAND_ECC_SOFT; + nand->chip_delay = NAND_DELAY_US; + nand->options = NAND_BUSWIDTH_16; + nand->read_byte = delta_read_byte; + nand->cmdfunc = delta_cmdfunc; + /* nand->options = NAND_SAMSUNG_LP_OPTIONS; */ +} + +#else +#error "U-Boot legacy NAND support not available for delta board." +#endif +#endif diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 44532c9c16..05ed96945d 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1003,12 +1003,51 @@ typedef void (*ExcpHndlr) (void) ; #define GSDR(x) __REG2(0x40E00400, ((x) & 0x60) >> 3) #define GCDR(x) __REG2(0x40300420, ((x) & 0x60) >> 3) -/* Multi-funktion Pin Registers, uncomplete, only GPIO relevant pins for now */ +/* Multi-funktion Pin Registers, uncomplete, only: + * - GPIO + * - Data Flash DF_* pins defined. + */ #define GPIO0 __REG(0x40e10124) #define GPIO1 __REG(0x40e10128) #define GPIO2 __REG(0x40e1012c) #define GPIO3 __REG(0x40e10130) #define GPIO4 __REG(0x40e10134) +#define nXCVREN __REG(0x40e10138) + +#define DF_CLE_NOE __REG(0x40e10204) +#define DF_ALE_WE1 __REG(0x40e10208) + +#define DF_SCLK_E __REG(0x40e10210) +#define nBE0 __REG(0x40e10214) +#define nBE1 __REG(0x40e10218) +#define DF_ALE_WE2 __REG(0x40e1021c) +#define DF_INT_RnB __REG(0x40e10220) +#define DF_nCS0 __REG(0x40e10224) +#define DF_nCS1 __REG(0x40e10228) +#define DF_nWE __REG(0x40e1022c) +#define DF_nRE __REG(0x40e10230) +#define nLUA __REG(0x40e10234) +#define nLLA __REG(0x40e10238) +#define DF_ADDR0 __REG(0x40e1023c) +#define DF_ADDR1 __REG(0x40e10240) +#define DF_ADDR2 __REG(0x40e10244) +#define DF_ADDR3 __REG(0x40e10248) +#define DF_IO0 __REG(0x40e1024c) +#define DF_IO8 __REG(0x40e10250) +#define DF_IO1 __REG(0x40e10254) +#define DF_IO9 __REG(0x40e10258) +#define DF_IO2 __REG(0x40e1025c) +#define DF_IO10 __REG(0x40e10260) +#define DF_IO3 __REG(0x40e10264) +#define DF_IO11 __REG(0x40e10268) +#define DF_IO4 __REG(0x40e1026c) +#define DF_IO12 __REG(0x40e10270) +#define DF_IO5 __REG(0x40e10274) +#define DF_IO13 __REG(0x40e10278) +#define DF_IO6 __REG(0x40e1027c) +#define DF_IO14 __REG(0x40e10280) +#define DF_IO7 __REG(0x40e10284) +#define DF_IO15 __REG(0x40e10288) #define GPIO5 __REG(0x40e1028c) #define GPIO6 __REG(0x40e10290) @@ -2022,19 +2061,19 @@ typedef void (*ExcpHndlr) (void) ; /* Data Flash Controller Registers */ -#define NDCR __REG_2(0x43100000) /* Data Flash Control register */ -#define NDTR0CS0 __REG_2(0x43100004) /* Data Controller Timing Parameter 0 Register for ND_nCS0 */ -#define NDTR0CS1 __REG_2(0x43100008) /* Data Controller Timing Parameter 0 Register for ND_nCS1 */ -#define NDTR1CS0 __REG_2(0x4310000C) /* Data Controller Timing Parameter 1 Register for ND_nCS0 */ -#define NDTR1CS1 __REG_2(0x43100010) /* Data Controller Timing Parameter 1 Register for ND_nCS1 */ -#define NDSR __REG_2(0x43100014) /* Data Controller Status Register */ -#define NDPCR __REG_2(0x43100018) /* Data Controller Page Count Register */ -#define NDBDR0 __REG_2(0x4310001C) /* Data Controller Bad Block Register 0 */ -#define NDBDR1 __REG_2(0x43100020) /* Data Controller Bad Block Register 1 */ -#define NDDB __REG_2(0x43100040) /* Data Controller Data Buffer */ -#define NDCB0 __REG_2(0x43100048) /* Data Controller Command Buffer0 */ -#define NDCB1 __REG_2(0x4310004C) /* Data Controller Command Buffer1 */ -#define NDCB2 __REG_2(0x43100050) /* Data Controller Command Buffer2 */ +#define NDCR __REG(0x43100000) /* Data Flash Control register */ +#define NDTR0CS0 __REG(0x43100004) /* Data Controller Timing Parameter 0 Register for ND_nCS0 */ +/* #define NDTR0CS1 __REG(0x43100008) /\* Data Controller Timing Parameter 0 Register for ND_nCS1 *\/ */ +#define NDTR1CS0 __REG(0x4310000C) /* Data Controller Timing Parameter 1 Register for ND_nCS0 */ +/* #define NDTR1CS1 __REG(0x43100010) /\* Data Controller Timing Parameter 1 Register for ND_nCS1 *\/ */ +#define NDSR __REG(0x43100014) /* Data Controller Status Register */ +#define NDPCR __REG(0x43100018) /* Data Controller Page Count Register */ +#define NDBDR0 __REG(0x4310001C) /* Data Controller Bad Block Register 0 */ +#define NDBDR1 __REG(0x43100020) /* Data Controller Bad Block Register 1 */ +#define NDDB __REG(0x43100040) /* Data Controller Data Buffer */ +#define NDCB0 __REG(0x43100048) /* Data Controller Command Buffer0 */ +#define NDCB1 __REG(0x4310004C) /* Data Controller Command Buffer1 */ +#define NDCB2 __REG(0x43100050) /* Data Controller Command Buffer2 */ #define NDCR_SPARE_EN (0x1<<31) #define NDCR_ECC_EN (0x1<<30) @@ -2052,6 +2091,18 @@ typedef void (*ExcpHndlr) (void) ; #define NDCR_RA_START (0x1<<15) #define NDCR_PG_PER_BLK (0x1<<14) #define NDCR_ND_ARB_EN (0x1<<12) +#define NDCE_RDYM (0x1<<11) +#define NDCE_CS0_PAGEDM (0x1<<10) +#define NDCE_CS1_PAGEDM (0x1<<9) +#define NDCE_CS0_CMDDM (0x1<<8) +#define NDCE_CS1_CMDDM (0x1<<7) +#define NDCE_CS0_BBDM (0x1<<6) +#define NDCE_CS1_BBDM (0x1<<5) +#define NDCE_DBERRM (0x1<<4) +#define NDCE_SBERRM (0x1<<3) +#define NDCE_WRDREQM (0x1<<2) +#define NDCE_RDDREQM (0x1<<1) +#define NDCE_WRCMDREQM (0x1) #define NDSR_RDY (0x1<<11) #define NDSR_CS0_PAGED (0x1<<10) diff --git a/include/configs/delta.h b/include/configs/delta.h index 5b42069694..9bc2954902 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -73,7 +73,9 @@ #ifdef TURN_ON_ETHERNET # define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_PING) #else -# define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_NET) +# define CONFIG_COMMANDS ((CONFIG_CMD_DFL | CFG_CMD_NAND) \ + & ~(CFG_CMD_NET | CFG_CMD_FLASH | \ + CFG_CMD_ENV | CFG_CMD_IMLS)) #endif @@ -152,20 +154,41 @@ #define PHYS_SDRAM_4 0xa3000000 /* SDRAM Bank #4 */ #define PHYS_SDRAM_4_SIZE 0x1000000 /* 64 MB */ -#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ -#define PHYS_FLASH_2 0x04000000 /* Flash Bank #2 */ -#define PHYS_FLASH_SIZE 0x02000000 /* 32 MB */ -#define PHYS_FLASH_BANK_SIZE 0x02000000 /* 32 MB Banks */ -#define PHYS_FLASH_SECT_SIZE 0x00040000 /* 256 KB sectors (x2) */ - #define CFG_DRAM_BASE 0xa0000000 /* at CS0 */ #define CFG_DRAM_SIZE 0x04000000 /* 64 MB Ram */ #define CFG_SKIP_DRAM_SCRUB 1 -#define CFG_FLASH_BASE PHYS_FLASH_1 +/* + * NAND Flash + */ +/* Use the new NAND code. (BOARDLIBS = drivers/nand/libnand.a required) */ +#define CONFIG_NEW_NAND_CODE +#define CFG_NAND0_BASE 0x10000000 +#undef CFG_NAND1_BASE -#define FPGA_REGS_BASE_PHYSICAL 0x08000000 +#define CFG_NAND_BASE_LIST { CFG_NAND0_BASE } +#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ +#define SECTORSIZE 512 +/* #define NAND_NO_RB */ +#define NAND_DELAY_US 25 /* mk@tbd: could be 0, I guess */ + +#define ADDR_COLUMN 1 +#define ADDR_PAGE 2 +#define ADDR_COLUMN_PAGE 3 + +#define NAND_ChipID_UNKNOWN 0x00 +#define NAND_MAX_FLOORS 1 +#define NAND_MAX_CHIPS 1 + +#define CFG_NO_FLASH 1 +#ifndef CGF_NO_FLASH +/* these are required by the environment code */ +#define PHYS_FLASH_1 CFG_NAND0_BASE /* Flash Bank #1 */ +#define PHYS_FLASH_SIZE 0x04000000 /* 64 MB */ +#define PHYS_FLASH_BANK_SIZE 0x04000000 /* 64 MB Banks */ +#define PHYS_FLASH_SECT_SIZE (SECTORSIZE*1024) /* KB sectors (x2) */ +#endif /* * GPIO settings @@ -215,6 +238,7 @@ /* * FLASH and environment organization */ +#ifndef CFG_NO_FLASH #define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */ #define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ @@ -222,30 +246,16 @@ #define CFG_FLASH_ERASE_TOUT (25*CFG_HZ) /* Timeout for Flash Erase */ #define CFG_FLASH_WRITE_TOUT (25*CFG_HZ) /* Timeout for Flash Write */ + /* NOTE: many default partitioning schemes assume the kernel starts at the * second sector, not an environment. You have been warned! */ #define CFG_MONITOR_LEN PHYS_FLASH_SECT_SIZE +#endif /* #ifndef CFG_NO_FLASH */ -#define CFG_ENV_IS_IN_FLASH 1 -#define CFG_ENV_ADDR (PHYS_FLASH_1 + PHYS_FLASH_SECT_SIZE) -#define CFG_ENV_SECT_SIZE PHYS_FLASH_SECT_SIZE -#define CFG_ENV_SIZE (PHYS_FLASH_SECT_SIZE / 16) - - -/* - * FPGA Offsets - */ -#define WHOAMI_OFFSET 0x00 -#define HEXLED_OFFSET 0x10 -#define BLANKLED_OFFSET 0x40 -#define DISCRETELED_OFFSET 0x40 -#define CNFG_SWITCHES_OFFSET 0x50 -#define USER_SWITCHES_OFFSET 0x60 -#define MISC_WR_OFFSET 0x80 -#define MISC_RD_OFFSET 0x90 -#define INT_MASK_OFFSET 0xC0 -#define INT_CLEAR_OFFSET 0xD0 -#define GP_OFFSET 0x100 +#define CFG_ENV_IS_NOWHERE +/* #define CFG_ENV_IS_IN_NAND 1 */ +#define CFG_ENV_OFFSET 0x40000 +#define CFG_ENV_SIZE 0x4000 #endif /* __CONFIG_H */ diff --git a/lib_arm/board.c b/lib_arm/board.c index a420de15e5..0f3a999d14 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -179,11 +179,13 @@ static int display_dram_config (void) return (0); } +#ifndef CFG_NO_FLASH static void display_flash_config (ulong size) { puts ("Flash: "); print_size (size, "\n"); } +#endif /* CFG_NO_FLASH */ /* @@ -259,9 +261,11 @@ void start_armboot (void) } } +#ifndef CFG_NO_FLASH /* configure available FLASH banks */ size = flash_init (); display_flash_config (size); +#endif /* CFG_NO_FLASH */ #ifdef CONFIG_VFD # ifndef PAGE_SIZE From 82f2e33a8dc8ec6e3d33d41028f6e57bde015e95 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 28 Feb 2006 18:39:20 +0100 Subject: [PATCH 022/102] Update mcc200 config: Disable PCI and DoC, use 133 MHz IPB clock, use hush shell. --- CHANGELOG | 3 ++ include/configs/mcc200.h | 65 +++++++--------------------------------- 2 files changed, 13 insertions(+), 55 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index baa9537cb9..0c4407c9af 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Update mcc200 config: Disable PCI and DoC, use 133 MHz IPB clock, + use hush shell. + * Convert mcc200 to use common CFI flash driver Patch by Stefan Roese, 28 Feb 2006 diff --git a/include/configs/mcc200.h b/include/configs/mcc200.h index a8a8934012..a48c21b53a 100644 --- a/include/configs/mcc200.h +++ b/include/configs/mcc200.h @@ -52,52 +52,19 @@ #define CONFIG_BAUDRATE 115200 #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 230400 } -/* - * PCI Mapping: - * 0x40000000 - 0x4fffffff - PCI Memory - * 0x50000000 - 0x50ffffff - PCI IO Space - */ -#define CONFIG_PCI 1 -#define CONFIG_PCI_PNP 1 -#define CONFIG_PCI_SCAN_SHOW 1 -#undef CONFIG_PCI_SCAN_SHOW - -#define CONFIG_PCI_MEM_BUS 0x40000000 -#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS -#define CONFIG_PCI_MEM_SIZE 0x10000000 - -#define CONFIG_PCI_IO_BUS 0x50000000 -#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS -#define CONFIG_PCI_IO_SIZE 0x01000000 - -#define CONFIG_NET_MULTI 1 #define CONFIG_MII 1 -#define CONFIG_EEPRO100 1 -#define CFG_RX_ETH_BUFFER 8 /* use 8 rx buffer on eepro100 */ -#undef CONFIG_NS8382X -#define ADD_PCI_CMD CFG_CMD_PCI - -/* Partitions */ #define CONFIG_DOS_PARTITION /* USB */ -#if 1 #define CONFIG_USB_OHCI #define ADD_USB_CMD CFG_CMD_USB | CFG_CMD_FAT #define CONFIG_USB_STORAGE -#else -#define ADD_USB_CMD 0 -#endif - -#define ADD_DOC_CMD CFG_CMD_DOC /* * Supported commands */ #define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ - ADD_DOC_CMD | \ - ADD_PCI_CMD | \ ADD_USB_CMD | \ CFG_CMD_BEDBUG | \ CFG_CMD_DATE | \ @@ -136,27 +103,29 @@ "flash_self=run ramargs addip;" \ "bootm ${kernel_addr} ${ramdisk_addr}\0" \ "net_nfs=tftp 200000 ${bootfile};run nfsargs addip;bootm\0" \ - "rootpath=/opt/eldk/ppc_82xx\0" \ + "rootpath=/opt/eldk/ppc_6xx\0" \ "bootfile=/tftpboot/mcc200/uImage\0" \ "baudrate=115200\0" \ - "load=tftp 100000 /tftpboot/mcc200/u-boot.bin\0" \ - "update=protect off fff00000 fff3ffff;era fff00000 fff3ffff;" \ - "cp.b 100000 fff00000 40000;" \ - "setenv filesize;saveenv\0" \ - "upd=run load;run update\0" \ + "load=tftp 200000 /tftpboot/mcc200/u-boot.bin\0" \ + "update=protect off FFF00000 +${filesize};" \ + "era FFF00000 +${filesize};" \ + "cp.b 200000 FFF00000 ${filesize}\0" \ "serverip=192.168.1.1\0" \ "ipaddr=192.168.133.144\0" \ "netmask=255.255.0.0\0" \ "unlock=yes\0" \ - "ethaddr=00:02:44:7d:73:3b\0" \ + "ethaddr=00:02:44:7D:73:3B\0" \ "" #define CONFIG_BOOTCOMMAND "run flash_self" +#define CFG_HUSH_PARSER 1 /* use "hush" command parser */ +#define CFG_PROMPT_HUSH_PS2 "> " + /* * IPB Bus clocking configuration. */ -#undef CFG_IPBSPEED_133 /* define for 133MHz speed */ +#define CFG_IPBSPEED_133 /* define for 133MHz speed */ /* * I2C configuration @@ -181,17 +150,6 @@ #define CONFIG_RTC_PCF8563 #define CFG_I2C_RTC_ADDR 0x51 -/* - * Disk-On-Chip configuration - */ -#define CFG_DOC_SHORT_TIMEOUT -#define CFG_MAX_DOC_DEVICE 1 /* Max number of DOC devices */ - -#define CFG_DOC_SUPPORT_2000 -#define CFG_DOC_SUPPORT_MILLENNIUM -#define CFG_DOC_BASE 0xE0000000 -#define CFG_DOC_SIZE 0x00100000 - /* * Flash configuration (8,16 or 32 MB) * TEXT base always at 0xFFF00000 @@ -308,9 +266,6 @@ #define CFG_BOOTCS_CFG 0x0004fb00 #define CFG_CS0_START CFG_FLASH_BASE #define CFG_CS0_SIZE CFG_FLASH_SIZE -#define CFG_CS1_START CFG_DOC_BASE -#define CFG_CS1_SIZE CFG_DOC_SIZE -#define CFG_CS1_CFG 0x00047800 #define CFG_CS_BURST 0x00000000 #define CFG_CS_DEADCYCLE 0x33333333 From 00c35bd2140f02111612771ca9c53dc8b58205eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Tue, 28 Feb 2006 22:51:01 +0100 Subject: [PATCH 023/102] Added GPIO initialization of DF signal. Still not working. --- board/delta/nand.c | 42 +++++++++++++++++++++++++++++++++++++++-- config.mk | 7 ++++++- cpu/pxa/config.mk | 1 + include/configs/delta.h | 2 +- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/board/delta/nand.c b/board/delta/nand.c index 9caddba064..bd1bb4f698 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -141,7 +141,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, switch (command) { case NAND_CMD_READID: printk("delta_cmdfunc: NAND_CMD_READID.\n"); - ndcb0 |= ((3 << 21) | (2 << 16)); + ndcb0 |= ((3 << 21) | (1 << 16)); /* addr cycles*/ break; case NAND_CMD_PAGEPROG: case NAND_CMD_ERASE1: @@ -161,6 +161,43 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, NDCB2 = ndcb2; } +void delta_dfc_gpio_init() +{ + printf("Setting up DFC GPIO's.\n"); + + /* no idea what is done here, see zylonite.c */ + GPIO4 = 0x1; + + DF_ALE_WE1 = 0x00000001; + DF_ALE_WE2 = 0x00000001; + DF_nCS0 = 0x00000001; + DF_nCS1 = 0x00000001; + DF_nWE = 0x00000001; + DF_nRE = 0x00000001; + DF_IO0 = 0x00000001; + DF_IO8 = 0x00000001; + DF_IO1 = 0x00000001; + DF_IO9 = 0x00000001; + DF_IO2 = 0x00000001; + DF_IO10 = 0x00000001; + DF_IO3 = 0x00000001; + DF_IO11 = 0x00000001; + DF_IO4 = 0x00000001; + DF_IO12 = 0x00000001; + DF_IO5 = 0x00000001; + DF_IO13 = 0x00000001; + DF_IO6 = 0x00000001; + DF_IO14 = 0x00000001; + DF_IO7 = 0x00000001; + DF_IO15 = 0x00000001; + + DF_nWE = 0x1901; + DF_nRE = 0x1901; + DF_CLE_NOE = 0x1900; + DF_ALE_WE1 = 0x1901; + DF_INT_RnB = 0x1900; +} + /* * Board-specific NAND initialization. The following members of the * argument are board-specific (per include/linux/mtd/nand_new.h): @@ -184,7 +221,8 @@ void board_nand_init(struct nand_chip *nand) unsigned long tCH, tCS, tWH, tWP, tRH, tRP, tRP_high, tR, tWHR, tAR; /* set up GPIO Control Registers */ - + delta_dfc_gpio_init(); + /* turn on the NAND Controller Clock (104 MHz @ D0) */ CKENA |= (CKENA_4_NAND | CKENA_9_SMC); diff --git a/config.mk b/config.mk index 2c6cfb4b3c..aef099ec86 100644 --- a/config.mk +++ b/config.mk @@ -132,9 +132,14 @@ CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes endif ifdef WILD_WILD_WEST -CFLAGS := $(CFLAGS) -Werror +CFLAGS := $(CPPFLAGS) -Werror endif +ifdef NO_JUMP +CFLAGS := $(CPPFLAGS) -fno-schedule-insns -fno-schedule-insns2 +endif + + # avoid trigraph warnings while parsing pci.h (produced by NIOS gcc-2.9) # this option have to be placed behind -Wall -- that's why it is here ifeq ($(ARCH),nios) diff --git a/cpu/pxa/config.mk b/cpu/pxa/config.mk index fb810ca7c2..f30a1fe1ad 100644 --- a/cpu/pxa/config.mk +++ b/cpu/pxa/config.mk @@ -33,4 +33,5 @@ PLATFORM_CPPFLAGS += -march=armv5 -mtune=xscale # # ======================================================================== PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +# for gcc-3x: PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/include/configs/delta.h b/include/configs/delta.h index 9bc2954902..ac412ee878 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -164,7 +164,7 @@ */ /* Use the new NAND code. (BOARDLIBS = drivers/nand/libnand.a required) */ #define CONFIG_NEW_NAND_CODE -#define CFG_NAND0_BASE 0x10000000 +#define CFG_NAND0_BASE 0x43100040 /* 0x10000000 */ #undef CFG_NAND1_BASE #define CFG_NAND_BASE_LIST { CFG_NAND0_BASE } From e8cd00835ebcae4681e9a673bf33318687756eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Tue, 28 Feb 2006 23:11:07 +0100 Subject: [PATCH 024/102] All subsystem clocks not immediately need are turned at reset. --- cpu/pxa/start.S | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cpu/pxa/start.S b/cpu/pxa/start.S index 994082691d..159447efe3 100644 --- a/cpu/pxa/start.S +++ b/cpu/pxa/start.S @@ -30,6 +30,7 @@ #include #include +#include .globl _start _start: b reset @@ -217,6 +218,15 @@ cpu_init_crit: mov r1, #0 mcr p6, 0, r1, c1, c0, 0 @ ICMR mcr p6, 0, r1, c7, c0, 0 @ ICMR2 + + /* turn off all clocks but the ones we will definitly require */ + ldr r1, =CKENA + ldr r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC) + str r2, [r1] + ldr r1, =CKENB + ldr r2, =(CKENB_6_IRQ) + str r2, [r1] + #endif #ifndef CONFIG_CPU_MONAHANS From f18e874ad548034552cc4a2cdfe1a21edd9ca392 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 1 Mar 2006 17:00:49 +0100 Subject: [PATCH 025/102] Fix problem with flash_get_size() from CFI driver update Patch by Stefan Roese, 1 Mar 2006 --- CHANGELOG | 3 +++ board/mcc200/mcc200.c | 2 ++ board/tqm85xx/tqm85xx.c | 1 + drivers/cfi_flash.c | 1 + include/flash.h | 1 - 5 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index baa9537cb9..8e9115eb75 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix problem with flash_get_size() from CFI driver update + Patch by Stefan Roese, 1 Mar 2006 + * Convert mcc200 to use common CFI flash driver Patch by Stefan Roese, 28 Feb 2006 diff --git a/board/mcc200/mcc200.c b/board/mcc200/mcc200.c index 47073907e1..acc0e06862 100644 --- a/board/mcc200/mcc200.c +++ b/board/mcc200/mcc200.c @@ -38,6 +38,8 @@ extern flash_info_t flash_info[]; /* FLASH chips info */ +ulong flash_get_size (ulong base, int banknum); + //###CHD: wenn RAMBOOT gehen wuerde, .... #ifndef CFG_RAMBOOT static void sdram_start (int hi_addr) diff --git a/board/tqm85xx/tqm85xx.c b/board/tqm85xx/tqm85xx.c index b36beadea7..c03b60d11a 100644 --- a/board/tqm85xx/tqm85xx.c +++ b/board/tqm85xx/tqm85xx.c @@ -40,6 +40,7 @@ extern flash_info_t flash_info[]; /* FLASH chips info */ void local_bus_init (void); long int fixed_sdram (void); +ulong flash_get_size (ulong base, int banknum); #ifdef CONFIG_CPM2 /* diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c index df17da5eaf..ff4d85f3f0 100644 --- a/drivers/cfi_flash.c +++ b/drivers/cfi_flash.c @@ -203,6 +203,7 @@ static int flash_detect_cfi (flash_info_t * info); static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword); static int flash_full_status_check (flash_info_t * info, flash_sect_t sector, ulong tout, char *prompt); +ulong flash_get_size (ulong base, int banknum); #if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE) static flash_info_t *flash_get_info(ulong base); #endif diff --git a/include/flash.h b/include/flash.h index 9108723366..8493191789 100644 --- a/include/flash.h +++ b/include/flash.h @@ -80,7 +80,6 @@ extern void flash_print_info (flash_info_t *); extern int flash_erase (flash_info_t *, int, int); extern int flash_sect_erase (ulong addr_first, ulong addr_last); extern int flash_sect_protect (int flag, ulong addr_first, ulong addr_last); -extern ulong flash_get_size (ulong base, int banknum); /* common/flash.c */ extern void flash_protect (int flag, ulong from, ulong to, flash_info_t *info); From 481911c78c7aebd3a007c4e246e928e7f6a0f051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Wed, 1 Mar 2006 23:33:27 +0100 Subject: [PATCH 026/102] Further NAND stuff implemented. Basic read commands seem to work. --- board/delta/nand.c | 229 ++++++++++++++++++---------- include/asm-arm/arch-pxa/pxa-regs.h | 32 ++-- 2 files changed, 163 insertions(+), 98 deletions(-) diff --git a/board/delta/nand.c b/board/delta/nand.c index bd1bb4f698..7255827671 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -29,39 +29,13 @@ #include /* - * hardware specific access to control-lines - * function borrowed from Linux 2.6 (drivers/mtd/nand/ppchameleonevb.c) + * not required for Monahans DFC */ static void delta_hwcontrol(struct mtd_info *mtdinfo, int cmd) { -#if 0 - struct nand_chip *this = mtdinfo->priv; - ulong base = (ulong) this->IO_ADDR_W; - - switch(cmd) { - case NAND_CTL_SETCLE: - MACRO_NAND_CTL_SETCLE((unsigned long)base); - break; - case NAND_CTL_CLRCLE: - MACRO_NAND_CTL_CLRCLE((unsigned long)base); - break; - case NAND_CTL_SETALE: - MACRO_NAND_CTL_SETALE((unsigned long)base); - break; - case NAND_CTL_CLRALE: - MACRO_NAND_CTL_CLRALE((unsigned long)base); - break; - case NAND_CTL_SETNCE: - MACRO_NAND_ENABLE_CE((unsigned long)base); - break; - case NAND_CTL_CLRNCE: - MACRO_NAND_DISABLE_CE((unsigned long)base); - break; - } -#endif + return; } - /* read device ready pin */ static int delta_device_ready(struct mtd_info *mtdinfo) { @@ -69,35 +43,18 @@ static int delta_device_ready(struct mtd_info *mtdinfo) return 1; else return 0; -#if 0 - struct nand_chip *this = mtdinfo->priv; - ulong rb_gpio_pin; - - /* use the base addr to find out which chip are we dealing with */ - switch((ulong) this->IO_ADDR_W) { - case CFG_NAND0_BASE: - rb_gpio_pin = CFG_NAND0_RDY; - break; - case CFG_NAND1_BASE: - rb_gpio_pin = CFG_NAND1_RDY; - break; - default: /* this should never happen */ - return 0; - break; - } - - if (in32(GPIO0_IR) & rb_gpio_pin) - return 1; -#endif return 0; } -static u_char delta_read_byte(struct mtd_info *mtd) +/* The original: + * static void delta_read_buf(struct mtd_info *mtd, const u_char *buf, int len) + * + * Shouldn't this be "u_char * const buf" ? + */ +static void delta_read_buf(struct mtd_info *mtd, u_char* const buf, int len) { -/* struct nand_chip *this = mtd->priv; */ - unsigned long tmp; + int i, j; - /* wait for read request */ while(1) { if(NDSR & NDSR_RDDREQ) { NDSR |= NDSR_RDDREQ; @@ -105,9 +62,53 @@ static u_char delta_read_byte(struct mtd_info *mtd) } } - tmp = NDDB; - printk("delta_read_byte: 0x%x.\n", tmp); - return (u_char) tmp; + /* we have to be carefull not to overflow the buffer if len is + * not a multiple of 4 */ + unsigned long num_words = len & 0xfffffffc; + unsigned long rest = len & 0x3; + + /* if there are any, first copy multiple of 4 bytes */ + if(num_words) { + for(i=0; i>j) & 0xff); + } + + return; +} + +/* global var, too bad */ +static unsigned long read_buf = 0; +static unsigned char bytes_read = 0; + +static u_char delta_read_byte(struct mtd_info *mtd) +{ +/* struct nand_chip *this = mtd->priv; */ + unsigned char byte; + + if(bytes_read == 0) { + /* wait for read request */ + while(1) { + if(NDSR & NDSR_RDDREQ) { + NDSR |= NDSR_RDDREQ; + break; + } + } + read_buf = NDDB; + printk("delta_read_byte: 0x%x.\n", read_buf); + } + byte = (unsigned char) (read_buf>>(8 * bytes_read++)); + if(bytes_read >= 4) + bytes_read = 0; + + printf("delta_read_byte: returning 0x%x.\n", byte); + return byte; } /* this is really monahans, not board specific ... */ @@ -116,8 +117,11 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, { /* register struct nand_chip *this = mtd->priv; */ unsigned long ndcb0=0, ndcb1=0, ndcb2=0; - uchar command2; + /* clear the ugly byte read buffer */ + bytes_read = 0; + read_buf = 0; + /* Clear NDSR */ NDSR = 0xFFF; @@ -134,34 +138,58 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, } } - /* if command is a double byte cmd, we set bit double cmd bit 19 */ - command2 = (command>>8) & 0xFF; - ndcb0 = command | ((command2 ? 1 : 0) << 19); + /* if command is a double byte cmd, we set bit double cmd bit 19 */ + /* command2 = (command>>8) & 0xFF; */ + /* ndcb0 = command | ((command2 ? 1 : 0) << 19); *\/ */ switch (command) { + case NAND_CMD_READ0: + ndcb0 = (NAND_CMD_READ0 | (4<<16)); + column >>= 1; /* adjust for 16 bit bus */ + ndcb1 = (((column>>1) & 0xff) | + ((page_addr<<8) & 0xff00) | + ((page_addr<<8) & 0xff0000) | + ((page_addr<<8) & 0xff000000)); /* make this 0x01000000 ? */ + break; case NAND_CMD_READID: printk("delta_cmdfunc: NAND_CMD_READID.\n"); - ndcb0 |= ((3 << 21) | (1 << 16)); /* addr cycles*/ + ndcb0 = (NAND_CMD_READID | (3 << 21) | (1 << 16)); /* addr cycles*/ break; case NAND_CMD_PAGEPROG: + break; case NAND_CMD_ERASE1: case NAND_CMD_ERASE2: + break; case NAND_CMD_SEQIN: + ndcb0 = (NAND_CMD_SEQIN<<8) | (1<<19) | (4<<16); + if(column >= mtd->oobblock) { + /* OOB area */ + column -= mtd->oobblock; + ndcb0 |= NAND_CMD_READOOB; + } else if (column < 256) { + /* First 256 bytes --> READ0 */ + ndcb0 |= NAND_CMD_READ0; + } else { + /* Only for 8 bit devices - not delta!!! */ + column -= 256; + ndcb0 |= NAND_CMD_READ1; + } + break; case NAND_CMD_STATUS: return; case NAND_CMD_RESET: return; default: - printk("delta_cmdfunc: error, unkown command issued.\n"); + printk("delta_cmdfunc: error, unsupported command.\n"); return; } NDCB0 = ndcb0; - NDCB1 = ndcb1; - NDCB2 = ndcb2; + NDCB0 = ndcb1; + NDCB0 = ndcb2; } -void delta_dfc_gpio_init() +static void delta_dfc_gpio_init() { printf("Setting up DFC GPIO's.\n"); @@ -216,6 +244,23 @@ void delta_dfc_gpio_init() * Members with a "?" were not set in the merged testing-NAND branch, * so they are not set here either. */ +void wait(unsigned long us) +{ +#define OSCR_CLK_FREQ 3.250 /* kHz */ + + unsigned long start = OSCR; + unsigned long delta = 0, cur; + us *= OSCR_CLK_FREQ; + + while (delta < us) { + cur = OSCR; + if(cur < start) /* OSCR overflowed */ + delta = cur + (start^0xffffffff); + else + delta = cur - start; + } +} + void board_nand_init(struct nand_chip *nand) { unsigned long tCH, tCS, tWH, tWP, tRH, tRP, tRP_high, tR, tWHR, tAR; @@ -225,14 +270,24 @@ void board_nand_init(struct nand_chip *nand) /* turn on the NAND Controller Clock (104 MHz @ D0) */ CKENA |= (CKENA_4_NAND | CKENA_9_SMC); - + + /* wait ? */ +/* printf("stupid loop start...\n"); */ +/* wait(200); */ +/* printf("stupid loop end.\n"); */ + + /* NAND Timing Parameters (in ns) */ #define NAND_TIMING_tCH 10 #define NAND_TIMING_tCS 0 #define NAND_TIMING_tWH 20 #define NAND_TIMING_tWP 40 -#define NAND_TIMING_tRH 20 -#define NAND_TIMING_tRP 40 +/* #define NAND_TIMING_tRH 20 */ +/* #define NAND_TIMING_tRP 40 */ + +#define NAND_TIMING_tRH 25 +#define NAND_TIMING_tRP 50 + #define NAND_TIMING_tR 11123 #define NAND_TIMING_tWHR 110 #define NAND_TIMING_tAR 10 @@ -274,6 +329,8 @@ void board_nand_init(struct nand_chip *nand) DFC_MAX_tAR); + printf("tCH=%u, tCS=%u, tWH=%u, tWP=%u, tRH=%u, tRP=%u, tR=%u, tWHR=%u, tAR=%u.\n", tCH, tCS, tWH, tWP, tRH, tRP, tR, tWHR, tAR); + /* tRP value is split in the register */ if(tRP & (1 << 4)) { tRP_high = 1; @@ -307,33 +364,39 @@ void board_nand_init(struct nand_chip *nand) * - cs don't care, see if we can enable later! * - row address start position (after second cycle) * - pages per block = 32 + * - ND_RDY : clears command buffer */ - NDCR = (NDCR_ND_ARB_EN | /* enable bus arbiter */ - NDCR_SPARE_EN | /* use the spare area */ + NDCR = (NDCR_SPARE_EN | /* use the spare area */ NDCR_DWIDTH_C | /* 16bit DFC data bus width */ NDCR_DWIDTH_M | /* 16 bit Flash device data bus width */ - (2 << 16) | /* read id count = 7 ???? mk@tbd */ - NDCE_RDYM | /* flash device ready ir masked */ - NDCE_CS0_PAGEDM | /* ND_nCSx page done ir masked */ - NDCE_CS1_PAGEDM | - NDCE_CS0_CMDDM | /* ND_CSx command done ir masked */ - NDCE_CS1_CMDDM | - NDCE_CS0_BBDM | /* ND_CSx bad block detect ir masked */ - NDCE_CS1_BBDM | - NDCE_DBERRM | /* double bit error ir masked */ - NDCE_SBERRM | /* single bit error ir masked */ - NDCE_WRDREQM | /* write data request ir masked */ - NDCE_RDDREQM | /* read data request ir masked */ - NDCE_WRCMDREQM); /* write command request ir masked */ + NDCR_NCSX | /* Chip select busy don't care */ + (7 << 16) | /* read id count = 7 ???? mk@tbd */ + NDCR_ND_ARB_EN | /* enable bus arbiter */ + NDCR_RDYM | /* flash device ready ir masked */ + NDCR_CS0_PAGEDM | /* ND_nCSx page done ir masked */ + NDCR_CS1_PAGEDM | + NDCR_CS0_CMDDM | /* ND_CSx command done ir masked */ + NDCR_CS1_CMDDM | + NDCR_CS0_BBDM | /* ND_CSx bad block detect ir masked */ + NDCR_CS1_BBDM | + NDCR_DBERRM | /* double bit error ir masked */ + NDCR_SBERRM | /* single bit error ir masked */ + NDCR_WRDREQM | /* write data request ir masked */ + NDCR_RDDREQM | /* read data request ir masked */ + NDCR_WRCMDREQM); /* write command request ir masked */ + + /* wait 10 us due to cmd buffer clear reset */ +/* wait(10); */ nand->hwcontrol = delta_hwcontrol; - nand->dev_ready = delta_device_ready; +/* nand->dev_ready = delta_device_ready; */ nand->eccmode = NAND_ECC_SOFT; nand->chip_delay = NAND_DELAY_US; nand->options = NAND_BUSWIDTH_16; nand->read_byte = delta_read_byte; + nand->read_buf = delta_read_buf; nand->cmdfunc = delta_cmdfunc; /* nand->options = NAND_SAMSUNG_LP_OPTIONS; */ } diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 05ed96945d..6236405b3a 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -2083,26 +2083,28 @@ typedef void (*ExcpHndlr) (void) ; #define NDCR_DWIDTH_M (0x1<<26) #define NDCR_PAGE_SZ (0x3<<24) #define NDCR_NCSX (0x1<<23) -#define NDCR_ND_MODE (0x3<<21) -#define NDCR_NAND_MODE 0x0 +#define NDCR_ND_STOP (0x1<<22) +/* reserved: + * #define NDCR_ND_MODE (0x3<<21) + * #define NDCR_NAND_MODE 0x0 */ #define NDCR_CLR_PG_CNT (0x1<<20) #define NDCR_CLR_ECC (0x1<<19) #define NDCR_RD_ID_CNT (0x7<<16) #define NDCR_RA_START (0x1<<15) #define NDCR_PG_PER_BLK (0x1<<14) #define NDCR_ND_ARB_EN (0x1<<12) -#define NDCE_RDYM (0x1<<11) -#define NDCE_CS0_PAGEDM (0x1<<10) -#define NDCE_CS1_PAGEDM (0x1<<9) -#define NDCE_CS0_CMDDM (0x1<<8) -#define NDCE_CS1_CMDDM (0x1<<7) -#define NDCE_CS0_BBDM (0x1<<6) -#define NDCE_CS1_BBDM (0x1<<5) -#define NDCE_DBERRM (0x1<<4) -#define NDCE_SBERRM (0x1<<3) -#define NDCE_WRDREQM (0x1<<2) -#define NDCE_RDDREQM (0x1<<1) -#define NDCE_WRCMDREQM (0x1) +#define NDCR_RDYM (0x1<<11) +#define NDCR_CS0_PAGEDM (0x1<<10) +#define NDCR_CS1_PAGEDM (0x1<<9) +#define NDCR_CS0_CMDDM (0x1<<8) +#define NDCR_CS1_CMDDM (0x1<<7) +#define NDCR_CS0_BBDM (0x1<<6) +#define NDCR_CS1_BBDM (0x1<<5) +#define NDCR_DBERRM (0x1<<4) +#define NDCR_SBERRM (0x1<<3) +#define NDCR_WRDREQM (0x1<<2) +#define NDCR_RDDREQM (0x1<<1) +#define NDCR_WRCMDREQM (0x1) #define NDSR_RDY (0x1<<11) #define NDSR_CS0_PAGED (0x1<<10) @@ -2111,7 +2113,7 @@ typedef void (*ExcpHndlr) (void) ; #define NDSR_CS1_CMDD (0x1<<7) #define NDSR_CS0_BBD (0x1<<6) #define NDSR_CS1_BBD (0x1<<5) -#define NDSR_BDERR (0x1<<4) +#define NDSR_DBERR (0x1<<4) #define NDSR_SBERR (0x1<<3) #define NDSR_WRDREQ (0x1<<2) #define NDSR_RDDREQ (0x1<<1) From 4f718664701369d1c23d39c1916967d2895d25db Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Thu, 2 Mar 2006 11:03:05 +0100 Subject: [PATCH 027/102] Make CFG_NO_FLASH work on ARM systems Patch by Markus Klotzbuecher, 27 Feb 2006 --- CHANGELOG | 3 +++ lib_arm/board.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 0c4407c9af..2e0a957a66 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Make CFG_NO_FLASH work on ARM systems + Patch by Markus Klotzbuecher, 27 Feb 2006 + * Update mcc200 config: Disable PCI and DoC, use 133 MHz IPB clock, use hush shell. diff --git a/lib_arm/board.c b/lib_arm/board.c index 3048cbe408..f7ee9ee708 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -178,11 +178,13 @@ static int display_dram_config (void) return (0); } +#ifndef CFG_NO_FLASH static void display_flash_config (ulong size) { puts ("Flash: "); print_size (size, "\n"); } +#endif /* CFG_NO_FLASH */ /* @@ -260,9 +262,11 @@ void start_armboot (void) } } +#ifndef CFG_NO_FLASH /* configure available FLASH banks */ size = flash_init (); display_flash_config (size); +#endif /* CFG_NO_FLASH */ #ifdef CONFIG_VFD # ifndef PAGE_SIZE From bb1ff049fbac1a4edf8f0655071383e3837d337e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Thu, 2 Mar 2006 12:10:01 +0100 Subject: [PATCH 028/102] Read bug fixed. Now "nand bad" list the badblocks correctly (i hope, since there are 0) --- board/delta/nand.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/board/delta/nand.c b/board/delta/nand.c index 7255827671..50d2ec244c 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -69,8 +69,11 @@ static void delta_read_buf(struct mtd_info *mtd, u_char* const buf, int len) /* if there are any, first copy multiple of 4 bytes */ if(num_words) { - for(i=0; i Date: Thu, 2 Mar 2006 14:02:36 +0100 Subject: [PATCH 029/102] Moved the waiting loop for "Read Data Request" RDDREQ into the delta_cmdfunc function, because this bit is only set once after a command is sent and this allows read functions to be called multiple times. --- board/delta/nand.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/board/delta/nand.c b/board/delta/nand.c index 50d2ec244c..da6430dcfa 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -55,13 +55,6 @@ static void delta_read_buf(struct mtd_info *mtd, u_char* const buf, int len) { int i, j; - while(1) { - if(NDSR & NDSR_RDDREQ) { - NDSR |= NDSR_RDDREQ; - break; - } - } - /* we have to be carefull not to overflow the buffer if len is * not a multiple of 4 */ unsigned long num_words = len & 0xfffffffc; @@ -90,19 +83,25 @@ static void delta_read_buf(struct mtd_info *mtd, u_char* const buf, int len) static unsigned long read_buf = 0; static unsigned char bytes_read = 0; +/* wait for read request */ +static void delta_wait_event(unsigned long event) +{ + if(!event) + return; + + while(1) { + if(NDSR & event) { + NDSR |= event; + break; + } + } +} static u_char delta_read_byte(struct mtd_info *mtd) { /* struct nand_chip *this = mtd->priv; */ unsigned char byte; if(bytes_read == 0) { - /* wait for read request */ - while(1) { - if(NDSR & NDSR_RDDREQ) { - NDSR |= NDSR_RDDREQ; - break; - } - } read_buf = NDDB; printk("delta_read_byte: 0x%x.\n", read_buf); } @@ -119,7 +118,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { /* register struct nand_chip *this = mtd->priv; */ - unsigned long ndcb0=0, ndcb1=0, ndcb2=0; + unsigned long ndcb0=0, ndcb1=0, ndcb2=0, event=0; /* clear the ugly byte read buffer */ bytes_read = 0; @@ -153,10 +152,12 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, ((page_addr<<8) & 0xff00) | ((page_addr<<8) & 0xff0000) | ((page_addr<<8) & 0xff000000)); /* make this 0x01000000 ? */ + event = NDSR_RDDREQ; break; case NAND_CMD_READID: printk("delta_cmdfunc: NAND_CMD_READID.\n"); ndcb0 = (NAND_CMD_READID | (3 << 21) | (1 << 16)); /* addr cycles*/ + event = NDSR_RDDREQ; break; case NAND_CMD_PAGEPROG: break; @@ -190,6 +191,9 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, NDCB0 = ndcb0; NDCB0 = ndcb1; NDCB0 = ndcb2; + + /* wait for event */ + delta_wait_event(event); } static void delta_dfc_gpio_init() From 19fdeff4331eccf8b5080014fd7c1f0be6fbac73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Fri, 3 Mar 2006 12:11:11 +0100 Subject: [PATCH 030/102] Implemented writing, not working yet. --- board/delta/nand.c | 212 +++++++++++++++++++++++++++++++++------------ 1 file changed, 158 insertions(+), 54 deletions(-) diff --git a/board/delta/nand.c b/board/delta/nand.c index da6430dcfa..ef78e304d0 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -46,6 +46,48 @@ static int delta_device_ready(struct mtd_info *mtdinfo) return 0; } +/* + * Write buf to the DFC Controller Data Buffer + */ +static void delta_write_buf(struct mtd_info *mtd, const u_char *buf, int len) +{ + unsigned long bytes_multi = len & 0xfffffffc; + unsigned long rest = len & 0x3; + unsigned long *long_buf; + int i; + + if(bytes_multi) { + for(i=0; i>j) & 0xff); } return; } -/* global var, too bad */ +static void delta_read_word(struct mtd_info *mtd, u_char byte) +{ + printf("delta_write_byte: UNIMPLEMENTED.\n"); +} + +/* global var, too bad: mk@tbd: move to ->priv pointer */ static unsigned long read_buf = 0; static unsigned char bytes_read = 0; -/* wait for read request */ -static void delta_wait_event(unsigned long event) -{ - if(!event) - return; - - while(1) { - if(NDSR & event) { - NDSR |= event; - break; - } - } -} static u_char delta_read_byte(struct mtd_info *mtd) { /* struct nand_chip *this = mtd->priv; */ @@ -113,16 +147,50 @@ static u_char delta_read_byte(struct mtd_info *mtd) return byte; } +/* delay function */ +static void wait(unsigned long us) +{ +#define OSCR_CLK_FREQ 3.250 /* kHz */ + + unsigned long start = OSCR; + unsigned long delta = 0, cur; + us *= OSCR_CLK_FREQ; + + while (delta < us) { + cur = OSCR; + if(cur < start) /* OSCR overflowed */ + delta = cur + (start^0xffffffff); + else + delta = cur - start; + } +} + +/* poll the NAND Controller Status Register for event */ +static void delta_wait_event(unsigned long event) +{ + if(!event) + return; + + while(1) { + if(NDSR & event) { + NDSR |= event; + break; + } + } +} + /* this is really monahans, not board specific ... */ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { /* register struct nand_chip *this = mtd->priv; */ unsigned long ndcb0=0, ndcb1=0, ndcb2=0, event=0; + unsigned long what_the_hack; /* clear the ugly byte read buffer */ bytes_read = 0; read_buf = 0; + /* Clear NDSR */ NDSR = 0xFFF; @@ -160,29 +228,76 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, event = NDSR_RDDREQ; break; case NAND_CMD_PAGEPROG: + printk("delta_cmdfunc: NAND_CMD_PAGEPROG.\n"); + ndcb0 = (NAND_CMD_PAGEPROG | (1 << 21)); break; case NAND_CMD_ERASE1: case NAND_CMD_ERASE2: + printf("delta_cmdfunc: NAND_CMD_ERASEx unimplemented.\n"); break; case NAND_CMD_SEQIN: - ndcb0 = (NAND_CMD_SEQIN<<8) | (1<<19) | (4<<16); - if(column >= mtd->oobblock) { - /* OOB area */ - column -= mtd->oobblock; - ndcb0 |= NAND_CMD_READOOB; - } else if (column < 256) { - /* First 256 bytes --> READ0 */ - ndcb0 |= NAND_CMD_READ0; - } else { - /* Only for 8 bit devices - not delta!!! */ - column -= 256; - ndcb0 |= NAND_CMD_READ1; - } + /* send PAGE_PROG command(0x80) */ + printf("delta_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG.\n"); + ndcb0 = (NAND_CMD_SEQIN | (1<<21) | (3<<16)); + column >>= 1; /* adjust for 16 bit bus */ + ndcb1 = (((column>>1) & 0xff) | + ((page_addr<<8) & 0xff00) | + ((page_addr<<8) & 0xff0000) | + ((page_addr<<8) & 0xff000000)); /* make this 0x01000000 ? */ + event = NDSR_WRDREQ; break; +/* case NAND_CMD_SEQIN_pointer_operation: */ + +/* /\* This is confusing because the command names are */ +/* * different compared to the ones in the K9K12Q0C */ +/* * datasheet. Infact this has nothing to do with */ +/* * reading, as the but with page programming */ +/* * (writing). */ +/* * Here we send the multibyte commands */ +/* * cmd1=0x00, cmd2=0x80 (for programming main area) or */ +/* * cmd1=0x50, cmd2=0x80 (for spare area) */ +/* * */ +/* * When all data is written to the buffer, the page */ +/* * program command (0x10) is sent to actually write */ +/* * the data. */ +/* *\/ */ + +/* printf("delta_cmdfunc: NAND_CMD_SEQIN pointer op called.\n"); */ + +/* ndcb0 = (NAND_CMD_SEQIN<<8) | (1<<21) | (1<<19) | (4<<16); */ +/* if(column >= mtd->oobblock) { */ +/* /\* OOB area *\/ */ +/* column -= mtd->oobblock; */ +/* ndcb0 |= NAND_CMD_READOOB; */ +/* } else if (column < 256) { */ +/* /\* First 256 bytes --> READ0 *\/ */ +/* ndcb0 |= NAND_CMD_READ0; */ +/* } else { */ +/* /\* Only for 8 bit devices - not delta!!! *\/ */ +/* column -= 256; */ +/* ndcb0 |= NAND_CMD_READ1; */ +/* } */ +/* event = NDSR_WRDREQ; */ +/* break; */ case NAND_CMD_STATUS: - return; + /* oh, this is not nice. for some reason the real + * status byte is in the second read from the data + * buffer. The hack is to read the first byte right + * here, so the next read access by the nand code + * yields the right one. + */ + ndcb0 = (NAND_CMD_STATUS | (4<<21)); + event = NDSR_RDDREQ; + NDCB0 = ndcb0; + NDCB0 = ndcb1; + NDCB0 = ndcb2; + delta_wait_event(event); + what_the_hack = NDDB; + goto end; + break; case NAND_CMD_RESET: - return; + printf("delta_cmdfunc: NAND_CMD_RESET unimplemented.\n"); + break; default: printk("delta_cmdfunc: error, unsupported command.\n"); return; @@ -194,6 +309,8 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, /* wait for event */ delta_wait_event(event); + end: + return; } static void delta_dfc_gpio_init() @@ -251,23 +368,6 @@ static void delta_dfc_gpio_init() * Members with a "?" were not set in the merged testing-NAND branch, * so they are not set here either. */ -void wait(unsigned long us) -{ -#define OSCR_CLK_FREQ 3.250 /* kHz */ - - unsigned long start = OSCR; - unsigned long delta = 0, cur; - us *= OSCR_CLK_FREQ; - - while (delta < us) { - cur = OSCR; - if(cur < start) /* OSCR overflowed */ - delta = cur + (start^0xffffffff); - else - delta = cur - start; - } -} - void board_nand_init(struct nand_chip *nand) { unsigned long tCH, tCS, tWH, tWP, tRH, tRP, tRP_high, tR, tWHR, tAR; @@ -402,13 +502,17 @@ void board_nand_init(struct nand_chip *nand) nand->eccmode = NAND_ECC_SOFT; nand->chip_delay = NAND_DELAY_US; nand->options = NAND_BUSWIDTH_16; + nand->read_byte = delta_read_byte; + nand->write_byte = delta_write_byte; + nand->read_word = delta_read_word; + nand->write_word = delta_write_word; nand->read_buf = delta_read_buf; + nand->write_buf = delta_write_buf; nand->cmdfunc = delta_cmdfunc; - /* nand->options = NAND_SAMSUNG_LP_OPTIONS; */ } #else -#error "U-Boot legacy NAND support not available for delta board." + #error "U-Boot legacy NAND support not available for delta board." #endif #endif From 9187a35b6c3167162c156a24e90622463e2ced08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Fri, 3 Mar 2006 15:37:01 +0100 Subject: [PATCH 031/102] Writing is working, but there's still a bug that causes the data written to start at an offset of 4 bytes from the start of the page. --- board/delta/nand.c | 98 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 25 deletions(-) diff --git a/board/delta/nand.c b/board/delta/nand.c index ef78e304d0..e09b92aa03 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -121,7 +121,7 @@ static void delta_read_buf(struct mtd_info *mtd, u_char* const buf, int len) return; } -static void delta_read_word(struct mtd_info *mtd, u_char byte) +static u16 delta_read_word(struct mtd_info *mtd) { printf("delta_write_byte: UNIMPLEMENTED.\n"); } @@ -179,6 +179,66 @@ static void delta_wait_event(unsigned long event) } } +static unsigned long delta_wait_event2(unsigned long event) +{ + unsigned long ndsr; + if(!event) + return; + + while(1) { + ndsr = NDSR; + if(ndsr & event) { + NDSR |= event; + break; + } + } + return ndsr; +} + +/* we don't always wan't to do this */ +static void delta_new_cmd() +{ + /* Clear NDSR */ + NDSR = 0xFFF; + + /* apparently NDCR[NDRUN] needs to be set before writing to NDCBx */ + if(!(NDCR & NDCR_ND_RUN)) { + NDCR |= NDCR_ND_RUN; + + while(1) { + if(NDSR & NDSR_WRCMDREQ) { + NDSR |= NDSR_WRCMDREQ; /* Ack */ + break; + } + } + } +} + +static int delta_wait(struct mtd_info *mtd, struct nand_chip *this, int state) +{ +/* unsigned long timeo; */ + unsigned long ndsr=0, event=0; + unsigned long dummy; + + /* mk@tbd set appropriate timeouts */ + /* if (state == FL_ERASING) */ + /* timeo = CFG_HZ * 400; */ + /* else */ + /* timeo = CFG_HZ * 20; */ + if(state == FL_WRITING) { + event = NDSR_CS0_CMDD | NDSR_CS0_BBD; + } else if(state == FL_ERASING) { + /* do something else */ + } + +/* dummy = NDDB; */ + ndsr = delta_wait_event2(event); + + if(ndsr & NDSR_CS0_BBD) + return(0x1); /* Status Read error */ + return 0; +} + /* this is really monahans, not board specific ... */ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) @@ -190,30 +250,14 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, /* clear the ugly byte read buffer */ bytes_read = 0; read_buf = 0; - - /* Clear NDSR */ - NDSR = 0xFFF; - - /* apparently NDCR[NDRUN] needs to be set before writing to NDCBx */ - NDCR |= NDCR_ND_RUN; - - /* wait for write command request - * hmm, might be nice if this could time-out. mk@tbd - */ - while(1) { - if(NDSR & NDSR_WRCMDREQ) { - NDSR |= NDSR_WRCMDREQ; /* Ack */ - break; - } - } - /* if command is a double byte cmd, we set bit double cmd bit 19 */ /* command2 = (command>>8) & 0xFF; */ /* ndcb0 = command | ((command2 ? 1 : 0) << 19); *\/ */ switch (command) { case NAND_CMD_READ0: + delta_new_cmd(); ndcb0 = (NAND_CMD_READ0 | (4<<16)); column >>= 1; /* adjust for 16 bit bus */ ndcb1 = (((column>>1) & 0xff) | @@ -223,22 +267,24 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, event = NDSR_RDDREQ; break; case NAND_CMD_READID: + delta_new_cmd(); printk("delta_cmdfunc: NAND_CMD_READID.\n"); ndcb0 = (NAND_CMD_READID | (3 << 21) | (1 << 16)); /* addr cycles*/ event = NDSR_RDDREQ; break; case NAND_CMD_PAGEPROG: + /* sent as a multicommand in NAND_CMD_SEQIN */ printk("delta_cmdfunc: NAND_CMD_PAGEPROG.\n"); - ndcb0 = (NAND_CMD_PAGEPROG | (1 << 21)); - break; + goto end; case NAND_CMD_ERASE1: case NAND_CMD_ERASE2: printf("delta_cmdfunc: NAND_CMD_ERASEx unimplemented.\n"); - break; + goto end; case NAND_CMD_SEQIN: - /* send PAGE_PROG command(0x80) */ + /* send PAGE_PROG command(0x1080) */ + delta_new_cmd(); printf("delta_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG.\n"); - ndcb0 = (NAND_CMD_SEQIN | (1<<21) | (3<<16)); + ndcb0 = (0x1080 | (1<<25) | (1<<21) | (1<<19) | (4<<16)); column >>= 1; /* adjust for 16 bit bus */ ndcb1 = (((column>>1) & 0xff) | ((page_addr<<8) & 0xff00) | @@ -286,6 +332,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, * here, so the next read access by the nand code * yields the right one. */ + delta_new_cmd(); ndcb0 = (NAND_CMD_STATUS | (4<<21)); event = NDSR_RDDREQ; NDCB0 = ndcb0; @@ -307,7 +354,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, NDCB0 = ndcb1; NDCB0 = ndcb2; - /* wait for event */ + wait_event: delta_wait_event(event); end: return; @@ -502,13 +549,14 @@ void board_nand_init(struct nand_chip *nand) nand->eccmode = NAND_ECC_SOFT; nand->chip_delay = NAND_DELAY_US; nand->options = NAND_BUSWIDTH_16; - + nand->waitfunc = delta_wait; nand->read_byte = delta_read_byte; nand->write_byte = delta_write_byte; nand->read_word = delta_read_word; nand->write_word = delta_write_word; nand->read_buf = delta_read_buf; nand->write_buf = delta_write_buf; + nand->cmdfunc = delta_cmdfunc; } From 24e1217be3b3c912ec8f7796195fda41275a7f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Fri, 3 Mar 2006 16:09:28 +0100 Subject: [PATCH 032/102] Write operation is working. Turned out that the READSTATUS hack was wrong after all. --- board/delta/nand.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/board/delta/nand.c b/board/delta/nand.c index e09b92aa03..d37a49e195 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -335,12 +335,14 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, delta_new_cmd(); ndcb0 = (NAND_CMD_STATUS | (4<<21)); event = NDSR_RDDREQ; +#ifdef READ_STATUS_BUG NDCB0 = ndcb0; NDCB0 = ndcb1; NDCB0 = ndcb2; delta_wait_event(event); what_the_hack = NDDB; goto end; +#endif break; case NAND_CMD_RESET: printf("delta_cmdfunc: NAND_CMD_RESET unimplemented.\n"); From f8785e96c9f7249328b267d4c82e2218748e3729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Fri, 3 Mar 2006 20:13:43 +0100 Subject: [PATCH 033/102] Erasing works too now. The CS don't care causes problem with READSTATUS, don't ask me why. There are still bugs in the bad block logic. --- board/delta/nand.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/board/delta/nand.c b/board/delta/nand.c index d37a49e195..bc6d7a47bb 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -218,7 +218,6 @@ static int delta_wait(struct mtd_info *mtd, struct nand_chip *this, int state) { /* unsigned long timeo; */ unsigned long ndsr=0, event=0; - unsigned long dummy; /* mk@tbd set appropriate timeouts */ /* if (state == FL_ERASING) */ @@ -228,10 +227,9 @@ static int delta_wait(struct mtd_info *mtd, struct nand_chip *this, int state) if(state == FL_WRITING) { event = NDSR_CS0_CMDD | NDSR_CS0_BBD; } else if(state == FL_ERASING) { - /* do something else */ + event = NDSR_CS0_CMDD | NDSR_CS0_BBD; } -/* dummy = NDDB; */ ndsr = delta_wait_event2(event); if(ndsr & NDSR_CS0_BBD) @@ -277,8 +275,13 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, printk("delta_cmdfunc: NAND_CMD_PAGEPROG.\n"); goto end; case NAND_CMD_ERASE1: + printf("delta_cmdfunc: NAND_CMD_ERASE1.\n"); + delta_new_cmd(); + ndcb0 = (0xd060 | (1<<25) | (2<<21) | (1<<19) | (3<<16)); + ndcb1 = (page_addr & 0x00ffffff); + break; case NAND_CMD_ERASE2: - printf("delta_cmdfunc: NAND_CMD_ERASEx unimplemented.\n"); + printf("delta_cmdfunc: NAND_CMD_ERASE1 empty due to multicmd.\n"); goto end; case NAND_CMD_SEQIN: /* send PAGE_PROG command(0x1080) */ @@ -335,6 +338,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, delta_new_cmd(); ndcb0 = (NAND_CMD_STATUS | (4<<21)); event = NDSR_RDDREQ; +/* #define READ_STATUS_BUG 1 */ #ifdef READ_STATUS_BUG NDCB0 = ndcb0; NDCB0 = ndcb1; @@ -522,10 +526,11 @@ void board_nand_init(struct nand_chip *nand) * - pages per block = 32 * - ND_RDY : clears command buffer */ + /* NDCR_NCSX | /\* Chip select busy don't care *\/ */ + NDCR = (NDCR_SPARE_EN | /* use the spare area */ NDCR_DWIDTH_C | /* 16bit DFC data bus width */ NDCR_DWIDTH_M | /* 16 bit Flash device data bus width */ - NDCR_NCSX | /* Chip select busy don't care */ (7 << 16) | /* read id count = 7 ???? mk@tbd */ NDCR_ND_ARB_EN | /* enable bus arbiter */ NDCR_RDYM | /* flash device ready ir masked */ From f1ee982506d8e58262ff0e5d1fb208e703640e34 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Sat, 4 Mar 2006 14:57:03 +0100 Subject: [PATCH 034/102] Add lowboot target to mcc200 board Patch by Stefan Roese, 4 Mar 2006 --- CHANGELOG | 3 +++ Makefile | 8 +++++++- board/mcc200/config.mk | 16 ++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 85ae3efbd5..4cc66295d8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add lowboot target to mcc200 board + Patch by Stefan Roese, 4 Mar 2006 + * Fix problem with flash_get_size() from CFI driver update Patch by Stefan Roese, 1 Mar 2006 diff --git a/Makefile b/Makefile index eafbfb604b..30a1d1f334 100644 --- a/Makefile +++ b/Makefile @@ -294,7 +294,13 @@ icecube_5100_config: unconfig inka4x0_config: unconfig @./mkconfig inka4x0 ppc mpc5xxx inka4x0 -mcc200_config: unconfig +mcc200_config \ +mcc200_lowboot_config: unconfig + @ >include/config.h + @[ -z "$(findstring lowboot_,$@)" ] || \ + { echo "TEXT_BASE = 0xFE000000" >board/mcc200/config.tmp ; \ + echo "... with lowboot configuration" ; \ + } @./mkconfig mcc200 ppc mpc5xxx mcc200 o2dnt_config: diff --git a/board/mcc200/config.mk b/board/mcc200/config.mk index 0a278b16bf..fa55673adf 100644 --- a/board/mcc200/config.mk +++ b/board/mcc200/config.mk @@ -22,10 +22,22 @@ # # -# MCC200 board +# MCC200 board: +# +# Valid values for TEXT_BASE are: +# +# 0xFFF00000 boot high (standard configuration) +# 0xFE000000 boot low +# 0x00100000 boot from RAM (for testing only) # -TEXT_BASE = 0xfff00000 +sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp + +ifndef TEXT_BASE +## Standard: boot high +TEXT_BASE = 0xFFF00000 +## For testing: boot from RAM # TEXT_BASE = 0x00100000 +endif PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board From bf7cac033b27589c7de71a5f37f0c8e872ad489a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Sat, 4 Mar 2006 18:35:51 +0100 Subject: [PATCH 035/102] Lots of new stuff: * Debug message can be turned on and off. * Waiting for events now times out. * Implemented RESET command. * Added appropriate nand_bbt_descriptor and nand_oobinfo. Remaining Problems: * Read Status still behaves weird an returns invalid stuff sometimes. * ECC Placement does not respect our scheme in nand_oobinfo. --- board/delta/nand.c | 265 +++++++++++++++++++++++++++++----------- cpu/pxa/start.S | 2 +- include/configs/delta.h | 5 + 3 files changed, 197 insertions(+), 75 deletions(-) diff --git a/board/delta/nand.c b/board/delta/nand.c index bc6d7a47bb..9f882a52b9 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -28,6 +28,41 @@ #include #include +/* mk@tbd move this to pxa-regs */ +#define OSCR_CLK_FREQ 3.250 /* MHz */ + +#define CFG_DFC_DEBUG1 +#define CFG_DFC_DEBUG2 + +#ifdef CFG_DFC_DEBUG1 +# define DFC_DEBUG1(fmt, args...) printf(fmt, ##args) +#else +# define DFC_DEBUG1(fmt, args...) +#endif + +#ifdef CFG_DFC_DEBUG2 +# define DFC_DEBUG2(fmt, args...) printf(fmt, ##args) +#else +# define DFC_DEBUG2(fmt, args...) +#endif + +static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; + +static struct nand_bbt_descr delta_bbt_descr = { + .options = 0, + .offs = 0, + .len = 2, + .pattern = scan_ff_pattern +}; + +static struct nand_oobinfo delta_oob = { + .useecc = MTD_NANDECC_AUTOPLACE, + .eccbytes = 6, + .eccpos = {2, 3, 4, 5, 6, 7}, + .oobfree = { {8, 2}, {12, 4} } +}; + + /* * not required for Monahans DFC */ @@ -121,6 +156,9 @@ static void delta_read_buf(struct mtd_info *mtd, u_char* const buf, int len) return; } +/* + * read a word. Not implemented as not used in NAND code. + */ static u16 delta_read_word(struct mtd_info *mtd) { printf("delta_write_byte: UNIMPLEMENTED.\n"); @@ -128,43 +166,86 @@ static u16 delta_read_word(struct mtd_info *mtd) /* global var, too bad: mk@tbd: move to ->priv pointer */ static unsigned long read_buf = 0; -static unsigned char bytes_read = 0; +static int bytes_read = -1; +/* read a byte from NDDB Because we can only read 4 bytes from NDDB at + * a time, we buffer the remaining bytes. The buffer is reset when a + * new command is sent to the chip. + */ static u_char delta_read_byte(struct mtd_info *mtd) { /* struct nand_chip *this = mtd->priv; */ unsigned char byte; - if(bytes_read == 0) { + if(bytes_read < 0) { read_buf = NDDB; - printk("delta_read_byte: 0x%x.\n", read_buf); + bytes_read = 0; } byte = (unsigned char) (read_buf>>(8 * bytes_read++)); if(bytes_read >= 4) - bytes_read = 0; + bytes_read = -1; - printf("delta_read_byte: returning 0x%x.\n", byte); + DFC_DEBUG2("delta_read_byte: byte %u: 0x%x of (0x%x).\n", bytes_read, byte, read_buf); return byte; } -/* delay function */ -static void wait(unsigned long us) +/* calculate delta between OSCR values start and now */ +static unsigned long get_delta(unsigned long start) { -#define OSCR_CLK_FREQ 3.250 /* kHz */ + unsigned long cur = OSCR; + + if(cur < start) /* OSCR overflowed */ + return (cur + (start^0xffffffff)); + else + return (cur - start); +} +/* delay function, this doesn't belong here */ +static void wait_us(unsigned long us) +{ unsigned long start = OSCR; - unsigned long delta = 0, cur; us *= OSCR_CLK_FREQ; - while (delta < us) { - cur = OSCR; - if(cur < start) /* OSCR overflowed */ - delta = cur + (start^0xffffffff); - else - delta = cur - start; + while (get_delta(start) < us) { + /* do nothing */ } } +static void delta_clear_nddb() +{ + NDCR &= ~NDCR_ND_RUN; + wait_us(CFG_NAND_OTHER_TO); +} + +/* wait_event with timeout */ +static unsigned long delta_wait_event2(unsigned long event) +{ + unsigned long ndsr, timeout, start = OSCR; + + if(!event) + return 0xff000000; + else if(event & (NDSR_CS0_CMDD | NDSR_CS0_BBD)) + timeout = CFG_NAND_PROG_ERASE_TO * OSCR_CLK_FREQ; + else + timeout = CFG_NAND_OTHER_TO * OSCR_CLK_FREQ; + + while(1) { + ndsr = NDSR; + if(ndsr & event) { + NDSR |= event; + break; + } + if(get_delta(start) > timeout) { + DFC_DEBUG1("delta_wait_event: TIMEOUT waiting for event: 0x%x.\n", event); + return 0xff000000; + } + + } + return ndsr; +} + + +#if DEADCODE /* poll the NAND Controller Status Register for event */ static void delta_wait_event(unsigned long event) { @@ -178,45 +259,46 @@ static void delta_wait_event(unsigned long event) } } } - -static unsigned long delta_wait_event2(unsigned long event) -{ - unsigned long ndsr; - if(!event) - return; - - while(1) { - ndsr = NDSR; - if(ndsr & event) { - NDSR |= event; - break; - } - } - return ndsr; -} +#endif /* we don't always wan't to do this */ static void delta_new_cmd() { - /* Clear NDSR */ - NDSR = 0xFFF; - - /* apparently NDCR[NDRUN] needs to be set before writing to NDCBx */ - if(!(NDCR & NDCR_ND_RUN)) { - NDCR |= NDCR_ND_RUN; + int retry = 0; + unsigned long status; + + while(retry++ <= CFG_NAND_SENDCMD_RETRY) { + /* Clear NDSR */ + NDSR = 0xFFF; - while(1) { - if(NDSR & NDSR_WRCMDREQ) { - NDSR |= NDSR_WRCMDREQ; /* Ack */ - break; - } + /* set NDCR[NDRUN] */ + if(!(NDCR & NDCR_ND_RUN)) + NDCR |= NDCR_ND_RUN; + + status = delta_wait_event2(NDSR_WRCMDREQ); + + if(status & NDSR_WRCMDREQ) + return; + + DFC_DEBUG2("delta_new_cmd: FAILED to get WRITECMDREQ, retry: %d.\n", retry); + delta_clear_nddb(); + } + DFC_DEBUG1("delta_new_cmd: giving up after %d retries.\n", retry); + +#if DEADCODE + while(1) { + if(NDSR & NDSR_WRCMDREQ) { + NDSR |= NDSR_WRCMDREQ; /* Ack */ + break; } } +#endif + } - +/* this function is called after Programm and Erase Operations to + * check for success or failure */ static int delta_wait(struct mtd_info *mtd, struct nand_chip *this, int state) { -/* unsigned long timeo; */ unsigned long ndsr=0, event=0; /* mk@tbd set appropriate timeouts */ @@ -232,12 +314,12 @@ static int delta_wait(struct mtd_info *mtd, struct nand_chip *this, int state) ndsr = delta_wait_event2(event); - if(ndsr & NDSR_CS0_BBD) + if((ndsr & NDSR_CS0_BBD) || (ndsr & 0xff000000)) return(0x1); /* Status Read error */ return 0; } -/* this is really monahans, not board specific ... */ +/* cmdfunc send commands to the DFC */ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { @@ -246,7 +328,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, unsigned long what_the_hack; /* clear the ugly byte read buffer */ - bytes_read = 0; + bytes_read = -1; read_buf = 0; /* if command is a double byte cmd, we set bit double cmd bit 19 */ @@ -263,30 +345,30 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, ((page_addr<<8) & 0xff0000) | ((page_addr<<8) & 0xff000000)); /* make this 0x01000000 ? */ event = NDSR_RDDREQ; - break; + goto write_cmd; case NAND_CMD_READID: delta_new_cmd(); - printk("delta_cmdfunc: NAND_CMD_READID.\n"); + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_READID.\n"); ndcb0 = (NAND_CMD_READID | (3 << 21) | (1 << 16)); /* addr cycles*/ event = NDSR_RDDREQ; - break; + goto write_cmd; case NAND_CMD_PAGEPROG: /* sent as a multicommand in NAND_CMD_SEQIN */ - printk("delta_cmdfunc: NAND_CMD_PAGEPROG.\n"); + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_PAGEPROG empty due to multicmd.\n"); goto end; case NAND_CMD_ERASE1: - printf("delta_cmdfunc: NAND_CMD_ERASE1.\n"); + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_ERASE1.\n"); delta_new_cmd(); ndcb0 = (0xd060 | (1<<25) | (2<<21) | (1<<19) | (3<<16)); ndcb1 = (page_addr & 0x00ffffff); - break; + goto write_cmd; case NAND_CMD_ERASE2: - printf("delta_cmdfunc: NAND_CMD_ERASE1 empty due to multicmd.\n"); + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_ERASE2 empty due to multicmd.\n"); goto end; case NAND_CMD_SEQIN: /* send PAGE_PROG command(0x1080) */ delta_new_cmd(); - printf("delta_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG.\n"); + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG.\n"); ndcb0 = (0x1080 | (1<<25) | (1<<21) | (1<<19) | (4<<16)); column >>= 1; /* adjust for 16 bit bus */ ndcb1 = (((column>>1) & 0xff) | @@ -294,7 +376,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, ((page_addr<<8) & 0xff0000) | ((page_addr<<8) & 0xff000000)); /* make this 0x01000000 ? */ event = NDSR_WRDREQ; - break; + goto write_cmd; /* case NAND_CMD_SEQIN_pointer_operation: */ /* /\* This is confusing because the command names are */ @@ -329,6 +411,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, /* event = NDSR_WRDREQ; */ /* break; */ case NAND_CMD_STATUS: + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_STATUS.\n"); /* oh, this is not nice. for some reason the real * status byte is in the second read from the data * buffer. The hack is to read the first byte right @@ -336,39 +419,47 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, * yields the right one. */ delta_new_cmd(); - ndcb0 = (NAND_CMD_STATUS | (4<<21)); + ndcb0 = NAND_CMD_STATUS | (4<<21); event = NDSR_RDDREQ; -/* #define READ_STATUS_BUG 1 */ +#undef READ_STATUS_BUG #ifdef READ_STATUS_BUG NDCB0 = ndcb0; NDCB0 = ndcb1; NDCB0 = ndcb2; - delta_wait_event(event); + delta_wait_event2(event); what_the_hack = NDDB; + if(what_the_hack != 0xffffffff) { + DFC_DEBUG2("what the hack.\n"); + read_buf = what_the_hack; + bytes_read = 0; + } goto end; #endif - break; + goto write_cmd; case NAND_CMD_RESET: - printf("delta_cmdfunc: NAND_CMD_RESET unimplemented.\n"); - break; + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_RESET.\n"); + ndcb0 = NAND_CMD_RESET | (5<<21); + event = NDSR_CS0_CMDD; + goto write_cmd; default: printk("delta_cmdfunc: error, unsupported command.\n"); - return; + goto end; } + write_cmd: NDCB0 = ndcb0; NDCB0 = ndcb1; NDCB0 = ndcb2; wait_event: - delta_wait_event(event); + delta_wait_event2(event); end: return; } static void delta_dfc_gpio_init() { - printf("Setting up DFC GPIO's.\n"); + DFC_DEBUG2("Setting up DFC GPIO's.\n"); /* no idea what is done here, see zylonite.c */ GPIO4 = 0x1; @@ -442,14 +533,16 @@ void board_nand_init(struct nand_chip *nand) #define NAND_TIMING_tCS 0 #define NAND_TIMING_tWH 20 #define NAND_TIMING_tWP 40 -/* #define NAND_TIMING_tRH 20 */ -/* #define NAND_TIMING_tRP 40 */ -#define NAND_TIMING_tRH 25 -#define NAND_TIMING_tRP 50 +#define NAND_TIMING_tRH 20 +#define NAND_TIMING_tRP 40 + +/* #define NAND_TIMING_tRH 25 */ +/* #define NAND_TIMING_tRP 50 */ #define NAND_TIMING_tR 11123 -#define NAND_TIMING_tWHR 110 +/* #define NAND_TIMING_tWHR 110 */ +#define NAND_TIMING_tWHR 100 #define NAND_TIMING_tAR 10 /* Maximum values for NAND Interface Timing Registers in DFC clock @@ -468,7 +561,8 @@ void board_nand_init(struct nand_chip *nand) #define DFC_CLK_PER_US DFC_CLOCK/1000 /* clock period in ns */ #define MIN(x, y) ((x < y) ? x : y) - + +#ifndef CFG_TIMING_TIGHT tCH = MIN(((unsigned long) (NAND_TIMING_tCH * DFC_CLK_PER_US) + 1), DFC_MAX_tCH); tCS = MIN(((unsigned long) (NAND_TIMING_tCS * DFC_CLK_PER_US) + 1), @@ -487,9 +581,30 @@ void board_nand_init(struct nand_chip *nand) DFC_MAX_tWHR); tAR = MIN(((unsigned long) (NAND_TIMING_tAR * DFC_CLK_PER_US) + 1), DFC_MAX_tAR); - +#else /* this is the tight timing */ - printf("tCH=%u, tCS=%u, tWH=%u, tWP=%u, tRH=%u, tRP=%u, tR=%u, tWHR=%u, tAR=%u.\n", tCH, tCS, tWH, tWP, tRH, tRP, tR, tWHR, tAR); + tCH = MIN(((unsigned long) (NAND_TIMING_tCH * DFC_CLK_PER_US)), + DFC_MAX_tCH); + tCS = MIN(((unsigned long) (NAND_TIMING_tCS * DFC_CLK_PER_US)), + DFC_MAX_tCS); + tWH = MIN(((unsigned long) (NAND_TIMING_tWH * DFC_CLK_PER_US)), + DFC_MAX_tWH); + tWP = MIN(((unsigned long) (NAND_TIMING_tWP * DFC_CLK_PER_US)), + DFC_MAX_tWP); + tRH = MIN(((unsigned long) (NAND_TIMING_tRH * DFC_CLK_PER_US)), + DFC_MAX_tRH); + tRP = MIN(((unsigned long) (NAND_TIMING_tRP * DFC_CLK_PER_US)), + DFC_MAX_tRP); + tR = MIN(((unsigned long) (NAND_TIMING_tR * DFC_CLK_PER_US) - tCH - 2), + DFC_MAX_tR); + tWHR = MIN(((unsigned long) (NAND_TIMING_tWHR * DFC_CLK_PER_US) - tCH - 2), + DFC_MAX_tWHR); + tAR = MIN(((unsigned long) (NAND_TIMING_tAR * DFC_CLK_PER_US) - 2), + DFC_MAX_tAR); +#endif /* CFG_TIMING_TIGHT */ + + + DFC_DEBUG2("tCH=%u, tCS=%u, tWH=%u, tWP=%u, tRH=%u, tRP=%u, tR=%u, tWHR=%u, tAR=%u.\n", tCH, tCS, tWH, tWP, tRH, tRP, tR, tWHR, tAR); /* tRP value is split in the register */ if(tRP & (1 << 4)) { @@ -548,7 +663,7 @@ void board_nand_init(struct nand_chip *nand) /* wait 10 us due to cmd buffer clear reset */ -/* wait(10); */ + /* wait(10); */ nand->hwcontrol = delta_hwcontrol; @@ -565,6 +680,8 @@ void board_nand_init(struct nand_chip *nand) nand->write_buf = delta_write_buf; nand->cmdfunc = delta_cmdfunc; + nand->autooob = &delta_oob; + nand->badblock_pattern = &delta_bbt_descr; } #else diff --git a/cpu/pxa/start.S b/cpu/pxa/start.S index 159447efe3..0eb811f20e 100644 --- a/cpu/pxa/start.S +++ b/cpu/pxa/start.S @@ -189,7 +189,7 @@ cpuspeed: .word CFG_CPUSPEED #else #error "You have to define CFG_CPUSPEED!!" #endif - + /* takes care the CP15 update has taken place */ .macro CPWAIT reg diff --git a/include/configs/delta.h b/include/configs/delta.h index ac412ee878..99ce0f621b 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -173,6 +173,11 @@ /* #define NAND_NO_RB */ #define NAND_DELAY_US 25 /* mk@tbd: could be 0, I guess */ +/* nand timeout values */ +#define CFG_NAND_PROG_ERASE_TO 300 +#define CFG_NAND_OTHER_TO 100 +#define CFG_NAND_SENDCMD_RETRY 3 + #define ADDR_COLUMN 1 #define ADDR_PAGE 2 #define ADDR_COLUMN_PAGE 3 From addb2e1650fdf872334478393f482dfdce965a61 Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Sun, 5 Mar 2006 18:57:33 +0100 Subject: [PATCH 036/102] Re-factoring the legacy NAND code (legacy NAND now only in board-specific code and in SoC code). Boards using the old way have CFG_NAND_LEGACY and BOARDLIBS = drivers/nand_legacy/libnand_legacy.a added. Build breakage for NETTA.ERR and NETTA_ISDN - will go away when the new NAND support is implemented for these boards. --- MAKEALL | 8 +- board/amcc/bamboo/bamboo.c | 2 +- board/amcc/bamboo/config.mk | 4 + board/bmw/config.mk | 1 + board/dave/PPChameleonEVB/config.mk | 6 +- board/dave/PPChameleonEVB/nand.c | 36 +- board/esd/ash405/ash405.c | 2 +- board/esd/ash405/config.mk | 3 + board/esd/cms700/cms700.c | 2 +- board/esd/cms700/config.mk | 3 + board/esd/common/auto_update.c | 28 +- board/esd/cpci405/config.mk | 4 + board/esd/hh405/config.mk | 4 + board/esd/hh405/hh405.c | 2 +- board/esd/hub405/config.mk | 4 + board/esd/hub405/hub405.c | 2 +- board/esd/plu405/config.mk | 3 + board/esd/plu405/plu405.c | 2 +- board/esd/voh405/config.mk | 3 + board/esd/voh405/voh405.c | 2 +- board/esd/wuh405/config.mk | 3 + board/esd/wuh405/wuh405.c | 2 +- board/g2000/g2000.c | 2 +- board/netphone/config.mk | 3 + board/netphone/netphone.c | 2 +- board/netstar/config.mk | 2 +- board/netstar/setup.S | 4 +- board/netta2/config.mk | 4 + board/netta2/netta2.c | 2 +- board/netvia/config.mk | 3 + board/netvia/netvia.c | 2 +- board/omap2420h4/omap2420h4.c | 2 +- board/sixnet/config.mk | 3 + board/sixnet/sixnet.c | 2 +- board/stxxtc/stxxtc.c | 2 +- common/Makefile | 2 +- common/cmd_doc.c | 3 +- common/cmd_jffs2.c | 17 +- common/cmd_nand.c | 1959 ++++++--------------------- common/cmd_nand_new.c | 364 ----- common/env_nand.c | 49 +- drivers/nand/diskonchip.c | 7 +- drivers/nand/nand.c | 7 +- drivers/nand/nand_base.c | 11 +- drivers/nand/nand_bbt.c | 7 +- drivers/nand/nand_ecc.c | 7 +- drivers/nand/nand_ids.c | 7 +- drivers/nand_legacy/Makefile | 16 + drivers/nand_legacy/nand_legacy.c | 1615 ++++++++++++++++++++++ fs/jffs2/jffs2_1pass.c | 24 +- fs/jffs2/jffs2_nand_1pass.c | 2 +- include/configs/ASH405.h | 3 + include/configs/BMW.h | 4 + include/configs/CMS700.h | 2 + include/configs/CPCI405.h | 2 + include/configs/CPCI4052.h | 2 + include/configs/CPCI405AB.h | 3 + include/configs/CPCI405DT.h | 2 + include/configs/CPU86.h | 2 + include/configs/CPU87.h | 2 + include/configs/GEN860T.h | 2 + include/configs/HH405.h | 2 + include/configs/HUB405.h | 2 + include/configs/MIP405.h | 2 + include/configs/NETPHONE.h | 1 + include/configs/NETTA2.h | 1 + include/configs/NETVIA.h | 2 + include/configs/PCIPPC2.h | 1 + include/configs/PCIPPC6.h | 1 + include/configs/PIP405.h | 2 + include/configs/PLU405.h | 2 + include/configs/PM520.h | 2 + include/configs/PM826.h | 2 + include/configs/PM828.h | 1 + include/configs/PPChameleonEVB.h | 103 +- include/configs/RBC823.h | 2 + include/configs/SXNI855T.h | 1 + include/configs/VOH405.h | 2 + include/configs/WUH405.h | 2 + include/configs/bamboo.h | 1 + include/configs/netstar.h | 2 +- include/configs/svm_sc8xx.h | 1 + include/linux/mtd/nand.h | 502 +++++-- include/linux/mtd/nand_ids.h | 4 + include/linux/mtd/nand_legacy.h | 203 +++ include/linux/mtd/nand_new.h | 469 ------- 86 files changed, 2881 insertions(+), 2712 deletions(-) delete mode 100644 common/cmd_nand_new.c create mode 100644 drivers/nand_legacy/Makefile create mode 100644 drivers/nand_legacy/nand_legacy.c create mode 100644 include/linux/mtd/nand_legacy.h delete mode 100644 include/linux/mtd/nand_new.h diff --git a/MAKEALL b/MAKEALL index fcbab47cab..d563227d89 100755 --- a/MAKEALL +++ b/MAKEALL @@ -177,10 +177,10 @@ LIST_ARM9=" \ ap920t ap922_XA10 ap926ejs ap946es \ ap966 cp920t cp922_XA10 cp926ejs \ cp946es cp966 lpd7a400 mp2usb \ - mx1ads mx1fs2 omap1510inn omap1610h2 \ - omap1610inn omap730p2 scb9328 smdk2400 \ - smdk2410 trab VCMA9 versatile \ - versatileab versatilepb voiceblue + mx1ads mx1fs2 netstar omap1510inn \ + omap1610h2 omap1610inn omap730p2 scb9328 \ + smdk2400 smdk2410 trab VCMA9 \ + versatile versatileab versatilepb voiceblue " ######################################################################### diff --git a/board/amcc/bamboo/bamboo.c b/board/amcc/bamboo/bamboo.c index 803995ae5d..7c989200fe 100644 --- a/board/amcc/bamboo/bamboo.c +++ b/board/amcc/bamboo/bamboo.c @@ -277,7 +277,7 @@ int board_early_init_f(void) } #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; /*----------------------------------------------------------------------------+ diff --git a/board/amcc/bamboo/config.mk b/board/amcc/bamboo/config.mk index 35cb65584a..b6495de692 100644 --- a/board/amcc/bamboo/config.mk +++ b/board/amcc/bamboo/config.mk @@ -32,3 +32,7 @@ endif ifeq ($(dbcr),1) PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000 endif + +# legacy nand support +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a + diff --git a/board/bmw/config.mk b/board/bmw/config.mk index f9915496ad..10b7a9f5ea 100644 --- a/board/bmw/config.mk +++ b/board/bmw/config.mk @@ -30,3 +30,4 @@ TEXT_BASE = 0xFFF00000 PLATFORM_CPPFLAGS += -DEMBEDDED -DBIG_ENDIAN_HOST -DINCLUDE_5701_AX_FIX=1\ -DDBG=0 -DT3_JUMBO_RCV_RCB_ENTRY_COUNT=256\ -DTEXT_BASE=$(TEXT_BASE) + diff --git a/board/dave/PPChameleonEVB/config.mk b/board/dave/PPChameleonEVB/config.mk index 6e03b72b66..5d3df0c858 100644 --- a/board/dave/PPChameleonEVB/config.mk +++ b/board/dave/PPChameleonEVB/config.mk @@ -27,5 +27,9 @@ # Reserve 320 kB for Monitor TEXT_BASE = 0xFFFB0000 -# Compile the new NAND code (needed iff #ifdef CONFIG_NEW_NAND_CODE) +# Compile the new NAND code (CFG_NAND_LEGACY mustn't be defined) BOARDLIBS = drivers/nand/libnand.a + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +#BOARDLIBS = drivers/nand_legacy/libnand_legacy.a + diff --git a/board/dave/PPChameleonEVB/nand.c b/board/dave/PPChameleonEVB/nand.c index 16c67cd972..61edc787fa 100644 --- a/board/dave/PPChameleonEVB/nand.c +++ b/board/dave/PPChameleonEVB/nand.c @@ -22,9 +22,8 @@ #include + #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#ifdef CONFIG_NEW_NAND_CODE -/* new NAND handling */ #include @@ -90,7 +89,7 @@ static int ppchameleonevb_device_ready(struct mtd_info *mtdinfo) /* * Board-specific NAND initialization. The following members of the - * argument are board-specific (per include/linux/mtd/nand_new.h): + * argument are board-specific (per include/linux/mtd/nand.h): * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device * - hwcontrol: hardwarespecific function for accesing control-lines @@ -115,33 +114,4 @@ void board_nand_init(struct nand_chip *nand) nand->chip_delay = NAND_BIG_DELAY_US; nand->options = NAND_SAMSUNG_LP_OPTIONS; } - -#else - -/* old NAND handling */ -extern ulong -nand_probe(ulong physadr); - -void -nand_init(void) -{ - ulong totlen = 0; - -/* - The HI model is equipped with a large block NAND chip not supported yet - by U-Boot - (CONFIG_PPCHAMELEON_MODULE_MODEL == CONFIG_PPCHAMELEON_MODULE_HI) -*/ - -#if (CONFIG_PPCHAMELEON_MODULE_MODEL == CONFIG_PPCHAMELEON_MODULE_ME) - debug ("Probing at 0x%.8x\n", CFG_NAND0_BASE); - totlen += nand_probe (CFG_NAND0_BASE); -#endif /* CONFIG_PPCHAMELEON_MODULE_ME, CONFIG_PPCHAMELEON_MODULE_HI */ - - debug ("Probing at 0x%.8x\n", CFG_NAND1_BASE); - totlen += nand_probe (CFG_NAND1_BASE); - - printf ("%3lu MB\n", totlen >>20); -} -#endif -#endif +#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ diff --git a/board/esd/ash405/ash405.c b/board/esd/ash405/ash405.c index 03ae7fda4b..84fc3a01dc 100644 --- a/board/esd/ash405/ash405.c +++ b/board/esd/ash405/ash405.c @@ -239,7 +239,7 @@ int testdram (void) /* ------------------------------------------------------------------------- */ #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; void nand_init(void) diff --git a/board/esd/ash405/config.mk b/board/esd/ash405/config.mk index 1d743a9f87..3cf5dd85bf 100644 --- a/board/esd/ash405/config.mk +++ b/board/esd/ash405/config.mk @@ -26,3 +26,6 @@ # TEXT_BASE = 0xFFFC0000 + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a diff --git a/board/esd/cms700/cms700.c b/board/esd/cms700/cms700.c index e4cfe1466b..e283a92764 100644 --- a/board/esd/cms700/cms700.c +++ b/board/esd/cms700/cms700.c @@ -238,7 +238,7 @@ U_BOOT_CMD(eepwren, 2, 0, do_eep_wren, /* ------------------------------------------------------------------------- */ #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; void nand_init(void) diff --git a/board/esd/cms700/config.mk b/board/esd/cms700/config.mk index 5c3c01cf87..0c56c40b9f 100644 --- a/board/esd/cms700/config.mk +++ b/board/esd/cms700/config.mk @@ -26,3 +26,6 @@ # TEXT_BASE = 0xFFFC0000 + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c index 1decc0ec0c..5a70176fad 100644 --- a/board/esd/common/auto_update.c +++ b/board/esd/common/auto_update.c @@ -23,10 +23,15 @@ */ #include + +#ifndef CFG_NAND_LEGACY +#error CFG_NAND_LEGACY not defined in a file using the legacy NAND support! +#endif + #include #include #include -#include +#include #include #include "auto_update.h" @@ -37,6 +42,9 @@ #error "must define CFG_CMD_FAT" #endif + + + extern au_image_t au_image[]; extern int N_AU_IMAGES; @@ -76,9 +84,9 @@ extern block_dev_desc_t *get_dev (char*, int); #define NANDRW_JFFS2 0x02 #define NANDRW_JFFS2_SKIP 0x04 extern struct nand_chip nand_dev_desc[]; -extern int nand_rw(struct nand_chip* nand, int cmd, size_t start, size_t len, +extern int nand_legacy_rw(struct nand_chip* nand, int cmd, size_t start, size_t len, size_t * retlen, u_char * buf); -extern int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean); +extern int nand_legacy_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean); #endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ extern block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE]; @@ -259,9 +267,9 @@ int au_do_update(int i, long sz) } else { #if (CONFIG_COMMANDS & CFG_CMD_NAND) printf("Updating NAND FLASH with image %s\n", au_image[i].name); - debug ("nand_erase(%lx, %lx);\n", start, end); - rc = nand_erase (nand_dev_desc, start, end - start + 1, 0); - debug ("nand_erase returned %x\n", rc); + debug ("nand_legacy_erase(%lx, %lx);\n", start, end); + rc = nand_legacy_erase (nand_dev_desc, start, end - start + 1, 0); + debug ("nand_legacy_erase returned %x\n", rc); #endif } @@ -286,10 +294,10 @@ int au_do_update(int i, long sz) rc = flash_write((char *)addr, start, nbytes); } else { #if (CONFIG_COMMANDS & CFG_CMD_NAND) - debug ("nand_rw(%p, %lx %x)\n", addr, start, nbytes); - rc = nand_rw(nand_dev_desc, NANDRW_WRITE | NANDRW_JFFS2, + debug ("nand_legacy_rw(%p, %lx %x)\n", addr, start, nbytes); + rc = nand_legacy_rw(nand_dev_desc, NANDRW_WRITE | NANDRW_JFFS2, start, nbytes, (size_t *)&total, (uchar *)addr); - debug ("nand_rw: ret=%x total=%d nbytes=%d\n", rc, total, nbytes); + debug ("nand_legacy_rw: ret=%x total=%d nbytes=%d\n", rc, total, nbytes); #endif } if (rc != 0) { @@ -304,7 +312,7 @@ int au_do_update(int i, long sz) rc = crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)); } else { #if (CONFIG_COMMANDS & CFG_CMD_NAND) - rc = nand_rw(nand_dev_desc, NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP, + rc = nand_legacy_rw(nand_dev_desc, NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP, start, nbytes, (size_t *)&total, (uchar *)addr); rc = crc32 (0, (uchar *)(addr + off), ntohl(hdr->ih_size)); #endif diff --git a/board/esd/cpci405/config.mk b/board/esd/cpci405/config.mk index 0be45c70d7..320346f089 100644 --- a/board/esd/cpci405/config.mk +++ b/board/esd/cpci405/config.mk @@ -38,3 +38,7 @@ TEXT_BASE = 0xFFFD0000 endif endif endif + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a + diff --git a/board/esd/hh405/config.mk b/board/esd/hh405/config.mk index 7129ad568b..ca1f57572b 100644 --- a/board/esd/hh405/config.mk +++ b/board/esd/hh405/config.mk @@ -29,3 +29,7 @@ TEXT_BASE = 0xFFF80000 #TEXT_BASE = 0xFFFC0000 #TEXT_BASE = 0x00FC0000 + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a + diff --git a/board/esd/hh405/hh405.c b/board/esd/hh405/hh405.c index 9c582b121c..a3e935a87a 100644 --- a/board/esd/hh405/hh405.c +++ b/board/esd/hh405/hh405.c @@ -665,7 +665,7 @@ void ide_set_reset(int on) #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; void nand_init(void) diff --git a/board/esd/hub405/config.mk b/board/esd/hub405/config.mk index a6d31aad2b..22ff1226bc 100644 --- a/board/esd/hub405/config.mk +++ b/board/esd/hub405/config.mk @@ -26,3 +26,7 @@ # TEXT_BASE = 0xFFFC0000 + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a + diff --git a/board/esd/hub405/hub405.c b/board/esd/hub405/hub405.c index e77dba8a86..0c6771fb12 100644 --- a/board/esd/hub405/hub405.c +++ b/board/esd/hub405/hub405.c @@ -265,7 +265,7 @@ int testdram (void) #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; void nand_init(void) diff --git a/board/esd/plu405/config.mk b/board/esd/plu405/config.mk index 25b2105799..916b285261 100644 --- a/board/esd/plu405/config.mk +++ b/board/esd/plu405/config.mk @@ -27,3 +27,6 @@ TEXT_BASE = 0xFFFC0000 #TEXT_BASE = 0x00FC0000 + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a diff --git a/board/esd/plu405/plu405.c b/board/esd/plu405/plu405.c index 5b9d0631f8..37b92fb65a 100644 --- a/board/esd/plu405/plu405.c +++ b/board/esd/plu405/plu405.c @@ -269,7 +269,7 @@ void ide_set_reset(int on) #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; void nand_init(void) diff --git a/board/esd/voh405/config.mk b/board/esd/voh405/config.mk index 219a4eba15..72e81030ab 100644 --- a/board/esd/voh405/config.mk +++ b/board/esd/voh405/config.mk @@ -26,3 +26,6 @@ # TEXT_BASE = 0xFFF80000 + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a diff --git a/board/esd/voh405/voh405.c b/board/esd/voh405/voh405.c index eda3fd9d9d..22995b5020 100644 --- a/board/esd/voh405/voh405.c +++ b/board/esd/voh405/voh405.c @@ -343,7 +343,7 @@ void ide_set_reset(int on) #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; void nand_init(void) diff --git a/board/esd/wuh405/config.mk b/board/esd/wuh405/config.mk index 1d743a9f87..3cf5dd85bf 100644 --- a/board/esd/wuh405/config.mk +++ b/board/esd/wuh405/config.mk @@ -26,3 +26,6 @@ # TEXT_BASE = 0xFFFC0000 + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a diff --git a/board/esd/wuh405/wuh405.c b/board/esd/wuh405/wuh405.c index db24122c5e..5a1a3f3e8e 100644 --- a/board/esd/wuh405/wuh405.c +++ b/board/esd/wuh405/wuh405.c @@ -239,7 +239,7 @@ int testdram (void) /* ------------------------------------------------------------------------- */ #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; void nand_init(void) diff --git a/board/g2000/g2000.c b/board/g2000/g2000.c index 3f7875334d..39b5c701e0 100644 --- a/board/g2000/g2000.c +++ b/board/g2000/g2000.c @@ -185,7 +185,7 @@ int testdram (void) #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; void nand_init(void) diff --git a/board/netphone/config.mk b/board/netphone/config.mk index 8497ebc812..de179c2d65 100644 --- a/board/netphone/config.mk +++ b/board/netphone/config.mk @@ -26,3 +26,6 @@ # TEXT_BASE = 0x40000000 + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a diff --git a/board/netphone/netphone.c b/board/netphone/netphone.c index dd03e4bd5b..297de97a55 100644 --- a/board/netphone/netphone.c +++ b/board/netphone/netphone.c @@ -599,7 +599,7 @@ int board_early_init_f(void) #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern ulong nand_probe(ulong physadr); extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; diff --git a/board/netstar/config.mk b/board/netstar/config.mk index 57a34c4957..2e3921b101 100644 --- a/board/netstar/config.mk +++ b/board/netstar/config.mk @@ -10,6 +10,6 @@ # XXX TEXT_BASE = 0x20012000 TEXT_BASE = 0x13FC0000 -# Compile the new NAND code (needed iff #ifdef CONFIG_NEW_NAND_CODE) +# Compile the new NAND code BOARDLIBS = drivers/nand/libnand.a diff --git a/board/netstar/setup.S b/board/netstar/setup.S index 82c0342357..f67786d182 100644 --- a/board/netstar/setup.S +++ b/board/netstar/setup.S @@ -129,8 +129,8 @@ MUX_CONFIG_OFFSETS: .byte 0x0c @ COMP_MODE_CTRL_0 .byte 0xff -.globl platformsetup -platformsetup: +.globl lowlevel_init +lowlevel_init: /* Improve performance a bit... */ mrc p15, 0, r1, c0, c0, 0 @ read C15 ID register mrc p15, 0, r1, c0, c0, 1 @ read C15 Cache information register diff --git a/board/netta2/config.mk b/board/netta2/config.mk index 8497ebc812..4b636ed88d 100644 --- a/board/netta2/config.mk +++ b/board/netta2/config.mk @@ -26,3 +26,7 @@ # TEXT_BASE = 0x40000000 + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a + diff --git a/board/netta2/netta2.c b/board/netta2/netta2.c index c9b405145e..3ca7bd3c86 100644 --- a/board/netta2/netta2.c +++ b/board/netta2/netta2.c @@ -597,7 +597,7 @@ int board_early_init_f(void) #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern ulong nand_probe(ulong physadr); extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; diff --git a/board/netvia/config.mk b/board/netvia/config.mk index 9dddaad54b..583174a489 100644 --- a/board/netvia/config.mk +++ b/board/netvia/config.mk @@ -26,3 +26,6 @@ # TEXT_BASE = 0x40000000 + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a diff --git a/board/netvia/netvia.c b/board/netvia/netvia.c index fb7f7700cf..3e6c61663f 100644 --- a/board/netvia/netvia.c +++ b/board/netvia/netvia.c @@ -418,7 +418,7 @@ int board_early_init_f(void) #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern ulong nand_probe(ulong physadr); extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; diff --git a/board/omap2420h4/omap2420h4.c b/board/omap2420h4/omap2420h4.c index 6ae1a490a5..2387176ebc 100644 --- a/board/omap2420h4/omap2420h4.c +++ b/board/omap2420h4/omap2420h4.c @@ -32,7 +32,7 @@ #include #include #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; #endif diff --git a/board/sixnet/config.mk b/board/sixnet/config.mk index 0cd8f44148..8e73d2f369 100644 --- a/board/sixnet/config.mk +++ b/board/sixnet/config.mk @@ -26,3 +26,6 @@ # TEXT_BASE = 0xF8000000 + +# Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) +BOARDLIBS = drivers/nand_legacy/libnand_legacy.a diff --git a/board/sixnet/sixnet.c b/board/sixnet/sixnet.c index 867589f918..a25dffdad5 100644 --- a/board/sixnet/sixnet.c +++ b/board/sixnet/sixnet.c @@ -34,7 +34,7 @@ #endif #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; #endif diff --git a/board/stxxtc/stxxtc.c b/board/stxxtc/stxxtc.c index aa3d129f9c..7caf06a086 100644 --- a/board/stxxtc/stxxtc.c +++ b/board/stxxtc/stxxtc.c @@ -576,7 +576,7 @@ int board_early_init_f(void) #if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include +#include extern ulong nand_probe(ulong physadr); extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; diff --git a/common/Makefile b/common/Makefile index 7e45a7c716..7dbf84a555 100644 --- a/common/Makefile +++ b/common/Makefile @@ -37,7 +37,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o \ cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \ cmd_load.o cmd_log.o \ cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \ - cmd_nand.o cmd_nand_new.o cmd_net.o cmd_nvedit.o \ + cmd_nand.o cmd_net.o cmd_nvedit.o \ cmd_pci.o cmd_pcmcia.o cmd_portio.o \ cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \ cmd_usb.o cmd_vfd.o \ diff --git a/common/cmd_doc.c b/common/cmd_doc.c index 5e9bea3045..c726957cac 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -22,8 +22,9 @@ #if (CONFIG_COMMANDS & CFG_CMD_DOC) #include -#include +#include #include + #include #include diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index ecadb79634..201c3c1553 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -91,7 +91,6 @@ #include #include #include -#include #include #include @@ -99,10 +98,14 @@ #include -#ifdef CONFIG_NEW_NAND_CODE +#if (CONFIG_COMMANDS & CFG_CMD_NAND) +#ifdef CFG_NAND_LEGACY +#include +#else /* !CFG_NAND_LEGACY */ +#include #include -#endif - +#endif /* !CFG_NAND_LEGACY */ +#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ /* enable/disable debugging messages */ #define DEBUG_JFFS #undef DEBUG_JFFS @@ -467,7 +470,7 @@ static int part_del(struct mtd_device *dev, struct part_info *part) } } -#ifndef CONFIG_NEW_NAND_CODE +#ifdef CFG_NAND_LEGACY jffs2_free_cache(part); #endif list_del(&part->link); @@ -496,7 +499,7 @@ static void part_delall(struct list_head *head) list_for_each_safe(entry, n, head) { part_tmp = list_entry(entry, struct part_info, link); -#ifndef CONFIG_NEW_NAND_CODE +#ifdef CFG_NAND_LEGACY jffs2_free_cache(part_tmp); #endif list_del(entry); @@ -732,7 +735,7 @@ static int device_validate(u8 type, u8 num, u32 *size) } else if (type == MTD_DEV_TYPE_NAND) { #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) if (num < CFG_MAX_NAND_DEVICE) { -#ifdef CONFIG_NEW_NAND_CODE +#ifndef CFG_NAND_LEGACY *size = nand_info[num].size; #else extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 152873f1ae..e46ed1d3c4 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -9,6 +9,387 @@ */ #include + + +#ifndef CFG_NAND_LEGACY +/* + * + * New NAND support + * + */ +#include + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) + +#include +#include +#include +#include + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# include +# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) +#else +# define SHOW_BOOT_PROGRESS(arg) +#endif + +#include +#include + +extern nand_info_t nand_info[]; /* info for NAND chips */ + +static int nand_dump_oob(nand_info_t *nand, ulong off) +{ + return 0; +} + +static int nand_dump(nand_info_t *nand, ulong off) +{ + int i; + u_char *buf, *p; + + buf = malloc(nand->oobblock + nand->oobsize); + if (!buf) { + puts("No memory for page buffer\n"); + return 1; + } + off &= ~(nand->oobblock - 1); + i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize); + if (i < 0) { + printf("Error (%d) reading page %08x\n", i, off); + free(buf); + return 1; + } + printf("Page %08x dump:\n", off); + i = nand->oobblock >> 4; p = buf; + while (i--) { + printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x" + " %02x %02x %02x %02x %02x %02x %02x %02x\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); + p += 16; + } + puts("OOB:\n"); + i = nand->oobsize >> 3; + while (i--) { + printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + p += 8; + } + free(buf); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static void +arg_off_size(int argc, char *argv[], ulong *off, ulong *size, ulong totsize) +{ + *off = 0; + *size = 0; + +#if defined(CONFIG_JFFS2_NAND) && defined(CFG_JFFS_CUSTOM_PART) + if (argc >= 1 && strcmp(argv[0], "partition") == 0) { + int part_num; + struct part_info *part; + const char *partstr; + + if (argc >= 2) + partstr = argv[1]; + else + partstr = getenv("partition"); + + if (partstr) + part_num = (int)simple_strtoul(partstr, NULL, 10); + else + part_num = 0; + + part = jffs2_part_info(part_num); + if (part == NULL) { + printf("\nInvalid partition %d\n", part_num); + return; + } + *size = part->size; + *off = (ulong)part->offset; + } else +#endif + { + if (argc >= 1) + *off = (ulong)simple_strtoul(argv[0], NULL, 16); + else + *off = 0; + + if (argc >= 2) + *size = (ulong)simple_strtoul(argv[1], NULL, 16); + else + *size = totsize - *off; + + } + +} + +int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + int i, dev, ret; + ulong addr, off, size; + char *cmd, *s; + nand_info_t *nand; + + /* at least two arguments please */ + if (argc < 2) + goto usage; + + cmd = argv[1]; + + if (strcmp(cmd, "info") == 0) { + + putc('\n'); + for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { + if (nand_info[i].name) + printf("Device %d: %s, sector size %lu KiB\n", + i, nand_info[i].name, + nand_info[i].erasesize >> 10); + } + return 0; + } + + if (strcmp(cmd, "device") == 0) { + + if (argc < 3) { + if ((nand_curr_device < 0) || + (nand_curr_device >= CFG_MAX_NAND_DEVICE)) + puts("\nno devices available\n"); + else + printf("\nDevice %d: %s\n", nand_curr_device, + nand_info[nand_curr_device].name); + return 0; + } + dev = (int)simple_strtoul(argv[2], NULL, 10); + if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { + puts("No such device\n"); + return 1; + } + printf("Device %d: %s", dev, nand_info[dev].name); + puts("... is now current device\n"); + nand_curr_device = dev; + return 0; + } + + if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && + strncmp(cmd, "dump", 4) != 0 && + strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0) + goto usage; + + /* the following commands operate on the current device */ + if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE || + !nand_info[nand_curr_device].name) { + puts("\nno devices available\n"); + return 1; + } + nand = &nand_info[nand_curr_device]; + + if (strcmp(cmd, "bad") == 0) { + printf("\nDevice %d bad blocks:\n", nand_curr_device); + for (off = 0; off < nand->size; off += nand->erasesize) + if (nand_block_isbad(nand, off)) + printf(" %08x\n", off); + return 0; + } + + if (strcmp(cmd, "erase") == 0) { + arg_off_size(argc - 2, argv + 2, &off, &size, nand->size); + if (off == 0 && size == 0) + return 1; + + printf("\nNAND erase: device %d offset 0x%x, size 0x%x ", + nand_curr_device, off, size); + ret = nand_erase(nand, off, size); + printf("%s\n", ret ? "ERROR" : "OK"); + + return ret == 0 ? 0 : 1; + } + + if (strncmp(cmd, "dump", 4) == 0) { + if (argc < 3) + goto usage; + + s = strchr(cmd, '.'); + off = (int)simple_strtoul(argv[2], NULL, 16); + + if (s != NULL && strcmp(s, ".oob") == 0) + ret = nand_dump_oob(nand, off); + else + ret = nand_dump(nand, off); + + return ret == 0 ? 1 : 0; + + } + + /* read write */ + if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { + if (argc < 4) + goto usage; +/* + s = strchr(cmd, '.'); + clean = CLEAN_NONE; + if (s != NULL) { + if (strcmp(s, ".jffs2") == 0 || strcmp(s, ".e") == 0 + || strcmp(s, ".i")) + clean = CLEAN_JFFS2; + } +*/ + addr = (ulong)simple_strtoul(argv[2], NULL, 16); + + arg_off_size(argc - 3, argv + 3, &off, &size, nand->size); + if (off == 0 && size == 0) + return 1; + + i = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ + printf("\nNAND %s: device %d offset %u, size %u ... ", + i ? "read" : "write", nand_curr_device, off, size); + + if (i) + ret = nand_read(nand, off, &size, (u_char *)addr); + else + ret = nand_write(nand, off, &size, (u_char *)addr); + + printf(" %d bytes %s: %s\n", size, + i ? "read" : "written", ret ? "ERROR" : "OK"); + + return ret == 0 ? 0 : 1; + } +usage: + printf("Usage:\n%s\n", cmdtp->usage); + return 1; +} + +U_BOOT_CMD(nand, 5, 1, do_nand, + "nand - NAND sub-system\n", + "info - show available NAND devices\n" + "nand device [dev] - show or set current device\n" + "nand read[.jffs2] - addr off size\n" + "nand write[.jffs2] - addr off size - read/write `size' bytes starting\n" + " at offset `off' to/from memory address `addr'\n" + "nand erase [clean] [off size] - erase `size' bytes from\n" + " offset `off' (entire device if not specified)\n" + "nand bad - show bad blocks\n" + "nand dump[.oob] off - dump page\n" + "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n" + "nand markbad off - mark bad block at offset (UNSAFE)\n" + "nand biterr off - make a bit error at offset (UNSAFE)\n"); + +int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + char *boot_device = NULL; + char *ep; + int dev; + int r; + ulong addr, cnt, offset = 0; + image_header_t *hdr; + nand_info_t *nand; + + switch (argc) { + case 1: + addr = CFG_LOAD_ADDR; + boot_device = getenv("bootdevice"); + break; + case 2: + addr = simple_strtoul(argv[1], NULL, 16); + boot_device = getenv("bootdevice"); + break; + case 3: + addr = simple_strtoul(argv[1], NULL, 16); + boot_device = argv[2]; + break; + case 4: + addr = simple_strtoul(argv[1], NULL, 16); + boot_device = argv[2]; + offset = simple_strtoul(argv[3], NULL, 16); + break; + default: + printf("Usage:\n%s\n", cmdtp->usage); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + if (!boot_device) { + puts("\n** No boot device **\n"); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + dev = simple_strtoul(boot_device, &ep, 16); + + if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { + printf("\n** Device %d not available\n", dev); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + nand = &nand_info[dev]; + printf("\nLoading from device %d: %s (offset 0x%lx)\n", + dev, nand->name, offset); + + cnt = nand->oobblock; + r = nand_read(nand, offset, &cnt, (u_char *) addr); + if (r) { + printf("** Read error on %d\n", dev); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + hdr = (image_header_t *) addr; + + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + print_image_hdr(hdr); + + cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t)); + + r = nand_read(nand, offset, &cnt, (u_char *) addr); + if (r) { + printf("** Read error on %d\n", dev); + SHOW_BOOT_PROGRESS(-1); + return 1; + } + + /* Loading ok, update default load address */ + + load_addr = addr; + + /* Check if we should attempt an auto-start */ + if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) { + char *local_args[2]; + extern int do_bootm(cmd_tbl_t *, int, int, char *[]); + + local_args[0] = argv[0]; + local_args[1] = NULL; + + printf("Automatic boot of image at addr 0x%08lx ...\n", addr); + + do_bootm(cmdtp, 0, 1, local_args); + return 1; + } + return 0; +} + +U_BOOT_CMD(nboot, 4, 1, do_nandboot, + "nboot - boot from NAND device\n", "loadAddr dev\n"); + + +#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ + +#else /* CFG_NAND_LEGACY */ +/* + * + * Legacy NAND support - to be phased out + * + */ #include #include #include @@ -21,11 +402,12 @@ # define SHOW_BOOT_PROGRESS(arg) #endif -#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) - -#include +#if (CONFIG_COMMANDS & CFG_CMD_NAND) +#include +#if 0 #include #include +#endif #ifdef CONFIG_OMAP1510 void archflashwp(void *archdata, int wp); @@ -33,15 +415,6 @@ void archflashwp(void *archdata, int wp); #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) -/* - * Definition of the out of band configuration structure - */ -struct nand_oob_config { - int ecc_pos[6]; /* position of ECC bytes inside oob */ - int badblock_pos; /* position of bad block flag inside oob -1 = inactive */ - int eccvalid_pos; /* position of ECC valid flag inside oob -1 = inactive */ -} oob_config = { {0}, 0, 0}; - #undef NAND_DEBUG #undef PSYCHO_DEBUG @@ -63,41 +436,30 @@ struct nand_oob_config { #define CONFIG_MTD_NAND_ECC /* enable ECC */ #define CONFIG_MTD_NAND_ECC_JFFS2 -/* bits for nand_rw() `cmd'; or together as needed */ +/* bits for nand_legacy_rw() `cmd'; or together as needed */ #define NANDRW_READ 0x01 #define NANDRW_WRITE 0x00 #define NANDRW_JFFS2 0x02 #define NANDRW_JFFS2_SKIP 0x04 + + /* - * Function Prototypes + * Imports from nand_legacy.c */ -static void nand_print(struct nand_chip *nand); -int nand_rw (struct nand_chip* nand, int cmd, - size_t start, size_t len, - size_t * retlen, u_char * buf); -int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean); -static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len, - size_t * retlen, u_char *buf, u_char *ecc_code); -static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len, - size_t * retlen, const u_char * buf, u_char * ecc_code); -static void nand_print_bad(struct nand_chip *nand); -static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, - size_t * retlen, u_char * buf); -static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, - size_t * retlen, const u_char * buf); -static int NanD_WaitReady(struct nand_chip *nand, int ale_wait); -#ifdef CONFIG_MTD_NAND_ECC -static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); -static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); -#endif +extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; +extern int curr_device; +extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, + size_t len, int clean); +extern int nand_legacy_rw(struct nand_chip *nand, int cmd, size_t start, + size_t len, size_t *retlen, u_char *buf); +extern void nand_print(struct nand_chip *nand); +extern void nand_print_bad(struct nand_chip *nand); +extern int nand_read_oob(struct nand_chip *nand, size_t ofs, + size_t len, size_t *retlen, u_char *buf); +extern int nand_write_oob(struct nand_chip *nand, size_t ofs, + size_t len, size_t *retlen, const u_char *buf); -struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}}; - -/* Current NAND Device */ -static int curr_device = -1; - -/* ------------------------------------------------------------------------- */ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { @@ -174,7 +536,7 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf ("\nNAND erase: device %d offset %ld, size %ld ... ", curr_device, off, size); - ret = nand_erase (nand, off, size, 1); + ret = nand_legacy_erase (nand, off, size, 1); printf("%s\n", ret ? "ERROR" : "OK"); @@ -240,7 +602,7 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) (cmd & NANDRW_READ) ? "read" : "write", curr_device, off, size); - ret = nand_rw(nand_dev_desc + curr_device, cmd, off, size, + ret = nand_legacy_rw(nand_dev_desc + curr_device, cmd, off, size, (size_t *)&total, (u_char*)addr); printf (" %d bytes %s: %s\n", total, @@ -258,7 +620,8 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf ("\nNAND erase: device %d offset %ld, size %ld ... ", curr_device, off, size); - ret = nand_erase (nand_dev_desc + curr_device, off, size, clean); + ret = nand_legacy_erase (nand_dev_desc + curr_device, + off, size, clean); printf("%s\n", ret ? "ERROR" : "OK"); @@ -340,8 +703,8 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR, offset); - if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset, - SECTORSIZE, NULL, (u_char *)addr)) { + if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, offset, + SECTORSIZE, NULL, (u_char *)addr)) { printf ("** Read error on %d\n", dev); SHOW_BOOT_PROGRESS (-1); return 1; @@ -361,8 +724,9 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset + SECTORSIZE, cnt, - NULL, (u_char *)(addr+SECTORSIZE))) { + if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, + offset + SECTORSIZE, cnt, NULL, + (u_char *)(addr+SECTORSIZE))) { printf ("** Read error on %d\n", dev); SHOW_BOOT_PROGRESS (-1); return 1; @@ -394,1505 +758,6 @@ U_BOOT_CMD( "loadAddr dev\n" ); -/* returns 0 if block containing pos is OK: - * valid erase block and - * not marked bad, or no bad mark position is specified - * returns 1 if marked bad or otherwise invalid - */ -int check_block (struct nand_chip *nand, unsigned long pos) -{ - size_t retlen; - uint8_t oob_data; - uint16_t oob_data16[6]; - int page0 = pos & (-nand->erasesize); - int page1 = page0 + nand->oobblock; - int badpos = oob_config.badblock_pos; - - if (pos >= nand->totlen) - return 1; - - if (badpos < 0) - return 0; /* no way to check, assume OK */ - - if (nand->bus16) { - if (nand_read_oob(nand, (page0 + 0), 12, &retlen, (uint8_t *)oob_data16) - || (oob_data16[2] & 0xff00) != 0xff00) - return 1; - if (nand_read_oob(nand, (page1 + 0), 12, &retlen, (uint8_t *)oob_data16) - || (oob_data16[2] & 0xff00) != 0xff00) - return 1; - } else { - /* Note - bad block marker can be on first or second page */ - if (nand_read_oob(nand, page0 + badpos, 1, &retlen, (unsigned char *)&oob_data) - || oob_data != 0xff - || nand_read_oob (nand, page1 + badpos, 1, &retlen, (unsigned char *)&oob_data) - || oob_data != 0xff) - return 1; - } - - return 0; -} - -/* print bad blocks in NAND flash */ -static void nand_print_bad(struct nand_chip* nand) -{ - unsigned long pos; - - for (pos = 0; pos < nand->totlen; pos += nand->erasesize) { - if (check_block(nand, pos)) - printf(" 0x%8.8lx\n", pos); - } - puts("\n"); -} - -/* cmd: 0: NANDRW_WRITE write, fail on bad block - * 1: NANDRW_READ read, fail on bad block - * 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks - * 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks - * 7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks - */ -int nand_rw (struct nand_chip* nand, int cmd, - size_t start, size_t len, - size_t * retlen, u_char * buf) -{ - int ret = 0, n, total = 0; - char eccbuf[6]; - /* eblk (once set) is the start of the erase block containing the - * data being processed. - */ - unsigned long eblk = ~0; /* force mismatch on first pass */ - unsigned long erasesize = nand->erasesize; - - while (len) { - if ((start & (-erasesize)) != eblk) { - /* have crossed into new erase block, deal with - * it if it is sure marked bad. - */ - eblk = start & (-erasesize); /* start of block */ - if (check_block(nand, eblk)) { - if (cmd == (NANDRW_READ | NANDRW_JFFS2)) { - while (len > 0 && - start - eblk < erasesize) { - *(buf++) = 0xff; - ++start; - ++total; - --len; - } - continue; - } else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) { - start += erasesize; - continue; - } else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) { - /* skip bad block */ - start += erasesize; - continue; - } else { - ret = 1; - break; - } - } - } - /* The ECC will not be calculated correctly if - less than 512 is written or read */ - /* Is request at least 512 bytes AND it starts on a proper boundry */ - if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200)) - printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n"); - - if (cmd & NANDRW_READ) { - ret = nand_read_ecc(nand, start, - min(len, eblk + erasesize - start), - (size_t *)&n, (u_char*)buf, (u_char *)eccbuf); - } else { - ret = nand_write_ecc(nand, start, - min(len, eblk + erasesize - start), - (size_t *)&n, (u_char*)buf, (u_char *)eccbuf); - } - - if (ret) - break; - - start += n; - buf += n; - total += n; - len -= n; - } - if (retlen) - *retlen = total; - - return ret; -} - -static void nand_print(struct nand_chip *nand) -{ - if (nand->numchips > 1) { - printf("%s at 0x%lx,\n" - "\t %d chips %s, size %d MB, \n" - "\t total size %ld MB, sector size %ld kB\n", - nand->name, nand->IO_ADDR, nand->numchips, - nand->chips_name, 1 << (nand->chipshift - 20), - nand->totlen >> 20, nand->erasesize >> 10); - } - else { - printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR); - print_size(nand->totlen, ", "); - print_size(nand->erasesize, " sector)\n"); - } -} - -/* ------------------------------------------------------------------------- */ - -static int NanD_WaitReady(struct nand_chip *nand, int ale_wait) -{ - /* This is inline, to optimise the common case, where it's ready instantly */ - int ret = 0; - -#ifdef NAND_NO_RB /* in config file, shorter delays currently wrap accesses */ - if(ale_wait) - NAND_WAIT_READY(nand); /* do the worst case 25us wait */ - else - udelay(10); -#else /* has functional r/b signal */ - NAND_WAIT_READY(nand); -#endif - return ret; -} - -/* NanD_Command: Send a flash command to the flash chip */ - -static inline int NanD_Command(struct nand_chip *nand, unsigned char command) -{ - unsigned long nandptr = nand->IO_ADDR; - - /* Assert the CLE (Command Latch Enable) line to the flash chip */ - NAND_CTL_SETCLE(nandptr); - - /* Send the command */ - WRITE_NAND_COMMAND(command, nandptr); - - /* Lower the CLE line */ - NAND_CTL_CLRCLE(nandptr); - -#ifdef NAND_NO_RB - if(command == NAND_CMD_RESET){ - u_char ret_val; - NanD_Command(nand, NAND_CMD_STATUS); - do { - ret_val = READ_NAND(nandptr);/* wait till ready */ - } while((ret_val & 0x40) != 0x40); - } -#endif - return NanD_WaitReady(nand, 0); -} - -/* NanD_Address: Set the current address for the flash chip */ - -static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs) -{ - unsigned long nandptr; - int i; - - nandptr = nand->IO_ADDR; - - /* Assert the ALE (Address Latch Enable) line to the flash chip */ - NAND_CTL_SETALE(nandptr); - - /* Send the address */ - /* Devices with 256-byte page are addressed as: - * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31) - * there is no device on the market with page256 - * and more than 24 bits. - * Devices with 512-byte page are addressed as: - * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31) - * 25-31 is sent only if the chip support it. - * bit 8 changes the read command to be sent - * (NAND_CMD_READ0 or NAND_CMD_READ1). - */ - - if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) - WRITE_NAND_ADDRESS(ofs, nandptr); - - ofs = ofs >> nand->page_shift; - - if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) { - for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) { - WRITE_NAND_ADDRESS(ofs, nandptr); - } - } - - /* Lower the ALE line */ - NAND_CTL_CLRALE(nandptr); - - /* Wait for the chip to respond */ - return NanD_WaitReady(nand, 1); -} - -/* NanD_SelectChip: Select a given flash chip within the current floor */ - -static inline int NanD_SelectChip(struct nand_chip *nand, int chip) -{ - /* Wait for it to be ready */ - return NanD_WaitReady(nand, 0); -} - -/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */ - -static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip) -{ - int mfr, id, i; - - NAND_ENABLE_CE(nand); /* set pin low */ - /* Reset the chip */ - if (NanD_Command(nand, NAND_CMD_RESET)) { -#ifdef NAND_DEBUG - printf("NanD_Command (reset) for %d,%d returned true\n", - floor, chip); -#endif - NAND_DISABLE_CE(nand); /* set pin high */ - return 0; - } - - /* Read the NAND chip ID: 1. Send ReadID command */ - if (NanD_Command(nand, NAND_CMD_READID)) { -#ifdef NAND_DEBUG - printf("NanD_Command (ReadID) for %d,%d returned true\n", - floor, chip); -#endif - NAND_DISABLE_CE(nand); /* set pin high */ - return 0; - } - - /* Read the NAND chip ID: 2. Send address byte zero */ - NanD_Address(nand, ADDR_COLUMN, 0); - - /* Read the manufacturer and device id codes from the device */ - - mfr = READ_NAND(nand->IO_ADDR); - - id = READ_NAND(nand->IO_ADDR); - - NAND_DISABLE_CE(nand); /* set pin high */ - -#ifdef NAND_DEBUG - printf("NanD_Command (ReadID) got %x %x\n", mfr, id); -#endif - if (mfr == 0xff || mfr == 0) { - /* No response - return failure */ - return 0; - } - - /* Check it's the same as the first chip we identified. - * M-Systems say that any given nand_chip device should only - * contain _one_ type of flash part, although that's not a - * hardware restriction. */ - if (nand->mfr) { - if (nand->mfr == mfr && nand->id == id) { - return 1; /* This is another the same the first */ - } else { - printf("Flash chip at floor %d, chip %d is different:\n", - floor, chip); - } - } - - /* Print and store the manufacturer and ID codes. */ - for (i = 0; nand_flash_ids[i].name != NULL; i++) { - if (mfr == nand_flash_ids[i].manufacture_id && - id == nand_flash_ids[i].model_id) { -#ifdef NAND_DEBUG - printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, " - "Chip ID: 0x%2.2X (%s)\n", mfr, id, - nand_flash_ids[i].name); -#endif - if (!nand->mfr) { - nand->mfr = mfr; - nand->id = id; - nand->chipshift = - nand_flash_ids[i].chipshift; - nand->page256 = nand_flash_ids[i].page256; - nand->eccsize = 256; - if (nand->page256) { - nand->oobblock = 256; - nand->oobsize = 8; - nand->page_shift = 8; - } else { - nand->oobblock = 512; - nand->oobsize = 16; - nand->page_shift = 9; - } - nand->pageadrlen = nand_flash_ids[i].pageadrlen; - nand->erasesize = nand_flash_ids[i].erasesize; - nand->chips_name = nand_flash_ids[i].name; - nand->bus16 = nand_flash_ids[i].bus16; - return 1; - } - return 0; - } - } - - -#ifdef NAND_DEBUG - /* We haven't fully identified the chip. Print as much as we know. */ - printf("Unknown flash chip found: %2.2X %2.2X\n", - id, mfr); -#endif - - return 0; -} - -/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */ - -static void NanD_ScanChips(struct nand_chip *nand) -{ - int floor, chip; - int numchips[NAND_MAX_FLOORS]; - int maxchips = NAND_MAX_CHIPS; - int ret = 1; - - nand->numchips = 0; - nand->mfr = 0; - nand->id = 0; - - - /* For each floor, find the number of valid chips it contains */ - for (floor = 0; floor < NAND_MAX_FLOORS; floor++) { - ret = 1; - numchips[floor] = 0; - for (chip = 0; chip < maxchips && ret != 0; chip++) { - - ret = NanD_IdentChip(nand, floor, chip); - if (ret) { - numchips[floor]++; - nand->numchips++; - } - } - } - - /* If there are none at all that we recognise, bail */ - if (!nand->numchips) { -#ifdef NAND_DEBUG - puts ("No NAND flash chips recognised.\n"); -#endif - return; - } - - /* Allocate an array to hold the information for each chip */ - nand->chips = malloc(sizeof(struct Nand) * nand->numchips); - if (!nand->chips) { - puts ("No memory for allocating chip info structures\n"); - return; - } - - ret = 0; - - /* Fill out the chip array with {floor, chipno} for each - * detected chip in the device. */ - for (floor = 0; floor < NAND_MAX_FLOORS; floor++) { - for (chip = 0; chip < numchips[floor]; chip++) { - nand->chips[ret].floor = floor; - nand->chips[ret].chip = chip; - nand->chips[ret].curadr = 0; - nand->chips[ret].curmode = 0x50; - ret++; - } - } - - /* Calculate and print the total size of the device */ - nand->totlen = nand->numchips * (1 << nand->chipshift); - -#ifdef NAND_DEBUG - printf("%d flash chips found. Total nand_chip size: %ld MB\n", - nand->numchips, nand->totlen >> 20); -#endif -} - -/* we need to be fast here, 1 us per read translates to 1 second per meg */ -static void NanD_ReadBuf (struct nand_chip *nand, u_char * data_buf, int cntr) -{ - unsigned long nandptr = nand->IO_ADDR; - - NanD_Command (nand, NAND_CMD_READ0); - - if (nand->bus16) { - u16 val; - - while (cntr >= 16) { - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - cntr -= 16; - } - - while (cntr > 0) { - val = READ_NAND (nandptr); - *data_buf++ = val & 0xff; - *data_buf++ = val >> 8; - cntr -= 2; - } - } else { - while (cntr >= 16) { - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - *data_buf++ = READ_NAND (nandptr); - cntr -= 16; - } - - while (cntr > 0) { - *data_buf++ = READ_NAND (nandptr); - cntr--; - } - } -} - -/* - * NAND read with ECC - */ -static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len, - size_t * retlen, u_char *buf, u_char *ecc_code) -{ - int col, page; - int ecc_status = 0; -#ifdef CONFIG_MTD_NAND_ECC - int j; - int ecc_failed = 0; - u_char *data_poi; - u_char ecc_calc[6]; -#endif - - /* Do not allow reads past end of device */ - if ((start + len) > nand->totlen) { - printf ("%s: Attempt read beyond end of device %x %x %x\n", - __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen); - *retlen = 0; - return -1; - } - - /* First we calculate the starting page */ - /*page = shr(start, nand->page_shift);*/ - page = start >> nand->page_shift; - - /* Get raw starting column */ - col = start & (nand->oobblock - 1); - - /* Initialize return value */ - *retlen = 0; - - /* Select the NAND device */ - NAND_ENABLE_CE(nand); /* set pin low */ - - /* Loop until all data read */ - while (*retlen < len) { - -#ifdef CONFIG_MTD_NAND_ECC - /* Do we have this page in cache ? */ - if (nand->cache_page == page) - goto readdata; - /* Send the read command */ - NanD_Command(nand, NAND_CMD_READ0); - if (nand->bus16) { - NanD_Address(nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address(nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - - /* Read in a page + oob data */ - NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize); - - /* copy data into cache, for read out of cache and if ecc fails */ - if (nand->data_cache) { - memcpy (nand->data_cache, nand->data_buf, - nand->oobblock + nand->oobsize); - } - - /* Pick the ECC bytes out of the oob data */ - for (j = 0; j < 6; j++) { - ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])]; - } - - /* Calculate the ECC and verify it */ - /* If block was not written with ECC, skip ECC */ - if (oob_config.eccvalid_pos != -1 && - (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) { - - nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]); - switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) { - case -1: - printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page); - ecc_failed++; - break; - case 1: - case 2: /* transfer ECC corrected data to cache */ - if (nand->data_cache) - memcpy (nand->data_cache, nand->data_buf, 256); - break; - } - } - - if (oob_config.eccvalid_pos != -1 && - nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) { - - nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]); - switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) { - case -1: - printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page); - ecc_failed++; - break; - case 1: - case 2: /* transfer ECC corrected data to cache */ - if (nand->data_cache) - memcpy (&nand->data_cache[256], &nand->data_buf[256], 256); - break; - } - } -readdata: - /* Read the data from ECC data buffer into return buffer */ - data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf; - data_poi += col; - if ((*retlen + (nand->oobblock - col)) >= len) { - memcpy (buf + *retlen, data_poi, len - *retlen); - *retlen = len; - } else { - memcpy (buf + *retlen, data_poi, nand->oobblock - col); - *retlen += nand->oobblock - col; - } - /* Set cache page address, invalidate, if ecc_failed */ - nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1; - - ecc_status += ecc_failed; - ecc_failed = 0; - -#else - /* Send the read command */ - NanD_Command(nand, NAND_CMD_READ0); - if (nand->bus16) { - NanD_Address(nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address(nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - - /* Read the data directly into the return buffer */ - if ((*retlen + (nand->oobblock - col)) >= len) { - NanD_ReadBuf(nand, buf + *retlen, len - *retlen); - *retlen = len; - /* We're done */ - continue; - } else { - NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col); - *retlen += nand->oobblock - col; - } -#endif - /* For subsequent reads align to page boundary. */ - col = 0; - /* Increment page address */ - page++; - } - - /* De-select the NAND device */ - NAND_DISABLE_CE(nand); /* set pin high */ - - /* - * Return success, if no ECC failures, else -EIO - * fs driver will take care of that, because - * retlen == desired len and result == -EIO - */ - return ecc_status ? -1 : 0; -} - -/* - * Nand_page_program function is used for write and writev ! - */ -static int nand_write_page (struct nand_chip *nand, - int page, int col, int last, u_char * ecc_code) -{ - - int i; - unsigned long nandptr = nand->IO_ADDR; - -#ifdef CONFIG_MTD_NAND_ECC -#ifdef CONFIG_MTD_NAND_VERIFY_WRITE - int ecc_bytes = (nand->oobblock == 512) ? 6 : 3; -#endif -#endif - /* pad oob area */ - for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++) - nand->data_buf[i] = 0xff; - -#ifdef CONFIG_MTD_NAND_ECC - /* Zero out the ECC array */ - for (i = 0; i < 6; i++) - ecc_code[i] = 0x00; - - /* Read back previous written data, if col > 0 */ - if (col) { - NanD_Command (nand, NAND_CMD_READ0); - if (nand->bus16) { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - - if (nand->bus16) { - u16 val; - - for (i = 0; i < col; i += 2) { - val = READ_NAND (nandptr); - nand->data_buf[i] = val & 0xff; - nand->data_buf[i + 1] = val >> 8; - } - } else { - for (i = 0; i < col; i++) - nand->data_buf[i] = READ_NAND (nandptr); - } - } - - /* Calculate and write the ECC if we have enough data */ - if ((col < nand->eccsize) && (last >= nand->eccsize)) { - nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0])); - for (i = 0; i < 3; i++) { - nand->data_buf[(nand->oobblock + - oob_config.ecc_pos[i])] = ecc_code[i]; - } - if (oob_config.eccvalid_pos != -1) { - nand->data_buf[nand->oobblock + - oob_config.eccvalid_pos] = 0xf0; - } - } - - /* Calculate and write the second ECC if we have enough data */ - if ((nand->oobblock == 512) && (last == nand->oobblock)) { - nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3])); - for (i = 3; i < 6; i++) { - nand->data_buf[(nand->oobblock + - oob_config.ecc_pos[i])] = ecc_code[i]; - } - if (oob_config.eccvalid_pos != -1) { - nand->data_buf[nand->oobblock + - oob_config.eccvalid_pos] &= 0x0f; - } - } -#endif - /* Prepad for partial page programming !!! */ - for (i = 0; i < col; i++) - nand->data_buf[i] = 0xff; - - /* Postpad for partial page programming !!! oob is already padded */ - for (i = last; i < nand->oobblock; i++) - nand->data_buf[i] = 0xff; - - /* Send command to begin auto page programming */ - NanD_Command (nand, NAND_CMD_READ0); - NanD_Command (nand, NAND_CMD_SEQIN); - if (nand->bus16) { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - - /* Write out complete page of data */ - if (nand->bus16) { - for (i = 0; i < (nand->oobblock + nand->oobsize); i += 2) { - WRITE_NAND (nand->data_buf[i] + - (nand->data_buf[i + 1] << 8), - nand->IO_ADDR); - } - } else { - for (i = 0; i < (nand->oobblock + nand->oobsize); i++) - WRITE_NAND (nand->data_buf[i], nand->IO_ADDR); - } - - /* Send command to actually program the data */ - NanD_Command (nand, NAND_CMD_PAGEPROG); - NanD_Command (nand, NAND_CMD_STATUS); -#ifdef NAND_NO_RB - { - u_char ret_val; - - do { - ret_val = READ_NAND (nandptr); /* wait till ready */ - } while ((ret_val & 0x40) != 0x40); - } -#endif - /* See if device thinks it succeeded */ - if (READ_NAND (nand->IO_ADDR) & 0x01) { - printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, - page); - return -1; - } -#ifdef CONFIG_MTD_NAND_VERIFY_WRITE - /* - * The NAND device assumes that it is always writing to - * a cleanly erased page. Hence, it performs its internal - * write verification only on bits that transitioned from - * 1 to 0. The device does NOT verify the whole page on a - * byte by byte basis. It is possible that the page was - * not completely erased or the page is becoming unusable - * due to wear. The read with ECC would catch the error - * later when the ECC page check fails, but we would rather - * catch it early in the page write stage. Better to write - * no data than invalid data. - */ - - /* Send command to read back the page */ - if (col < nand->eccsize) - NanD_Command (nand, NAND_CMD_READ0); - else - NanD_Command (nand, NAND_CMD_READ1); - if (nand->bus16) { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - - /* Loop through and verify the data */ - if (nand->bus16) { - for (i = col; i < last; i = +2) { - if ((nand->data_buf[i] + - (nand->data_buf[i + 1] << 8)) != READ_NAND (nand->IO_ADDR)) { - printf ("%s: Failed write verify, page 0x%08x ", - __FUNCTION__, page); - return -1; - } - } - } else { - for (i = col; i < last; i++) { - if (nand->data_buf[i] != READ_NAND (nand->IO_ADDR)) { - printf ("%s: Failed write verify, page 0x%08x ", - __FUNCTION__, page); - return -1; - } - } - } - -#ifdef CONFIG_MTD_NAND_ECC - /* - * We also want to check that the ECC bytes wrote - * correctly for the same reasons stated above. - */ - NanD_Command (nand, NAND_CMD_READOOB); - if (nand->bus16) { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + (col >> 1)); - } else { - NanD_Address (nand, ADDR_COLUMN_PAGE, - (page << nand->page_shift) + col); - } - if (nand->bus16) { - for (i = 0; i < nand->oobsize; i += 2) { - u16 val; - - val = READ_NAND (nand->IO_ADDR); - nand->data_buf[i] = val & 0xff; - nand->data_buf[i + 1] = val >> 8; - } - } else { - for (i = 0; i < nand->oobsize; i++) { - nand->data_buf[i] = READ_NAND (nand->IO_ADDR); - } - } - for (i = 0; i < ecc_bytes; i++) { - if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) { - printf ("%s: Failed ECC write " - "verify, page 0x%08x, " - "%6i bytes were succesful\n", - __FUNCTION__, page, i); - return -1; - } - } -#endif /* CONFIG_MTD_NAND_ECC */ -#endif /* CONFIG_MTD_NAND_VERIFY_WRITE */ - return 0; -} - -static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len, - size_t * retlen, const u_char * buf, u_char * ecc_code) -{ - int i, page, col, cnt, ret = 0; - - /* Do not allow write past end of device */ - if ((to + len) > nand->totlen) { - printf ("%s: Attempt to write past end of page\n", __FUNCTION__); - return -1; - } - - /* Shift to get page */ - page = ((int) to) >> nand->page_shift; - - /* Get the starting column */ - col = to & (nand->oobblock - 1); - - /* Initialize return length value */ - *retlen = 0; - - /* Select the NAND device */ -#ifdef CONFIG_OMAP1510 - archflashwp(0,0); -#endif -#ifdef CFG_NAND_WP - NAND_WP_OFF(); -#endif - - NAND_ENABLE_CE(nand); /* set pin low */ - - /* Check the WP bit */ - NanD_Command(nand, NAND_CMD_STATUS); - if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { - printf ("%s: Device is write protected!!!\n", __FUNCTION__); - ret = -1; - goto out; - } - - /* Loop until all data is written */ - while (*retlen < len) { - /* Invalidate cache, if we write to this page */ - if (nand->cache_page == page) - nand->cache_page = -1; - - /* Write data into buffer */ - if ((col + len) >= nand->oobblock) { - for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++) { - nand->data_buf[i] = buf[(*retlen + cnt)]; - } - } else { - for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++) { - nand->data_buf[i] = buf[(*retlen + cnt)]; - } - } - /* We use the same function for write and writev !) */ - ret = nand_write_page (nand, page, col, i, ecc_code); - if (ret) - goto out; - - /* Next data start at page boundary */ - col = 0; - - /* Update written bytes count */ - *retlen += cnt; - - /* Increment page address */ - page++; - } - - /* Return happy */ - *retlen = len; - -out: - /* De-select the NAND device */ - NAND_DISABLE_CE(nand); /* set pin high */ -#ifdef CONFIG_OMAP1510 - archflashwp(0,1); -#endif -#ifdef CFG_NAND_WP - NAND_WP_ON(); -#endif - - return ret; -} - -/* read from the 16 bytes of oob data that correspond to a 512 byte - * page or 2 256-byte pages. - */ -static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, - size_t * retlen, u_char * buf) -{ - int len256 = 0; - struct Nand *mychip; - int ret = 0; - - mychip = &nand->chips[ofs >> nand->chipshift]; - - /* update address for 2M x 8bit devices. OOB starts on the second */ - /* page to maintain compatibility with nand_read_ecc. */ - if (nand->page256) { - if (!(ofs & 0x8)) - ofs += 0x100; - else - ofs -= 0x8; - } - - NAND_ENABLE_CE(nand); /* set pin low */ - NanD_Command(nand, NAND_CMD_READOOB); - if (nand->bus16) { - NanD_Address(nand, ADDR_COLUMN_PAGE, - ((ofs >> nand->page_shift) << nand->page_shift) + - ((ofs & (nand->oobblock - 1)) >> 1)); - } else { - NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); - } - - /* treat crossing 8-byte OOB data for 2M x 8bit devices */ - /* Note: datasheet says it should automaticaly wrap to the */ - /* next OOB block, but it didn't work here. mf. */ - if (nand->page256 && ofs + len > (ofs | 0x7) + 1) { - len256 = (ofs | 0x7) + 1 - ofs; - NanD_ReadBuf(nand, buf, len256); - - NanD_Command(nand, NAND_CMD_READOOB); - NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff)); - } - - NanD_ReadBuf(nand, &buf[len256], len - len256); - - *retlen = len; - /* Reading the full OOB data drops us off of the end of the page, - * causing the flash device to go into busy mode, so we need - * to wait until ready 11.4.1 and Toshiba TC58256FT nands */ - - ret = NanD_WaitReady(nand, 1); - NAND_DISABLE_CE(nand); /* set pin high */ - - return ret; - -} - -/* write to the 16 bytes of oob data that correspond to a 512 byte - * page or 2 256-byte pages. - */ -static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, - size_t * retlen, const u_char * buf) -{ - int len256 = 0; - int i; - unsigned long nandptr = nand->IO_ADDR; - -#ifdef PSYCHO_DEBUG - printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n", - (long)ofs, len, buf[0], buf[1], buf[2], buf[3], - buf[8], buf[9], buf[14],buf[15]); -#endif - - NAND_ENABLE_CE(nand); /* set pin low to enable chip */ - - /* Reset the chip */ - NanD_Command(nand, NAND_CMD_RESET); - - /* issue the Read2 command to set the pointer to the Spare Data Area. */ - NanD_Command(nand, NAND_CMD_READOOB); - if (nand->bus16) { - NanD_Address(nand, ADDR_COLUMN_PAGE, - ((ofs >> nand->page_shift) << nand->page_shift) + - ((ofs & (nand->oobblock - 1)) >> 1)); - } else { - NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); - } - - /* update address for 2M x 8bit devices. OOB starts on the second */ - /* page to maintain compatibility with nand_read_ecc. */ - if (nand->page256) { - if (!(ofs & 0x8)) - ofs += 0x100; - else - ofs -= 0x8; - } - - /* issue the Serial Data In command to initial the Page Program process */ - NanD_Command(nand, NAND_CMD_SEQIN); - if (nand->bus16) { - NanD_Address(nand, ADDR_COLUMN_PAGE, - ((ofs >> nand->page_shift) << nand->page_shift) + - ((ofs & (nand->oobblock - 1)) >> 1)); - } else { - NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); - } - - /* treat crossing 8-byte OOB data for 2M x 8bit devices */ - /* Note: datasheet says it should automaticaly wrap to the */ - /* next OOB block, but it didn't work here. mf. */ - if (nand->page256 && ofs + len > (ofs | 0x7) + 1) { - len256 = (ofs | 0x7) + 1 - ofs; - for (i = 0; i < len256; i++) - WRITE_NAND(buf[i], nandptr); - - NanD_Command(nand, NAND_CMD_PAGEPROG); - NanD_Command(nand, NAND_CMD_STATUS); -#ifdef NAND_NO_RB - { u_char ret_val; - do { - ret_val = READ_NAND(nandptr); /* wait till ready */ - } while ((ret_val & 0x40) != 0x40); - } -#endif - if (READ_NAND(nandptr) & 1) { - puts ("Error programming oob data\n"); - /* There was an error */ - NAND_DISABLE_CE(nand); /* set pin high */ - *retlen = 0; - return -1; - } - NanD_Command(nand, NAND_CMD_SEQIN); - NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff)); - } - - if (nand->bus16) { - for (i = len256; i < len; i += 2) { - WRITE_NAND(buf[i] + (buf[i+1] << 8), nandptr); - } - } else { - for (i = len256; i < len; i++) - WRITE_NAND(buf[i], nandptr); - } - - NanD_Command(nand, NAND_CMD_PAGEPROG); - NanD_Command(nand, NAND_CMD_STATUS); -#ifdef NAND_NO_RB - { u_char ret_val; - do { - ret_val = READ_NAND(nandptr); /* wait till ready */ - } while ((ret_val & 0x40) != 0x40); - } -#endif - if (READ_NAND(nandptr) & 1) { - puts ("Error programming oob data\n"); - /* There was an error */ - NAND_DISABLE_CE(nand); /* set pin high */ - *retlen = 0; - return -1; - } - - NAND_DISABLE_CE(nand); /* set pin high */ - *retlen = len; - return 0; - -} - -int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean) -{ - /* This is defined as a structure so it will work on any system - * using native endian jffs2 (the default). - */ - static struct jffs2_unknown_node clean_marker = { - JFFS2_MAGIC_BITMASK, - JFFS2_NODETYPE_CLEANMARKER, - 8 /* 8 bytes in this node */ - }; - unsigned long nandptr; - struct Nand *mychip; - int ret = 0; - - if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) { - printf ("Offset and size must be sector aligned, erasesize = %d\n", - (int) nand->erasesize); - return -1; - } - - nandptr = nand->IO_ADDR; - - /* Select the NAND device */ -#ifdef CONFIG_OMAP1510 - archflashwp(0,0); -#endif -#ifdef CFG_NAND_WP - NAND_WP_OFF(); -#endif - NAND_ENABLE_CE(nand); /* set pin low */ - - /* Check the WP bit */ - NanD_Command(nand, NAND_CMD_STATUS); - if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { - printf ("nand_write_ecc: Device is write protected!!!\n"); - ret = -1; - goto out; - } - - /* Check the WP bit */ - NanD_Command(nand, NAND_CMD_STATUS); - if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { - printf ("%s: Device is write protected!!!\n", __FUNCTION__); - ret = -1; - goto out; - } - - /* FIXME: Do nand in the background. Use timers or schedule_task() */ - while(len) { - /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/ - mychip = &nand->chips[ofs >> nand->chipshift]; - - /* always check for bad block first, genuine bad blocks - * should _never_ be erased. - */ - if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) { - /* Select the NAND device */ - NAND_ENABLE_CE(nand); /* set pin low */ - - NanD_Command(nand, NAND_CMD_ERASE1); - NanD_Address(nand, ADDR_PAGE, ofs); - NanD_Command(nand, NAND_CMD_ERASE2); - - NanD_Command(nand, NAND_CMD_STATUS); - -#ifdef NAND_NO_RB - { u_char ret_val; - do { - ret_val = READ_NAND(nandptr); /* wait till ready */ - } while ((ret_val & 0x40) != 0x40); - } -#endif - if (READ_NAND(nandptr) & 1) { - printf ("%s: Error erasing at 0x%lx\n", - __FUNCTION__, (long)ofs); - /* There was an error */ - ret = -1; - goto out; - } - if (clean) { - int n; /* return value not used */ - int p, l; - - /* clean marker position and size depend - * on the page size, since 256 byte pages - * only have 8 bytes of oob data - */ - if (nand->page256) { - p = NAND_JFFS2_OOB8_FSDAPOS; - l = NAND_JFFS2_OOB8_FSDALEN; - } else { - p = NAND_JFFS2_OOB16_FSDAPOS; - l = NAND_JFFS2_OOB16_FSDALEN; - } - - ret = nand_write_oob(nand, ofs + p, l, (size_t *)&n, - (u_char *)&clean_marker); - /* quit here if write failed */ - if (ret) - goto out; - } - } - ofs += nand->erasesize; - len -= nand->erasesize; - } - -out: - /* De-select the NAND device */ - NAND_DISABLE_CE(nand); /* set pin high */ -#ifdef CONFIG_OMAP1510 - archflashwp(0,1); -#endif -#ifdef CFG_NAND_WP - NAND_WP_ON(); -#endif - - return ret; -} - -static inline int nandcheck(unsigned long potential, unsigned long physadr) -{ - return 0; -} - -unsigned long nand_probe(unsigned long physadr) -{ - struct nand_chip *nand = NULL; - int i = 0, ChipID = 1; - -#ifdef CONFIG_MTD_NAND_ECC_JFFS2 - oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0; - oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1; - oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2; - oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3; - oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4; - oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5; - oob_config.eccvalid_pos = 4; -#else - oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0; - oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1; - oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2; - oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3; - oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4; - oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5; - oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS; -#endif - oob_config.badblock_pos = 5; - - for (i=0; iIO_ADDR = physadr; - nand->cache_page = -1; /* init the cache page */ - NanD_ScanChips(nand); - - if (nand->totlen == 0) { - /* no chips found, clean up and quit */ - memset((char *)nand, 0, sizeof(struct nand_chip)); - nand->ChipID = NAND_ChipID_UNKNOWN; - return (0); - } - - nand->ChipID = ChipID; - if (curr_device == -1) - curr_device = i; - - nand->data_buf = malloc (nand->oobblock + nand->oobsize); - if (!nand->data_buf) { - puts ("Cannot allocate memory for data structures.\n"); - return (0); - } - - return (nand->totlen); -} - -#ifdef CONFIG_MTD_NAND_ECC -/* - * Pre-calculated 256-way 1 byte column parity - */ -static const u_char nand_ecc_precalc_table[] = { - 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, - 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, - 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, - 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, - 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, - 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, - 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, - 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, - 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, - 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, - 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, - 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, - 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, - 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, - 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, - 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, - 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, - 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, - 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, - 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, - 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, - 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, - 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, - 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, - 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, - 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, - 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, - 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, - 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, - 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, - 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, - 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 -}; - - -/* - * Creates non-inverted ECC code from line parity - */ -static void nand_trans_result(u_char reg2, u_char reg3, - u_char *ecc_code) -{ - u_char a, b, i, tmp1, tmp2; - - /* Initialize variables */ - a = b = 0x80; - tmp1 = tmp2 = 0; - - /* Calculate first ECC byte */ - for (i = 0; i < 4; i++) { - if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ - tmp1 |= b; - b >>= 1; - if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */ - tmp1 |= b; - b >>= 1; - a >>= 1; - } - - /* Calculate second ECC byte */ - b = 0x80; - for (i = 0; i < 4; i++) { - if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */ - tmp2 |= b; - b >>= 1; - if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */ - tmp2 |= b; - b >>= 1; - a >>= 1; - } - - /* Store two of the ECC bytes */ - ecc_code[0] = tmp1; - ecc_code[1] = tmp2; -} - -/* - * Calculate 3 byte ECC code for 256 byte block - */ -static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code) -{ - u_char idx, reg1, reg3; - int j; - - /* Initialize variables */ - reg1 = reg3 = 0; - ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; - - /* Build up column parity */ - for(j = 0; j < 256; j++) { - - /* Get CP0 - CP5 from table */ - idx = nand_ecc_precalc_table[dat[j]]; - reg1 ^= idx; - - /* All bit XOR = 1 ? */ - if (idx & 0x40) { - reg3 ^= (u_char) j; - } - } - - /* Create non-inverted ECC code from line parity */ - nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code); - - /* Calculate final ECC code */ - ecc_code[0] = ~ecc_code[0]; - ecc_code[1] = ~ecc_code[1]; - ecc_code[2] = ((~reg1) << 2) | 0x03; -} - -/* - * Detect and correct a 1 bit error for 256 byte block - */ -static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc) -{ - u_char a, b, c, d1, d2, d3, add, bit, i; - - /* Do error detection */ - d1 = calc_ecc[0] ^ read_ecc[0]; - d2 = calc_ecc[1] ^ read_ecc[1]; - d3 = calc_ecc[2] ^ read_ecc[2]; - - if ((d1 | d2 | d3) == 0) { - /* No errors */ - return 0; - } else { - a = (d1 ^ (d1 >> 1)) & 0x55; - b = (d2 ^ (d2 >> 1)) & 0x55; - c = (d3 ^ (d3 >> 1)) & 0x54; - - /* Found and will correct single bit error in the data */ - if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { - c = 0x80; - add = 0; - a = 0x80; - for (i=0; i<4; i++) { - if (d1 & c) - add |= a; - c >>= 2; - a >>= 1; - } - c = 0x80; - for (i=0; i<4; i++) { - if (d2 & c) - add |= a; - c >>= 2; - a >>= 1; - } - bit = 0; - b = 0x04; - c = 0x80; - for (i=0; i<3; i++) { - if (d3 & c) - bit |= b; - c >>= 2; - b >>= 1; - } - b = 0x01; - a = dat[add]; - a ^= (b << bit); - dat[add] = a; - return 1; - } - else { - i = 0; - while (d1) { - if (d1 & 0x01) - ++i; - d1 >>= 1; - } - while (d2) { - if (d2 & 0x01) - ++i; - d2 >>= 1; - } - while (d3) { - if (d3 & 0x01) - ++i; - d3 >>= 1; - } - if (i == 1) { - /* ECC Code Error Correction */ - read_ecc[0] = calc_ecc[0]; - read_ecc[1] = calc_ecc[1]; - read_ecc[2] = calc_ecc[2]; - return 2; - } - else { - /* Uncorrectable Error */ - return -1; - } - } - } - - /* Should never happen */ - return -1; -} - -#endif - -#ifdef CONFIG_JFFS2_NAND - -int read_jffs2_nand(size_t start, size_t len, - size_t * retlen, u_char * buf, int nanddev) -{ - return nand_rw(nand_dev_desc + nanddev, NANDRW_READ | NANDRW_JFFS2, - start, len, retlen, buf); -} - -#endif /* CONFIG_JFFS2_NAND */ - - #endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ + +#endif /* CFG_NAND_LEGACY */ diff --git a/common/cmd_nand_new.c b/common/cmd_nand_new.c deleted file mode 100644 index 3ff2ebaf60..0000000000 --- a/common/cmd_nand_new.c +++ /dev/null @@ -1,364 +0,0 @@ -#include - -#if (CONFIG_COMMANDS & CFG_CMD_NAND) && defined CONFIG_NEW_NAND_CODE - -#include -#include -#include -#include - -#ifdef CONFIG_SHOW_BOOT_PROGRESS -# include -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) -#else -# define SHOW_BOOT_PROGRESS(arg) -#endif - -#include -#include - -extern nand_info_t nand_info[]; /* info for NAND chips */ - -static int nand_dump_oob(nand_info_t *nand, ulong off) -{ - return 0; -} - -static int nand_dump(nand_info_t *nand, ulong off) -{ - int i; - u_char *buf, *p; - - buf = malloc(nand->oobblock + nand->oobsize); - if (!buf) { - puts("No memory for page buffer\n"); - return 1; - } - off &= ~(nand->oobblock - 1); - i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize); - if (i < 0) { - printf("Error (%d) reading page %08x\n", i, off); - free(buf); - return 1; - } - printf("Page %08x dump:\n", off); - i = nand->oobblock >> 4; p = buf; - while (i--) { - printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x" - " %02x %02x %02x %02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], - p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); - p += 16; - } - puts("OOB:\n"); - i = nand->oobsize >> 3; - while (i--) { - printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - p += 8; - } - free(buf); - - return 0; -} - -/* ------------------------------------------------------------------------- */ - -static void -arg_off_size(int argc, char *argv[], ulong *off, ulong *size, ulong totsize) -{ - *off = 0; - *size = 0; - -#if defined(CONFIG_JFFS2_NAND) && defined(CFG_JFFS_CUSTOM_PART) - if (argc >= 1 && strcmp(argv[0], "partition") == 0) { - int part_num; - struct part_info *part; - const char *partstr; - - if (argc >= 2) - partstr = argv[1]; - else - partstr = getenv("partition"); - - if (partstr) - part_num = (int)simple_strtoul(partstr, NULL, 10); - else - part_num = 0; - - part = jffs2_part_info(part_num); - if (part == NULL) { - printf("\nInvalid partition %d\n", part_num); - return; - } - *size = part->size; - *off = (ulong)part->offset; - } else -#endif - { - if (argc >= 1) - *off = (ulong)simple_strtoul(argv[0], NULL, 16); - else - *off = 0; - - if (argc >= 2) - *size = (ulong)simple_strtoul(argv[1], NULL, 16); - else - *size = totsize - *off; - - } - -} - -int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - int i, dev, ret; - ulong addr, off, size; - char *cmd, *s; - nand_info_t *nand; - - /* at least two arguments please */ - if (argc < 2) - goto usage; - - cmd = argv[1]; - - if (strcmp(cmd, "info") == 0) { - - putc('\n'); - for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { - if (nand_info[i].name) - printf("Device %d: %s\n", i, nand_info[i].name); - } - return 0; - } - - if (strcmp(cmd, "device") == 0) { - - if (argc < 3) { - if ((nand_curr_device < 0) || - (nand_curr_device >= CFG_MAX_NAND_DEVICE)) - puts("\nno devices available\n"); - else - printf("\nDevice %d: %s\n", nand_curr_device, - nand_info[nand_curr_device].name); - return 0; - } - dev = (int)simple_strtoul(argv[2], NULL, 10); - if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { - puts("No such device\n"); - return 1; - } - printf("Device %d: %s", dev, nand_info[dev].name); - puts("... is now current device\n"); - nand_curr_device = dev; - return 0; - } - - if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && - strncmp(cmd, "dump", 4) != 0 && - strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0) - goto usage; - - /* the following commands operate on the current device */ - if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE || - !nand_info[nand_curr_device].name) { - puts("\nno devices available\n"); - return 1; - } - nand = &nand_info[nand_curr_device]; - - if (strcmp(cmd, "bad") == 0) { - printf("\nDevice %d bad blocks:\n", nand_curr_device); - for (off = 0; off < nand->size; off += nand->erasesize) - if (nand_block_isbad(nand, off)) - printf(" %08x\n", off); - return 0; - } - - if (strcmp(cmd, "erase") == 0) { - arg_off_size(argc - 2, argv + 2, &off, &size, nand->size); - if (off == 0 && size == 0) - return 1; - - printf("\nNAND erase: device %d offset 0x%x, size 0x%x ", - nand_curr_device, off, size); - ret = nand_erase(nand, off, size); - printf("%s\n", ret ? "ERROR" : "OK"); - - return ret == 0 ? 0 : 1; - } - - if (strncmp(cmd, "dump", 4) == 0) { - if (argc < 3) - goto usage; - - s = strchr(cmd, '.'); - off = (int)simple_strtoul(argv[2], NULL, 16); - - if (s != NULL && strcmp(s, ".oob") == 0) - ret = nand_dump_oob(nand, off); - else - ret = nand_dump(nand, off); - - return ret == 0 ? 1 : 0; - - } - - /* read write */ - if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { - if (argc < 4) - goto usage; -/* - s = strchr(cmd, '.'); - clean = CLEAN_NONE; - if (s != NULL) { - if (strcmp(s, ".jffs2") == 0 || strcmp(s, ".e") == 0 - || strcmp(s, ".i")) - clean = CLEAN_JFFS2; - } -*/ - addr = (ulong)simple_strtoul(argv[2], NULL, 16); - - arg_off_size(argc - 3, argv + 3, &off, &size, nand->size); - if (off == 0 && size == 0) - return 1; - - i = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ - printf("\nNAND %s: device %d offset %u, size %u ... ", - i ? "read" : "write", nand_curr_device, off, size); - - if (i) - ret = nand_read(nand, off, &size, (u_char *)addr); - else - ret = nand_write(nand, off, &size, (u_char *)addr); - - printf(" %d bytes %s: %s\n", size, - i ? "read" : "written", ret ? "ERROR" : "OK"); - - return ret == 0 ? 0 : 1; - } -usage: - printf("Usage:\n%s\n", cmdtp->usage); - return 1; -} - -U_BOOT_CMD(nand, 5, 1, do_nand, - "nand - NAND sub-system\n", - "info - show available NAND devices\n" - "nand device [dev] - show or set current device\n" - "nand read[.jffs2] - addr off size\n" - "nand write[.jffs2] - addr off size - read/write `size' bytes starting\n" - " at offset `off' to/from memory address `addr'\n" - "nand erase [clean] [off size] - erase `size' bytes from\n" - " offset `off' (entire device if not specified)\n" - "nand bad - show bad blocks\n" - "nand dump[.oob] off - dump page\n" - "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n" - "nand markbad off - mark bad block at offset (UNSAFE)\n" - "nand biterr off - make a bit error at offset (UNSAFE)\n"); - -int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - char *boot_device = NULL; - char *ep; - int dev; - int r; - ulong addr, cnt, offset = 0; - image_header_t *hdr; - nand_info_t *nand; - - switch (argc) { - case 1: - addr = CFG_LOAD_ADDR; - boot_device = getenv("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - case 4: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - offset = simple_strtoul(argv[3], NULL, 16); - break; - default: - printf("Usage:\n%s\n", cmdtp->usage); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - if (!boot_device) { - puts("\n** No boot device **\n"); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - dev = simple_strtoul(boot_device, &ep, 16); - - if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { - printf("\n** Device %d not available\n", dev); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - nand = &nand_info[dev]; - printf("\nLoading from device %d: %s (offset 0x%lx)\n", - dev, nand->name, offset); - - cnt = nand->oobblock; - r = nand_read(nand, offset, &cnt, (u_char *) addr); - if (r) { - printf("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - hdr = (image_header_t *) addr; - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - print_image_hdr(hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t)); - - r = nand_read(nand, offset, &cnt, (u_char *) addr); - if (r) { - printf("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - /* Loading ok, update default load address */ - - load_addr = addr; - - /* Check if we should attempt an auto-start */ - if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) { - char *local_args[2]; - extern int do_bootm(cmd_tbl_t *, int, int, char *[]); - - local_args[0] = argv[0]; - local_args[1] = NULL; - - printf("Automatic boot of image at addr 0x%08lx ...\n", addr); - - do_bootm(cmdtp, 0, 1, local_args); - return 1; - } - return 0; -} - -U_BOOT_CMD(nboot, 4, 1, do_nandboot, - "nboot - boot from NAND device\n", "loadAddr dev\n"); - - -#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ diff --git a/common/env_nand.c b/common/env_nand.c index 60aba1e7e6..4896853530 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_NAND)) == (CFG_CMD_ENV|CFG_CMD_NAND)) #define CMD_SAVEENV @@ -55,16 +55,12 @@ #error CONFIG_INFERNO not supported yet #endif -/* references to names in cmd_nand.c */ -#define NANDRW_READ 0x01 -#define NANDRW_WRITE 0x00 -#define NANDRW_JFFS2 0x02 -extern struct nand_chip nand_dev_desc[]; -int nand_rw (struct nand_chip* nand, int cmd, +int nand_legacy_rw (struct nand_chip* nand, int cmd, size_t start, size_t len, size_t * retlen, u_char * buf); -int nand_erase(struct nand_chip* nand, size_t ofs, - size_t len, int clean); + +/* info for NAND chips, defined in drivers/nand/nand.c */ +extern nand_info_t nand_info[]; /* references to names in env_common.c */ extern uchar default_environment[]; @@ -110,34 +106,43 @@ int env_init(void) } #ifdef CMD_SAVEENV +/* + * The legacy NAND code saved the environment in the first NAND device i.e., + * nand_dev_desc + 0. This is also the behaviour using the new NAND code. + */ int saveenv(void) { int total, ret = 0; - puts ("Erasing Nand..."); - if (nand_erase(nand_dev_desc + 0, CFG_ENV_OFFSET, CFG_ENV_SIZE, 0)) - return 1; - puts ("Writing to Nand... "); - ret = nand_rw(nand_dev_desc + 0, - NANDRW_WRITE | NANDRW_JFFS2, CFG_ENV_OFFSET, CFG_ENV_SIZE, - &total, (u_char*)env_ptr); - if (ret || total != CFG_ENV_SIZE) + puts ("Erasing Nand..."); + if (nand_erase(&nand_info[0], CFG_NEW_OFFSET, CFG_ENV_SIZE)) return 1; - puts ("done\n"); - return ret; + puts ("Writing to Nand... "); + total = CFG_ENV_SIZE; + ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, + (u_char*) env_ptr); + if (ret || total != CFG_ENV_SIZE) + return 1; + + puts ("done\n"); + return ret; } #endif /* CMD_SAVEENV */ +/* + * The legacy NAND code saved the environment in the first NAND device i.e., + * nand_dev_desc + 0. This is also the behaviour using the new NAND code. + */ void env_relocate_spec (void) { #if !defined(ENV_IS_EMBEDDED) int ret, total; - ret = nand_rw(nand_dev_desc + 0, - NANDRW_READ | NANDRW_JFFS2, CFG_ENV_OFFSET, CFG_ENV_SIZE, - &total, (u_char*)env_ptr); + total = CFG_ENV_SIZE; + ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, + (u_char*) env_ptr); if (ret || total != CFG_ENV_SIZE) return use_default(); diff --git a/drivers/nand/diskonchip.c b/drivers/nand/diskonchip.c index 07e2549352..afaae834f1 100644 --- a/drivers/nand/diskonchip.c +++ b/drivers/nand/diskonchip.c @@ -20,7 +20,11 @@ */ #include -#ifdef CONFIG_NEW_NAND_CODE + +#ifdef CFG_NAND_LEGACY +#error CFG_NAND_LEGACY defined in a file not using the legacy NAND support! +#endif + #include #include #include @@ -1782,4 +1786,3 @@ module_exit(cleanup_nanddoc); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse "); MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n"); -#endif /* CONFIG_NEW_NAND_CODE */ diff --git a/drivers/nand/nand.c b/drivers/nand/nand.c index bc85005b2a..dd80026fe0 100644 --- a/drivers/nand/nand.c +++ b/drivers/nand/nand.c @@ -23,7 +23,10 @@ #include -#ifdef CONFIG_NEW_NAND_CODE +#ifdef CFG_NAND_LEGACY +#error CFG_NAND_LEGACY defined in a file not using the legacy NAND support! +#endif + #if (CONFIG_COMMANDS & CFG_CMD_NAND) #include @@ -72,5 +75,3 @@ void nand_init(void) } #endif -#endif /* CONFIG_NEW_NAND_CODE */ - diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c index b039c3cd8c..b2cd62e37e 100644 --- a/drivers/nand/nand_base.c +++ b/drivers/nand/nand_base.c @@ -71,7 +71,10 @@ #endif #include -#ifdef CONFIG_NEW_NAND_CODE + +#ifdef CFG_NAND_LEGACY +#error CFG_NAND_LEGACY defined in a file not using the legacy NAND support! +#endif #if (CONFIG_COMMANDS & CFG_CMD_NAND) @@ -864,10 +867,10 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) break; } } - - /* XXX nand device 1 on dave (PPChameleonEVB) needs more time */ +#ifdef PPCHAMELON_NAND_TIMER_HACK reset_timer(); while (get_timer(0) < 10); +#endif /* PPCHAMELON_NAND_TIMER_HACK */ return this->read_byte(mtd); } @@ -2660,5 +2663,3 @@ void nand_release (struct mtd_info *mtd) } #endif -#endif /* CONFIG_NEW_NAND_CODE */ - diff --git a/drivers/nand/nand_bbt.c b/drivers/nand/nand_bbt.c index f4813088b5..ac168723e2 100644 --- a/drivers/nand/nand_bbt.c +++ b/drivers/nand/nand_bbt.c @@ -54,7 +54,10 @@ #include -#ifdef CONFIG_NEW_NAND_CODE +#ifdef CFG_NAND_LEGACY +#error CFG_NAND_LEGACY defined in a file not using the legacy NAND support! +#endif + #if (CONFIG_COMMANDS & CFG_CMD_NAND) #include @@ -1051,5 +1054,3 @@ int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt) } #endif -#endif /* CONFIG_NEW_NAND_CODE */ - diff --git a/drivers/nand/nand_ecc.c b/drivers/nand/nand_ecc.c index 4e610c1123..e0d0e8bcc4 100644 --- a/drivers/nand/nand_ecc.c +++ b/drivers/nand/nand_ecc.c @@ -37,7 +37,10 @@ #include -#ifdef CONFIG_NEW_NAND_CODE +#ifdef CFG_NAND_LEGACY +#error CFG_NAND_LEGACY defined in a file not using the legacy NAND support! +#endif + #if (CONFIG_COMMANDS & CFG_CMD_NAND) #include @@ -243,5 +246,3 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha } #endif /* CONFIG_COMMANDS & CFG_CMD_NAND */ -#endif /* CONFIG_NEW_NAND_CODE */ - diff --git a/drivers/nand/nand_ids.c b/drivers/nand/nand_ids.c index d355326107..3d4d372f17 100644 --- a/drivers/nand/nand_ids.c +++ b/drivers/nand/nand_ids.c @@ -13,7 +13,10 @@ #include -#ifdef CONFIG_NEW_NAND_CODE +#ifdef CFG_NAND_LEGACY +#error CFG_NAND_LEGACY defined in a file not using the legacy NAND support! +#endif + #if (CONFIG_COMMANDS & CFG_CMD_NAND) #include @@ -127,5 +130,3 @@ struct nand_manufacturers nand_manuf_ids[] = { {0x0, "Unknown"} }; #endif -#endif /* CONFIG_NEW_NAND_CODE */ - diff --git a/drivers/nand_legacy/Makefile b/drivers/nand_legacy/Makefile new file mode 100644 index 0000000000..7e2cf66730 --- /dev/null +++ b/drivers/nand_legacy/Makefile @@ -0,0 +1,16 @@ +include $(TOPDIR)/config.mk + +LIB := libnand_legacy.a + +OBJS := nand_legacy.o +all: $(LIB) + +$(LIB): $(OBJS) + $(AR) crv $@ $(OBJS) + +######################################################################### + +.depend: Makefile $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ + +sinclude .depend diff --git a/drivers/nand_legacy/nand_legacy.c b/drivers/nand_legacy/nand_legacy.c new file mode 100644 index 0000000000..3989ca2a2d --- /dev/null +++ b/drivers/nand_legacy/nand_legacy.c @@ -0,0 +1,1615 @@ +/* + * (C) 2006 Denx + * Driver for NAND support, Rick Bronson + * borrowed heavily from: + * (c) 1999 Machine Vision Holdings, Inc. + * (c) 1999, 2000 David Woodhouse + * + * Added 16-bit nand support + * (C) 2004 Texas Instruments + */ + +#include + +#ifndef CFG_NAND_LEGACY +#error CFG_NAND_LEGACY not defined in a file using the legacy NAND support! +#endif + +#include +#include +#include +#include + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# include +# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) +#else +# define SHOW_BOOT_PROGRESS(arg) +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) + +#include +#include +#include + +#ifdef CONFIG_OMAP1510 +void archflashwp(void *archdata, int wp); +#endif + +#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) + +#undef PSYCHO_DEBUG +#undef NAND_DEBUG + +/* ****************** WARNING ********************* + * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will + * erase (or at least attempt to erase) blocks that are marked + * bad. This can be very handy if you are _sure_ that the block + * is OK, say because you marked a good block bad to test bad + * block handling and you are done testing, or if you have + * accidentally marked blocks bad. + * + * Erasing factory marked bad blocks is a _bad_ idea. If the + * erase succeeds there is no reliable way to find them again, + * and attempting to program or erase bad blocks can affect + * the data in _other_ (good) blocks. + */ +#define ALLOW_ERASE_BAD_DEBUG 0 + +#define CONFIG_MTD_NAND_ECC /* enable ECC */ +#define CONFIG_MTD_NAND_ECC_JFFS2 + +/* bits for nand_legacy_rw() `cmd'; or together as needed */ +#define NANDRW_READ 0x01 +#define NANDRW_WRITE 0x00 +#define NANDRW_JFFS2 0x02 +#define NANDRW_JFFS2_SKIP 0x04 + + +/* + * Exported variables etc. + */ + +/* Definition of the out of band configuration structure */ +struct nand_oob_config { + /* position of ECC bytes inside oob */ + int ecc_pos[6]; + /* position of bad blk flag inside oob -1 = inactive */ + int badblock_pos; + /* position of ECC valid flag inside oob -1 = inactive */ + int eccvalid_pos; +} oob_config = { {0}, 0, 0}; + +struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}}; + +int curr_device = -1; /* Current NAND Device */ + + +/* + * Exported functionss + */ +int nand_legacy_erase(struct nand_chip* nand, size_t ofs, + size_t len, int clean); +int nand_legacy_rw(struct nand_chip* nand, int cmd, + size_t start, size_t len, + size_t * retlen, u_char * buf); +void nand_print(struct nand_chip *nand); +void nand_print_bad(struct nand_chip *nand); +int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, u_char * buf); +int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, const u_char * buf); + +/* + * Internals + */ +static int NanD_WaitReady(struct nand_chip *nand, int ale_wait); +static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len, + size_t * retlen, u_char *buf, u_char *ecc_code); +static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len, + size_t * retlen, const u_char * buf, + u_char * ecc_code); +#ifdef CONFIG_MTD_NAND_ECC +static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); +static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); +#endif + + +/* + * + * Function definitions + * + */ + +/* returns 0 if block containing pos is OK: + * valid erase block and + * not marked bad, or no bad mark position is specified + * returns 1 if marked bad or otherwise invalid + */ +static int check_block (struct nand_chip *nand, unsigned long pos) +{ + size_t retlen; + uint8_t oob_data; + uint16_t oob_data16[6]; + int page0 = pos & (-nand->erasesize); + int page1 = page0 + nand->oobblock; + int badpos = oob_config.badblock_pos; + + if (pos >= nand->totlen) + return 1; + + if (badpos < 0) + return 0; /* no way to check, assume OK */ + + if (nand->bus16) { + if (nand_read_oob(nand, (page0 + 0), 12, &retlen, (uint8_t *)oob_data16) + || (oob_data16[2] & 0xff00) != 0xff00) + return 1; + if (nand_read_oob(nand, (page1 + 0), 12, &retlen, (uint8_t *)oob_data16) + || (oob_data16[2] & 0xff00) != 0xff00) + return 1; + } else { + /* Note - bad block marker can be on first or second page */ + if (nand_read_oob(nand, page0 + badpos, 1, &retlen, (unsigned char *)&oob_data) + || oob_data != 0xff + || nand_read_oob (nand, page1 + badpos, 1, &retlen, (unsigned char *)&oob_data) + || oob_data != 0xff) + return 1; + } + + return 0; +} + +/* print bad blocks in NAND flash */ +void nand_print_bad(struct nand_chip* nand) +{ + unsigned long pos; + + for (pos = 0; pos < nand->totlen; pos += nand->erasesize) { + if (check_block(nand, pos)) + printf(" 0x%8.8lx\n", pos); + } + puts("\n"); +} + +/* cmd: 0: NANDRW_WRITE write, fail on bad block + * 1: NANDRW_READ read, fail on bad block + * 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks + * 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks + * 7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks + */ +int nand_legacy_rw (struct nand_chip* nand, int cmd, + size_t start, size_t len, + size_t * retlen, u_char * buf) +{ + int ret = 0, n, total = 0; + char eccbuf[6]; + /* eblk (once set) is the start of the erase block containing the + * data being processed. + */ + unsigned long eblk = ~0; /* force mismatch on first pass */ + unsigned long erasesize = nand->erasesize; + + while (len) { + if ((start & (-erasesize)) != eblk) { + /* have crossed into new erase block, deal with + * it if it is sure marked bad. + */ + eblk = start & (-erasesize); /* start of block */ + if (check_block(nand, eblk)) { + if (cmd == (NANDRW_READ | NANDRW_JFFS2)) { + while (len > 0 && + start - eblk < erasesize) { + *(buf++) = 0xff; + ++start; + ++total; + --len; + } + continue; + } else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) { + start += erasesize; + continue; + } else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) { + /* skip bad block */ + start += erasesize; + continue; + } else { + ret = 1; + break; + } + } + } + /* The ECC will not be calculated correctly if + less than 512 is written or read */ + /* Is request at least 512 bytes AND it starts on a proper boundry */ + if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200)) + printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n"); + + if (cmd & NANDRW_READ) { + ret = nand_read_ecc(nand, start, + min(len, eblk + erasesize - start), + (size_t *)&n, (u_char*)buf, (u_char *)eccbuf); + } else { + ret = nand_write_ecc(nand, start, + min(len, eblk + erasesize - start), + (size_t *)&n, (u_char*)buf, (u_char *)eccbuf); + } + + if (ret) + break; + + start += n; + buf += n; + total += n; + len -= n; + } + if (retlen) + *retlen = total; + + return ret; +} + +void nand_print(struct nand_chip *nand) +{ + if (nand->numchips > 1) { + printf("%s at 0x%lx,\n" + "\t %d chips %s, size %d MB, \n" + "\t total size %ld MB, sector size %ld kB\n", + nand->name, nand->IO_ADDR, nand->numchips, + nand->chips_name, 1 << (nand->chipshift - 20), + nand->totlen >> 20, nand->erasesize >> 10); + } + else { + printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR); + print_size(nand->totlen, ", "); + print_size(nand->erasesize, " sector)\n"); + } +} + +/* ------------------------------------------------------------------------- */ + +static int NanD_WaitReady(struct nand_chip *nand, int ale_wait) +{ + /* This is inline, to optimise the common case, where it's ready instantly */ + int ret = 0; + +#ifdef NAND_NO_RB /* in config file, shorter delays currently wrap accesses */ + if(ale_wait) + NAND_WAIT_READY(nand); /* do the worst case 25us wait */ + else + udelay(10); +#else /* has functional r/b signal */ + NAND_WAIT_READY(nand); +#endif + return ret; +} + +/* NanD_Command: Send a flash command to the flash chip */ + +static inline int NanD_Command(struct nand_chip *nand, unsigned char command) +{ + unsigned long nandptr = nand->IO_ADDR; + + /* Assert the CLE (Command Latch Enable) line to the flash chip */ + NAND_CTL_SETCLE(nandptr); + + /* Send the command */ + WRITE_NAND_COMMAND(command, nandptr); + + /* Lower the CLE line */ + NAND_CTL_CLRCLE(nandptr); + +#ifdef NAND_NO_RB + if(command == NAND_CMD_RESET){ + u_char ret_val; + NanD_Command(nand, NAND_CMD_STATUS); + do { + ret_val = READ_NAND(nandptr);/* wait till ready */ + } while((ret_val & 0x40) != 0x40); + } +#endif + return NanD_WaitReady(nand, 0); +} + +/* NanD_Address: Set the current address for the flash chip */ + +static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs) +{ + unsigned long nandptr; + int i; + + nandptr = nand->IO_ADDR; + + /* Assert the ALE (Address Latch Enable) line to the flash chip */ + NAND_CTL_SETALE(nandptr); + + /* Send the address */ + /* Devices with 256-byte page are addressed as: + * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31) + * there is no device on the market with page256 + * and more than 24 bits. + * Devices with 512-byte page are addressed as: + * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31) + * 25-31 is sent only if the chip support it. + * bit 8 changes the read command to be sent + * (NAND_CMD_READ0 or NAND_CMD_READ1). + */ + + if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) + WRITE_NAND_ADDRESS(ofs, nandptr); + + ofs = ofs >> nand->page_shift; + + if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) { + for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) { + WRITE_NAND_ADDRESS(ofs, nandptr); + } + } + + /* Lower the ALE line */ + NAND_CTL_CLRALE(nandptr); + + /* Wait for the chip to respond */ + return NanD_WaitReady(nand, 1); +} + +/* NanD_SelectChip: Select a given flash chip within the current floor */ + +static inline int NanD_SelectChip(struct nand_chip *nand, int chip) +{ + /* Wait for it to be ready */ + return NanD_WaitReady(nand, 0); +} + +/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */ + +static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip) +{ + int mfr, id, i; + + NAND_ENABLE_CE(nand); /* set pin low */ + /* Reset the chip */ + if (NanD_Command(nand, NAND_CMD_RESET)) { +#ifdef NAND_DEBUG + printf("NanD_Command (reset) for %d,%d returned true\n", + floor, chip); +#endif + NAND_DISABLE_CE(nand); /* set pin high */ + return 0; + } + + /* Read the NAND chip ID: 1. Send ReadID command */ + if (NanD_Command(nand, NAND_CMD_READID)) { +#ifdef NAND_DEBUG + printf("NanD_Command (ReadID) for %d,%d returned true\n", + floor, chip); +#endif + NAND_DISABLE_CE(nand); /* set pin high */ + return 0; + } + + /* Read the NAND chip ID: 2. Send address byte zero */ + NanD_Address(nand, ADDR_COLUMN, 0); + + /* Read the manufacturer and device id codes from the device */ + + mfr = READ_NAND(nand->IO_ADDR); + + id = READ_NAND(nand->IO_ADDR); + + NAND_DISABLE_CE(nand); /* set pin high */ + +#ifdef NAND_DEBUG + printf("NanD_Command (ReadID) got %x %x\n", mfr, id); +#endif + if (mfr == 0xff || mfr == 0) { + /* No response - return failure */ + return 0; + } + + /* Check it's the same as the first chip we identified. + * M-Systems say that any given nand_chip device should only + * contain _one_ type of flash part, although that's not a + * hardware restriction. */ + if (nand->mfr) { + if (nand->mfr == mfr && nand->id == id) { + return 1; /* This is another the same the first */ + } else { + printf("Flash chip at floor %d, chip %d is different:\n", + floor, chip); + } + } + + /* Print and store the manufacturer and ID codes. */ + for (i = 0; nand_flash_ids[i].name != NULL; i++) { + if (mfr == nand_flash_ids[i].manufacture_id && + id == nand_flash_ids[i].model_id) { +#ifdef NAND_DEBUG + printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, " + "Chip ID: 0x%2.2X (%s)\n", mfr, id, + nand_flash_ids[i].name); +#endif + if (!nand->mfr) { + nand->mfr = mfr; + nand->id = id; + nand->chipshift = + nand_flash_ids[i].chipshift; + nand->page256 = nand_flash_ids[i].page256; + nand->eccsize = 256; + if (nand->page256) { + nand->oobblock = 256; + nand->oobsize = 8; + nand->page_shift = 8; + } else { + nand->oobblock = 512; + nand->oobsize = 16; + nand->page_shift = 9; + } + nand->pageadrlen = nand_flash_ids[i].pageadrlen; + nand->erasesize = nand_flash_ids[i].erasesize; + nand->chips_name = nand_flash_ids[i].name; + nand->bus16 = nand_flash_ids[i].bus16; + return 1; + } + return 0; + } + } + + +#ifdef NAND_DEBUG + /* We haven't fully identified the chip. Print as much as we know. */ + printf("Unknown flash chip found: %2.2X %2.2X\n", + id, mfr); +#endif + + return 0; +} + +/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */ + +static void NanD_ScanChips(struct nand_chip *nand) +{ + int floor, chip; + int numchips[NAND_MAX_FLOORS]; + int maxchips = NAND_MAX_CHIPS; + int ret = 1; + + nand->numchips = 0; + nand->mfr = 0; + nand->id = 0; + + + /* For each floor, find the number of valid chips it contains */ + for (floor = 0; floor < NAND_MAX_FLOORS; floor++) { + ret = 1; + numchips[floor] = 0; + for (chip = 0; chip < maxchips && ret != 0; chip++) { + + ret = NanD_IdentChip(nand, floor, chip); + if (ret) { + numchips[floor]++; + nand->numchips++; + } + } + } + + /* If there are none at all that we recognise, bail */ + if (!nand->numchips) { +#ifdef NAND_DEBUG + puts ("No NAND flash chips recognised.\n"); +#endif + return; + } + + /* Allocate an array to hold the information for each chip */ + nand->chips = malloc(sizeof(struct Nand) * nand->numchips); + if (!nand->chips) { + puts ("No memory for allocating chip info structures\n"); + return; + } + + ret = 0; + + /* Fill out the chip array with {floor, chipno} for each + * detected chip in the device. */ + for (floor = 0; floor < NAND_MAX_FLOORS; floor++) { + for (chip = 0; chip < numchips[floor]; chip++) { + nand->chips[ret].floor = floor; + nand->chips[ret].chip = chip; + nand->chips[ret].curadr = 0; + nand->chips[ret].curmode = 0x50; + ret++; + } + } + + /* Calculate and print the total size of the device */ + nand->totlen = nand->numchips * (1 << nand->chipshift); + +#ifdef NAND_DEBUG + printf("%d flash chips found. Total nand_chip size: %ld MB\n", + nand->numchips, nand->totlen >> 20); +#endif +} + +/* we need to be fast here, 1 us per read translates to 1 second per meg */ +static void NanD_ReadBuf (struct nand_chip *nand, u_char * data_buf, int cntr) +{ + unsigned long nandptr = nand->IO_ADDR; + + NanD_Command (nand, NAND_CMD_READ0); + + if (nand->bus16) { + u16 val; + + while (cntr >= 16) { + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + cntr -= 16; + } + + while (cntr > 0) { + val = READ_NAND (nandptr); + *data_buf++ = val & 0xff; + *data_buf++ = val >> 8; + cntr -= 2; + } + } else { + while (cntr >= 16) { + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + *data_buf++ = READ_NAND (nandptr); + cntr -= 16; + } + + while (cntr > 0) { + *data_buf++ = READ_NAND (nandptr); + cntr--; + } + } +} + +/* + * NAND read with ECC + */ +static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len, + size_t * retlen, u_char *buf, u_char *ecc_code) +{ + int col, page; + int ecc_status = 0; +#ifdef CONFIG_MTD_NAND_ECC + int j; + int ecc_failed = 0; + u_char *data_poi; + u_char ecc_calc[6]; +#endif + + /* Do not allow reads past end of device */ + if ((start + len) > nand->totlen) { + printf ("%s: Attempt read beyond end of device %x %x %x\n", + __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen); + *retlen = 0; + return -1; + } + + /* First we calculate the starting page */ + /*page = shr(start, nand->page_shift);*/ + page = start >> nand->page_shift; + + /* Get raw starting column */ + col = start & (nand->oobblock - 1); + + /* Initialize return value */ + *retlen = 0; + + /* Select the NAND device */ + NAND_ENABLE_CE(nand); /* set pin low */ + + /* Loop until all data read */ + while (*retlen < len) { + +#ifdef CONFIG_MTD_NAND_ECC + /* Do we have this page in cache ? */ + if (nand->cache_page == page) + goto readdata; + /* Send the read command */ + NanD_Command(nand, NAND_CMD_READ0); + if (nand->bus16) { + NanD_Address(nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address(nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + + /* Read in a page + oob data */ + NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize); + + /* copy data into cache, for read out of cache and if ecc fails */ + if (nand->data_cache) { + memcpy (nand->data_cache, nand->data_buf, + nand->oobblock + nand->oobsize); + } + + /* Pick the ECC bytes out of the oob data */ + for (j = 0; j < 6; j++) { + ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])]; + } + + /* Calculate the ECC and verify it */ + /* If block was not written with ECC, skip ECC */ + if (oob_config.eccvalid_pos != -1 && + (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) { + + nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]); + switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) { + case -1: + printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page); + ecc_failed++; + break; + case 1: + case 2: /* transfer ECC corrected data to cache */ + if (nand->data_cache) + memcpy (nand->data_cache, nand->data_buf, 256); + break; + } + } + + if (oob_config.eccvalid_pos != -1 && + nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) { + + nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]); + switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) { + case -1: + printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page); + ecc_failed++; + break; + case 1: + case 2: /* transfer ECC corrected data to cache */ + if (nand->data_cache) + memcpy (&nand->data_cache[256], &nand->data_buf[256], 256); + break; + } + } +readdata: + /* Read the data from ECC data buffer into return buffer */ + data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf; + data_poi += col; + if ((*retlen + (nand->oobblock - col)) >= len) { + memcpy (buf + *retlen, data_poi, len - *retlen); + *retlen = len; + } else { + memcpy (buf + *retlen, data_poi, nand->oobblock - col); + *retlen += nand->oobblock - col; + } + /* Set cache page address, invalidate, if ecc_failed */ + nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1; + + ecc_status += ecc_failed; + ecc_failed = 0; + +#else + /* Send the read command */ + NanD_Command(nand, NAND_CMD_READ0); + if (nand->bus16) { + NanD_Address(nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address(nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + + /* Read the data directly into the return buffer */ + if ((*retlen + (nand->oobblock - col)) >= len) { + NanD_ReadBuf(nand, buf + *retlen, len - *retlen); + *retlen = len; + /* We're done */ + continue; + } else { + NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col); + *retlen += nand->oobblock - col; + } +#endif + /* For subsequent reads align to page boundary. */ + col = 0; + /* Increment page address */ + page++; + } + + /* De-select the NAND device */ + NAND_DISABLE_CE(nand); /* set pin high */ + + /* + * Return success, if no ECC failures, else -EIO + * fs driver will take care of that, because + * retlen == desired len and result == -EIO + */ + return ecc_status ? -1 : 0; +} + +/* + * Nand_page_program function is used for write and writev ! + */ +static int nand_write_page (struct nand_chip *nand, + int page, int col, int last, u_char * ecc_code) +{ + + int i; + unsigned long nandptr = nand->IO_ADDR; + +#ifdef CONFIG_MTD_NAND_ECC +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE + int ecc_bytes = (nand->oobblock == 512) ? 6 : 3; +#endif +#endif + /* pad oob area */ + for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++) + nand->data_buf[i] = 0xff; + +#ifdef CONFIG_MTD_NAND_ECC + /* Zero out the ECC array */ + for (i = 0; i < 6; i++) + ecc_code[i] = 0x00; + + /* Read back previous written data, if col > 0 */ + if (col) { + NanD_Command (nand, NAND_CMD_READ0); + if (nand->bus16) { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + + if (nand->bus16) { + u16 val; + + for (i = 0; i < col; i += 2) { + val = READ_NAND (nandptr); + nand->data_buf[i] = val & 0xff; + nand->data_buf[i + 1] = val >> 8; + } + } else { + for (i = 0; i < col; i++) + nand->data_buf[i] = READ_NAND (nandptr); + } + } + + /* Calculate and write the ECC if we have enough data */ + if ((col < nand->eccsize) && (last >= nand->eccsize)) { + nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0])); + for (i = 0; i < 3; i++) { + nand->data_buf[(nand->oobblock + + oob_config.ecc_pos[i])] = ecc_code[i]; + } + if (oob_config.eccvalid_pos != -1) { + nand->data_buf[nand->oobblock + + oob_config.eccvalid_pos] = 0xf0; + } + } + + /* Calculate and write the second ECC if we have enough data */ + if ((nand->oobblock == 512) && (last == nand->oobblock)) { + nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3])); + for (i = 3; i < 6; i++) { + nand->data_buf[(nand->oobblock + + oob_config.ecc_pos[i])] = ecc_code[i]; + } + if (oob_config.eccvalid_pos != -1) { + nand->data_buf[nand->oobblock + + oob_config.eccvalid_pos] &= 0x0f; + } + } +#endif + /* Prepad for partial page programming !!! */ + for (i = 0; i < col; i++) + nand->data_buf[i] = 0xff; + + /* Postpad for partial page programming !!! oob is already padded */ + for (i = last; i < nand->oobblock; i++) + nand->data_buf[i] = 0xff; + + /* Send command to begin auto page programming */ + NanD_Command (nand, NAND_CMD_READ0); + NanD_Command (nand, NAND_CMD_SEQIN); + if (nand->bus16) { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + + /* Write out complete page of data */ + if (nand->bus16) { + for (i = 0; i < (nand->oobblock + nand->oobsize); i += 2) { + WRITE_NAND (nand->data_buf[i] + + (nand->data_buf[i + 1] << 8), + nand->IO_ADDR); + } + } else { + for (i = 0; i < (nand->oobblock + nand->oobsize); i++) + WRITE_NAND (nand->data_buf[i], nand->IO_ADDR); + } + + /* Send command to actually program the data */ + NanD_Command (nand, NAND_CMD_PAGEPROG); + NanD_Command (nand, NAND_CMD_STATUS); +#ifdef NAND_NO_RB + { + u_char ret_val; + + do { + ret_val = READ_NAND (nandptr); /* wait till ready */ + } while ((ret_val & 0x40) != 0x40); + } +#endif + /* See if device thinks it succeeded */ + if (READ_NAND (nand->IO_ADDR) & 0x01) { + printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, + page); + return -1; + } +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE + /* + * The NAND device assumes that it is always writing to + * a cleanly erased page. Hence, it performs its internal + * write verification only on bits that transitioned from + * 1 to 0. The device does NOT verify the whole page on a + * byte by byte basis. It is possible that the page was + * not completely erased or the page is becoming unusable + * due to wear. The read with ECC would catch the error + * later when the ECC page check fails, but we would rather + * catch it early in the page write stage. Better to write + * no data than invalid data. + */ + + /* Send command to read back the page */ + if (col < nand->eccsize) + NanD_Command (nand, NAND_CMD_READ0); + else + NanD_Command (nand, NAND_CMD_READ1); + if (nand->bus16) { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + + /* Loop through and verify the data */ + if (nand->bus16) { + for (i = col; i < last; i = +2) { + if ((nand->data_buf[i] + + (nand->data_buf[i + 1] << 8)) != READ_NAND (nand->IO_ADDR)) { + printf ("%s: Failed write verify, page 0x%08x ", + __FUNCTION__, page); + return -1; + } + } + } else { + for (i = col; i < last; i++) { + if (nand->data_buf[i] != READ_NAND (nand->IO_ADDR)) { + printf ("%s: Failed write verify, page 0x%08x ", + __FUNCTION__, page); + return -1; + } + } + } + +#ifdef CONFIG_MTD_NAND_ECC + /* + * We also want to check that the ECC bytes wrote + * correctly for the same reasons stated above. + */ + NanD_Command (nand, NAND_CMD_READOOB); + if (nand->bus16) { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + (col >> 1)); + } else { + NanD_Address (nand, ADDR_COLUMN_PAGE, + (page << nand->page_shift) + col); + } + if (nand->bus16) { + for (i = 0; i < nand->oobsize; i += 2) { + u16 val; + + val = READ_NAND (nand->IO_ADDR); + nand->data_buf[i] = val & 0xff; + nand->data_buf[i + 1] = val >> 8; + } + } else { + for (i = 0; i < nand->oobsize; i++) { + nand->data_buf[i] = READ_NAND (nand->IO_ADDR); + } + } + for (i = 0; i < ecc_bytes; i++) { + if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) { + printf ("%s: Failed ECC write " + "verify, page 0x%08x, " + "%6i bytes were succesful\n", + __FUNCTION__, page, i); + return -1; + } + } +#endif /* CONFIG_MTD_NAND_ECC */ +#endif /* CONFIG_MTD_NAND_VERIFY_WRITE */ + return 0; +} + +static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len, + size_t * retlen, const u_char * buf, u_char * ecc_code) +{ + int i, page, col, cnt, ret = 0; + + /* Do not allow write past end of device */ + if ((to + len) > nand->totlen) { + printf ("%s: Attempt to write past end of page\n", __FUNCTION__); + return -1; + } + + /* Shift to get page */ + page = ((int) to) >> nand->page_shift; + + /* Get the starting column */ + col = to & (nand->oobblock - 1); + + /* Initialize return length value */ + *retlen = 0; + + /* Select the NAND device */ +#ifdef CONFIG_OMAP1510 + archflashwp(0,0); +#endif +#ifdef CFG_NAND_WP + NAND_WP_OFF(); +#endif + + NAND_ENABLE_CE(nand); /* set pin low */ + + /* Check the WP bit */ + NanD_Command(nand, NAND_CMD_STATUS); + if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { + printf ("%s: Device is write protected!!!\n", __FUNCTION__); + ret = -1; + goto out; + } + + /* Loop until all data is written */ + while (*retlen < len) { + /* Invalidate cache, if we write to this page */ + if (nand->cache_page == page) + nand->cache_page = -1; + + /* Write data into buffer */ + if ((col + len) >= nand->oobblock) { + for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++) { + nand->data_buf[i] = buf[(*retlen + cnt)]; + } + } else { + for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++) { + nand->data_buf[i] = buf[(*retlen + cnt)]; + } + } + /* We use the same function for write and writev !) */ + ret = nand_write_page (nand, page, col, i, ecc_code); + if (ret) + goto out; + + /* Next data start at page boundary */ + col = 0; + + /* Update written bytes count */ + *retlen += cnt; + + /* Increment page address */ + page++; + } + + /* Return happy */ + *retlen = len; + +out: + /* De-select the NAND device */ + NAND_DISABLE_CE(nand); /* set pin high */ +#ifdef CONFIG_OMAP1510 + archflashwp(0,1); +#endif +#ifdef CFG_NAND_WP + NAND_WP_ON(); +#endif + + return ret; +} + +/* read from the 16 bytes of oob data that correspond to a 512 byte + * page or 2 256-byte pages. + */ +int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, u_char * buf) +{ + int len256 = 0; + struct Nand *mychip; + int ret = 0; + + mychip = &nand->chips[ofs >> nand->chipshift]; + + /* update address for 2M x 8bit devices. OOB starts on the second */ + /* page to maintain compatibility with nand_read_ecc. */ + if (nand->page256) { + if (!(ofs & 0x8)) + ofs += 0x100; + else + ofs -= 0x8; + } + + NAND_ENABLE_CE(nand); /* set pin low */ + NanD_Command(nand, NAND_CMD_READOOB); + if (nand->bus16) { + NanD_Address(nand, ADDR_COLUMN_PAGE, + ((ofs >> nand->page_shift) << nand->page_shift) + + ((ofs & (nand->oobblock - 1)) >> 1)); + } else { + NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); + } + + /* treat crossing 8-byte OOB data for 2M x 8bit devices */ + /* Note: datasheet says it should automaticaly wrap to the */ + /* next OOB block, but it didn't work here. mf. */ + if (nand->page256 && ofs + len > (ofs | 0x7) + 1) { + len256 = (ofs | 0x7) + 1 - ofs; + NanD_ReadBuf(nand, buf, len256); + + NanD_Command(nand, NAND_CMD_READOOB); + NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff)); + } + + NanD_ReadBuf(nand, &buf[len256], len - len256); + + *retlen = len; + /* Reading the full OOB data drops us off of the end of the page, + * causing the flash device to go into busy mode, so we need + * to wait until ready 11.4.1 and Toshiba TC58256FT nands */ + + ret = NanD_WaitReady(nand, 1); + NAND_DISABLE_CE(nand); /* set pin high */ + + return ret; + +} + +/* write to the 16 bytes of oob data that correspond to a 512 byte + * page or 2 256-byte pages. + */ +int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, const u_char * buf) +{ + int len256 = 0; + int i; + unsigned long nandptr = nand->IO_ADDR; + +#ifdef PSYCHO_DEBUG + printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n", + (long)ofs, len, buf[0], buf[1], buf[2], buf[3], + buf[8], buf[9], buf[14],buf[15]); +#endif + + NAND_ENABLE_CE(nand); /* set pin low to enable chip */ + + /* Reset the chip */ + NanD_Command(nand, NAND_CMD_RESET); + + /* issue the Read2 command to set the pointer to the Spare Data Area. */ + NanD_Command(nand, NAND_CMD_READOOB); + if (nand->bus16) { + NanD_Address(nand, ADDR_COLUMN_PAGE, + ((ofs >> nand->page_shift) << nand->page_shift) + + ((ofs & (nand->oobblock - 1)) >> 1)); + } else { + NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); + } + + /* update address for 2M x 8bit devices. OOB starts on the second */ + /* page to maintain compatibility with nand_read_ecc. */ + if (nand->page256) { + if (!(ofs & 0x8)) + ofs += 0x100; + else + ofs -= 0x8; + } + + /* issue the Serial Data In command to initial the Page Program process */ + NanD_Command(nand, NAND_CMD_SEQIN); + if (nand->bus16) { + NanD_Address(nand, ADDR_COLUMN_PAGE, + ((ofs >> nand->page_shift) << nand->page_shift) + + ((ofs & (nand->oobblock - 1)) >> 1)); + } else { + NanD_Address(nand, ADDR_COLUMN_PAGE, ofs); + } + + /* treat crossing 8-byte OOB data for 2M x 8bit devices */ + /* Note: datasheet says it should automaticaly wrap to the */ + /* next OOB block, but it didn't work here. mf. */ + if (nand->page256 && ofs + len > (ofs | 0x7) + 1) { + len256 = (ofs | 0x7) + 1 - ofs; + for (i = 0; i < len256; i++) + WRITE_NAND(buf[i], nandptr); + + NanD_Command(nand, NAND_CMD_PAGEPROG); + NanD_Command(nand, NAND_CMD_STATUS); +#ifdef NAND_NO_RB + { u_char ret_val; + do { + ret_val = READ_NAND(nandptr); /* wait till ready */ + } while ((ret_val & 0x40) != 0x40); + } +#endif + if (READ_NAND(nandptr) & 1) { + puts ("Error programming oob data\n"); + /* There was an error */ + NAND_DISABLE_CE(nand); /* set pin high */ + *retlen = 0; + return -1; + } + NanD_Command(nand, NAND_CMD_SEQIN); + NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff)); + } + + if (nand->bus16) { + for (i = len256; i < len; i += 2) { + WRITE_NAND(buf[i] + (buf[i+1] << 8), nandptr); + } + } else { + for (i = len256; i < len; i++) + WRITE_NAND(buf[i], nandptr); + } + + NanD_Command(nand, NAND_CMD_PAGEPROG); + NanD_Command(nand, NAND_CMD_STATUS); +#ifdef NAND_NO_RB + { u_char ret_val; + do { + ret_val = READ_NAND(nandptr); /* wait till ready */ + } while ((ret_val & 0x40) != 0x40); + } +#endif + if (READ_NAND(nandptr) & 1) { + puts ("Error programming oob data\n"); + /* There was an error */ + NAND_DISABLE_CE(nand); /* set pin high */ + *retlen = 0; + return -1; + } + + NAND_DISABLE_CE(nand); /* set pin high */ + *retlen = len; + return 0; + +} + +int nand_legacy_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean) +{ + /* This is defined as a structure so it will work on any system + * using native endian jffs2 (the default). + */ + static struct jffs2_unknown_node clean_marker = { + JFFS2_MAGIC_BITMASK, + JFFS2_NODETYPE_CLEANMARKER, + 8 /* 8 bytes in this node */ + }; + unsigned long nandptr; + struct Nand *mychip; + int ret = 0; + + if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) { + printf ("Offset and size must be sector aligned, erasesize = %d\n", + (int) nand->erasesize); + return -1; + } + + nandptr = nand->IO_ADDR; + + /* Select the NAND device */ +#ifdef CONFIG_OMAP1510 + archflashwp(0,0); +#endif +#ifdef CFG_NAND_WP + NAND_WP_OFF(); +#endif + NAND_ENABLE_CE(nand); /* set pin low */ + + /* Check the WP bit */ + NanD_Command(nand, NAND_CMD_STATUS); + if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { + printf ("nand_write_ecc: Device is write protected!!!\n"); + ret = -1; + goto out; + } + + /* Check the WP bit */ + NanD_Command(nand, NAND_CMD_STATUS); + if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { + printf ("%s: Device is write protected!!!\n", __FUNCTION__); + ret = -1; + goto out; + } + + /* FIXME: Do nand in the background. Use timers or schedule_task() */ + while(len) { + /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/ + mychip = &nand->chips[ofs >> nand->chipshift]; + + /* always check for bad block first, genuine bad blocks + * should _never_ be erased. + */ + if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) { + /* Select the NAND device */ + NAND_ENABLE_CE(nand); /* set pin low */ + + NanD_Command(nand, NAND_CMD_ERASE1); + NanD_Address(nand, ADDR_PAGE, ofs); + NanD_Command(nand, NAND_CMD_ERASE2); + + NanD_Command(nand, NAND_CMD_STATUS); + +#ifdef NAND_NO_RB + { u_char ret_val; + do { + ret_val = READ_NAND(nandptr); /* wait till ready */ + } while ((ret_val & 0x40) != 0x40); + } +#endif + if (READ_NAND(nandptr) & 1) { + printf ("%s: Error erasing at 0x%lx\n", + __FUNCTION__, (long)ofs); + /* There was an error */ + ret = -1; + goto out; + } + if (clean) { + int n; /* return value not used */ + int p, l; + + /* clean marker position and size depend + * on the page size, since 256 byte pages + * only have 8 bytes of oob data + */ + if (nand->page256) { + p = NAND_JFFS2_OOB8_FSDAPOS; + l = NAND_JFFS2_OOB8_FSDALEN; + } else { + p = NAND_JFFS2_OOB16_FSDAPOS; + l = NAND_JFFS2_OOB16_FSDALEN; + } + + ret = nand_write_oob(nand, ofs + p, l, (size_t *)&n, + (u_char *)&clean_marker); + /* quit here if write failed */ + if (ret) + goto out; + } + } + ofs += nand->erasesize; + len -= nand->erasesize; + } + +out: + /* De-select the NAND device */ + NAND_DISABLE_CE(nand); /* set pin high */ +#ifdef CONFIG_OMAP1510 + archflashwp(0,1); +#endif +#ifdef CFG_NAND_WP + NAND_WP_ON(); +#endif + + return ret; +} + + +static inline int nandcheck(unsigned long potential, unsigned long physadr) +{ + return 0; +} + +unsigned long nand_probe(unsigned long physadr) +{ + struct nand_chip *nand = NULL; + int i = 0, ChipID = 1; + +#ifdef CONFIG_MTD_NAND_ECC_JFFS2 + oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0; + oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1; + oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2; + oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3; + oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4; + oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5; + oob_config.eccvalid_pos = 4; +#else + oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0; + oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1; + oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2; + oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3; + oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4; + oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5; + oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS; +#endif + oob_config.badblock_pos = 5; + + for (i=0; iIO_ADDR = physadr; + nand->cache_page = -1; /* init the cache page */ + NanD_ScanChips(nand); + + if (nand->totlen == 0) { + /* no chips found, clean up and quit */ + memset((char *)nand, 0, sizeof(struct nand_chip)); + nand->ChipID = NAND_ChipID_UNKNOWN; + return (0); + } + + nand->ChipID = ChipID; + if (curr_device == -1) + curr_device = i; + + nand->data_buf = malloc (nand->oobblock + nand->oobsize); + if (!nand->data_buf) { + puts ("Cannot allocate memory for data structures.\n"); + return (0); + } + + return (nand->totlen); +} + +#ifdef CONFIG_MTD_NAND_ECC +/* + * Pre-calculated 256-way 1 byte column parity + */ +static const u_char nand_ecc_precalc_table[] = { + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, + 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, + 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, + 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, + 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, + 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, + 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, + 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, + 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, + 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, + 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, + 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, + 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, + 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, + 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, + 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, + 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 +}; + + +/* + * Creates non-inverted ECC code from line parity + */ +static void nand_trans_result(u_char reg2, u_char reg3, + u_char *ecc_code) +{ + u_char a, b, i, tmp1, tmp2; + + /* Initialize variables */ + a = b = 0x80; + tmp1 = tmp2 = 0; + + /* Calculate first ECC byte */ + for (i = 0; i < 4; i++) { + if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ + tmp1 |= b; + b >>= 1; + if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */ + tmp1 |= b; + b >>= 1; + a >>= 1; + } + + /* Calculate second ECC byte */ + b = 0x80; + for (i = 0; i < 4; i++) { + if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */ + tmp2 |= b; + b >>= 1; + if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */ + tmp2 |= b; + b >>= 1; + a >>= 1; + } + + /* Store two of the ECC bytes */ + ecc_code[0] = tmp1; + ecc_code[1] = tmp2; +} + +/* + * Calculate 3 byte ECC code for 256 byte block + */ +static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code) +{ + u_char idx, reg1, reg3; + int j; + + /* Initialize variables */ + reg1 = reg3 = 0; + ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; + + /* Build up column parity */ + for(j = 0; j < 256; j++) { + + /* Get CP0 - CP5 from table */ + idx = nand_ecc_precalc_table[dat[j]]; + reg1 ^= idx; + + /* All bit XOR = 1 ? */ + if (idx & 0x40) { + reg3 ^= (u_char) j; + } + } + + /* Create non-inverted ECC code from line parity */ + nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code); + + /* Calculate final ECC code */ + ecc_code[0] = ~ecc_code[0]; + ecc_code[1] = ~ecc_code[1]; + ecc_code[2] = ((~reg1) << 2) | 0x03; +} + +/* + * Detect and correct a 1 bit error for 256 byte block + */ +static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc) +{ + u_char a, b, c, d1, d2, d3, add, bit, i; + + /* Do error detection */ + d1 = calc_ecc[0] ^ read_ecc[0]; + d2 = calc_ecc[1] ^ read_ecc[1]; + d3 = calc_ecc[2] ^ read_ecc[2]; + + if ((d1 | d2 | d3) == 0) { + /* No errors */ + return 0; + } else { + a = (d1 ^ (d1 >> 1)) & 0x55; + b = (d2 ^ (d2 >> 1)) & 0x55; + c = (d3 ^ (d3 >> 1)) & 0x54; + + /* Found and will correct single bit error in the data */ + if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { + c = 0x80; + add = 0; + a = 0x80; + for (i=0; i<4; i++) { + if (d1 & c) + add |= a; + c >>= 2; + a >>= 1; + } + c = 0x80; + for (i=0; i<4; i++) { + if (d2 & c) + add |= a; + c >>= 2; + a >>= 1; + } + bit = 0; + b = 0x04; + c = 0x80; + for (i=0; i<3; i++) { + if (d3 & c) + bit |= b; + c >>= 2; + b >>= 1; + } + b = 0x01; + a = dat[add]; + a ^= (b << bit); + dat[add] = a; + return 1; + } + else { + i = 0; + while (d1) { + if (d1 & 0x01) + ++i; + d1 >>= 1; + } + while (d2) { + if (d2 & 0x01) + ++i; + d2 >>= 1; + } + while (d3) { + if (d3 & 0x01) + ++i; + d3 >>= 1; + } + if (i == 1) { + /* ECC Code Error Correction */ + read_ecc[0] = calc_ecc[0]; + read_ecc[1] = calc_ecc[1]; + read_ecc[2] = calc_ecc[2]; + return 2; + } + else { + /* Uncorrectable Error */ + return -1; + } + } + } + + /* Should never happen */ + return -1; +} + +#endif + +#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index f1156481d4..6361d06d20 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -143,7 +143,8 @@ /* keeps pointer to currentlu processed partition */ static struct part_info *current_part; -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) +#include /* * Support for jffs2 on top of NAND-flash * @@ -154,9 +155,8 @@ static struct part_info *current_part; * */ -/* this one defined in cmd_nand.c */ -int read_jffs2_nand(size_t start, size_t len, - size_t * retlen, u_char * buf, int nanddev); +/* info for NAND chips, defined in drivers/nand/nand.c */ +extern nand_info_t nand_info[]; #define NAND_PAGE_SIZE 512 #define NAND_PAGE_SHIFT 9 @@ -167,6 +167,7 @@ int read_jffs2_nand(size_t start, size_t len, #endif #define NAND_CACHE_SIZE (NAND_CACHE_PAGES*NAND_PAGE_SIZE) +#ifdef CFG_NAND_LEGACY static u8* nand_cache = NULL; static u32 nand_cache_off = (u32)-1; @@ -174,7 +175,7 @@ static int read_nand_cached(u32 off, u32 size, u_char *buf) { struct mtdids *id = current_part->dev->id; u32 bytes_read = 0; - size_t retlen; + ulong retlen; int cpy_bytes; while (bytes_read < size) { @@ -191,8 +192,10 @@ static int read_nand_cached(u32 off, u32 size, u_char *buf) return -1; } } - if (read_jffs2_nand(nand_cache_off, NAND_CACHE_SIZE, - &retlen, nand_cache, id->num) < 0 || + + retlen = NAND_CACHE_SIZE; + if (nand_read(&nand_info[id->num], nand_cache_off, + &retlen, nand_cache) != 0 || retlen != NAND_CACHE_SIZE) { printf("read_nand_cached: error reading nand off %#x size %d bytes\n", nand_cache_off, NAND_CACHE_SIZE); @@ -248,6 +251,7 @@ static void put_fl_mem_nand(void *buf) { free(buf); } +#endif /* CFG_NAND_LEGACY */ #endif /* #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ @@ -290,7 +294,7 @@ static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf) return get_fl_mem_nor(off); #endif -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && defined(CFG_NAND_LEGACY) if (id->type == MTD_DEV_TYPE_NAND) return get_fl_mem_nand(off, size, ext_buf); #endif @@ -308,7 +312,7 @@ static inline void *get_node_mem(u32 off) return get_node_mem_nor(off); #endif -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && defined(CFG_NAND_LEGACY) if (id->type == MTD_DEV_TYPE_NAND) return get_node_mem_nand(off); #endif @@ -319,7 +323,7 @@ static inline void *get_node_mem(u32 off) static inline void put_fl_mem(void *buf) { -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && defined(CFG_NAND_LEGACY) struct mtdids *id = current_part->dev->id; if (id->type == MTD_DEV_TYPE_NAND) diff --git a/fs/jffs2/jffs2_nand_1pass.c b/fs/jffs2/jffs2_nand_1pass.c index e5c2a7dd41..e78af7578b 100644 --- a/fs/jffs2/jffs2_nand_1pass.c +++ b/fs/jffs2/jffs2_nand_1pass.c @@ -1,6 +1,6 @@ #include -#if defined(CONFIG_NEW_NAND_CODE) && (CONFIG_COMMANDS & CFG_CMD_JFFS2) +#if !defined(CFG_NAND_LEGACY) && (CONFIG_COMMANDS & CFG_CMD_JFFS2) #include #include diff --git a/include/configs/ASH405.h b/include/configs/ASH405.h index 9841893899..d03c05bf34 100644 --- a/include/configs/ASH405.h +++ b/include/configs/ASH405.h @@ -132,6 +132,9 @@ * NAND-FLASH stuff *----------------------------------------------------------------------- */ + +#define CFG_NAND_LEGACY + #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512 diff --git a/include/configs/BMW.h b/include/configs/BMW.h index 050054d274..3bd43d8369 100644 --- a/include/configs/BMW.h +++ b/include/configs/BMW.h @@ -69,6 +69,10 @@ CFG_CMD_DOC | \ CFG_CMD_ELF | \ 0 ) + +/* CFG_CMD_DOC required legacy NAND support */ +#define CFG_NAND_LEGACY + #if 0 #define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_DHCP | \ CFG_CMD_PCI | CFG_CMD_DOC | CFG_CMD_DATE) diff --git a/include/configs/CMS700.h b/include/configs/CMS700.h index 6025886e3e..1cca2859f4 100644 --- a/include/configs/CMS700.h +++ b/include/configs/CMS700.h @@ -81,6 +81,8 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY + #undef CONFIG_WATCHDOG /* watchdog disabled */ #define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */ diff --git a/include/configs/CPCI405.h b/include/configs/CPCI405.h index efc3adaece..047e2f1eef 100644 --- a/include/configs/CPCI405.h +++ b/include/configs/CPCI405.h @@ -79,6 +79,8 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY + #undef CONFIG_WATCHDOG /* watchdog disabled */ #define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */ diff --git a/include/configs/CPCI4052.h b/include/configs/CPCI4052.h index 1347f2afca..d756f447f7 100644 --- a/include/configs/CPCI4052.h +++ b/include/configs/CPCI4052.h @@ -100,6 +100,8 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY + #undef CONFIG_WATCHDOG /* watchdog disabled */ #define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */ diff --git a/include/configs/CPCI405AB.h b/include/configs/CPCI405AB.h index 9d52815092..852d94a410 100644 --- a/include/configs/CPCI405AB.h +++ b/include/configs/CPCI405AB.h @@ -87,6 +87,9 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY + + #undef CONFIG_WATCHDOG /* watchdog disabled */ #define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */ diff --git a/include/configs/CPCI405DT.h b/include/configs/CPCI405DT.h index 946a0fd194..2260327c3f 100644 --- a/include/configs/CPCI405DT.h +++ b/include/configs/CPCI405DT.h @@ -98,6 +98,8 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY + #undef CONFIG_WATCHDOG /* watchdog disabled */ #define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */ diff --git a/include/configs/CPU86.h b/include/configs/CPU86.h index 16a9ea5dd7..1e9a99eed3 100644 --- a/include/configs/CPU86.h +++ b/include/configs/CPU86.h @@ -178,6 +178,8 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY + /* * Miscellaneous configurable options */ diff --git a/include/configs/CPU87.h b/include/configs/CPU87.h index a23d7e50b7..9a98e5c191 100644 --- a/include/configs/CPU87.h +++ b/include/configs/CPU87.h @@ -189,6 +189,8 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY + /* * Miscellaneous configurable options */ diff --git a/include/configs/GEN860T.h b/include/configs/GEN860T.h index de8f7ae711..6613f90a77 100644 --- a/include/configs/GEN860T.h +++ b/include/configs/GEN860T.h @@ -284,6 +284,8 @@ */ #include +#define CFG_NAND_LEGACY + /* * Verbose help from command monitor. */ diff --git a/include/configs/HH405.h b/include/configs/HH405.h index 131c21555d..41a35d2c53 100644 --- a/include/configs/HH405.h +++ b/include/configs/HH405.h @@ -122,6 +122,8 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY + #undef CONFIG_BZIP2 /* include support for bzip2 compressed images */ #undef CONFIG_WATCHDOG /* watchdog disabled */ diff --git a/include/configs/HUB405.h b/include/configs/HUB405.h index eb627e881d..f84e356216 100644 --- a/include/configs/HUB405.h +++ b/include/configs/HUB405.h @@ -135,6 +135,8 @@ * NAND-FLASH stuff *----------------------------------------------------------------------- */ +#define CFG_NAND_LEGACY + #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512 diff --git a/include/configs/MIP405.h b/include/configs/MIP405.h index db2147b481..1f01e7be0b 100644 --- a/include/configs/MIP405.h +++ b/include/configs/MIP405.h @@ -87,6 +87,8 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY + #define CFG_HUSH_PARSER #define CFG_PROMPT_HUSH_PS2 "> " /************************************************************** diff --git a/include/configs/NETPHONE.h b/include/configs/NETPHONE.h index bf4c899592..444f721cc8 100644 --- a/include/configs/NETPHONE.h +++ b/include/configs/NETPHONE.h @@ -491,6 +491,7 @@ /****************************************************************/ /* NAND */ +#define CFG_NAND_LEGACY #define CFG_NAND_BASE NAND_BASE #define CONFIG_MTD_NAND_ECC_JFFS2 #define CONFIG_MTD_NAND_VERIFY_WRITE diff --git a/include/configs/NETTA2.h b/include/configs/NETTA2.h index 529cb4cbae..e20e72495c 100644 --- a/include/configs/NETTA2.h +++ b/include/configs/NETTA2.h @@ -491,6 +491,7 @@ /****************************************************************/ /* NAND */ +#define CFG_NAND_LEGACY #define CFG_NAND_BASE NAND_BASE #define CONFIG_MTD_NAND_ECC_JFFS2 #define CONFIG_MTD_NAND_VERIFY_WRITE diff --git a/include/configs/NETVIA.h b/include/configs/NETVIA.h index dc6b15fcdc..e30be0987a 100644 --- a/include/configs/NETVIA.h +++ b/include/configs/NETVIA.h @@ -387,6 +387,8 @@ /*****************************************************************************/ +#define CFG_NAND_LEGACY + #if defined(CONFIG_NETVIA_VERSION) && CONFIG_NETVIA_VERSION >= 2 /* NAND */ diff --git a/include/configs/PCIPPC2.h b/include/configs/PCIPPC2.h index d03706e193..3a97fbcbde 100644 --- a/include/configs/PCIPPC2.h +++ b/include/configs/PCIPPC2.h @@ -77,6 +77,7 @@ */ #include +#define CFG_NAND_LEGACY /* * Miscellaneous configurable options diff --git a/include/configs/PCIPPC6.h b/include/configs/PCIPPC6.h index 92b2f7cf83..130beb78e6 100644 --- a/include/configs/PCIPPC6.h +++ b/include/configs/PCIPPC6.h @@ -79,6 +79,7 @@ */ #include +#define CFG_NAND_LEGACY /* * Miscellaneous configurable options diff --git a/include/configs/PIP405.h b/include/configs/PIP405.h index 9668fb0ce2..091b768a99 100644 --- a/include/configs/PIP405.h +++ b/include/configs/PIP405.h @@ -69,6 +69,8 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY + #define CFG_HUSH_PARSER #define CFG_PROMPT_HUSH_PS2 "> " /************************************************************** diff --git a/include/configs/PLU405.h b/include/configs/PLU405.h index 54ecfa4c5e..dd5d831680 100644 --- a/include/configs/PLU405.h +++ b/include/configs/PLU405.h @@ -160,6 +160,8 @@ * NAND-FLASH stuff *----------------------------------------------------------------------- */ +#define CFG_NAND_LEGACY + #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512 diff --git a/include/configs/PM520.h b/include/configs/PM520.h index e73ad5100c..9c241e67e7 100644 --- a/include/configs/PM520.h +++ b/include/configs/PM520.h @@ -101,6 +101,8 @@ #define ADD_DOC_CMD 0 #else #define ADD_DOC_CMD CFG_CMD_DOC +/* DoC requires legacy NAND for now */ +#define CFG_NAND_LEGACY #endif /* diff --git a/include/configs/PM826.h b/include/configs/PM826.h index 6e5e3bbe18..88fdb51ade 100644 --- a/include/configs/PM826.h +++ b/include/configs/PM826.h @@ -180,6 +180,8 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY + /* * Disk-On-Chip configuration */ diff --git a/include/configs/PM828.h b/include/configs/PM828.h index 982a1f8143..37ee9771b5 100644 --- a/include/configs/PM828.h +++ b/include/configs/PM828.h @@ -183,6 +183,7 @@ /* * Disk-On-Chip configuration */ +#define CFG_NAND_LEGACY #define CFG_DOC_SHORT_TIMEOUT #define CFG_MAX_DOC_DEVICE 1 /* Max number of DOC devices */ diff --git a/include/configs/PPChameleonEVB.h b/include/configs/PPChameleonEVB.h index c406c8f4bc..88e6db491b 100644 --- a/include/configs/PPChameleonEVB.h +++ b/include/configs/PPChameleonEVB.h @@ -188,36 +188,31 @@ * NAND-FLASH stuff *----------------------------------------------------------------------- */ +/* + * nand device 1 on dave (PPChameleonEVB) needs more time, + * so we just introduce additional wait in nand_wait(), + * effectively for both devices. + */ +#define PPCHAMELON_NAND_TIMER_HACK -/* Use the new NAND code. (BOARDLIBS = drivers/nand/libnand.a required) */ -#define CONFIG_NEW_NAND_CODE #define CFG_NAND0_BASE 0xFF400000 #define CFG_NAND1_BASE 0xFF000000 #define CFG_NAND_BASE_LIST { CFG_NAND0_BASE, CFG_NAND1_BASE } #define NAND_BIG_DELAY_US 25 #define CFG_MAX_NAND_DEVICE 2 /* Max number of NAND devices */ -#define SECTORSIZE 512 -#define NAND_NO_RB -#define ADDR_COLUMN 1 -#define ADDR_PAGE 2 -#define ADDR_COLUMN_PAGE 3 - -#define NAND_ChipID_UNKNOWN 0x00 -#define NAND_MAX_FLOORS 1 #define NAND_MAX_CHIPS 1 #define CFG_NAND0_CE (0x80000000 >> 1) /* our CE is GPIO1 */ +#define CFG_NAND0_RDY (0x80000000 >> 4) /* our RDY is GPIO4 */ #define CFG_NAND0_CLE (0x80000000 >> 2) /* our CLE is GPIO2 */ #define CFG_NAND0_ALE (0x80000000 >> 3) /* our ALE is GPIO3 */ -#define CFG_NAND0_RDY (0x80000000 >> 4) /* our RDY is GPIO4 */ #define CFG_NAND1_CE (0x80000000 >> 14) /* our CE is GPIO14 */ +#define CFG_NAND1_RDY (0x80000000 >> 31) /* our RDY is GPIO31 */ #define CFG_NAND1_CLE (0x80000000 >> 15) /* our CLE is GPIO15 */ #define CFG_NAND1_ALE (0x80000000 >> 16) /* our ALE is GPIO16 */ -#define CFG_NAND1_RDY (0x80000000 >> 31) /* our RDY is GPIO31 */ -#ifdef CONFIG_NEW_NAND_CODE #define MACRO_NAND_DISABLE_CE(nandptr) do \ { \ switch((unsigned long)nandptr) \ @@ -293,83 +288,19 @@ break; \ } \ } while(0) -#else -#define NAND_DISABLE_CE(nand) do \ -{ \ - switch((unsigned long)(((struct nand_chip *)nand)->IO_ADDR)) \ - { \ - case CFG_NAND0_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND0_CE); \ - break; \ - case CFG_NAND1_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND1_CE); \ - break; \ - } \ -} while(0) -#define NAND_ENABLE_CE(nand) do \ -{ \ - switch((unsigned long)(((struct nand_chip *)nand)->IO_ADDR)) \ - { \ - case CFG_NAND0_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND0_CE); \ - break; \ - case CFG_NAND1_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND1_CE); \ - break; \ - } \ -} while(0) +#if 0 +#define SECTORSIZE 512 +#define NAND_NO_RB -#define NAND_CTL_CLRALE(nandptr) do \ -{ \ - switch((unsigned long)nandptr) \ - { \ - case CFG_NAND0_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND0_ALE); \ - break; \ - case CFG_NAND1_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND1_ALE); \ - break; \ - } \ -} while(0) +#define ADDR_COLUMN 1 +#define ADDR_PAGE 2 +#define ADDR_COLUMN_PAGE 3 -#define NAND_CTL_SETALE(nandptr) do \ -{ \ - switch((unsigned long)nandptr) \ - { \ - case CFG_NAND0_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND0_ALE); \ - break; \ - case CFG_NAND1_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND1_ALE); \ - break; \ - } \ -} while(0) +#define NAND_ChipID_UNKNOWN 0x00 +#define NAND_MAX_FLOORS 1 -#define NAND_CTL_CLRCLE(nandptr) do \ -{ \ - switch((unsigned long)nandptr) \ - { \ - case CFG_NAND0_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND0_CLE); \ - break; \ - case CFG_NAND1_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND1_CLE); \ - break; \ - } \ -} while(0) -#define NAND_CTL_SETCLE(nandptr) do { \ - switch((unsigned long)nandptr) { \ - case CFG_NAND0_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND0_CLE); \ - break; \ - case CFG_NAND1_BASE: \ - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND1_CLE); \ - break; \ - } \ -} while(0) -#endif /* !CONFIG_NEW_NAND_CODE */ #ifdef NAND_NO_RB /* constant delay (see also tR in the datasheet) */ @@ -385,7 +316,7 @@ #define WRITE_NAND_ADDRESS(d, adr) do{ *(volatile __u8 *)((unsigned long)adr) = (__u8)(d); } while(0) #define WRITE_NAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr) = (__u8)d; } while(0) #define READ_NAND(adr) ((volatile unsigned char)(*(volatile __u8 *)(unsigned long)adr)) - +#endif /*----------------------------------------------------------------------- * PCI stuff *----------------------------------------------------------------------- diff --git a/include/configs/RBC823.h b/include/configs/RBC823.h index 242c837a3b..21945a343c 100644 --- a/include/configs/RBC823.h +++ b/include/configs/RBC823.h @@ -326,6 +326,8 @@ /************************************************************ * Disk-On-Chip configuration ************************************************************/ +#define CFG_NAND_LEGACY + #define CFG_MAX_DOC_DEVICE 1 /* Max number of DOC devices */ #define CFG_DOC_SHORT_TIMEOUT #define CFG_DOC_SUPPORT_2000 diff --git a/include/configs/SXNI855T.h b/include/configs/SXNI855T.h index c1c765f39d..a8454d99fc 100644 --- a/include/configs/SXNI855T.h +++ b/include/configs/SXNI855T.h @@ -183,6 +183,7 @@ */ /* NAND flash support */ +#define CFG_NAND_LEGACY #define CONFIG_MTD_NAND_ECC_JFFS2 #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512 diff --git a/include/configs/VOH405.h b/include/configs/VOH405.h index 3ca137e53a..96f3d26cc5 100644 --- a/include/configs/VOH405.h +++ b/include/configs/VOH405.h @@ -141,6 +141,8 @@ * NAND-FLASH stuff *----------------------------------------------------------------------- */ +#define CFG_NAND_LEGACY + #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512 diff --git a/include/configs/WUH405.h b/include/configs/WUH405.h index d92f81f78e..faf855d249 100644 --- a/include/configs/WUH405.h +++ b/include/configs/WUH405.h @@ -133,6 +133,8 @@ * NAND-FLASH stuff *----------------------------------------------------------------------- */ +#define CFG_NAND_LEGACY + #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512 diff --git a/include/configs/bamboo.h b/include/configs/bamboo.h index eacc74446c..6d3282150d 100644 --- a/include/configs/bamboo.h +++ b/include/configs/bamboo.h @@ -43,6 +43,7 @@ * 2nd ethernet port you have to "undef" the following define. */ #define CONFIG_BAMBOO_NAND 1 /* enable nand flash support */ +#define CFG_NAND_LEGACY /*----------------------------------------------------------------------- * Base addresses -- Note these are effective addresses where the diff --git a/include/configs/netstar.h b/include/configs/netstar.h index 30d2654732..697796a114 100644 --- a/include/configs/netstar.h +++ b/include/configs/netstar.h @@ -130,8 +130,8 @@ * NAND flash */ #define CFG_MAX_NAND_DEVICE 1 +#define NAND_MAX_CHIPS 1 #define CFG_NAND_BASE 0x04000000 + (2 << 23) -#define CONFIG_NEW_NAND_CODE /* * JFFS2 partitions (mtdparts command line support) diff --git a/include/configs/svm_sc8xx.h b/include/configs/svm_sc8xx.h index 7118f3f74b..92ee8cb333 100644 --- a/include/configs/svm_sc8xx.h +++ b/include/configs/svm_sc8xx.h @@ -141,6 +141,7 @@ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include +#define CFG_NAND_LEGACY /* * Miscellaneous configurable options diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index b0894c5e83..c105ecc3ac 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -2,10 +2,10 @@ * linux/include/linux/mtd/nand.h * * Copyright (c) 2000 David Woodhouse - * Steven J. Hill - * Thomas Gleixner + * Steven J. Hill + * Thomas Gleixner * - * $Id: nand.h,v 1.7 2003/07/24 23:30:46 a0384864 Exp $ + * $Id: nand.h,v 1.68 2004/11/12 10:40:37 gleixner Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -32,13 +32,66 @@ * command delay times for different chips * 04-28-2002 TG OOB config defines moved from nand.c to avoid duplicate * defines in jffs2/wbuf.c + * 08-07-2002 TG forced bad block location to byte 5 of OOB, even if + * CONFIG_MTD_NAND_ECC_JFFS2 is not set + * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC + * + * 08-29-2002 tglx nand_chip structure: data_poi for selecting + * internal / fs-driver buffer + * support for 6byte/512byte hardware ECC + * read_ecc, write_ecc extended for different oob-layout + * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB, + * NAND_YAFFS_OOB + * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL + * Split manufacturer and device ID structures + * + * 02-08-2004 tglx added option field to nand structure for chip anomalities + * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id + * update of nand_chip structure description */ #ifndef __LINUX_MTD_NAND_H #define __LINUX_MTD_NAND_H -#ifdef CONFIG_NEW_NAND_CODE -#include "nand_new.h" -#else +#include +#include + +struct mtd_info; +/* Scan and identify a NAND device */ +extern int nand_scan (struct mtd_info *mtd, int max_chips); +/* Free resources held by the NAND device */ +extern void nand_release (struct mtd_info *mtd); + +/* Read raw data from the device without ECC */ +extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen); + + + +/* This constant declares the max. oobsize / page, which + * is supported now. If you add a chip with bigger oobsize/page + * adjust this accordingly. + */ +#define NAND_MAX_OOBSIZE 64 + +/* + * Constants for hardware specific CLE/ALE/NCE function +*/ +/* Select the chip by setting nCE to low */ +#define NAND_CTL_SETNCE 1 +/* Deselect the chip by setting nCE to high */ +#define NAND_CTL_CLRNCE 2 +/* Select the command latch by setting CLE to high */ +#define NAND_CTL_SETCLE 3 +/* Deselect the command latch by setting CLE to low */ +#define NAND_CTL_CLRCLE 4 +/* Select the address latch by setting ALE to high */ +#define NAND_CTL_SETALE 5 +/* Deselect the address latch by setting ALE to low */ +#define NAND_CTL_CLRALE 6 +/* Set write protection by setting WP to high. Not used! */ +#define NAND_CTL_SETWP 7 +/* Clear write protection by setting WP to low. Not used! */ +#define NAND_CTL_CLRWP 8 + /* * Standard NAND flash commands */ @@ -48,12 +101,104 @@ #define NAND_CMD_READOOB 0x50 #define NAND_CMD_ERASE1 0x60 #define NAND_CMD_STATUS 0x70 +#define NAND_CMD_STATUS_MULTI 0x71 #define NAND_CMD_SEQIN 0x80 #define NAND_CMD_READID 0x90 #define NAND_CMD_ERASE2 0xd0 #define NAND_CMD_RESET 0xff +/* Extended commands for large page devices */ +#define NAND_CMD_READSTART 0x30 +#define NAND_CMD_CACHEDPROG 0x15 + +/* Status bits */ +#define NAND_STATUS_FAIL 0x01 +#define NAND_STATUS_FAIL_N1 0x02 +#define NAND_STATUS_TRUE_READY 0x20 +#define NAND_STATUS_READY 0x40 +#define NAND_STATUS_WP 0x80 + /* + * Constants for ECC_MODES + */ + +/* No ECC. Usage is not recommended ! */ +#define NAND_ECC_NONE 0 +/* Software ECC 3 byte ECC per 256 Byte data */ +#define NAND_ECC_SOFT 1 +/* Hardware ECC 3 byte ECC per 256 Byte data */ +#define NAND_ECC_HW3_256 2 +/* Hardware ECC 3 byte ECC per 512 Byte data */ +#define NAND_ECC_HW3_512 3 +/* Hardware ECC 3 byte ECC per 512 Byte data */ +#define NAND_ECC_HW6_512 4 +/* Hardware ECC 8 byte ECC per 512 Byte data */ +#define NAND_ECC_HW8_512 6 +/* Hardware ECC 12 byte ECC per 2048 Byte data */ +#define NAND_ECC_HW12_2048 7 + +/* + * Constants for Hardware ECC +*/ +/* Reset Hardware ECC for read */ +#define NAND_ECC_READ 0 +/* Reset Hardware ECC for write */ +#define NAND_ECC_WRITE 1 +/* Enable Hardware ECC before syndrom is read back from flash */ +#define NAND_ECC_READSYN 2 + +/* Option constants for bizarre disfunctionality and real +* features +*/ +/* Chip can not auto increment pages */ +#define NAND_NO_AUTOINCR 0x00000001 +/* Buswitdh is 16 bit */ +#define NAND_BUSWIDTH_16 0x00000002 +/* Device supports partial programming without padding */ +#define NAND_NO_PADDING 0x00000004 +/* Chip has cache program function */ +#define NAND_CACHEPRG 0x00000008 +/* Chip has copy back function */ +#define NAND_COPYBACK 0x00000010 +/* AND Chip which has 4 banks and a confusing page / block + * assignment. See Renesas datasheet for further information */ +#define NAND_IS_AND 0x00000020 +/* Chip has a array of 4 pages which can be read without + * additional ready /busy waits */ +#define NAND_4PAGE_ARRAY 0x00000040 + +/* Options valid for Samsung large page devices */ +#define NAND_SAMSUNG_LP_OPTIONS \ + (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK) + +/* Macros to identify the above */ +#define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR)) +#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING)) +#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) +#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK)) + +/* Mask to zero out the chip options, which come from the id table */ +#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR) + +/* Non chip related options */ +/* Use a flash based bad block table. This option is passed to the + * default bad block table function. */ +#define NAND_USE_FLASH_BBT 0x00010000 +/* The hw ecc generator provides a syndrome instead a ecc value on read + * This can only work if we have the ecc bytes directly behind the + * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ +#define NAND_HWECC_SYNDROME 0x00020000 + + +/* Options set by nand scan */ +/* Nand scan has allocated oob_buf */ +#define NAND_OOBBUF_ALLOC 0x40000000 +/* Nand scan has allocated data_buf */ +#define NAND_DATABUF_ALLOC 0x80000000 + + +/* + * nand_state_t - chip states * Enumeration for NAND flash chip state */ typedef enum { @@ -61,71 +206,138 @@ typedef enum { FL_READING, FL_WRITING, FL_ERASING, - FL_SYNCING + FL_SYNCING, + FL_CACHEDPRG, } nand_state_t; +/* Keep gcc happy */ +struct nand_chip; -/* - * NAND Private Flash Chip Data - * - * Structure overview: - * - * IO_ADDR - address to access the 8 I/O lines of the flash device - * - * hwcontrol - hardwarespecific function for accesing control-lines - * - * dev_ready - hardwarespecific function for accesing device ready/busy line - * - * chip_lock - spinlock used to protect access to this structure - * - * wq - wait queue to sleep on if a NAND operation is in progress - * - * state - give the current state of the NAND device - * - * page_shift - number of address bits in a page (column address bits) - * - * data_buf - data buffer passed to/from MTD user modules - * - * data_cache - data cache for redundant page access and shadow for - * ECC failure - * - * ecc_code_buf - used only for holding calculated or read ECCs for - * a page read or written when ECC is in use - * - * reserved - padding to make structure fall on word boundary if - * when ECC is in use +#if 0 +/** + * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices + * @lock: protection lock + * @active: the mtd device which holds the controller currently */ -struct Nand { - char floor, chip; - unsigned long curadr; - unsigned char curmode; - /* Also some erase/write/pipeline info when we get that far */ +struct nand_hw_control { + spinlock_t lock; + struct nand_chip *active; }; +#endif + +/** + * struct nand_chip - NAND Private Flash Chip Data + * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device + * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device + * @read_byte: [REPLACEABLE] read one byte from the chip + * @write_byte: [REPLACEABLE] write one byte to the chip + * @read_word: [REPLACEABLE] read one word from the chip + * @write_word: [REPLACEABLE] write one word to the chip + * @write_buf: [REPLACEABLE] write data from the buffer to the chip + * @read_buf: [REPLACEABLE] read data from the chip into the buffer + * @verify_buf: [REPLACEABLE] verify buffer contents against the chip data + * @select_chip: [REPLACEABLE] select chip nr + * @block_bad: [REPLACEABLE] check, if the block is bad + * @block_markbad: [REPLACEABLE] mark the block bad + * @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines + * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line + * If set to NULL no access to ready/busy is available and the ready/busy information + * is read from the chip status register + * @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip + * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready + * @calculate_ecc: [REPLACEABLE] function for ecc calculation or readback from ecc hardware + * @correct_data: [REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw) + * @enable_hwecc: [BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only + * be provided if a hardware ECC is available + * @erase_cmd: [INTERN] erase command write function, selectable due to AND support + * @scan_bbt: [REPLACEABLE] function to scan bad block table + * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines + * @eccsize: [INTERN] databytes used per ecc-calculation + * @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step + * @eccsteps: [INTERN] number of ecc calculation steps per page + * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR) + * @chip_lock: [INTERN] spinlock used to protect access to this structure and the chip + * @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress + * @state: [INTERN] the current state of the NAND device + * @page_shift: [INTERN] number of address bits in a page (column address bits) + * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock + * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry + * @chip_shift: [INTERN] number of address bits in one chip + * @data_buf: [INTERN] internal buffer for one page + oob + * @oob_buf: [INTERN] oob buffer for one eraseblock + * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized + * @data_poi: [INTERN] pointer to a data buffer + * @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about + * special functionality. See the defines for further explanation + * @badblockpos: [INTERN] position of the bad block marker in the oob area + * @numchips: [INTERN] number of physical chips + * @chipsize: [INTERN] the size of one chip for multichip arrays + * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 + * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf + * @autooob: [REPLACEABLE] the default (auto)placement scheme + * @bbt: [INTERN] bad block table pointer + * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup + * @bbt_md: [REPLACEABLE] bad block table mirror descriptor + * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan + * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices + * @priv: [OPTIONAL] pointer to private chip date + */ struct nand_chip { + void __iomem *IO_ADDR_R; + void __iomem *IO_ADDR_W; + + u_char (*read_byte)(struct mtd_info *mtd); + void (*write_byte)(struct mtd_info *mtd, u_char byte); + u16 (*read_word)(struct mtd_info *mtd); + void (*write_word)(struct mtd_info *mtd, u16 word); + + void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); + void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len); + int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len); + void (*select_chip)(struct mtd_info *mtd, int chip); + int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); + int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); + void (*hwcontrol)(struct mtd_info *mtd, int cmd); + int (*dev_ready)(struct mtd_info *mtd); + void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); + int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); + int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); + int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); + void (*enable_hwecc)(struct mtd_info *mtd, int mode); + void (*erase_cmd)(struct mtd_info *mtd, int page); + int (*scan_bbt)(struct mtd_info *mtd); + int eccmode; + int eccsize; + int eccbytes; + int eccsteps; + int chip_delay; +#if 0 + spinlock_t chip_lock; + wait_queue_head_t wq; + nand_state_t state; +#endif int page_shift; + int phys_erase_shift; + int bbt_erase_shift; + int chip_shift; u_char *data_buf; - u_char *data_cache; - int cache_page; - u_char ecc_code_buf[6]; - u_char reserved[2]; - char ChipID; /* Type of DiskOnChip */ - struct Nand *chips; - int chipshift; - char* chips_name; - unsigned long erasesize; - unsigned long mfr; /* Flash IDs - only one type of flash per device */ - unsigned long id; - char* name; - int numchips; - char page256; - char pageadrlen; - unsigned long IO_ADDR; /* address to access the 8 I/O lines to the flash device */ - unsigned long totlen; - uint oobblock; /* Size of OOB blocks (e.g. 512) */ - uint oobsize; /* Amount of OOB data per block (e.g. 16) */ - uint eccsize; - int bus16; + u_char *oob_buf; + int oobdirty; + u_char *data_poi; + unsigned int options; + int badblockpos; + int numchips; + unsigned long chipsize; + int pagemask; + int pagebuf; + struct nand_oobinfo *autooob; + uint8_t *bbt; + struct nand_bbt_descr *bbt_td; + struct nand_bbt_descr *bbt_md; + struct nand_bbt_descr *badblock_pattern; + struct nand_hw_control *controller; + void *priv; }; /* @@ -133,71 +345,125 @@ struct nand_chip { */ #define NAND_MFR_TOSHIBA 0x98 #define NAND_MFR_SAMSUNG 0xec +#define NAND_MFR_FUJITSU 0x04 +#define NAND_MFR_NATIONAL 0x8f +#define NAND_MFR_RENESAS 0x07 +#define NAND_MFR_STMICRO 0x20 -/* - * NAND Flash Device ID Structure +/** + * struct nand_flash_dev - NAND Flash Device ID Structure * - * Structure overview: - * - * name - Complete name of device - * - * manufacture_id - manufacturer ID code of device. - * - * model_id - model ID code of device. - * - * chipshift - total number of address bits for the device which - * is used to calculate address offsets and the total - * number of bytes the device is capable of. - * - * page256 - denotes if flash device has 256 byte pages or not. - * - * pageadrlen - number of bytes minus one needed to hold the - * complete address into the flash array. Keep in - * mind that when a read or write is done to a - * specific address, the address is input serially - * 8 bits at a time. This structure member is used - * by the read/write routines as a loop index for - * shifting the address out 8 bits at a time. - * - * erasesize - size of an erase block in the flash device. + * @name: Identify the device type + * @id: device ID code + * @pagesize: Pagesize in bytes. Either 256 or 512 or 0 + * If the pagesize is 0, then the real pagesize + * and the eraseize are determined from the + * extended id bytes in the chip + * @erasesize: Size of an erase block in the flash device. + * @chipsize: Total chipsize in Mega Bytes + * @options: Bitfield to store chip relevant options */ struct nand_flash_dev { - char * name; - int manufacture_id; - int model_id; - int chipshift; - char page256; - char pageadrlen; + char *name; + int id; + unsigned long pagesize; + unsigned long chipsize; unsigned long erasesize; - int bus16; + unsigned long options; }; +/** + * struct nand_manufacturers - NAND Flash Manufacturer ID Structure + * @name: Manufacturer name + * @id: manufacturer ID code of device. +*/ +struct nand_manufacturers { + int id; + char * name; +}; + +extern struct nand_flash_dev nand_flash_ids[]; +extern struct nand_manufacturers nand_manuf_ids[]; + +/** + * struct nand_bbt_descr - bad block table descriptor + * @options: options for this descriptor + * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE + * when bbt is searched, then we store the found bbts pages here. + * Its an array and supports up to 8 chips now + * @offs: offset of the pattern in the oob area of the page + * @veroffs: offset of the bbt version counter in the oob are of the page + * @version: version read from the bbt page during scan + * @len: length of the pattern, if 0 no pattern check is performed + * @maxblocks: maximum number of blocks to search for a bbt. This number of + * blocks is reserved at the end of the device where the tables are + * written. + * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than + * bad) block in the stored bbt + * @pattern: pattern to identify bad block table or factory marked good / + * bad blocks, can be NULL, if len = 0 + * + * Descriptor for the bad block table marker and the descriptor for the + * pattern which identifies good and bad blocks. The assumption is made + * that the pattern and the version count are always located in the oob area + * of the first block. + */ +struct nand_bbt_descr { + int options; + int pages[NAND_MAX_CHIPS]; + int offs; + int veroffs; + uint8_t version[NAND_MAX_CHIPS]; + int len; + int maxblocks; + int reserved_block_code; + uint8_t *pattern; +}; + +/* Options for the bad block table descriptors */ + +/* The number of bits used per block in the bbt on the device */ +#define NAND_BBT_NRBITS_MSK 0x0000000F +#define NAND_BBT_1BIT 0x00000001 +#define NAND_BBT_2BIT 0x00000002 +#define NAND_BBT_4BIT 0x00000004 +#define NAND_BBT_8BIT 0x00000008 +/* The bad block table is in the last good block of the device */ +#define NAND_BBT_LASTBLOCK 0x00000010 +/* The bbt is at the given page, else we must scan for the bbt */ +#define NAND_BBT_ABSPAGE 0x00000020 +/* The bbt is at the given page, else we must scan for the bbt */ +#define NAND_BBT_SEARCH 0x00000040 +/* bbt is stored per chip on multichip devices */ +#define NAND_BBT_PERCHIP 0x00000080 +/* bbt has a version counter at offset veroffs */ +#define NAND_BBT_VERSION 0x00000100 +/* Create a bbt if none axists */ +#define NAND_BBT_CREATE 0x00000200 +/* Search good / bad pattern through all pages of a block */ +#define NAND_BBT_SCANALLPAGES 0x00000400 +/* Scan block empty during good / bad block scan */ +#define NAND_BBT_SCANEMPTY 0x00000800 +/* Write bbt if neccecary */ +#define NAND_BBT_WRITE 0x00001000 +/* Read and write back block contents when writing bbt */ +#define NAND_BBT_SAVECONTENT 0x00002000 +/* Search good / bad pattern on the first and the second page */ +#define NAND_BBT_SCAN2NDPAGE 0x00004000 + +/* The maximum number of blocks to scan for a bbt */ +#define NAND_BBT_SCAN_MAXBLOCKS 4 + +extern int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd); +extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs); +extern int nand_default_bbt (struct mtd_info *mtd); +extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt); +extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt); + /* * Constants for oob configuration */ -#define NAND_NOOB_ECCPOS0 0 -#define NAND_NOOB_ECCPOS1 1 -#define NAND_NOOB_ECCPOS2 2 -#define NAND_NOOB_ECCPOS3 3 -#define NAND_NOOB_ECCPOS4 6 -#define NAND_NOOB_ECCPOS5 7 -#define NAND_NOOB_BADBPOS -1 -#define NAND_NOOB_ECCVPOS -1 +#define NAND_SMALL_BADBLOCK_POS 5 +#define NAND_LARGE_BADBLOCK_POS 0 -#define NAND_JFFS2_OOB_ECCPOS0 0 -#define NAND_JFFS2_OOB_ECCPOS1 1 -#define NAND_JFFS2_OOB_ECCPOS2 2 -#define NAND_JFFS2_OOB_ECCPOS3 3 -#define NAND_JFFS2_OOB_ECCPOS4 6 -#define NAND_JFFS2_OOB_ECCPOS5 7 -#define NAND_JFFS2_OOB_BADBPOS 5 -#define NAND_JFFS2_OOB_ECCVPOS 4 - -#define NAND_JFFS2_OOB8_FSDAPOS 6 -#define NAND_JFFS2_OOB16_FSDAPOS 8 -#define NAND_JFFS2_OOB8_FSDALEN 2 -#define NAND_JFFS2_OOB16_FSDALEN 8 - -unsigned long nand_probe(unsigned long physadr); -#endif /* !CONFIG_NEW_NAND_CODE */ #endif /* __LINUX_MTD_NAND_H */ diff --git a/include/linux/mtd/nand_ids.h b/include/linux/mtd/nand_ids.h index 75c305b569..d9eb911828 100644 --- a/include/linux/mtd/nand_ids.h +++ b/include/linux/mtd/nand_ids.h @@ -28,6 +28,10 @@ #ifndef __LINUX_MTD_NAND_IDS_H #define __LINUX_MTD_NAND_IDS_H +#ifndef CFG_NAND_LEGACY +#error This module is for the legacy NAND support +#endif + static struct nand_flash_dev nand_flash_ids[] = { {"Toshiba TC5816BDC", NAND_MFR_TOSHIBA, 0x64, 21, 1, 2, 0x1000, 0}, {"Toshiba TC5832DC", NAND_MFR_TOSHIBA, 0x6b, 22, 0, 2, 0x2000, 0}, diff --git a/include/linux/mtd/nand_legacy.h b/include/linux/mtd/nand_legacy.h new file mode 100644 index 0000000000..a8769e72ad --- /dev/null +++ b/include/linux/mtd/nand_legacy.h @@ -0,0 +1,203 @@ +/* + * linux/include/linux/mtd/nand.h + * + * Copyright (c) 2000 David Woodhouse + * Steven J. Hill + * Thomas Gleixner + * + * $Id: nand.h,v 1.7 2003/07/24 23:30:46 a0384864 Exp $ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Info: + * Contains standard defines and IDs for NAND flash devices + * + * Changelog: + * 01-31-2000 DMW Created + * 09-18-2000 SJH Moved structure out of the Disk-On-Chip drivers + * so it can be used by other NAND flash device + * drivers. I also changed the copyright since none + * of the original contents of this file are specific + * to DoC devices. David can whack me with a baseball + * bat later if I did something naughty. + * 10-11-2000 SJH Added private NAND flash structure for driver + * 10-24-2000 SJH Added prototype for 'nand_scan' function + * 10-29-2001 TG changed nand_chip structure to support + * hardwarespecific function for accessing control lines + * 02-21-2002 TG added support for different read/write adress and + * ready/busy line access function + * 02-26-2002 TG added chip_delay to nand_chip structure to optimize + * command delay times for different chips + * 04-28-2002 TG OOB config defines moved from nand.c to avoid duplicate + * defines in jffs2/wbuf.c + */ +#ifndef __LINUX_MTD_NAND_LEGACY_H +#define __LINUX_MTD_NAND_LEGACY_H + +#ifndef CFG_NAND_LEGACY +#error This module is for the legacy NAND support +#endif + +/* + * Standard NAND flash commands + */ +#define NAND_CMD_READ0 0 +#define NAND_CMD_READ1 1 +#define NAND_CMD_PAGEPROG 0x10 +#define NAND_CMD_READOOB 0x50 +#define NAND_CMD_ERASE1 0x60 +#define NAND_CMD_STATUS 0x70 +#define NAND_CMD_SEQIN 0x80 +#define NAND_CMD_READID 0x90 +#define NAND_CMD_ERASE2 0xd0 +#define NAND_CMD_RESET 0xff + +/* + * Enumeration for NAND flash chip state + */ +typedef enum { + FL_READY, + FL_READING, + FL_WRITING, + FL_ERASING, + FL_SYNCING +} nand_state_t; + + +/* + * NAND Private Flash Chip Data + * + * Structure overview: + * + * IO_ADDR - address to access the 8 I/O lines of the flash device + * + * hwcontrol - hardwarespecific function for accesing control-lines + * + * dev_ready - hardwarespecific function for accesing device ready/busy line + * + * chip_lock - spinlock used to protect access to this structure + * + * wq - wait queue to sleep on if a NAND operation is in progress + * + * state - give the current state of the NAND device + * + * page_shift - number of address bits in a page (column address bits) + * + * data_buf - data buffer passed to/from MTD user modules + * + * data_cache - data cache for redundant page access and shadow for + * ECC failure + * + * ecc_code_buf - used only for holding calculated or read ECCs for + * a page read or written when ECC is in use + * + * reserved - padding to make structure fall on word boundary if + * when ECC is in use + */ +struct Nand { + char floor, chip; + unsigned long curadr; + unsigned char curmode; + /* Also some erase/write/pipeline info when we get that far */ +}; + +struct nand_chip { + int page_shift; + u_char *data_buf; + u_char *data_cache; + int cache_page; + u_char ecc_code_buf[6]; + u_char reserved[2]; + char ChipID; /* Type of DiskOnChip */ + struct Nand *chips; + int chipshift; + char* chips_name; + unsigned long erasesize; + unsigned long mfr; /* Flash IDs - only one type of flash per device */ + unsigned long id; + char* name; + int numchips; + char page256; + char pageadrlen; + unsigned long IO_ADDR; /* address to access the 8 I/O lines to the flash device */ + unsigned long totlen; + uint oobblock; /* Size of OOB blocks (e.g. 512) */ + uint oobsize; /* Amount of OOB data per block (e.g. 16) */ + uint eccsize; + int bus16; +}; + +/* + * NAND Flash Manufacturer ID Codes + */ +#define NAND_MFR_TOSHIBA 0x98 +#define NAND_MFR_SAMSUNG 0xec + +/* + * NAND Flash Device ID Structure + * + * Structure overview: + * + * name - Complete name of device + * + * manufacture_id - manufacturer ID code of device. + * + * model_id - model ID code of device. + * + * chipshift - total number of address bits for the device which + * is used to calculate address offsets and the total + * number of bytes the device is capable of. + * + * page256 - denotes if flash device has 256 byte pages or not. + * + * pageadrlen - number of bytes minus one needed to hold the + * complete address into the flash array. Keep in + * mind that when a read or write is done to a + * specific address, the address is input serially + * 8 bits at a time. This structure member is used + * by the read/write routines as a loop index for + * shifting the address out 8 bits at a time. + * + * erasesize - size of an erase block in the flash device. + */ +struct nand_flash_dev { + char * name; + int manufacture_id; + int model_id; + int chipshift; + char page256; + char pageadrlen; + unsigned long erasesize; + int bus16; +}; + +/* +* Constants for oob configuration +*/ +#define NAND_NOOB_ECCPOS0 0 +#define NAND_NOOB_ECCPOS1 1 +#define NAND_NOOB_ECCPOS2 2 +#define NAND_NOOB_ECCPOS3 3 +#define NAND_NOOB_ECCPOS4 6 +#define NAND_NOOB_ECCPOS5 7 +#define NAND_NOOB_BADBPOS -1 +#define NAND_NOOB_ECCVPOS -1 + +#define NAND_JFFS2_OOB_ECCPOS0 0 +#define NAND_JFFS2_OOB_ECCPOS1 1 +#define NAND_JFFS2_OOB_ECCPOS2 2 +#define NAND_JFFS2_OOB_ECCPOS3 3 +#define NAND_JFFS2_OOB_ECCPOS4 6 +#define NAND_JFFS2_OOB_ECCPOS5 7 +#define NAND_JFFS2_OOB_BADBPOS 5 +#define NAND_JFFS2_OOB_ECCVPOS 4 + +#define NAND_JFFS2_OOB8_FSDAPOS 6 +#define NAND_JFFS2_OOB16_FSDAPOS 8 +#define NAND_JFFS2_OOB8_FSDALEN 2 +#define NAND_JFFS2_OOB16_FSDALEN 8 + +unsigned long nand_probe(unsigned long physadr); +#endif /* __LINUX_MTD_NAND_LEGACY_H */ diff --git a/include/linux/mtd/nand_new.h b/include/linux/mtd/nand_new.h deleted file mode 100644 index 7d4b805b9a..0000000000 --- a/include/linux/mtd/nand_new.h +++ /dev/null @@ -1,469 +0,0 @@ -/* - * linux/include/linux/mtd/nand.h - * - * Copyright (c) 2000 David Woodhouse - * Steven J. Hill - * Thomas Gleixner - * - * $Id: nand.h,v 1.68 2004/11/12 10:40:37 gleixner Exp $ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Info: - * Contains standard defines and IDs for NAND flash devices - * - * Changelog: - * 01-31-2000 DMW Created - * 09-18-2000 SJH Moved structure out of the Disk-On-Chip drivers - * so it can be used by other NAND flash device - * drivers. I also changed the copyright since none - * of the original contents of this file are specific - * to DoC devices. David can whack me with a baseball - * bat later if I did something naughty. - * 10-11-2000 SJH Added private NAND flash structure for driver - * 10-24-2000 SJH Added prototype for 'nand_scan' function - * 10-29-2001 TG changed nand_chip structure to support - * hardwarespecific function for accessing control lines - * 02-21-2002 TG added support for different read/write adress and - * ready/busy line access function - * 02-26-2002 TG added chip_delay to nand_chip structure to optimize - * command delay times for different chips - * 04-28-2002 TG OOB config defines moved from nand.c to avoid duplicate - * defines in jffs2/wbuf.c - * 08-07-2002 TG forced bad block location to byte 5 of OOB, even if - * CONFIG_MTD_NAND_ECC_JFFS2 is not set - * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC - * - * 08-29-2002 tglx nand_chip structure: data_poi for selecting - * internal / fs-driver buffer - * support for 6byte/512byte hardware ECC - * read_ecc, write_ecc extended for different oob-layout - * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB, - * NAND_YAFFS_OOB - * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL - * Split manufacturer and device ID structures - * - * 02-08-2004 tglx added option field to nand structure for chip anomalities - * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id - * update of nand_chip structure description - */ -#ifndef __LINUX_MTD_NAND_NEW_H -#define __LINUX_MTD_NAND_NEW_H - -#include -#include - -struct mtd_info; -/* Scan and identify a NAND device */ -extern int nand_scan (struct mtd_info *mtd, int max_chips); -/* Free resources held by the NAND device */ -extern void nand_release (struct mtd_info *mtd); - -/* Read raw data from the device without ECC */ -extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen); - - - -/* This constant declares the max. oobsize / page, which - * is supported now. If you add a chip with bigger oobsize/page - * adjust this accordingly. - */ -#define NAND_MAX_OOBSIZE 64 - -/* - * Constants for hardware specific CLE/ALE/NCE function -*/ -/* Select the chip by setting nCE to low */ -#define NAND_CTL_SETNCE 1 -/* Deselect the chip by setting nCE to high */ -#define NAND_CTL_CLRNCE 2 -/* Select the command latch by setting CLE to high */ -#define NAND_CTL_SETCLE 3 -/* Deselect the command latch by setting CLE to low */ -#define NAND_CTL_CLRCLE 4 -/* Select the address latch by setting ALE to high */ -#define NAND_CTL_SETALE 5 -/* Deselect the address latch by setting ALE to low */ -#define NAND_CTL_CLRALE 6 -/* Set write protection by setting WP to high. Not used! */ -#define NAND_CTL_SETWP 7 -/* Clear write protection by setting WP to low. Not used! */ -#define NAND_CTL_CLRWP 8 - -/* - * Standard NAND flash commands - */ -#define NAND_CMD_READ0 0 -#define NAND_CMD_READ1 1 -#define NAND_CMD_PAGEPROG 0x10 -#define NAND_CMD_READOOB 0x50 -#define NAND_CMD_ERASE1 0x60 -#define NAND_CMD_STATUS 0x70 -#define NAND_CMD_STATUS_MULTI 0x71 -#define NAND_CMD_SEQIN 0x80 -#define NAND_CMD_READID 0x90 -#define NAND_CMD_ERASE2 0xd0 -#define NAND_CMD_RESET 0xff - -/* Extended commands for large page devices */ -#define NAND_CMD_READSTART 0x30 -#define NAND_CMD_CACHEDPROG 0x15 - -/* Status bits */ -#define NAND_STATUS_FAIL 0x01 -#define NAND_STATUS_FAIL_N1 0x02 -#define NAND_STATUS_TRUE_READY 0x20 -#define NAND_STATUS_READY 0x40 -#define NAND_STATUS_WP 0x80 - -/* - * Constants for ECC_MODES - */ - -/* No ECC. Usage is not recommended ! */ -#define NAND_ECC_NONE 0 -/* Software ECC 3 byte ECC per 256 Byte data */ -#define NAND_ECC_SOFT 1 -/* Hardware ECC 3 byte ECC per 256 Byte data */ -#define NAND_ECC_HW3_256 2 -/* Hardware ECC 3 byte ECC per 512 Byte data */ -#define NAND_ECC_HW3_512 3 -/* Hardware ECC 3 byte ECC per 512 Byte data */ -#define NAND_ECC_HW6_512 4 -/* Hardware ECC 8 byte ECC per 512 Byte data */ -#define NAND_ECC_HW8_512 6 -/* Hardware ECC 12 byte ECC per 2048 Byte data */ -#define NAND_ECC_HW12_2048 7 - -/* - * Constants for Hardware ECC -*/ -/* Reset Hardware ECC for read */ -#define NAND_ECC_READ 0 -/* Reset Hardware ECC for write */ -#define NAND_ECC_WRITE 1 -/* Enable Hardware ECC before syndrom is read back from flash */ -#define NAND_ECC_READSYN 2 - -/* Option constants for bizarre disfunctionality and real -* features -*/ -/* Chip can not auto increment pages */ -#define NAND_NO_AUTOINCR 0x00000001 -/* Buswitdh is 16 bit */ -#define NAND_BUSWIDTH_16 0x00000002 -/* Device supports partial programming without padding */ -#define NAND_NO_PADDING 0x00000004 -/* Chip has cache program function */ -#define NAND_CACHEPRG 0x00000008 -/* Chip has copy back function */ -#define NAND_COPYBACK 0x00000010 -/* AND Chip which has 4 banks and a confusing page / block - * assignment. See Renesas datasheet for further information */ -#define NAND_IS_AND 0x00000020 -/* Chip has a array of 4 pages which can be read without - * additional ready /busy waits */ -#define NAND_4PAGE_ARRAY 0x00000040 - -/* Options valid for Samsung large page devices */ -#define NAND_SAMSUNG_LP_OPTIONS \ - (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK) - -/* Macros to identify the above */ -#define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR)) -#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING)) -#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) -#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK)) - -/* Mask to zero out the chip options, which come from the id table */ -#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR) - -/* Non chip related options */ -/* Use a flash based bad block table. This option is passed to the - * default bad block table function. */ -#define NAND_USE_FLASH_BBT 0x00010000 -/* The hw ecc generator provides a syndrome instead a ecc value on read - * This can only work if we have the ecc bytes directly behind the - * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ -#define NAND_HWECC_SYNDROME 0x00020000 - - -/* Options set by nand scan */ -/* Nand scan has allocated oob_buf */ -#define NAND_OOBBUF_ALLOC 0x40000000 -/* Nand scan has allocated data_buf */ -#define NAND_DATABUF_ALLOC 0x80000000 - - -/* - * nand_state_t - chip states - * Enumeration for NAND flash chip state - */ -typedef enum { - FL_READY, - FL_READING, - FL_WRITING, - FL_ERASING, - FL_SYNCING, - FL_CACHEDPRG, -} nand_state_t; - -/* Keep gcc happy */ -struct nand_chip; - -#if 0 -/** - * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices - * @lock: protection lock - * @active: the mtd device which holds the controller currently - */ -struct nand_hw_control { - spinlock_t lock; - struct nand_chip *active; -}; -#endif - -/** - * struct nand_chip - NAND Private Flash Chip Data - * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device - * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device - * @read_byte: [REPLACEABLE] read one byte from the chip - * @write_byte: [REPLACEABLE] write one byte to the chip - * @read_word: [REPLACEABLE] read one word from the chip - * @write_word: [REPLACEABLE] write one word to the chip - * @write_buf: [REPLACEABLE] write data from the buffer to the chip - * @read_buf: [REPLACEABLE] read data from the chip into the buffer - * @verify_buf: [REPLACEABLE] verify buffer contents against the chip data - * @select_chip: [REPLACEABLE] select chip nr - * @block_bad: [REPLACEABLE] check, if the block is bad - * @block_markbad: [REPLACEABLE] mark the block bad - * @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines - * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line - * If set to NULL no access to ready/busy is available and the ready/busy information - * is read from the chip status register - * @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip - * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready - * @calculate_ecc: [REPLACEABLE] function for ecc calculation or readback from ecc hardware - * @correct_data: [REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw) - * @enable_hwecc: [BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only - * be provided if a hardware ECC is available - * @erase_cmd: [INTERN] erase command write function, selectable due to AND support - * @scan_bbt: [REPLACEABLE] function to scan bad block table - * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines - * @eccsize: [INTERN] databytes used per ecc-calculation - * @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step - * @eccsteps: [INTERN] number of ecc calculation steps per page - * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR) - * @chip_lock: [INTERN] spinlock used to protect access to this structure and the chip - * @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress - * @state: [INTERN] the current state of the NAND device - * @page_shift: [INTERN] number of address bits in a page (column address bits) - * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock - * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry - * @chip_shift: [INTERN] number of address bits in one chip - * @data_buf: [INTERN] internal buffer for one page + oob - * @oob_buf: [INTERN] oob buffer for one eraseblock - * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized - * @data_poi: [INTERN] pointer to a data buffer - * @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about - * special functionality. See the defines for further explanation - * @badblockpos: [INTERN] position of the bad block marker in the oob area - * @numchips: [INTERN] number of physical chips - * @chipsize: [INTERN] the size of one chip for multichip arrays - * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 - * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf - * @autooob: [REPLACEABLE] the default (auto)placement scheme - * @bbt: [INTERN] bad block table pointer - * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup - * @bbt_md: [REPLACEABLE] bad block table mirror descriptor - * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan - * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices - * @priv: [OPTIONAL] pointer to private chip date - */ - -struct nand_chip { - void __iomem *IO_ADDR_R; - void __iomem *IO_ADDR_W; - - u_char (*read_byte)(struct mtd_info *mtd); - void (*write_byte)(struct mtd_info *mtd, u_char byte); - u16 (*read_word)(struct mtd_info *mtd); - void (*write_word)(struct mtd_info *mtd, u16 word); - - void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); - void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len); - int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len); - void (*select_chip)(struct mtd_info *mtd, int chip); - int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); - int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); - void (*hwcontrol)(struct mtd_info *mtd, int cmd); - int (*dev_ready)(struct mtd_info *mtd); - void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); - int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); - int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); - int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); - void (*enable_hwecc)(struct mtd_info *mtd, int mode); - void (*erase_cmd)(struct mtd_info *mtd, int page); - int (*scan_bbt)(struct mtd_info *mtd); - int eccmode; - int eccsize; - int eccbytes; - int eccsteps; - int chip_delay; -#if 0 - spinlock_t chip_lock; - wait_queue_head_t wq; - nand_state_t state; -#endif - int page_shift; - int phys_erase_shift; - int bbt_erase_shift; - int chip_shift; - u_char *data_buf; - u_char *oob_buf; - int oobdirty; - u_char *data_poi; - unsigned int options; - int badblockpos; - int numchips; - unsigned long chipsize; - int pagemask; - int pagebuf; - struct nand_oobinfo *autooob; - uint8_t *bbt; - struct nand_bbt_descr *bbt_td; - struct nand_bbt_descr *bbt_md; - struct nand_bbt_descr *badblock_pattern; - struct nand_hw_control *controller; - void *priv; -}; - -/* - * NAND Flash Manufacturer ID Codes - */ -#define NAND_MFR_TOSHIBA 0x98 -#define NAND_MFR_SAMSUNG 0xec -#define NAND_MFR_FUJITSU 0x04 -#define NAND_MFR_NATIONAL 0x8f -#define NAND_MFR_RENESAS 0x07 -#define NAND_MFR_STMICRO 0x20 - -/** - * struct nand_flash_dev - NAND Flash Device ID Structure - * - * @name: Identify the device type - * @id: device ID code - * @pagesize: Pagesize in bytes. Either 256 or 512 or 0 - * If the pagesize is 0, then the real pagesize - * and the eraseize are determined from the - * extended id bytes in the chip - * @erasesize: Size of an erase block in the flash device. - * @chipsize: Total chipsize in Mega Bytes - * @options: Bitfield to store chip relevant options - */ -struct nand_flash_dev { - char *name; - int id; - unsigned long pagesize; - unsigned long chipsize; - unsigned long erasesize; - unsigned long options; -}; - -/** - * struct nand_manufacturers - NAND Flash Manufacturer ID Structure - * @name: Manufacturer name - * @id: manufacturer ID code of device. -*/ -struct nand_manufacturers { - int id; - char * name; -}; - -extern struct nand_flash_dev nand_flash_ids[]; -extern struct nand_manufacturers nand_manuf_ids[]; - -/** - * struct nand_bbt_descr - bad block table descriptor - * @options: options for this descriptor - * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE - * when bbt is searched, then we store the found bbts pages here. - * Its an array and supports up to 8 chips now - * @offs: offset of the pattern in the oob area of the page - * @veroffs: offset of the bbt version counter in the oob are of the page - * @version: version read from the bbt page during scan - * @len: length of the pattern, if 0 no pattern check is performed - * @maxblocks: maximum number of blocks to search for a bbt. This number of - * blocks is reserved at the end of the device where the tables are - * written. - * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than - * bad) block in the stored bbt - * @pattern: pattern to identify bad block table or factory marked good / - * bad blocks, can be NULL, if len = 0 - * - * Descriptor for the bad block table marker and the descriptor for the - * pattern which identifies good and bad blocks. The assumption is made - * that the pattern and the version count are always located in the oob area - * of the first block. - */ -struct nand_bbt_descr { - int options; - int pages[NAND_MAX_CHIPS]; - int offs; - int veroffs; - uint8_t version[NAND_MAX_CHIPS]; - int len; - int maxblocks; - int reserved_block_code; - uint8_t *pattern; -}; - -/* Options for the bad block table descriptors */ - -/* The number of bits used per block in the bbt on the device */ -#define NAND_BBT_NRBITS_MSK 0x0000000F -#define NAND_BBT_1BIT 0x00000001 -#define NAND_BBT_2BIT 0x00000002 -#define NAND_BBT_4BIT 0x00000004 -#define NAND_BBT_8BIT 0x00000008 -/* The bad block table is in the last good block of the device */ -#define NAND_BBT_LASTBLOCK 0x00000010 -/* The bbt is at the given page, else we must scan for the bbt */ -#define NAND_BBT_ABSPAGE 0x00000020 -/* The bbt is at the given page, else we must scan for the bbt */ -#define NAND_BBT_SEARCH 0x00000040 -/* bbt is stored per chip on multichip devices */ -#define NAND_BBT_PERCHIP 0x00000080 -/* bbt has a version counter at offset veroffs */ -#define NAND_BBT_VERSION 0x00000100 -/* Create a bbt if none axists */ -#define NAND_BBT_CREATE 0x00000200 -/* Search good / bad pattern through all pages of a block */ -#define NAND_BBT_SCANALLPAGES 0x00000400 -/* Scan block empty during good / bad block scan */ -#define NAND_BBT_SCANEMPTY 0x00000800 -/* Write bbt if neccecary */ -#define NAND_BBT_WRITE 0x00001000 -/* Read and write back block contents when writing bbt */ -#define NAND_BBT_SAVECONTENT 0x00002000 -/* Search good / bad pattern on the first and the second page */ -#define NAND_BBT_SCAN2NDPAGE 0x00004000 - -/* The maximum number of blocks to scan for a bbt */ -#define NAND_BBT_SCAN_MAXBLOCKS 4 - -extern int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd); -extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs); -extern int nand_default_bbt (struct mtd_info *mtd); -extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt); -extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt); - -/* -* Constants for oob configuration -*/ -#define NAND_SMALL_BADBLOCK_POS 5 -#define NAND_LARGE_BADBLOCK_POS 0 - -#endif /* __LINUX_MTD_NAND_NEW_H */ From bfc81252c0de3bfcf92c7c35bc04341fb33e4e4e Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Mon, 6 Mar 2006 13:03:37 +0100 Subject: [PATCH 037/102] Minor code cleanup --- CHANGELOG | 2 + board/amcc/bamboo/config.mk | 1 - board/bmw/config.mk | 1 - board/dave/PPChameleonEVB/config.mk | 1 - board/dave/PPChameleonEVB/nand.c | 2 +- board/esd/common/auto_update.c | 3 - board/esd/common/cmd_loadpci.c | 1 - board/esd/cpci2dp/cpci2dp.c | 4 +- board/esd/cpci405/config.mk | 1 - board/esd/cpci750/cpci750.c | 1 - board/esd/cpci750/pci.c | 192 ++++++------ board/esd/hh405/config.mk | 1 - board/esd/hub405/config.mk | 1 - board/mcc200/mcc200.c | 60 ---- board/mcc200/mt48lc8m32b2-6-7.h | 18 -- board/netstar/config.mk | 1 - board/netta2/config.mk | 1 - common/cmd_nand.c | 2 - doc/README.nand | 7 +- drivers/i8042.c | 436 ++++++++++++++-------------- include/configs/CPCI750.h | 218 +++++++------- include/configs/PPChameleonEVB.h | 2 - include/configs/mcc200.h | 5 +- include/linux/mtd/nand.h | 1 - 24 files changed, 433 insertions(+), 529 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 37d4158063..9af10e84c9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Minor code cleanup + * Merge the new NAND code (testing-NAND brach); see doc/README.nand Rewrite of NAND code based on what is in 2.6.12 Linux kernel Patch by Ladislav Michl, 29 Jun 2005 diff --git a/board/amcc/bamboo/config.mk b/board/amcc/bamboo/config.mk index b6495de692..433429bea7 100644 --- a/board/amcc/bamboo/config.mk +++ b/board/amcc/bamboo/config.mk @@ -35,4 +35,3 @@ endif # legacy nand support BOARDLIBS = drivers/nand_legacy/libnand_legacy.a - diff --git a/board/bmw/config.mk b/board/bmw/config.mk index 10b7a9f5ea..f9915496ad 100644 --- a/board/bmw/config.mk +++ b/board/bmw/config.mk @@ -30,4 +30,3 @@ TEXT_BASE = 0xFFF00000 PLATFORM_CPPFLAGS += -DEMBEDDED -DBIG_ENDIAN_HOST -DINCLUDE_5701_AX_FIX=1\ -DDBG=0 -DT3_JUMBO_RCV_RCB_ENTRY_COUNT=256\ -DTEXT_BASE=$(TEXT_BASE) - diff --git a/board/dave/PPChameleonEVB/config.mk b/board/dave/PPChameleonEVB/config.mk index 5d3df0c858..1dc635fbf0 100644 --- a/board/dave/PPChameleonEVB/config.mk +++ b/board/dave/PPChameleonEVB/config.mk @@ -32,4 +32,3 @@ BOARDLIBS = drivers/nand/libnand.a # Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) #BOARDLIBS = drivers/nand_legacy/libnand_legacy.a - diff --git a/board/dave/PPChameleonEVB/nand.c b/board/dave/PPChameleonEVB/nand.c index 61edc787fa..40a827c3e2 100644 --- a/board/dave/PPChameleonEVB/nand.c +++ b/board/dave/PPChameleonEVB/nand.c @@ -81,7 +81,7 @@ static int ppchameleonevb_device_ready(struct mtd_info *mtdinfo) break; } - if (in32(GPIO0_IR) & rb_gpio_pin) + if (in32(GPIO0_IR) & rb_gpio_pin) return 1; return 0; } diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c index 5a70176fad..cad82115cc 100644 --- a/board/esd/common/auto_update.c +++ b/board/esd/common/auto_update.c @@ -42,9 +42,6 @@ #error "must define CFG_CMD_FAT" #endif - - - extern au_image_t au_image[]; extern int N_AU_IMAGES; diff --git a/board/esd/common/cmd_loadpci.c b/board/esd/common/cmd_loadpci.c index 3478f825c5..bf796ff9d1 100644 --- a/board/esd/common/cmd_loadpci.c +++ b/board/esd/common/cmd_loadpci.c @@ -120,4 +120,3 @@ U_BOOT_CMD( ); #endif - diff --git a/board/esd/cpci2dp/cpci2dp.c b/board/esd/cpci2dp/cpci2dp.c index 2800420e2a..1a27ca0911 100644 --- a/board/esd/cpci2dp/cpci2dp.c +++ b/board/esd/cpci2dp/cpci2dp.c @@ -36,9 +36,9 @@ int board_early_init_f (void) cntrl0Reg = mfdcr(cntrl0); mtdcr(cntrl0, cntrl0Reg | ((CFG_EEPROM_WP | CFG_PB_LED | CFG_SELF_RST | CFG_INTA_FAKE) << 5)); - /* set output pins to high */ + /* set output pins to high */ out32(GPIO0_OR, CFG_EEPROM_WP); - /* setup for output (LED=off) */ + /* setup for output (LED=off) */ out32(GPIO0_TCR, CFG_EEPROM_WP | CFG_PB_LED); /* diff --git a/board/esd/cpci405/config.mk b/board/esd/cpci405/config.mk index 320346f089..ceff4c4d1e 100644 --- a/board/esd/cpci405/config.mk +++ b/board/esd/cpci405/config.mk @@ -41,4 +41,3 @@ endif # Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) BOARDLIBS = drivers/nand_legacy/libnand_legacy.a - diff --git a/board/esd/cpci750/cpci750.c b/board/esd/cpci750/cpci750.c index fd0f904cfe..dbed597173 100644 --- a/board/esd/cpci750/cpci750.c +++ b/board/esd/cpci750/cpci750.c @@ -378,7 +378,6 @@ int misc_init_r () CFG_MONITOR_BASE, CFG_MONITOR_BASE + monitor_flash_len - 1, &flash_info[3]); - } return 0; } diff --git a/board/esd/cpci750/pci.c b/board/esd/cpci750/pci.c index 37c7150423..c335ebf0bf 100644 --- a/board/esd/cpci750/pci.c +++ b/board/esd/cpci750/pci.c @@ -12,7 +12,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -46,8 +46,8 @@ static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = { #ifdef CONFIG_USE_CPCIDVI typedef struct { - unsigned int base; - unsigned int init; + unsigned int base; + unsigned int init; } GT_CPCIDVI_ROM_T; static GT_CPCIDVI_ROM_T gt_cpcidvi_rom = {0, 0}; @@ -133,20 +133,20 @@ static const unsigned int pci_p2p_configuration[] = { /******************************************************************** * pciWriteConfigReg - Write to a PCI configuration register -* - Make sure the GT is configured as a master before writing -* to another device on the PCI. -* - The function takes care of Big/Little endian conversion. +* - Make sure the GT is configured as a master before writing +* to another device on the PCI. +* - The function takes care of Big/Little endian conversion. * * * Inputs: unsigned int regOffset: The register offset as it apears in the GT spec -* (or any other PCI device spec) -* pciDevNum: The device number needs to be addressed. +* (or any other PCI device spec) +* pciDevNum: The device number needs to be addressed. * * Configuration Address 0xCF8: * -* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number +* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number * |congif|Reserved| Bus |Device|Function|Register|00| -* |Enable| |Number|Number| Number | Number | | <=field Name +* |Enable| |Number|Number| Number | Number | | <=field Name * *********************************************************************/ void pciWriteConfigReg (PCI_HOST host, unsigned int regOffset, @@ -180,20 +180,20 @@ void pciWriteConfigReg (PCI_HOST host, unsigned int regOffset, /******************************************************************** * pciReadConfigReg - Read from a PCI0 configuration register -* - Make sure the GT is configured as a master before reading -* from another device on the PCI. -* - The function takes care of Big/Little endian conversion. +* - Make sure the GT is configured as a master before reading +* from another device on the PCI. +* - The function takes care of Big/Little endian conversion. * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI -* spec) -* pciDevNum: The device number needs to be addressed. +* spec) +* pciDevNum: The device number needs to be addressed. * RETURNS: data , if the data == 0xffffffff check the master abort bit in the -* cause register to make sure the data is valid +* cause register to make sure the data is valid * * Configuration Address 0xCF8: * -* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number +* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number * |congif|Reserved| Bus |Device|Function|Register|00| -* |Enable| |Number|Number| Number | Number | | <=field Name +* |Enable| |Number|Number| Number | Number | | <=field Name * *********************************************************************/ unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset, @@ -228,21 +228,21 @@ unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset, /******************************************************************** * pciOverBridgeWriteConfigReg - Write to a PCI configuration register where -* the agent is placed on another Bus. For more -* information read P2P in the PCI spec. +* the agent is placed on another Bus. For more +* information read P2P in the PCI spec. * * Inputs: unsigned int regOffset - The register offset as it apears in the -* GT spec (or any other PCI device spec). -* unsigned int pciDevNum - The device number needs to be addressed. -* unsigned int busNum - On which bus does the Target agent connect -* to. -* unsigned int data - data to be written. +* GT spec (or any other PCI device spec). +* unsigned int pciDevNum - The device number needs to be addressed. +* unsigned int busNum - On which bus does the Target agent connect +* to. +* unsigned int data - data to be written. * * Configuration Address 0xCF8: * -* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number +* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number * |congif|Reserved| Bus |Device|Function|Register|01| -* |Enable| |Number|Number| Number | Number | | <=field Name +* |Enable| |Number|Number| Number | Number | | <=field Name * * The configuration Address is configure as type-I (bits[1:0] = '01') due to * PCI spec referring to P2P. @@ -273,23 +273,23 @@ void pciOverBridgeWriteConfigReg (PCI_HOST host, /******************************************************************** * pciOverBridgeReadConfigReg - Read from a PCIn configuration register where -* the agent target locate on another PCI bus. -* - Make sure the GT is configured as a master -* before reading from another device on the PCI. -* - The function takes care of Big/Little endian -* conversion. +* the agent target locate on another PCI bus. +* - Make sure the GT is configured as a master +* before reading from another device on the PCI. +* - The function takes care of Big/Little endian +* conversion. * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI -* spec). (configuration register offset.) -* pciDevNum: The device number needs to be addressed. -* busNum: the Bus number where the agent is place. +* spec). (configuration register offset.) +* pciDevNum: The device number needs to be addressed. +* busNum: the Bus number where the agent is place. * RETURNS: data , if the data == 0xffffffff check the master abort bit in the -* cause register to make sure the data is valid +* cause register to make sure the data is valid * * Configuration Address 0xCF8: * -* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number +* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number * |congif|Reserved| Bus |Device|Function|Register|01| -* |Enable| |Number|Number| Number | Number | | <=field Name +* |Enable| |Number|Number| Number | Number | | <=field Name * *********************************************************************/ unsigned int pciOverBridgeReadConfigReg (PCI_HOST host, @@ -393,7 +393,7 @@ static unsigned int pciGetRemapOffset (PCI_HOST host, PCI_REGION region) /******************************************************************** * pciGetBaseAddress - Gets the base address of a PCI. -* - If the PCI size is 0 then this base address has no meaning!!! +* - If the PCI size is 0 then this base address has no meaning!!! * * * INPUT: Bus, Region - The bus and region we ask for its base address. @@ -501,13 +501,13 @@ void pciMapMemoryBank (PCI_HOST host, MEMORY_BANK bank, /******************************************************************** * pciSetRegionFeatures - This function modifys one of the 8 regions with -* feature bits given as an input. -* - Be advised to check the spec before modifying them. +* feature bits given as an input. +* - Be advised to check the spec before modifying them. * Inputs: PCI_PROTECT_REGION region - one of the eight regions. -* unsigned int features - See file: pci.h there are defintion for those -* region features. -* unsigned int baseAddress - The region base Address. -* unsigned int topAddress - The region top Address. +* unsigned int features - See file: pci.h there are defintion for those +* region features. +* unsigned int baseAddress - The region base Address. +* unsigned int topAddress - The region top Address. * Returns: false if one of the parameters is erroneous true otherwise. *********************************************************************/ bool pciSetRegionFeatures (PCI_HOST host, PCI_ACCESS_REGIONS region, @@ -541,7 +541,7 @@ bool pciSetRegionFeatures (PCI_HOST host, PCI_ACCESS_REGIONS region, /******************************************************************** * pciDisableAccessRegion - Disable The given Region by writing MAX size -* to its low Address and MIN size to its high Address. +* to its low Address and MIN size to its high Address. * * Inputs: PCI_ACCESS_REGIONS region - The region we to be Disabled. * Returns: N/A. @@ -588,12 +588,12 @@ bool pciArbiterDisable (PCI_HOST host) * pciSetArbiterAgentsPriority - Priority setup for the PCI agents (Hi or Low) * * Inputs: PCI_AGENT_PRIO internalAgent - priotity for internal agent. -* PCI_AGENT_PRIO externalAgent0 - priotity for external#0 agent. -* PCI_AGENT_PRIO externalAgent1 - priotity for external#1 agent. -* PCI_AGENT_PRIO externalAgent2 - priotity for external#2 agent. -* PCI_AGENT_PRIO externalAgent3 - priotity for external#3 agent. -* PCI_AGENT_PRIO externalAgent4 - priotity for external#4 agent. -* PCI_AGENT_PRIO externalAgent5 - priotity for external#5 agent. +* PCI_AGENT_PRIO externalAgent0 - priotity for external#0 agent. +* PCI_AGENT_PRIO externalAgent1 - priotity for external#1 agent. +* PCI_AGENT_PRIO externalAgent2 - priotity for external#2 agent. +* PCI_AGENT_PRIO externalAgent3 - priotity for external#3 agent. +* PCI_AGENT_PRIO externalAgent4 - priotity for external#4 agent. +* PCI_AGENT_PRIO externalAgent5 - priotity for external#5 agent. * Returns: true *********************************************************************/ bool pciSetArbiterAgentsPriority (PCI_HOST host, PCI_AGENT_PRIO internalAgent, @@ -619,17 +619,17 @@ bool pciSetArbiterAgentsPriority (PCI_HOST host, PCI_AGENT_PRIO internalAgent, /******************************************************************** * pciParkingDisable - Park on last option disable, with this function you can -* disable the park on last mechanism for each agent. -* disabling this option for all agents results parking -* on the internal master. +* disable the park on last mechanism for each agent. +* disabling this option for all agents results parking +* on the internal master. * * Inputs: PCI_AGENT_PARK internalAgent - parking Disable for internal agent. -* PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent. -* PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent. -* PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent. -* PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent. -* PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent. -* PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent. +* PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent. +* PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent. +* PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent. +* PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent. +* PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent. +* PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent. * Returns: true *********************************************************************/ bool pciParkingDisable (PCI_HOST host, PCI_AGENT_PARK internalAgent, @@ -655,11 +655,11 @@ bool pciParkingDisable (PCI_HOST host, PCI_AGENT_PARK internalAgent, /******************************************************************** * pciEnableBrokenAgentDetection - A master is said to be broken if it fails to -* respond to grant assertion within a window specified in -* the input value: 'brokenValue'. +* respond to grant assertion within a window specified in +* the input value: 'brokenValue'. * * Inputs: unsigned char brokenValue - A value which limits the Master to hold the -* grant without asserting frame. +* grant without asserting frame. * Returns: Error for illegal broken value otherwise true. *********************************************************************/ bool pciEnableBrokenAgentDetection (PCI_HOST host, unsigned char brokenValue) @@ -678,9 +678,9 @@ bool pciEnableBrokenAgentDetection (PCI_HOST host, unsigned char brokenValue) /******************************************************************** * pciDisableBrokenAgentDetection - This function disable the Broken agent -* Detection mechanism. -* NOTE: This operation may cause a dead lock on the -* pci0 arbitration. +* Detection mechanism. +* NOTE: This operation may cause a dead lock on the +* pci0 arbitration. * * Inputs: N/A * Returns: true. @@ -697,15 +697,15 @@ bool pciDisableBrokenAgentDetection (PCI_HOST host) /******************************************************************** * pciP2PConfig - This function set the PCI_n P2P configurate. -* For more information on the P2P read PCI spec. +* For more information on the P2P read PCI spec. * * Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower -* Boundry. -* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper -* Boundry. -* unsigned int busNum - The CPI bus number to which the PCI interface -* is connected. -* unsigned int devNum - The PCI interface's device number. +* Boundry. +* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper +* Boundry. +* unsigned int busNum - The CPI bus number to which the PCI interface +* is connected. +* unsigned int devNum - The PCI interface's device number. * * Returns: true. *********************************************************************/ @@ -723,15 +723,15 @@ bool pciP2PConfig (PCI_HOST host, unsigned int SecondBusLow, /******************************************************************** * pciSetRegionSnoopMode - This function modifys one of the 4 regions which -* supports Cache Coherency in the PCI_n interface. +* supports Cache Coherency in the PCI_n interface. * Inputs: region - One of the four regions. -* snoopType - There is four optional Types: -* 1. No Snoop. -* 2. Snoop to WT region. -* 3. Snoop to WB region. -* 4. Snoop & Invalidate to WB region. -* baseAddress - Base Address of this region. -* regionLength - Region length. +* snoopType - There is four optional Types: +* 1. No Snoop. +* 2. Snoop to WT region. +* 3. Snoop to WB region. +* 4. Snoop & Invalidate to WB region. +* baseAddress - Base Address of this region. +* regionLength - Region length. * Returns: false if one of the parameters is wrong otherwise return true. *********************************************************************/ bool pciSetRegionSnoopMode (PCI_HOST host, PCI_SNOOP_REGION region, @@ -754,7 +754,7 @@ bool pciSetRegionSnoopMode (PCI_HOST host, PCI_SNOOP_REGION region, GT_REG_WRITE (snoopXtopAddress, 0); return true; } - baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */ + baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */ data = (baseAddress >> 20) | snoopType << 12; GT_REG_WRITE (snoopXbaseAddress, data); snoopHigh = (snoopHigh & 0xfff00000) >> 20; @@ -827,7 +827,7 @@ static void gt_setup_ide (struct pci_controller *hose, static void gt_setup_cpcidvi (struct pci_controller *hose, pci_dev_t dev, struct pci_config_table *entry) { - u32 bar_value, pci_response; + u32 bar_value, pci_response; pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &pci_response); pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0, 0xffffffff); @@ -843,30 +843,30 @@ static void gt_setup_cpcidvi (struct pci_controller *hose, unsigned char gt_cpcidvi_in8(unsigned int offset) { - unsigned char data; + unsigned char data; if (gt_cpcidvi_rom.init == 0) { - return(0); - } - data = in8((offset & 0x04) + 0x3f000 + gt_cpcidvi_rom.base); - return(data); + return(0); + } + data = in8((offset & 0x04) + 0x3f000 + gt_cpcidvi_rom.base); + return(data); } void gt_cpcidvi_out8(unsigned int offset, unsigned char data) { - unsigned int off; - + unsigned int off; + if (gt_cpcidvi_rom.init == 0) { - return; - } + return; + } off = data; off = ((off << 3) & 0x7f8) + (offset & 0x4) + 0x3e000 + gt_cpcidvi_rom.base; - in8(off); - return; + in8(off); + return; } #endif -/* TODO BJW: Change this for DB64360. This was pulled from the EV64260 */ +/* TODO BJW: Change this for DB64360. This was pulled from the EV64260 */ /* and is curently not called *. */ #if 0 static void gt_fixup_irq (struct pci_controller *hose, pci_dev_t dev) diff --git a/board/esd/hh405/config.mk b/board/esd/hh405/config.mk index ca1f57572b..798a3fa413 100644 --- a/board/esd/hh405/config.mk +++ b/board/esd/hh405/config.mk @@ -32,4 +32,3 @@ TEXT_BASE = 0xFFF80000 # Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) BOARDLIBS = drivers/nand_legacy/libnand_legacy.a - diff --git a/board/esd/hub405/config.mk b/board/esd/hub405/config.mk index 22ff1226bc..4c60c3566d 100644 --- a/board/esd/hub405/config.mk +++ b/board/esd/hub405/config.mk @@ -29,4 +29,3 @@ TEXT_BASE = 0xFFFC0000 # Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) BOARDLIBS = drivers/nand_legacy/libnand_legacy.a - diff --git a/board/mcc200/mcc200.c b/board/mcc200/mcc200.c index acc0e06862..d1c99fdd85 100644 --- a/board/mcc200/mcc200.c +++ b/board/mcc200/mcc200.c @@ -28,19 +28,12 @@ #include #include -//###CHD: es gibt eigentlich kein DDR bei uns -> weg damit!; dto. PCI! -#if defined(CONFIG_MPC5200_DDR) -#include "mt46v16m16-75.h" -#else -//#include "mt48lc16m16a2-75.h" #include "mt48lc8m32b2-6-7.h" -#endif extern flash_info_t flash_info[]; /* FLASH chips info */ ulong flash_get_size (ulong base, int banknum); -//###CHD: wenn RAMBOOT gehen wuerde, .... #ifndef CFG_RAMBOOT static void sdram_start (int hi_addr) { @@ -88,7 +81,6 @@ static void sdram_start (int hi_addr) * is something else than 0x00000000. */ -#if defined(CONFIG_MPC5200) long int initdram (int board_type) { ulong dramsize = 0; @@ -190,58 +182,6 @@ long int initdram (int board_type) return dramsize + dramsize2; } -//###CHD: sowas gibt es bei usn nicht! -#elif defined(CONFIG_MGT5100) - -long int initdram (int board_type) -{ - ulong dramsize = 0; -#ifndef CFG_RAMBOOT - ulong test1, test2; - - /* setup and enable SDRAM chip selects */ - *(vu_long *)MPC5XXX_SDRAM_START = 0x00000000; - *(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */ - *(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */ - __asm__ volatile ("sync"); - - /* setup config registers */ - *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1; - *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2; - - /* address select register */ - *(vu_long *)MPC5XXX_SDRAM_XLBSEL = SDRAM_ADDRSEL; - __asm__ volatile ("sync"); - - /* find RAM size */ - sdram_start(0); - test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x80000000); - sdram_start(1); - test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x80000000); - if (test1 > test2) { - sdram_start(0); - dramsize = test1; - } else { - dramsize = test2; - } - - /* set SDRAM end address according to size */ - *(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15); - -#else /* CFG_RAMBOOT */ - - /* Retrieve amount of SDRAM available */ - dramsize = ((*(vu_long *)MPC5XXX_SDRAM_STOP + 1) << 15); - -#endif /* CFG_RAMBOOT */ - - return dramsize; -} - -#else -#error Neither CONFIG_MPC5200 or CONFIG_MGT5100 defined -#endif - int checkboard (void) { puts ("Board: MCC200\n"); diff --git a/board/mcc200/mt48lc8m32b2-6-7.h b/board/mcc200/mt48lc8m32b2-6-7.h index 6c2b2b3b36..73dcd5c0a3 100644 --- a/board/mcc200/mt48lc8m32b2-6-7.h +++ b/board/mcc200/mt48lc8m32b2-6-7.h @@ -4,27 +4,9 @@ #define SDRAM_DDR 0 /* is SDR */ -#if defined(CONFIG_MPC5200) /* Settings for XLB = 132 MHz */ -//#define SDRAM_MODE 0x00cc0000 // CL-3 BURST-8 -> Mode Register—MBAR + 0x0100 -//#define SDRAM_CONTROL 0x501f0000 // Control Register—MBAR + 0x0104 -//#define SDRAM_CONFIG1 0xe2329000 // Delays between commands -> Configuration Register 1—MBAR + 0x0108 -//#define SDRAM_CONFIG2 0x46e70000 // Delays between commands -> Configuration Register 2—MBAR + 0x010C -//Christian -//#define SDRAM_MODE 0x00cd0000 // CL-3 BURST-8 -> Mode Register—MBAR + 0x0100 -//#define SDRAM_CONTROL 0x501f0000 // Control Register—MBAR + 0x0104 -//#define SDRAM_CONFIG1 0xd2322900 // Delays between commands -> Configuration Register 1—MBAR + 0x0108 -//#define SDRAM_CONFIG2 0x8ad70000 // Delays between commands -> Configuration Register 2—MBAR + 0x010C - -//###CHD: ordentliche Doku dazu! CAS=2, etc. -//STefan #define SDRAM_MODE 0x008d0000 // CL-3 BURST-8 -> Mode Register—MBAR + 0x0100 #define SDRAM_CONTROL 0x504f0000 // Control Register—MBAR + 0x0104 #define SDRAM_CONFIG1 0xc2222900 // Delays between commands -> Configuration Register 1—MBAR + 0x0108 #define SDRAM_CONFIG2 0x88c70000 // Delays between commands -> Configuration Register 2—MBAR + 0x010C - - -#else -#error CONFIG_MPC5200 not defined, please set parameters for your sdram controller in mt48lc8m32b2.h -#endif diff --git a/board/netstar/config.mk b/board/netstar/config.mk index 2e3921b101..50d647add0 100644 --- a/board/netstar/config.mk +++ b/board/netstar/config.mk @@ -12,4 +12,3 @@ TEXT_BASE = 0x13FC0000 # Compile the new NAND code BOARDLIBS = drivers/nand/libnand.a - diff --git a/board/netta2/config.mk b/board/netta2/config.mk index 4b636ed88d..de179c2d65 100644 --- a/board/netta2/config.mk +++ b/board/netta2/config.mk @@ -29,4 +29,3 @@ TEXT_BASE = 0x40000000 # Compile the legacy NAND code (CFG_NAND_LEGACY must be defined) BOARDLIBS = drivers/nand_legacy/libnand_legacy.a - diff --git a/common/cmd_nand.c b/common/cmd_nand.c index e46ed1d3c4..bb51d91fb3 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -442,8 +442,6 @@ void archflashwp(void *archdata, int wp); #define NANDRW_JFFS2 0x02 #define NANDRW_JFFS2_SKIP 0x04 - - /* * Imports from nand_legacy.c */ diff --git a/doc/README.nand b/doc/README.nand index cd7608cf7f..f2d6a5b1e6 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -179,7 +179,6 @@ More Definitions: #define NAND_MAX_CHIPS 1 - NOTE: ===== @@ -204,7 +203,7 @@ use JFFS, which has been adopted to use the new NAND, and at the same time use NAND in legacy mode. The breakage will disappear when the board-specific code is changed to the new NAND. -As mentioned above, the legacy code is still used by the DoC subsystem. -The consequence of this is that the legacy NAND can't be removed from -the tree until the DoC is ported to use the new NAND support (or boards +As mentioned above, the legacy code is still used by the DoC subsystem. +The consequence of this is that the legacy NAND can't be removed from +the tree until the DoC is ported to use the new NAND support (or boards with DoC will break). diff --git a/drivers/i8042.c b/drivers/i8042.c index 5f273a267d..22c2a4e3a0 100644 --- a/drivers/i8042.c +++ b/drivers/i8042.c @@ -12,7 +12,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -33,7 +33,7 @@ extern u8 gt_cpcidvi_in8(u32 offset); extern void gt_cpcidvi_out8(u32 offset, u8 data); -#define in8(a) gt_cpcidvi_in8(a) +#define in8(a) gt_cpcidvi_in8(a) #define out8(a, b) gt_cpcidvi_out8(a,b) #endif @@ -49,10 +49,10 @@ static int cursor_state = 0; /* locals */ -static int kbd_input = -1; /* no input yet */ -static int kbd_mapping = KBD_US; /* default US keyboard */ -static int kbd_flags = NORMAL; /* after reset */ -static int kbd_state = 0; /* unshift code */ +static int kbd_input = -1; /* no input yet */ +static int kbd_mapping = KBD_US; /* default US keyboard */ +static int kbd_flags = NORMAL; /* after reset */ +static int kbd_state = 0; /* unshift code */ static void kbd_conv_char (unsigned char scan_code); static void kbd_led_set (void); @@ -68,230 +68,230 @@ static int kbd_reset (void); static unsigned char kbd_fct_map [144] = { /* kbd_fct_map table for scan code */ - 0, AS, AS, AS, AS, AS, AS, AS, /* scan 0- 7 */ - AS, AS, AS, AS, AS, AS, AS, AS, /* scan 8- F */ - AS, AS, AS, AS, AS, AS, AS, AS, /* scan 10-17 */ - AS, AS, AS, AS, AS, CN, AS, AS, /* scan 18-1F */ - AS, AS, AS, AS, AS, AS, AS, AS, /* scan 20-27 */ - AS, AS, SH, AS, AS, AS, AS, AS, /* scan 28-2F */ - AS, AS, AS, AS, AS, AS, SH, AS, /* scan 30-37 */ - AS, AS, CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, ES, /* scan 40-47 */ - ES, ES, ES, ES, ES, ES, ES, ES, /* scan 48-4F */ - ES, ES, ES, ES, 0, 0, AS, 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - AS, 0, 0, AS, 0, 0, AS, 0, /* scan 70-77 */ - 0, AS, 0, 0, 0, AS, 0, 0, /* scan 78-7F */ - AS, CN, AS, AS, AK, ST, EX, EX, /* enhanced */ - AS, EX, EX, AS, EX, AS, EX, EX /* enhanced */ + 0, AS, AS, AS, AS, AS, AS, AS, /* scan 0- 7 */ + AS, AS, AS, AS, AS, AS, AS, AS, /* scan 8- F */ + AS, AS, AS, AS, AS, AS, AS, AS, /* scan 10-17 */ + AS, AS, AS, AS, AS, CN, AS, AS, /* scan 18-1F */ + AS, AS, AS, AS, AS, AS, AS, AS, /* scan 20-27 */ + AS, AS, SH, AS, AS, AS, AS, AS, /* scan 28-2F */ + AS, AS, AS, AS, AS, AS, SH, AS, /* scan 30-37 */ + AS, AS, CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, ES, /* scan 40-47 */ + ES, ES, ES, ES, ES, ES, ES, ES, /* scan 48-4F */ + ES, ES, ES, ES, 0, 0, AS, 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + AS, 0, 0, AS, 0, 0, AS, 0, /* scan 70-77 */ + 0, AS, 0, 0, 0, AS, 0, 0, /* scan 78-7F */ + AS, CN, AS, AS, AK, ST, EX, EX, /* enhanced */ + AS, EX, EX, AS, EX, AS, EX, EX /* enhanced */ }; static unsigned char kbd_key_map [2][5][144] = { { /* US keyboard */ { /* unshift code */ - 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ - '7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */ - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */ - 'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */ - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */ - '\'', '`', SH, '\\', 'z', 'x', 'c', 'v', /* scan 28-2F */ - 'b', 'n', 'm', ',', '.', '/', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ - '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ - '2', '3', '0', '.', 0, 0, 0, 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ + '7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */ + 'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */ + '\'', '`', SH, '\\', 'z', 'x', 'c', 'v', /* scan 28-2F */ + 'b', 'n', 'm', ',', '.', '/', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ + '2', '3', '0', '.', 0, 0, 0, 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ }, { /* shift code */ - 0, 0x1b, '!', '@', '#', '$', '%', '^', /* scan 0- 7 */ - '&', '*', '(', ')', '_', '+', 0x08, '\t', /* scan 8- F */ - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* scan 10-17 */ - 'O', 'P', '{', '}', '\r', CN, 'A', 'S', /* scan 18-1F */ - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* scan 20-27 */ - '"', '~', SH, '|', 'Z', 'X', 'C', 'V', /* scan 28-2F */ - 'B', 'N', 'M', '<', '>', '?', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ - '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ - '2', '3', '0', '.', 0, 0, 0, 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + 0, 0x1b, '!', '@', '#', '$', '%', '^', /* scan 0- 7 */ + '&', '*', '(', ')', '_', '+', 0x08, '\t', /* scan 8- F */ + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* scan 10-17 */ + 'O', 'P', '{', '}', '\r', CN, 'A', 'S', /* scan 18-1F */ + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* scan 20-27 */ + '"', '~', SH, '|', 'Z', 'X', 'C', 'V', /* scan 28-2F */ + 'B', 'N', 'M', '<', '>', '?', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ + '2', '3', '0', '.', 0, 0, 0, 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ }, { /* control code */ - 0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */ - 0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */ - 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */ - 0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */ - 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */ - 0xff, 0x1c, SH, 0xff, 0x1a, 0x18, 0x03, 0x16, /* scan 28-2F */ - 0x02, 0x0e, 0x0d, 0xff, 0xff, 0xff, SH, 0xff, /* scan 30-37 */ - 0xff, 0xff, CP, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */ - 0xff, 0xff, 0xff, 0xff, 0xff, NM, ST, 0xff, /* scan 40-47 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 0xff, 0xff, /* extended */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ + 0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */ + 0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */ + 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */ + 0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */ + 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */ + 0xff, 0x1c, SH, 0xff, 0x1a, 0x18, 0x03, 0x16, /* scan 28-2F */ + 0x02, 0x0e, 0x0d, 0xff, 0xff, 0xff, SH, 0xff, /* scan 30-37 */ + 0xff, 0xff, CP, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */ + 0xff, 0xff, 0xff, 0xff, 0xff, NM, ST, 0xff, /* scan 40-47 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 0xff, 0xff, /* extended */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ }, { /* non numeric code */ - 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ - '7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */ - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */ - 'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */ - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */ - '\'', '`', SH, '\\', 'z', 'x', 'c', 'v', /* scan 28-2F */ - 'b', 'n', 'm', ',', '.', '/', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, 'w', /* scan 40-47 */ - 'x', 'y', 'l', 't', 'u', 'v', 'm', 'q', /* scan 48-4F */ - 'r', 's', 'p', 'n', 0, 0, 0, 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ + '7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */ + 'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */ + '\'', '`', SH, '\\', 'z', 'x', 'c', 'v', /* scan 28-2F */ + 'b', 'n', 'm', ',', '.', '/', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, 'w', /* scan 40-47 */ + 'x', 'y', 'l', 't', 'u', 'v', 'm', 'q', /* scan 48-4F */ + 'r', 's', 'p', 'n', 0, 0, 0, 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ }, { /* right alt mode - not used in US keyboard */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 8 - F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50 -57 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 8 - F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50 -57 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ } }, { /* german keyboard */ { /* unshift code */ - 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ - '7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */ - 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */ - 'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */ - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */ - 0x84, '^', SH, '#', 'y', 'x', 'c', 'v', /* scan 28-2F */ - 'b', 'n', 'm', ',', '.', '-', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ - '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ - '2', '3', '0', ',', 0, 0, '<', 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ + '7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */ + 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */ + 'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */ + 0x84, '^', SH, '#', 'y', 'x', 'c', 'v', /* scan 28-2F */ + 'b', 'n', 'm', ',', '.', '-', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ + '2', '3', '0', ',', 0, 0, '<', 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ }, { /* shift code */ - 0, 0x1b, '!', '"', 0x15, '$', '%', '&', /* scan 0- 7 */ - '/', '(', ')', '=', '?', '`', 0x08, '\t', /* scan 8- F */ - 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', /* scan 10-17 */ - 'O', 'P', 0x9a, '*', '\r', CN, 'A', 'S', /* scan 18-1F */ - 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0x99, /* scan 20-27 */ - 0x8e, 0xf8, SH, '\'', 'Y', 'X', 'C', 'V', /* scan 28-2F */ - 'B', 'N', 'M', ';', ':', '_', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ - '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ - '2', '3', '0', ',', 0, 0, '>', 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + 0, 0x1b, '!', '"', 0x15, '$', '%', '&', /* scan 0- 7 */ + '/', '(', ')', '=', '?', '`', 0x08, '\t', /* scan 8- F */ + 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', /* scan 10-17 */ + 'O', 'P', 0x9a, '*', '\r', CN, 'A', 'S', /* scan 18-1F */ + 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0x99, /* scan 20-27 */ + 0x8e, 0xf8, SH, '\'', 'Y', 'X', 'C', 'V', /* scan 28-2F */ + 'B', 'N', 'M', ';', ':', '_', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ + '2', '3', '0', ',', 0, 0, '>', 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ }, { /* control code */ - 0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */ - 0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */ - 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */ - 0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */ - 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */ - 0xff, 0x1c, SH, 0xff, 0x1a, 0x18, 0x03, 0x16, /* scan 28-2F */ - 0x02, 0x0e, 0x0d, 0xff, 0xff, 0xff, SH, 0xff, /* scan 30-37 */ - 0xff, 0xff, CP, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */ - 0xff, 0xff, 0xff, 0xff, 0xff, NM, ST, 0xff, /* scan 40-47 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 0xff, 0xff, /* extended */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ + 0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */ + 0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */ + 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */ + 0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */ + 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */ + 0xff, 0x1c, SH, 0xff, 0x1a, 0x18, 0x03, 0x16, /* scan 28-2F */ + 0x02, 0x0e, 0x0d, 0xff, 0xff, 0xff, SH, 0xff, /* scan 30-37 */ + 0xff, 0xff, CP, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */ + 0xff, 0xff, 0xff, 0xff, 0xff, NM, ST, 0xff, /* scan 40-47 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 0xff, 0xff, /* extended */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ }, { /* non numeric code */ - 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ - '7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */ - 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */ - 'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */ - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */ - 0x84, '^', SH, 0, 'y', 'x', 'c', 'v', /* scan 28-2F */ - 'b', 'n', 'm', ',', '.', '-', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, 'w', /* scan 40-47 */ - 'x', 'y', 'l', 't', 'u', 'v', 'm', 'q', /* scan 48-4F */ - 'r', 's', 'p', 'n', 0, 0, '<', 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ + '7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */ + 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */ + 'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */ + 0x84, '^', SH, 0, 'y', 'x', 'c', 'v', /* scan 28-2F */ + 'b', 'n', 'm', ',', '.', '-', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, 'w', /* scan 40-47 */ + 'x', 'y', 'l', 't', 'u', 'v', 'm', 'q', /* scan 48-4F */ + 'r', 's', 'p', 'n', 0, 0, '<', 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ }, { /* Right alt mode - is used in German keyboard */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */ - '{', '[', ']', '}', '\\', 0xff, 0xff, 0xff, /* scan 8 - F */ - '@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */ - 0xff, 0xff, 0xff, '~', 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */ - 0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '|', 0xff, /* scan 50 -57 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */ + '{', '[', ']', '}', '\\', 0xff, 0xff, 0xff, /* scan 8 - F */ + '@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */ + 0xff, 0xff, 0xff, '~', 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */ + 0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '|', 0xff, /* scan 50 -57 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ } } }; @@ -328,8 +328,8 @@ int i8042_kbd_init (void) #ifdef CONFIG_USE_CPCIDVI if ((penv = getenv ("console")) != NULL) { - if (strncmp (penv, "serial", 7) == 0) { - return -1; + if (strncmp (penv, "serial", 7) == 0) { + return -1; } } #endif @@ -345,9 +345,9 @@ int i8042_kbd_init (void) { if (kbd_reset() == 0) { - kbd_mapping = keymap; - kbd_flags = NORMAL; - kbd_state = 0; + kbd_mapping = keymap; + kbd_flags = NORMAL; + kbd_state = 0; kbd_led_set(); return 0; } @@ -359,7 +359,7 @@ int i8042_kbd_init (void) /******************************************************************************* * * i8042_tstc - test if keyboard input is available - * option: cursor blinking if called in a loop + * option: cursor blinking if called in a loop */ int i8042_tstc (void) { @@ -395,7 +395,7 @@ int i8042_tstc (void) /******************************************************************************* * * i8042_getc - wait till keyboard input is available - * option: turn on/off cursor while waiting + * option: turn on/off cursor while waiting */ int i8042_getc (void) { @@ -448,8 +448,8 @@ static void kbd_conv_char (unsigned char scan_code) { if (scan_code == 0xe1) { - kbd_flags ^= BRK; /* reset the break flag */ - kbd_flags ^= E1; /* bitwise EXOR with E1 flag */ + kbd_flags ^= BRK; /* reset the break flag */ + kbd_flags ^= E1; /* bitwise EXOR with E1 flag */ } return; } @@ -560,7 +560,7 @@ static void kbd_caps (unsigned char scan_code) if ((kbd_flags & BRK) == NORMAL) { kbd_flags ^= CAPS; - kbd_led_set (); /* update keyboard LED */ + kbd_led_set (); /* update keyboard LED */ } } @@ -573,7 +573,7 @@ static void kbd_num (unsigned char scan_code) { kbd_flags ^= NUM; kbd_state = (kbd_flags & NUM) ? AS : NM; - kbd_led_set (); /* update keyboard LED */ + kbd_led_set (); /* update keyboard LED */ } } @@ -585,7 +585,7 @@ static void kbd_scroll (unsigned char scan_code) if ((kbd_flags & BRK) == NORMAL) { kbd_flags ^= STP; - kbd_led_set (); /* update keyboard LED */ + kbd_led_set (); /* update keyboard LED */ if (kbd_flags & STP) kbd_input = 0x13; else @@ -615,9 +615,9 @@ static void kbd_alt (unsigned char scan_code) static void kbd_led_set (void) { kbd_input_empty(); - out8 (I8042_DATA_REG, 0xed); /* SET LED command */ + out8 (I8042_DATA_REG, 0xed); /* SET LED command */ kbd_input_empty(); - out8 (I8042_DATA_REG, (kbd_flags & 0x7)); /* LED bits only */ + out8 (I8042_DATA_REG, (kbd_flags & 0x7)); /* LED bits only */ } diff --git a/include/configs/CPCI750.h b/include/configs/CPCI750.h index 1632f374c3..244e45a750 100644 --- a/include/configs/CPCI750.h +++ b/include/configs/CPCI750.h @@ -12,7 +12,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -57,7 +57,7 @@ #define CONFIG_CPCI750 1 /* this is an CPCI750 board */ -#define CONFIG_BAUDRATE 9600 /* console baudrate = 9600 */ +#define CONFIG_BAUDRATE 9600 /* console baudrate = 9600 */ #undef CONFIG_ECC /* enable ECC support */ @@ -84,19 +84,19 @@ * for your console driver. * * what to do: - * to use the DUART, undef CONFIG_MPSC. If you have hacked a serial + * to use the DUART, undef CONFIG_MPSC. If you have hacked a serial * cable onto the second DUART channel, change the CFG_DUART port from 1 * to 0 below. * * to use the MPSC, #define CONFIG_MPSC. If you have wired up another * mpsc channel, change CONFIG_MPSC_PORT to the desired value. */ -#define CONFIG_MPSC +#define CONFIG_MPSC #define CONFIG_MPSC_PORT 0 /* to change the default ethernet port, use this define (options: 0, 1, 2) */ #define CONFIG_NET_MULTI -#define MV_ETH_DEVS 1 +#define MV_ETH_DEVS 1 #define CONFIG_ETHER_PORT 0 #undef CONFIG_ETHER_PORT_MII /* use RMII */ @@ -118,38 +118,38 @@ #define CONFIG_SERIAL "AA000001" #define CONFIG_SERVERIP "10.0.0.79" -#define CONFIG_ROOTPATH "/export/nfs_cpci750/%s" +#define CONFIG_ROOTPATH "/export/nfs_cpci750/%s" #define CONFIG_TESTDRAMDATA y -#define CONFIG_TESTDRAMADDRESS n +#define CONFIG_TESTDRAMADDRESS n #define CONFIG_TESETDRAMWALK n /* ----------------------------------------------------------------------------- */ -#define CONFIG_LOADS_ECHO 0 /* echo off for serial download */ -#define CFG_LOADS_BAUD_CHANGE /* allow baudrate changes */ +#define CONFIG_LOADS_ECHO 0 /* echo off for serial download */ +#define CFG_LOADS_BAUD_CHANGE /* allow baudrate changes */ #undef CONFIG_WATCHDOG /* watchdog disabled */ -#undef CONFIG_ALTIVEC /* undef to disable */ +#undef CONFIG_ALTIVEC /* undef to disable */ #define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | \ CONFIG_BOOTP_BOOTFILESIZE) -#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ +#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ | CFG_CMD_ASKENV \ - | CFG_CMD_I2C \ + | CFG_CMD_I2C \ | CFG_CMD_CACHE \ | CFG_CMD_EEPROM \ - | CFG_CMD_PCI \ + | CFG_CMD_PCI \ | CFG_CMD_ELF \ | CFG_CMD_DATE \ - | CFG_CMD_NET \ - | CFG_CMD_PING \ - | CFG_CMD_IDE \ - | CFG_CMD_FAT \ - | CFG_CMD_EXT2 \ + | CFG_CMD_NET \ + | CFG_CMD_PING \ + | CFG_CMD_IDE \ + | CFG_CMD_FAT \ + | CFG_CMD_EXT2 \ ) #define CONFIG_DOS_PARTITION @@ -159,7 +159,7 @@ #define CONFIG_USE_CPCIDVI -#ifdef CONFIG_USE_CPCIDVI +#ifdef CONFIG_USE_CPCIDVI #define CONFIG_VIDEO #define CONFIG_VIDEO_CT69000 #define CONFIG_CFB_CONSOLE @@ -174,23 +174,23 @@ */ #define CFG_I2C_EEPROM_ADDR_LEN 2 #define CFG_I2C_MULTI_EEPROMS -#define CFG_I2C_SPEED 80000 /* I2C speed default */ +#define CFG_I2C_SPEED 80000 /* I2C speed default */ #define CFG_GT_DUAL_CPU /* also for JTAG even with one cpu */ -#define CFG_LONGHELP /* undef to save memory */ -#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ #if (CONFIG_COMMANDS & CFG_CMD_KGDB) -#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ #else -#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ #endif -#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ -#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ /*#define CFG_MEMTEST_START 0x00400000*/ /* memtest works on */ /*#define CFG_MEMTEST_END 0x00C00000*/ /* 4 ... 12 MB in DRAM */ -/*#define CFG_MEMTEST_END 0x07c00000*/ /* 4 ... 124 MB in DRAM */ +/*#define CFG_MEMTEST_END 0x07c00000*/ /* 4 ... 124 MB in DRAM */ /* #define CFG_DRAM_TEST @@ -198,21 +198,21 @@ * CFG_DRAM_TEST - enables the following tests. * * CFG_DRAM_TEST_DATA - Enables test for shorted or open data lines - * Environment variable 'test_dram_data' must be - * set to 'y'. + * Environment variable 'test_dram_data' must be + * set to 'y'. * CFG_DRAM_TEST_DATA - Enables test to verify that each word is uniquely - * addressable. Environment variable - * 'test_dram_address' must be set to 'y'. + * addressable. Environment variable + * 'test_dram_address' must be set to 'y'. * CFG_DRAM_TEST_WALK - Enables test a 64-bit walking ones pattern test. - * This test takes about 6 minutes to test 64 MB. - * Environment variable 'test_dram_walk' must be - * set to 'y'. + * This test takes about 6 minutes to test 64 MB. + * Environment variable 'test_dram_walk' must be + * set to 'y'. */ #define CFG_DRAM_TEST #if defined(CFG_DRAM_TEST) #define CFG_MEMTEST_START 0x00400000 /* memtest works on */ /*#define CFG_MEMTEST_END 0x00C00000*/ /* 4 ... 12 MB in DRAM */ -#define CFG_MEMTEST_END 0x07c00000 /* 4 ... 124 MB in DRAM */ +#define CFG_MEMTEST_END 0x07c00000 /* 4 ... 124 MB in DRAM */ #define CFG_DRAM_TEST_DATA #define CFG_DRAM_TEST_ADDRESS #define CFG_DRAM_TEST_WALK @@ -221,10 +221,10 @@ #define CONFIG_DISPLAY_MEMMAP /* at the end of the bootprocess show the memory map */ #undef CFG_DISPLAY_DIMM_SPD_CONTENT /* show SPD content during boot */ -#define CFG_LOAD_ADDR 0x00300000 /* default load address */ +#define CFG_LOAD_ADDR 0x00300000 /* default load address */ -#define CFG_HZ 1000 /* decr freq: 1ms ticks */ -#define CFG_BUS_HZ 133000000 /* 133 MHz (CPU = 5*Bus = 666MHz) */ +#define CFG_HZ 1000 /* decr freq: 1ms ticks */ +#define CFG_BUS_HZ 133000000 /* 133 MHz (CPU = 5*Bus = 666MHz) */ #define CFG_BUS_CLK CFG_BUS_HZ #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 230400 } @@ -251,7 +251,7 @@ * To an unused memory region. The stack will remain in cache until RAM * is initialized */ -#undef CFG_INIT_RAM_LOCK +#undef CFG_INIT_RAM_LOCK /* #define CFG_INIT_RAM_ADDR 0x40000000*/ /* unused memory region */ /* #define CFG_INIT_RAM_ADDR 0xfba00000*/ /* unused memory region */ #define CFG_INIT_RAM_ADDR 0xf1080000 /* unused memory region */ @@ -261,7 +261,7 @@ #define RELOCATE_INTERNAL_RAM_ADDR #ifdef RELOCATE_INTERNAL_RAM_ADDR -/*#define CFG_INTERNAL_RAM_ADDR 0xfba00000*/ +/*#define CFG_INTERNAL_RAM_ADDR 0xfba00000*/ #define CFG_INTERNAL_RAM_ADDR 0xf1080000 #endif @@ -270,16 +270,16 @@ * (Set up by the startup code) * Please note that CFG_SDRAM_BASE _must_ start at 0 */ -#define CFG_SDRAM_BASE 0x00000000 +#define CFG_SDRAM_BASE 0x00000000 /* Dummies for BAT 4-7 */ -#define CFG_SDRAM1_BASE 0x10000000 /* each 256 MByte */ -#define CFG_SDRAM2_BASE 0x20000000 -#define CFG_SDRAM3_BASE 0x30000000 -#define CFG_SDRAM4_BASE 0x40000000 +#define CFG_SDRAM1_BASE 0x10000000 /* each 256 MByte */ +#define CFG_SDRAM2_BASE 0x20000000 +#define CFG_SDRAM3_BASE 0x30000000 +#define CFG_SDRAM4_BASE 0x40000000 #define CFG_RESET_ADDRESS 0xfff00100 -#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ #define CFG_MONITOR_BASE 0xfff00000 -#define CFG_MALLOC_LEN (128 << 10) /* Reserve 256 kB for malloc */ +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 256 kB for malloc */ /*----------------------------------------------------------------------- * FLASH related @@ -289,15 +289,15 @@ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ #define CFG_FLASH_PROTECTION 1 /* use hardware protection */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ -#define CFG_FLASH_BASE 0xfc000000 /* start of flash banks */ +#define CFG_FLASH_BASE 0xfc000000 /* start of flash banks */ #define CFG_MAX_FLASH_BANKS 4 /* max number of memory banks */ -#define CFG_FLASH_INCREMENT 0x01000000 /* size of flash bank */ -#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ -#define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, \ - CFG_FLASH_BASE + 1*CFG_FLASH_INCREMENT, \ - CFG_FLASH_BASE + 2*CFG_FLASH_INCREMENT, \ - CFG_FLASH_BASE + 3*CFG_FLASH_INCREMENT } -#define CFG_FLASH_EMPTY_INFO 1 /* show if bank is empty */ +#define CFG_FLASH_INCREMENT 0x01000000 /* size of flash bank */ +#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ +#define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, \ + CFG_FLASH_BASE + 1*CFG_FLASH_INCREMENT, \ + CFG_FLASH_BASE + 2*CFG_FLASH_INCREMENT, \ + CFG_FLASH_BASE + 3*CFG_FLASH_INCREMENT } +#define CFG_FLASH_EMPTY_INFO 1 /* show if bank is empty */ /* areas to map different things with the GT in physical space */ #define CFG_DRAM_BANKS 4 @@ -308,20 +308,20 @@ /* Peripheral Device section */ /*******************************************************/ -/* We have on the cpci750 Board : */ -/* GT-Chipset Register Area */ -/* GT-Chipset internal SRAM 256k */ -/* SRAM on external device module */ -/* Real time clock on external device module */ -/* dobble UART on external device module */ -/* Data flash on external device module */ -/* Boot flash on external device module */ +/* We have on the cpci750 Board : */ +/* GT-Chipset Register Area */ +/* GT-Chipset internal SRAM 256k */ +/* SRAM on external device module */ +/* Real time clock on external device module */ +/* dobble UART on external device module */ +/* Data flash on external device module */ +/* Boot flash on external device module */ /*******************************************************/ #define CFG_DFL_GT_REGS 0x14000000 /* boot time GT_REGS */ -#define CFG_CPCI750_RESET_ADDR 0x14000000 /* After power on Reset the CPCI750 is here */ +#define CFG_CPCI750_RESET_ADDR 0x14000000 /* After power on Reset the CPCI750 is here */ -#undef MARVEL_STANDARD_CFG -#ifndef MARVEL_STANDARD_CFG +#undef MARVEL_STANDARD_CFG +#ifndef MARVEL_STANDARD_CFG /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #define CFG_GT_REGS 0xf1000000 /* GT Registers will be mapped here */ /*#define CFG_DEV_BASE 0xfc000000*/ /* GT Devices CS start here */ @@ -333,11 +333,11 @@ #define CFG_DEV2_SPACE 0xfe000000 /* DEV_CS2 flash 3 */ #define CFG_DEV3_SPACE 0xf0000000 /* DEV_CS3 nvram/can */ -#define CFG_BOOT_SIZE _16M /* cpci750 flash 0 */ -#define CFG_DEV0_SIZE _16M /* cpci750 flash 1 */ -#define CFG_DEV1_SIZE _16M /* cpci750 flash 2 */ -#define CFG_DEV2_SIZE _16M /* cpci750 flash 3 */ -#define CFG_DEV3_SIZE _16M /* cpci750 nvram/can */ +#define CFG_BOOT_SIZE _16M /* cpci750 flash 0 */ +#define CFG_DEV0_SIZE _16M /* cpci750 flash 1 */ +#define CFG_DEV1_SIZE _16M /* cpci750 flash 2 */ +#define CFG_DEV2_SIZE _16M /* cpci750 flash 3 */ +#define CFG_DEV3_SIZE _16M /* cpci750 nvram/can */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #endif @@ -346,22 +346,22 @@ #define CFG_DEV0_PAR 0x8FDFFFFF /* 16 bit flash */ #define CFG_DEV1_PAR 0x8FDFFFFF /* 16 bit flash */ #define CFG_DEV2_PAR 0x8FDFFFFF /* 16 bit flash */ -#define CFG_DEV3_PAR 0x8FCFFFFF /* nvram/can */ +#define CFG_DEV3_PAR 0x8FCFFFFF /* nvram/can */ #define CFG_BOOT_PAR 0x8FDFFFFF /* 16 bit flash */ - /* c 4 a 8 2 4 1 c */ - /* 33 22|2222|22 22|111 1|11 11|1 1 | | */ + /* c 4 a 8 2 4 1 c */ + /* 33 22|2222|22 22|111 1|11 11|1 1 | | */ /* 10 98|7654|32 10|987 6|54 32|1 098|7 654|3 210 */ /* 11|00|0100|10 10|100|0 00|10 0|100 0|001 1|100 */ /* 3| 0|.... ..| 2| 4 | 0 | 4 | 8 | 3 | 4 */ /* MPP Control MV64360 Appendix P P. 632*/ -#define CFG_MPP_CONTROL_0 0x00002222 /* */ -#define CFG_MPP_CONTROL_1 0x11110000 /* */ -#define CFG_MPP_CONTROL_2 0x11111111 /* */ -#define CFG_MPP_CONTROL_3 0x00001111 /* */ -/* #define CFG_SERIAL_PORT_MUX 0x00000102*/ /* */ +#define CFG_MPP_CONTROL_0 0x00002222 /* */ +#define CFG_MPP_CONTROL_1 0x11110000 /* */ +#define CFG_MPP_CONTROL_2 0x11111111 /* */ +#define CFG_MPP_CONTROL_3 0x00001111 /* */ +/* #define CFG_SERIAL_PORT_MUX 0x00000102*/ /* */ #define CFG_GPP_LEVEL_CONTROL 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111*/ @@ -378,12 +378,12 @@ ECC disable non registered DRAM */ /* 31:26 25:22 21:20 19 18 17 16 */ - /* 100001 0000 010 0 0 0 0 */ + /* 100001 0000 010 0 0 0 0 */ /* refresh_count=0x400 phisical interleaving disable virtual interleaving enable */ /* 15 14 13:0 */ - /* 0 1 0x400 */ + /* 0 1 0x400 */ # define CFG_SDRAM_CONFIG 0x58200400 /* 0x1400 copied from Dink32 bzw. VxWorks*/ @@ -392,14 +392,14 @@ *----------------------------------------------------------------------- */ -#define PCI_HOST_ADAPTER 0 /* configure ar pci adapter */ -#define PCI_HOST_FORCE 1 /* configure as pci host */ -#define PCI_HOST_AUTO 2 /* detected via arbiter enable */ +#define PCI_HOST_ADAPTER 0 /* configure ar pci adapter */ +#define PCI_HOST_FORCE 1 /* configure as pci host */ +#define PCI_HOST_AUTO 2 /* detected via arbiter enable */ -#define CONFIG_PCI /* include pci support */ -#define CONFIG_PCI_HOST PCI_HOST_FORCE /* select pci host function */ -#define CONFIG_PCI_PNP /* do pci plug-and-play */ -#define CONFIG_PCI_SCAN_SHOW /* show devices on bus */ +#define CONFIG_PCI /* include pci support */ +#define CONFIG_PCI_HOST PCI_HOST_FORCE /* select pci host function */ +#define CONFIG_PCI_PNP /* do pci plug-and-play */ +#define CONFIG_PCI_SCAN_SHOW /* show devices on bus */ /* PCI MEMORY MAP section */ #define CFG_PCI0_MEM_BASE 0x80000000 @@ -433,21 +433,21 @@ * IDE/ATA stuff *----------------------------------------------------------------------- */ -#undef CONFIG_IDE_8xx_DIRECT /* no pcmcia interface required */ -#undef CONFIG_IDE_LED /* no led for ide supported */ -#define CONFIG_IDE_RESET /* no reset for ide supported */ -#define CONFIG_IDE_PREINIT /* check for units */ +#undef CONFIG_IDE_8xx_DIRECT /* no pcmcia interface required */ +#undef CONFIG_IDE_LED /* no led for ide supported */ +#define CONFIG_IDE_RESET /* no reset for ide supported */ +#define CONFIG_IDE_PREINIT /* check for units */ -#define CFG_IDE_MAXBUS 2 /* max. 1 IDE busses */ -#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*2) /* max. 1 drives per IDE bus */ +#define CFG_IDE_MAXBUS 2 /* max. 1 IDE busses */ +#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*2) /* max. 1 drives per IDE bus */ -#define CFG_ATA_BASE_ADDR 0 -#define CFG_ATA_IDE0_OFFSET 0 -#define CFG_ATA_IDE1_OFFSET 0 +#define CFG_ATA_BASE_ADDR 0 +#define CFG_ATA_IDE0_OFFSET 0 +#define CFG_ATA_IDE1_OFFSET 0 -#define CFG_ATA_DATA_OFFSET 0x0000 /* Offset for data I/O */ -#define CFG_ATA_REG_OFFSET 0x0000 /* Offset for normal register accesses */ -#define CFG_ATA_ALT_OFFSET 0x0000 /* Offset for alternate registers */ +#define CFG_ATA_DATA_OFFSET 0x0000 /* Offset for data I/O */ +#define CFG_ATA_REG_OFFSET 0x0000 /* Offset for normal register accesses */ +#define CFG_ATA_ALT_OFFSET 0x0000 /* Offset for alternate registers */ /*---------------------------------------------------------------------- @@ -551,7 +551,7 @@ * have to be in the first 8 MB of memory, since this is * the maximum mapped by the Linux kernel during initialization. */ -#define CFG_BOOTMAPSZ (8<<20) /* Initial Memory map for Linux */ +#define CFG_BOOTMAPSZ (8<<20) /* Initial Memory map for Linux */ /*----------------------------------------------------------------------- * FLASH organization @@ -563,23 +563,23 @@ #define CFG_FLASH_LOCK_TOUT 500 /* Timeout for Flash Lock (in ms) */ #if 0 -#define CFG_ENV_IS_IN_FLASH 0 -#define CFG_ENV_SIZE 0x1000 /* Total Size of Environment Sector */ +#define CFG_ENV_IS_IN_FLASH 0 +#define CFG_ENV_SIZE 0x1000 /* Total Size of Environment Sector */ #define CFG_ENV_SECT_SIZE 0x10000 #define CFG_ENV_ADDR 0xFFF78000 /* Marvell 8-Bit Bootflash last sector */ -/* #define CFG_ENV_ADDR (CFG_FLASH_BASE+CFG_MONITOR_LEN-CFG_ENV_SECT_SIZE) */ +/* #define CFG_ENV_ADDR (CFG_FLASH_BASE+CFG_MONITOR_LEN-CFG_ENV_SECT_SIZE) */ #endif #define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ #define CFG_EEPROM_PAGE_WRITE_BITS 5 #define CFG_EEPROM_PAGE_WRITE_DELAY_MS 20 -#define CFG_I2C_EEPROM_ADDR 0x050 +#define CFG_I2C_EEPROM_ADDR 0x050 #define CFG_ENV_OFFSET 0x200 /* environment starts at the beginning of the EEPROM */ #define CFG_ENV_SIZE 0x600 /* 2048 bytes may be used for env vars*/ #define CFG_NVRAM_BASE_ADDR 0xf0000000 /* NVRAM base address */ #define CFG_NVRAM_SIZE (32*1024) /* NVRAM size */ -#define CFG_VXWORKS_MAC_PTR (CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-0x40) +#define CFG_VXWORKS_MAC_PTR (CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-0x40) /*----------------------------------------------------------------------- * Cache Configuration @@ -601,7 +601,7 @@ #if defined (CONFIG_750CX) || defined (CONFIG_750FX) #define L2_INIT 0 #else -#define L2_INIT (L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \ +#define L2_INIT (L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \ L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT) #endif @@ -612,9 +612,9 @@ * * Boot Flags */ -#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ -#define CFG_BOARD_ASM_INIT 1 +#define CFG_BOARD_ASM_INIT 1 #endif /* __CONFIG_H */ diff --git a/include/configs/PPChameleonEVB.h b/include/configs/PPChameleonEVB.h index 88e6db491b..e1155e2e43 100644 --- a/include/configs/PPChameleonEVB.h +++ b/include/configs/PPChameleonEVB.h @@ -300,8 +300,6 @@ #define NAND_ChipID_UNKNOWN 0x00 #define NAND_MAX_FLOORS 1 - - #ifdef NAND_NO_RB /* constant delay (see also tR in the datasheet) */ #define NAND_WAIT_READY(nand) do { \ diff --git a/include/configs/mcc200.h b/include/configs/mcc200.h index a48c21b53a..d4dee3b77a 100644 --- a/include/configs/mcc200.h +++ b/include/configs/mcc200.h @@ -229,9 +229,8 @@ /* * GPIO configuration */ -//###CHD: MSB = 1 -> 64MB: funktioniert nicht: ERRATA - BUG? -//###CHD: 0x10000004 = 32MB SDRAM -//###CHD: 0x90000004 = 64MB SDRAM +/* 0x10000004 = 32MB SDRAM */ +/* 0x90000004 = 64MB SDRAM */ #define CFG_GPS_PORT_CONFIG 0x10000004 /* diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index c105ecc3ac..a5227188d4 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -65,7 +65,6 @@ extern void nand_release (struct mtd_info *mtd); extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen); - /* This constant declares the max. oobsize / page, which * is supported now. If you add a chip with bigger oobsize/page * adjust this accordingly. From f9e029184be5ef550d05262e0f150d31fb09d19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Mon, 6 Mar 2006 13:45:42 +0100 Subject: [PATCH 038/102] NAND finally working. Two bugs fixed: * For READ_STATUS and READID commands always 8 bytes need to be read from NDDB. Otherwise they stay there and get send to flash as the first data word when writing. * In nand_base.c the oob variable is not reset so this->oob_buf is overwritten what eventually screws up the bad block descriptor table. --- board/delta/nand.c | 42 ++++++++++++++++++++++++++++++++-------- drivers/nand/nand_base.c | 13 +++++++++++-- include/configs/delta.h | 10 +++++++--- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/board/delta/nand.c b/board/delta/nand.c index 9f882a52b9..88e190268e 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -31,8 +31,13 @@ /* mk@tbd move this to pxa-regs */ #define OSCR_CLK_FREQ 3.250 /* MHz */ +/* usefull */ #define CFG_DFC_DEBUG1 -#define CFG_DFC_DEBUG2 +/* noisy */ +#undef CFG_DFC_DEBUG2 +/* wild west */ +#undef CFG_DFC_DEBUG3 + #ifdef CFG_DFC_DEBUG1 # define DFC_DEBUG1(fmt, args...) printf(fmt, ##args) @@ -46,6 +51,12 @@ # define DFC_DEBUG2(fmt, args...) #endif +#ifdef CFG_DFC_DEBUG3 +# define DFC_DEBUG3(fmt, args...) printf(fmt, ##args) +#else +# define DFC_DEBUG3(fmt, args...) +#endif + static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; static struct nand_bbt_descr delta_bbt_descr = { @@ -56,7 +67,7 @@ static struct nand_bbt_descr delta_bbt_descr = { }; static struct nand_oobinfo delta_oob = { - .useecc = MTD_NANDECC_AUTOPLACE, + .useecc = MTD_NANDECC_AUTOPL_USR, /* MTD_NANDECC_PLACEONLY, */ .eccbytes = 6, .eccpos = {2, 3, 4, 5, 6, 7}, .oobfree = { {8, 2}, {12, 4} } @@ -90,7 +101,8 @@ static void delta_write_buf(struct mtd_info *mtd, const u_char *buf, int len) unsigned long rest = len & 0x3; unsigned long *long_buf; int i; - + + DFC_DEBUG2("delta_write_buf: writing %d bytes starting with 0x%x.\n", len, *((unsigned long*) buf)); if(bytes_multi) { for(i=0; ipriv pointer */ static unsigned long read_buf = 0; static int bytes_read = -1; +static unsigned long last_cmd = 0; /* read a byte from NDDB Because we can only read 4 bytes from NDDB at * a time, we buffer the remaining bytes. The buffer is reset when a @@ -176,16 +190,18 @@ static u_char delta_read_byte(struct mtd_info *mtd) { /* struct nand_chip *this = mtd->priv; */ unsigned char byte; + unsigned long dummy; if(bytes_read < 0) { read_buf = NDDB; + dummy = NDDB; bytes_read = 0; } byte = (unsigned char) (read_buf>>(8 * bytes_read++)); if(bytes_read >= 4) bytes_read = -1; - DFC_DEBUG2("delta_read_byte: byte %u: 0x%x of (0x%x).\n", bytes_read, byte, read_buf); + DFC_DEBUG2("delta_read_byte: byte %u: 0x%x of (0x%x).\n", bytes_read - 1, byte, read_buf); return byte; } @@ -330,13 +346,15 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, /* clear the ugly byte read buffer */ bytes_read = -1; read_buf = 0; - + last_cmd = 0; + /* if command is a double byte cmd, we set bit double cmd bit 19 */ /* command2 = (command>>8) & 0xFF; */ /* ndcb0 = command | ((command2 ? 1 : 0) << 19); *\/ */ switch (command) { case NAND_CMD_READ0: + DFC_DEBUG3("delta_cmdfunc: NAND_CMD_READ0, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); delta_new_cmd(); ndcb0 = (NAND_CMD_READ0 | (4<<16)); column >>= 1; /* adjust for 16 bit bus */ @@ -346,7 +364,14 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, ((page_addr<<8) & 0xff000000)); /* make this 0x01000000 ? */ event = NDSR_RDDREQ; goto write_cmd; + case NAND_CMD_READ1: + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_READ1 unimplemented!\n"); + goto end; + case NAND_CMD_READOOB: + DFC_DEBUG1("delta_cmdfunc: NAND_CMD_READOOB unimplemented!\n"); + goto end; case NAND_CMD_READID: + last_cmd = NAND_CMD_READID; delta_new_cmd(); DFC_DEBUG2("delta_cmdfunc: NAND_CMD_READID.\n"); ndcb0 = (NAND_CMD_READID | (3 << 21) | (1 << 16)); /* addr cycles*/ @@ -357,7 +382,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, DFC_DEBUG2("delta_cmdfunc: NAND_CMD_PAGEPROG empty due to multicmd.\n"); goto end; case NAND_CMD_ERASE1: - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_ERASE1.\n"); + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_ERASE1, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); delta_new_cmd(); ndcb0 = (0xd060 | (1<<25) | (2<<21) | (1<<19) | (3<<16)); ndcb1 = (page_addr & 0x00ffffff); @@ -368,7 +393,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, case NAND_CMD_SEQIN: /* send PAGE_PROG command(0x1080) */ delta_new_cmd(); - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG.\n"); + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); ndcb0 = (0x1080 | (1<<25) | (1<<21) | (1<<19) | (4<<16)); column >>= 1; /* adjust for 16 bit bus */ ndcb1 = (((column>>1) & 0xff) | @@ -562,6 +587,7 @@ void board_nand_init(struct nand_chip *nand) #define MIN(x, y) ((x < y) ? x : y) +#undef CFG_TIMING_TIGHT #ifndef CFG_TIMING_TIGHT tCH = MIN(((unsigned long) (NAND_TIMING_tCH * DFC_CLK_PER_US) + 1), DFC_MAX_tCH); @@ -646,7 +672,7 @@ void board_nand_init(struct nand_chip *nand) NDCR = (NDCR_SPARE_EN | /* use the spare area */ NDCR_DWIDTH_C | /* 16bit DFC data bus width */ NDCR_DWIDTH_M | /* 16 bit Flash device data bus width */ - (7 << 16) | /* read id count = 7 ???? mk@tbd */ + (2 << 16) | /* read id count = 7 ???? mk@tbd */ NDCR_ND_ARB_EN | /* enable bus arbiter */ NDCR_RDYM | /* flash device ready ir masked */ NDCR_CS0_PAGEDM | /* ND_nCSx page done ir masked */ diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c index b039c3cd8c..a5792cfb52 100644 --- a/drivers/nand/nand_base.c +++ b/drivers/nand/nand_base.c @@ -489,6 +489,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) return nand_write_oob (mtd, ofs , 2, &retlen, buf); } +#if READ_STATUS_BUG /** * nand_check_wp - [GENERIC] check if the chip is write protected * @mtd: MTD device structure @@ -503,7 +504,12 @@ static int nand_check_wp (struct mtd_info *mtd) this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); return (this->read_byte(mtd) & 0x80) ? 0 : 1; } - +#else +static int nand_check_wp (struct mtd_info *mtd) +{ + return 0; +} +#endif /** * nand_block_checkbad - [GENERIC] Check if a block is marked bad * @mtd: MTD device structure @@ -1721,6 +1727,8 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, numpages = min (totalpages, ppblock); page &= this->pagemask; startpage = page; + oob = 0; + this->oobdirty = 1; oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages); /* Check, if we cross a chip boundary */ @@ -2145,13 +2153,14 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb instr->state = MTD_ERASING; while (len) { +#ifndef NAND_ALLOW_ERASE_ALL /* Check if we have a bad block, we do not erase bad blocks ! */ if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) { printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page); instr->state = MTD_ERASE_FAILED; goto erase_exit; } - +#endif /* Invalidate the page cache, if we erase the block which contains the current cached page */ if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) diff --git a/include/configs/delta.h b/include/configs/delta.h index 99ce0f621b..3a94661caf 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -43,7 +43,7 @@ /* * Size of malloc() pool */ -#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) +#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 256*1024) #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ /* @@ -164,7 +164,7 @@ */ /* Use the new NAND code. (BOARDLIBS = drivers/nand/libnand.a required) */ #define CONFIG_NEW_NAND_CODE -#define CFG_NAND0_BASE 0x43100040 /* 0x10000000 */ +#define CFG_NAND0_BASE 0x0 /* 0x43100040 */ /* 0x10000000 */ #undef CFG_NAND1_BASE #define CFG_NAND_BASE_LIST { CFG_NAND0_BASE } @@ -174,9 +174,13 @@ #define NAND_DELAY_US 25 /* mk@tbd: could be 0, I guess */ /* nand timeout values */ -#define CFG_NAND_PROG_ERASE_TO 300 +#define CFG_NAND_PROG_ERASE_TO 3000 #define CFG_NAND_OTHER_TO 100 #define CFG_NAND_SENDCMD_RETRY 3 +#define NAND_ALLOW_ERASE_ALL 1 + +#define CONFIG_MTD_DEBUG +#define CONFIG_MTD_DEBUG_VERBOSE 1 #define ADDR_COLUMN 1 #define ADDR_PAGE 2 From 43638c674a1bc57eef41439e87c281269a08cb16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Mon, 6 Mar 2006 15:04:25 +0100 Subject: [PATCH 039/102] Cleanup of NAND support of delta board using the Monahans Data Flash Controller. --- board/delta/nand.c | 278 ++++++++-------------------- cpu/pxa/start.S | 10 +- drivers/nand/nand_base.c | 8 +- include/asm-arm/arch-pxa/pxa-regs.h | 17 ++ include/configs/delta.h | 22 ++- 5 files changed, 124 insertions(+), 211 deletions(-) diff --git a/board/delta/nand.c b/board/delta/nand.c index 88e190268e..5876727f4e 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -28,17 +28,6 @@ #include #include -/* mk@tbd move this to pxa-regs */ -#define OSCR_CLK_FREQ 3.250 /* MHz */ - -/* usefull */ -#define CFG_DFC_DEBUG1 -/* noisy */ -#undef CFG_DFC_DEBUG2 -/* wild west */ -#undef CFG_DFC_DEBUG3 - - #ifdef CFG_DFC_DEBUG1 # define DFC_DEBUG1(fmt, args...) printf(fmt, ##args) #else @@ -57,6 +46,9 @@ # define DFC_DEBUG3(fmt, args...) #endif +#define MIN(x, y) ((x < y) ? x : y) + +/* These really don't belong here, as they are specific to the NAND Model */ static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; static struct nand_bbt_descr delta_bbt_descr = { @@ -77,13 +69,14 @@ static struct nand_oobinfo delta_oob = { /* * not required for Monahans DFC */ -static void delta_hwcontrol(struct mtd_info *mtdinfo, int cmd) +static void dfc_hwcontrol(struct mtd_info *mtdinfo, int cmd) { return; } +#if 0 /* read device ready pin */ -static int delta_device_ready(struct mtd_info *mtdinfo) +static int dfc_device_ready(struct mtd_info *mtdinfo) { if(NDSR & NDSR_RDY) return 1; @@ -91,18 +84,19 @@ static int delta_device_ready(struct mtd_info *mtdinfo) return 0; return 0; } +#endif /* * Write buf to the DFC Controller Data Buffer */ -static void delta_write_buf(struct mtd_info *mtd, const u_char *buf, int len) +static void dfc_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { unsigned long bytes_multi = len & 0xfffffffc; unsigned long rest = len & 0x3; unsigned long *long_buf; int i; - DFC_DEBUG2("delta_write_buf: writing %d bytes starting with 0x%x.\n", len, *((unsigned long*) buf)); + DFC_DEBUG2("dfc_write_buf: writing %d bytes starting with 0x%x.\n", len, *((unsigned long*) buf)); if(bytes_multi) { for(i=0; ipriv pointer */ static unsigned long read_buf = 0; static int bytes_read = -1; -static unsigned long last_cmd = 0; -/* read a byte from NDDB Because we can only read 4 bytes from NDDB at +/* + * read a byte from NDDB Because we can only read 4 bytes from NDDB at * a time, we buffer the remaining bytes. The buffer is reset when a * new command is sent to the chip. + * + * WARNING: + * This function is currently only used to read status and id + * bytes. For these commands always 8 bytes need to be read from + * NDDB. So we read and discard these bytes right now. In case this + * function is used for anything else in the future, we must check + * what was the last command issued and read the appropriate amount of + * bytes respectively. */ -static u_char delta_read_byte(struct mtd_info *mtd) +static u_char dfc_read_byte(struct mtd_info *mtd) { -/* struct nand_chip *this = mtd->priv; */ unsigned char byte; unsigned long dummy; @@ -201,7 +203,7 @@ static u_char delta_read_byte(struct mtd_info *mtd) if(bytes_read >= 4) bytes_read = -1; - DFC_DEBUG2("delta_read_byte: byte %u: 0x%x of (0x%x).\n", bytes_read - 1, byte, read_buf); + DFC_DEBUG2("dfc_read_byte: byte %u: 0x%x of (0x%x).\n", bytes_read - 1, byte, read_buf); return byte; } @@ -227,14 +229,14 @@ static void wait_us(unsigned long us) } } -static void delta_clear_nddb() +static void dfc_clear_nddb() { NDCR &= ~NDCR_ND_RUN; wait_us(CFG_NAND_OTHER_TO); } /* wait_event with timeout */ -static unsigned long delta_wait_event2(unsigned long event) +static unsigned long dfc_wait_event(unsigned long event) { unsigned long ndsr, timeout, start = OSCR; @@ -252,7 +254,7 @@ static unsigned long delta_wait_event2(unsigned long event) break; } if(get_delta(start) > timeout) { - DFC_DEBUG1("delta_wait_event: TIMEOUT waiting for event: 0x%x.\n", event); + DFC_DEBUG1("dfc_wait_event: TIMEOUT waiting for event: 0x%x.\n", event); return 0xff000000; } @@ -260,25 +262,8 @@ static unsigned long delta_wait_event2(unsigned long event) return ndsr; } - -#if DEADCODE -/* poll the NAND Controller Status Register for event */ -static void delta_wait_event(unsigned long event) -{ - if(!event) - return; - - while(1) { - if(NDSR & event) { - NDSR |= event; - break; - } - } -} -#endif - /* we don't always wan't to do this */ -static void delta_new_cmd() +static void dfc_new_cmd() { int retry = 0; unsigned long status; @@ -291,29 +276,20 @@ static void delta_new_cmd() if(!(NDCR & NDCR_ND_RUN)) NDCR |= NDCR_ND_RUN; - status = delta_wait_event2(NDSR_WRCMDREQ); + status = dfc_wait_event(NDSR_WRCMDREQ); if(status & NDSR_WRCMDREQ) return; - DFC_DEBUG2("delta_new_cmd: FAILED to get WRITECMDREQ, retry: %d.\n", retry); - delta_clear_nddb(); + DFC_DEBUG2("dfc_new_cmd: FAILED to get WRITECMDREQ, retry: %d.\n", retry); + dfc_clear_nddb(); } - DFC_DEBUG1("delta_new_cmd: giving up after %d retries.\n", retry); - -#if DEADCODE - while(1) { - if(NDSR & NDSR_WRCMDREQ) { - NDSR |= NDSR_WRCMDREQ; /* Ack */ - break; - } - } -#endif - + DFC_DEBUG1("dfc_new_cmd: giving up after %d retries.\n", retry); } + /* this function is called after Programm and Erase Operations to * check for success or failure */ -static int delta_wait(struct mtd_info *mtd, struct nand_chip *this, int state) +static int dfc_wait(struct mtd_info *mtd, struct nand_chip *this, int state) { unsigned long ndsr=0, event=0; @@ -328,7 +304,7 @@ static int delta_wait(struct mtd_info *mtd, struct nand_chip *this, int state) event = NDSR_CS0_CMDD | NDSR_CS0_BBD; } - ndsr = delta_wait_event2(event); + ndsr = dfc_wait_event(event); if((ndsr & NDSR_CS0_BBD) || (ndsr & 0xff000000)) return(0x1); /* Status Read error */ @@ -336,26 +312,20 @@ static int delta_wait(struct mtd_info *mtd, struct nand_chip *this, int state) } /* cmdfunc send commands to the DFC */ -static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, - int column, int page_addr) +static void dfc_cmdfunc(struct mtd_info *mtd, unsigned command, + int column, int page_addr) { /* register struct nand_chip *this = mtd->priv; */ unsigned long ndcb0=0, ndcb1=0, ndcb2=0, event=0; - unsigned long what_the_hack; /* clear the ugly byte read buffer */ bytes_read = -1; read_buf = 0; - last_cmd = 0; - - /* if command is a double byte cmd, we set bit double cmd bit 19 */ - /* command2 = (command>>8) & 0xFF; */ - /* ndcb0 = command | ((command2 ? 1 : 0) << 19); *\/ */ switch (command) { case NAND_CMD_READ0: - DFC_DEBUG3("delta_cmdfunc: NAND_CMD_READ0, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); - delta_new_cmd(); + DFC_DEBUG3("dfc_cmdfunc: NAND_CMD_READ0, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); + dfc_new_cmd(); ndcb0 = (NAND_CMD_READ0 | (4<<16)); column >>= 1; /* adjust for 16 bit bus */ ndcb1 = (((column>>1) & 0xff) | @@ -365,35 +335,34 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, event = NDSR_RDDREQ; goto write_cmd; case NAND_CMD_READ1: - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_READ1 unimplemented!\n"); + DFC_DEBUG2("dfc_cmdfunc: NAND_CMD_READ1 unimplemented!\n"); goto end; case NAND_CMD_READOOB: - DFC_DEBUG1("delta_cmdfunc: NAND_CMD_READOOB unimplemented!\n"); + DFC_DEBUG1("dfc_cmdfunc: NAND_CMD_READOOB unimplemented!\n"); goto end; case NAND_CMD_READID: - last_cmd = NAND_CMD_READID; - delta_new_cmd(); - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_READID.\n"); + dfc_new_cmd(); + DFC_DEBUG2("dfc_cmdfunc: NAND_CMD_READID.\n"); ndcb0 = (NAND_CMD_READID | (3 << 21) | (1 << 16)); /* addr cycles*/ event = NDSR_RDDREQ; goto write_cmd; case NAND_CMD_PAGEPROG: /* sent as a multicommand in NAND_CMD_SEQIN */ - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_PAGEPROG empty due to multicmd.\n"); + DFC_DEBUG2("dfc_cmdfunc: NAND_CMD_PAGEPROG empty due to multicmd.\n"); goto end; case NAND_CMD_ERASE1: - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_ERASE1, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); - delta_new_cmd(); + DFC_DEBUG2("dfc_cmdfunc: NAND_CMD_ERASE1, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); + dfc_new_cmd(); ndcb0 = (0xd060 | (1<<25) | (2<<21) | (1<<19) | (3<<16)); ndcb1 = (page_addr & 0x00ffffff); goto write_cmd; case NAND_CMD_ERASE2: - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_ERASE2 empty due to multicmd.\n"); + DFC_DEBUG2("dfc_cmdfunc: NAND_CMD_ERASE2 empty due to multicmd.\n"); goto end; case NAND_CMD_SEQIN: /* send PAGE_PROG command(0x1080) */ - delta_new_cmd(); - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); + dfc_new_cmd(); + DFC_DEBUG2("dfc_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); ndcb0 = (0x1080 | (1<<25) | (1<<21) | (1<<19) | (4<<16)); column >>= 1; /* adjust for 16 bit bus */ ndcb1 = (((column>>1) & 0xff) | @@ -402,72 +371,19 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, ((page_addr<<8) & 0xff000000)); /* make this 0x01000000 ? */ event = NDSR_WRDREQ; goto write_cmd; -/* case NAND_CMD_SEQIN_pointer_operation: */ - -/* /\* This is confusing because the command names are */ -/* * different compared to the ones in the K9K12Q0C */ -/* * datasheet. Infact this has nothing to do with */ -/* * reading, as the but with page programming */ -/* * (writing). */ -/* * Here we send the multibyte commands */ -/* * cmd1=0x00, cmd2=0x80 (for programming main area) or */ -/* * cmd1=0x50, cmd2=0x80 (for spare area) */ -/* * */ -/* * When all data is written to the buffer, the page */ -/* * program command (0x10) is sent to actually write */ -/* * the data. */ -/* *\/ */ - -/* printf("delta_cmdfunc: NAND_CMD_SEQIN pointer op called.\n"); */ - -/* ndcb0 = (NAND_CMD_SEQIN<<8) | (1<<21) | (1<<19) | (4<<16); */ -/* if(column >= mtd->oobblock) { */ -/* /\* OOB area *\/ */ -/* column -= mtd->oobblock; */ -/* ndcb0 |= NAND_CMD_READOOB; */ -/* } else if (column < 256) { */ -/* /\* First 256 bytes --> READ0 *\/ */ -/* ndcb0 |= NAND_CMD_READ0; */ -/* } else { */ -/* /\* Only for 8 bit devices - not delta!!! *\/ */ -/* column -= 256; */ -/* ndcb0 |= NAND_CMD_READ1; */ -/* } */ -/* event = NDSR_WRDREQ; */ -/* break; */ case NAND_CMD_STATUS: - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_STATUS.\n"); - /* oh, this is not nice. for some reason the real - * status byte is in the second read from the data - * buffer. The hack is to read the first byte right - * here, so the next read access by the nand code - * yields the right one. - */ - delta_new_cmd(); + DFC_DEBUG2("dfc_cmdfunc: NAND_CMD_STATUS.\n"); + dfc_new_cmd(); ndcb0 = NAND_CMD_STATUS | (4<<21); event = NDSR_RDDREQ; -#undef READ_STATUS_BUG -#ifdef READ_STATUS_BUG - NDCB0 = ndcb0; - NDCB0 = ndcb1; - NDCB0 = ndcb2; - delta_wait_event2(event); - what_the_hack = NDDB; - if(what_the_hack != 0xffffffff) { - DFC_DEBUG2("what the hack.\n"); - read_buf = what_the_hack; - bytes_read = 0; - } - goto end; -#endif goto write_cmd; case NAND_CMD_RESET: - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_RESET.\n"); + DFC_DEBUG2("dfc_cmdfunc: NAND_CMD_RESET.\n"); ndcb0 = NAND_CMD_RESET | (5<<21); event = NDSR_CS0_CMDD; goto write_cmd; default: - printk("delta_cmdfunc: error, unsupported command.\n"); + printk("dfc_cmdfunc: error, unsupported command.\n"); goto end; } @@ -476,13 +392,13 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, NDCB0 = ndcb1; NDCB0 = ndcb2; - wait_event: - delta_wait_event2(event); + /* wait_event: */ + dfc_wait_event(event); end: return; } -static void delta_dfc_gpio_init() +static void dfc_gpio_init() { DFC_DEBUG2("Setting up DFC GPIO's.\n"); @@ -542,51 +458,11 @@ void board_nand_init(struct nand_chip *nand) unsigned long tCH, tCS, tWH, tWP, tRH, tRP, tRP_high, tR, tWHR, tAR; /* set up GPIO Control Registers */ - delta_dfc_gpio_init(); + dfc_gpio_init(); /* turn on the NAND Controller Clock (104 MHz @ D0) */ CKENA |= (CKENA_4_NAND | CKENA_9_SMC); - /* wait ? */ -/* printf("stupid loop start...\n"); */ -/* wait(200); */ -/* printf("stupid loop end.\n"); */ - - - /* NAND Timing Parameters (in ns) */ -#define NAND_TIMING_tCH 10 -#define NAND_TIMING_tCS 0 -#define NAND_TIMING_tWH 20 -#define NAND_TIMING_tWP 40 - -#define NAND_TIMING_tRH 20 -#define NAND_TIMING_tRP 40 - -/* #define NAND_TIMING_tRH 25 */ -/* #define NAND_TIMING_tRP 50 */ - -#define NAND_TIMING_tR 11123 -/* #define NAND_TIMING_tWHR 110 */ -#define NAND_TIMING_tWHR 100 -#define NAND_TIMING_tAR 10 - -/* Maximum values for NAND Interface Timing Registers in DFC clock - * periods */ -#define DFC_MAX_tCH 7 -#define DFC_MAX_tCS 7 -#define DFC_MAX_tWH 7 -#define DFC_MAX_tWP 7 -#define DFC_MAX_tRH 7 -#define DFC_MAX_tRP 15 -#define DFC_MAX_tR 65535 -#define DFC_MAX_tWHR 15 -#define DFC_MAX_tAR 15 - -#define DFC_CLOCK 104 /* DFC Clock is 104 MHz */ -#define DFC_CLK_PER_US DFC_CLOCK/1000 /* clock period in ns */ -#define MIN(x, y) ((x < y) ? x : y) - - #undef CFG_TIMING_TIGHT #ifndef CFG_TIMING_TIGHT tCH = MIN(((unsigned long) (NAND_TIMING_tCH * DFC_CLK_PER_US) + 1), @@ -692,25 +568,25 @@ void board_nand_init(struct nand_chip *nand) /* wait(10); */ - nand->hwcontrol = delta_hwcontrol; -/* nand->dev_ready = delta_device_ready; */ + nand->hwcontrol = dfc_hwcontrol; +/* nand->dev_ready = dfc_device_ready; */ nand->eccmode = NAND_ECC_SOFT; nand->chip_delay = NAND_DELAY_US; nand->options = NAND_BUSWIDTH_16; - nand->waitfunc = delta_wait; - nand->read_byte = delta_read_byte; - nand->write_byte = delta_write_byte; - nand->read_word = delta_read_word; - nand->write_word = delta_write_word; - nand->read_buf = delta_read_buf; - nand->write_buf = delta_write_buf; + nand->waitfunc = dfc_wait; + nand->read_byte = dfc_read_byte; + nand->write_byte = dfc_write_byte; + nand->read_word = dfc_read_word; + nand->write_word = dfc_write_word; + nand->read_buf = dfc_read_buf; + nand->write_buf = dfc_write_buf; - nand->cmdfunc = delta_cmdfunc; + nand->cmdfunc = dfc_cmdfunc; nand->autooob = &delta_oob; nand->badblock_pattern = &delta_bbt_descr; } #else - #error "U-Boot legacy NAND support not available for delta board." + #error "U-Boot legacy NAND support not available for Monahans DFC." #endif #endif diff --git a/cpu/pxa/start.S b/cpu/pxa/start.S index 0eb811f20e..7e5a1ee495 100644 --- a/cpu/pxa/start.S +++ b/cpu/pxa/start.S @@ -165,7 +165,15 @@ _start_armboot: .word start_armboot /* - setup memory timing */ /* */ /****************************************************************************/ - +/* mk@tbd: Fix this! */ +#ifdef CONFIG_CPU_MONAHANS +#undef ICMR +#undef OSMR3 +#undef OSCR +#undef OWER +#undef OIER +#endif + /* Interrupt-Controller base address */ IC_BASE: .word 0x40d00000 #define ICMR 0x04 diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c index a5792cfb52..d6c84fb533 100644 --- a/drivers/nand/nand_base.c +++ b/drivers/nand/nand_base.c @@ -489,7 +489,6 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) return nand_write_oob (mtd, ofs , 2, &retlen, buf); } -#if READ_STATUS_BUG /** * nand_check_wp - [GENERIC] check if the chip is write protected * @mtd: MTD device structure @@ -504,12 +503,7 @@ static int nand_check_wp (struct mtd_info *mtd) this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); return (this->read_byte(mtd) & 0x80) ? 0 : 1; } -#else -static int nand_check_wp (struct mtd_info *mtd) -{ - return 0; -} -#endif + /** * nand_block_checkbad - [GENERIC] Check if a block is marked bad * @mtd: MTD device structure diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 6236405b3a..5d36b84b07 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -880,6 +880,8 @@ typedef void (*ExcpHndlr) (void) ; #define OMCR9 __REG(0x40A000D4) /* OS Match Control Register 9 */ #define OMCR10 __REG(0x40A000D8) /* OS Match Control Register 10 */ #define OMCR11 __REG(0x40A000DC) /* OS Match Control Register 11 */ + +#define OSCR_CLK_FREQ 3.250 /* MHz */ #endif /* CONFIG_CPU_MONAHANS */ #define OSSR_M4 (1 << 4) /* Match status channel 4 */ @@ -2132,6 +2134,21 @@ typedef void (*ExcpHndlr) (void) ; #define MCIO(s) MCIO0 #define MECR_CIT (1 << 1)/* Card Is There: 0 -> no card, 1 -> card inserted */ +/* Maximum values for NAND Interface Timing Registers in DFC clock + * periods */ +#define DFC_MAX_tCH 7 +#define DFC_MAX_tCS 7 +#define DFC_MAX_tWH 7 +#define DFC_MAX_tWP 7 +#define DFC_MAX_tRH 7 +#define DFC_MAX_tRP 15 +#define DFC_MAX_tR 65535 +#define DFC_MAX_tWHR 15 +#define DFC_MAX_tAR 15 + +#define DFC_CLOCK 104 /* DFC Clock is 104 MHz */ +#define DFC_CLK_PER_US DFC_CLOCK/1000 /* clock period in ns */ + #else /* CONFIG_CPU_MONAHANS */ #define MEMC_BASE __REG(0x48000000) /* Base of Memory Controller */ diff --git a/include/configs/delta.h b/include/configs/delta.h index 3a94661caf..2a0a8fd5ee 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -170,14 +170,32 @@ #define CFG_NAND_BASE_LIST { CFG_NAND0_BASE } #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512 -/* #define NAND_NO_RB */ #define NAND_DELAY_US 25 /* mk@tbd: could be 0, I guess */ /* nand timeout values */ #define CFG_NAND_PROG_ERASE_TO 3000 #define CFG_NAND_OTHER_TO 100 #define CFG_NAND_SENDCMD_RETRY 3 -#define NAND_ALLOW_ERASE_ALL 1 +#undef NAND_ALLOW_ERASE_ALL /* Allow erasing bad blocks - don't use */ + +/* NAND Timing Parameters (in ns) */ +#define NAND_TIMING_tCH 10 +#define NAND_TIMING_tCS 0 +#define NAND_TIMING_tWH 20 +#define NAND_TIMING_tWP 40 + +#define NAND_TIMING_tRH 20 +#define NAND_TIMING_tRP 40 + +#define NAND_TIMING_tR 11123 +/* #define NAND_TIMING_tWHR 110 */ +#define NAND_TIMING_tWHR 100 +#define NAND_TIMING_tAR 10 + +/* NAND debugging */ +#define CFG_DFC_DEBUG1 /* usefull */ +#undef CFG_DFC_DEBUG2 /* noisy */ +#undef CFG_DFC_DEBUG3 /* extremly noisy */ #define CONFIG_MTD_DEBUG #define CONFIG_MTD_DEBUG_VERBOSE 1 From ac7d97dcbb499c96c8182757f301dd2e09c9f49d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Mon, 6 Mar 2006 18:47:44 +0100 Subject: [PATCH 040/102] Turned on SDRAM scrubbing. --- include/configs/delta.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/delta.h b/include/configs/delta.h index 2a0a8fd5ee..8c848c35be 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -157,7 +157,7 @@ #define CFG_DRAM_BASE 0xa0000000 /* at CS0 */ #define CFG_DRAM_SIZE 0x04000000 /* 64 MB Ram */ -#define CFG_SKIP_DRAM_SCRUB 1 +#undef CFG_SKIP_DRAM_SCRUB /* * NAND Flash From 0be248fa9a32667d29b0eb1bad77bbd372903e61 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 7 Mar 2006 00:22:36 +0100 Subject: [PATCH 041/102] Cleanup (get rid of debug code that sneaked in) --- MAKEALL | 6 +++--- Makefile | 9 +++------ config.mk | 9 --------- cpu/pxa/config.mk | 1 - drivers/smc91111.c | 2 +- include/asm-arm/global_data.h | 7 +------ lib_arm/board.c | 2 -- 7 files changed, 8 insertions(+), 28 deletions(-) diff --git a/MAKEALL b/MAKEALL index 65b1761ee4..582357c71f 100755 --- a/MAKEALL +++ b/MAKEALL @@ -203,9 +203,9 @@ LIST_ARM11=" \ LIST_pxa=" \ adsvix cerf250 cradle csb226 \ - innokom lubbock pxa255_idp wepep250 \ - xaeniax xm250 xsengine zylonite \ - delta + delta innokom lubbock pxa255_idp \ + wepep250 xaeniax xm250 xsengine \ + zylonite \ " LIST_ixp="ixdp425" diff --git a/Makefile b/Makefile index 67eb0dc0bb..4192856a6f 100644 --- a/Makefile +++ b/Makefile @@ -208,9 +208,6 @@ etags: net disk rtc dtt drivers drivers/sk98lin common \ \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)` -ctags: - ctags -Re - System.map: u-boot @$(NM) $< | \ grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ @@ -1644,12 +1641,12 @@ cerf250_config : unconfig cradle_config : unconfig @./mkconfig $(@:_config=) arm pxa cradle -delta_config : - @./mkconfig $(@:_config=) arm pxa delta - csb226_config : unconfig @./mkconfig $(@:_config=) arm pxa csb226 +delta_config : + @./mkconfig $(@:_config=) arm pxa delta + innokom_config : unconfig @./mkconfig $(@:_config=) arm pxa innokom diff --git a/config.mk b/config.mk index aef099ec86..d85ac36b5e 100644 --- a/config.mk +++ b/config.mk @@ -131,15 +131,6 @@ else CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes endif -ifdef WILD_WILD_WEST -CFLAGS := $(CPPFLAGS) -Werror -endif - -ifdef NO_JUMP -CFLAGS := $(CPPFLAGS) -fno-schedule-insns -fno-schedule-insns2 -endif - - # avoid trigraph warnings while parsing pci.h (produced by NIOS gcc-2.9) # this option have to be placed behind -Wall -- that's why it is here ifeq ($(ARCH),nios) diff --git a/cpu/pxa/config.mk b/cpu/pxa/config.mk index f30a1fe1ad..fb810ca7c2 100644 --- a/cpu/pxa/config.mk +++ b/cpu/pxa/config.mk @@ -33,5 +33,4 @@ PLATFORM_CPPFLAGS += -march=armv5 -mtune=xscale # # ======================================================================== PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -# for gcc-3x: PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/drivers/smc91111.c b/drivers/smc91111.c index 7941244f17..060da8ff2a 100644 --- a/drivers/smc91111.c +++ b/drivers/smc91111.c @@ -72,7 +72,7 @@ #define NO_AUTOPROBE -#define SMC_DEBUG 3 +#define SMC_DEBUG 0 #if SMC_DEBUG > 1 static const char version[] = diff --git a/include/asm-arm/global_data.h b/include/asm-arm/global_data.h index 0b6c8171ed..c2d52915a8 100644 --- a/include/asm-arm/global_data.h +++ b/include/asm-arm/global_data.h @@ -61,11 +61,6 @@ typedef struct global_data { #define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */ #define GD_FLG_SILENT 0x00004 /* Silent mode */ -#undef GCC_4_SCREW_GDP -#ifdef GCC_4_SCREW_GDP -# define DECLARE_GLOBAL_DATA_PTR register gd_t* volatile gd asm ("r8"); -#else -# define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8") -#endif +#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8") #endif /* __ASM_GBL_DATA_H */ diff --git a/lib_arm/board.c b/lib_arm/board.c index 0f3a999d14..c73cf0c38f 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -38,8 +38,6 @@ * FIQ Stack: 00ebef7c */ -#define DEBUG 1 - #include #include #include From 1f62bc2d084e4ab9a19a4f803d355cc129b5fa4a Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 7 Mar 2006 00:32:07 +0100 Subject: [PATCH 042/102] Add support for TQM8260-AI boards. --- CHANGELOG | 2 ++ Makefile | 22 ++++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9af10e84c9..18eb5c5897 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add support for TQM8260-AI boards. + * Minor code cleanup * Merge the new NAND code (testing-NAND brach); see doc/README.nand diff --git a/Makefile b/Makefile index 4192856a6f..29d323a0ce 100644 --- a/Makefile +++ b/Makefile @@ -1208,18 +1208,20 @@ TQM8260_AE_config \ TQM8260_AF_config \ TQM8260_AG_config \ TQM8260_AH_config \ +TQM8260_AI_config \ TQM8265_AA_config: unconfig @case "$@" in \ - TQM8255_AA_config) CTYPE=MPC8255; CFREQ=300; CACHE=no; BMODE=8260;; \ - TQM8260_AA_config) CTYPE=MPC8260; CFREQ=200; CACHE=no; BMODE=8260;; \ - TQM8260_AB_config) CTYPE=MPC8260; CFREQ=200; CACHE=yes; BMODE=60x;; \ - TQM8260_AC_config) CTYPE=MPC8260; CFREQ=200; CACHE=yes; BMODE=60x;; \ - TQM8260_AD_config) CTYPE=MPC8260; CFREQ=300; CACHE=no; BMODE=60x;; \ - TQM8260_AE_config) CTYPE=MPC8260; CFREQ=266; CACHE=no; BMODE=8260;; \ - TQM8260_AF_config) CTYPE=MPC8260; CFREQ=300; CACHE=no; BMODE=60x;; \ - TQM8260_AG_config) CTYPE=MPC8260; CFREQ=300; CACHE=no; BMODE=8260;; \ - TQM8260_AH_config) CTYPE=MPC8260; CFREQ=300; CACHE=yes; BMODE=60x;; \ - TQM8265_AA_config) CTYPE=MPC8265; CFREQ=300; CACHE=no; BMODE=60x;; \ + TQM8255_AA_config) CTYPE=MPC8255; CFREQ=300; CACHE=no; BMODE=8260;; \ + TQM8260_AA_config) CTYPE=MPC8260; CFREQ=200; CACHE=no; BMODE=8260;; \ + TQM8260_AB_config) CTYPE=MPC8260; CFREQ=200; CACHE=yes; BMODE=60x;; \ + TQM8260_AC_config) CTYPE=MPC8260; CFREQ=200; CACHE=yes; BMODE=60x;; \ + TQM8260_AD_config) CTYPE=MPC8260; CFREQ=300; CACHE=no; BMODE=60x;; \ + TQM8260_AE_config) CTYPE=MPC8260; CFREQ=266; CACHE=no; BMODE=8260;; \ + TQM8260_AF_config) CTYPE=MPC8260; CFREQ=300; CACHE=no; BMODE=60x;; \ + TQM8260_AG_config) CTYPE=MPC8260; CFREQ=300; CACHE=no; BMODE=8260;; \ + TQM8260_AH_config) CTYPE=MPC8260; CFREQ=300; CACHE=yes; BMODE=60x;; \ + TQM8260_AI_config) CTYPE=MPC8260; CFREQ=300; CACHE=no; BMODE=60x;; \ + TQM8265_AA_config) CTYPE=MPC8265; CFREQ=300; CACHE=no; BMODE=60x;; \ esac; \ >include/config.h ; \ if [ "$${CTYPE}" != "MPC8260" ] ; then \ From 9c575e51dec11f304bfdc8bcc3aada7af79823b1 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 7 Mar 2006 00:33:28 +0100 Subject: [PATCH 043/102] Add support for Intel Monahans CPU on Zylonite and Delta boards (This is Work in Progress!) --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 18eb5c5897..17b0a3c53d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add support for Intel Monahans CPU on Zylonite and Delta boards + (This is Work in Progress!) + * Add support for TQM8260-AI boards. * Minor code cleanup From 3c4eb0880b5ea7c928e9abed943b3b0e0abf2de6 Mon Sep 17 00:00:00 2001 From: Markus Klotzbuecher Date: Wed, 8 Mar 2006 00:04:04 +0100 Subject: [PATCH 044/102] Some minor fixes to environment in NAND code. --- common/cmd_nvedit.c | 8 ++++++-- common/env_nand.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 1babffec2e..ecf1db489a 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -532,7 +532,9 @@ int getenv_r (char *name, char *buf, unsigned len) #if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \ ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \ - (CFG_CMD_ENV|CFG_CMD_FLASH)) + (CFG_CMD_ENV|CFG_CMD_FLASH)) || \ + ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_NAND)) == \ + (CFG_CMD_ENV|CFG_CMD_NAND)) int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { extern char * env_name_spec; @@ -588,7 +590,9 @@ U_BOOT_CMD( #if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \ ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \ - (CFG_CMD_ENV|CFG_CMD_FLASH)) + (CFG_CMD_ENV|CFG_CMD_FLASH)) || \ + ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_NAND)) == \ + (CFG_CMD_ENV|CFG_CMD_NAND)) U_BOOT_CMD( saveenv, 1, 0, do_saveenv, "saveenv - save environment variables to persistent storage\n", diff --git a/common/env_nand.c b/common/env_nand.c index 4896853530..4ae68c5a23 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -115,7 +115,7 @@ int saveenv(void) int total, ret = 0; puts ("Erasing Nand..."); - if (nand_erase(&nand_info[0], CFG_NEW_OFFSET, CFG_ENV_SIZE)) + if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE)) return 1; puts ("Writing to Nand... "); From 8371a2c0d466a3c7146083fe143cce204dd893d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Klotzb=FCcher?= Date: Wed, 8 Mar 2006 00:13:40 +0100 Subject: [PATCH 045/102] Enable simple (non-redundant) NAND environment on delta board. --- include/configs/delta.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/configs/delta.h b/include/configs/delta.h index 8e5e6128f0..b42a7e2c1a 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -73,9 +73,8 @@ #ifdef TURN_ON_ETHERNET # define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_PING) #else -# define CONFIG_COMMANDS ((CONFIG_CMD_DFL | CFG_CMD_NAND) \ - & ~(CFG_CMD_NET | CFG_CMD_FLASH | \ - CFG_CMD_ENV | CFG_CMD_IMLS)) +# define CONFIG_COMMANDS ((CONFIG_CMD_DFL | CFG_CMD_ENV | CFG_CMD_NAND) \ + & ~(CFG_CMD_NET | CFG_CMD_FLASH | CFG_CMD_IMLS)) #endif @@ -280,8 +279,8 @@ #define CFG_MONITOR_LEN PHYS_FLASH_SECT_SIZE #endif /* #ifndef CFG_NO_FLASH */ -#define CFG_ENV_IS_NOWHERE -/* #define CFG_ENV_IS_IN_NAND 1 */ +/* #define CFG_ENV_IS_NOWHERE */ +#define CFG_ENV_IS_IN_NAND 1 #define CFG_ENV_OFFSET 0x40000 #define CFG_ENV_SIZE 0x4000 From 3d65390e2116f53f5ee6615ad92262613198b66c Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Wed, 8 Mar 2006 08:32:43 +0100 Subject: [PATCH 046/102] Fixed a bug in saveenv(). Credit: Markus Klotzbuecher. > @@ -115,7 +115,7 @@ int saveenv(void) --- common/env_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/env_nand.c b/common/env_nand.c index 4896853530..4ae68c5a23 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -115,7 +115,7 @@ int saveenv(void) int total, ret = 0; puts ("Erasing Nand..."); - if (nand_erase(&nand_info[0], CFG_NEW_OFFSET, CFG_ENV_SIZE)) + if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE)) return 1; puts ("Writing to Nand... "); From 4367a01036bdb67e7fc3000cedba7195fbdee304 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sat, 11 Mar 2006 19:15:27 +0100 Subject: [PATCH 047/102] Update CHANGELOG --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 17b0a3c53d..df48e47af4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fixes to support environment in NAND flash; + enable NAND flash based environment for delta board. + * Add support for Intel Monahans CPU on Zylonite and Delta boards (This is Work in Progress!) From d52fb7e3d135704334bd6f97f3444e824665b76f Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sat, 11 Mar 2006 22:53:33 +0100 Subject: [PATCH 048/102] Some code cleanup for GCC 4.x --- CHANGELOG | 2 ++ board/at91rm9200dk/at45.c | 2 +- board/at91rm9200dk/flash.c | 4 +--- board/cmc_pu2/load_sernum_ethaddr.c | 4 ++-- board/delta/nand.c | 6 ++--- board/lart/flash.c | 2 +- board/lpd7a40x/flash.c | 3 +-- board/netstar/crcek | Bin 36168 -> 35971 bytes board/netstar/eeprom | Bin 72374 -> 40842 bytes board/netstar/flash.c | 2 +- board/netstar/nand.c | 2 ++ board/shannon/flash.c | 2 +- common/env_nand.c | 12 +++++----- cpu/arm920t/at91rm9200/i2c.c | 4 ++-- drivers/dataflash.c | 9 ++++---- drivers/lan91c96.c | 16 ++++++------- drivers/lan91c96.h | 2 +- drivers/nand/nand_base.c | 5 ++-- drivers/smc91111.c | 29 +++++++++++++++--------- drivers/smc91111.h | 2 +- include/asm-arm/arch-arm720t/s3c4510b.h | 2 -- lib_arm/armlinux.c | 4 ++-- lib_arm/board.c | 8 ++++--- rtc/rs5c372.c | 4 ++-- 24 files changed, 67 insertions(+), 59 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index df48e47af4..964e2b1f55 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Some code cleanup for GCC 4.x + * Fixes to support environment in NAND flash; enable NAND flash based environment for delta board. diff --git a/board/at91rm9200dk/at45.c b/board/at91rm9200dk/at45.c index 3c00132164..f886fe4820 100644 --- a/board/at91rm9200dk/at45.c +++ b/board/at91rm9200dk/at45.c @@ -593,7 +593,7 @@ int AT91F_DataFlashRead( if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK) return -1; - if (AT91F_DataFlashContinuousRead (pDataFlash, addr, buffer, SizeToRead) != DATAFLASH_OK) + if (AT91F_DataFlashContinuousRead (pDataFlash, addr, (uchar *)buffer, SizeToRead) != DATAFLASH_OK) return -1; size -= SizeToRead; diff --git a/board/at91rm9200dk/flash.c b/board/at91rm9200dk/flash.c index f6228ef03e..0513d61d73 100644 --- a/board/at91rm9200dk/flash.c +++ b/board/at91rm9200dk/flash.c @@ -393,8 +393,7 @@ outahere: * Copy memory to flash */ -volatile static int write_word (flash_info_t * info, ulong dest, - ulong data) +static int write_word (flash_info_t * info, ulong dest, ulong data) { volatile u16 *addr = (volatile u16 *) dest; ulong result; @@ -409,7 +408,6 @@ volatile static int write_word (flash_info_t * info, ulong dest, if ((result & data) != data) return ERR_NOT_ERASED; - /* * Disable interrupts which might cause a timeout * here. Remember that our exception vectors are diff --git a/board/cmc_pu2/load_sernum_ethaddr.c b/board/cmc_pu2/load_sernum_ethaddr.c index 94aa30df96..354566c05d 100644 --- a/board/cmc_pu2/load_sernum_ethaddr.c +++ b/board/cmc_pu2/load_sernum_ethaddr.c @@ -69,8 +69,8 @@ int i2c_read (unsigned char chip, unsigned int addr, int alen, void load_sernum_ethaddr (void) { struct manufacturer_data data; - unsigned char serial [9]; - unsigned char ethaddr[18]; + char ethaddr[18]; + char serial [9]; unsigned short chksum; unsigned char *p; unsigned short i, is, id; diff --git a/board/delta/nand.c b/board/delta/nand.c index 50def59090..c4df6e57eb 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -229,7 +229,7 @@ static void wait_us(unsigned long us) } } -static void dfc_clear_nddb() +static void dfc_clear_nddb(void) { NDCR &= ~NDCR_ND_RUN; wait_us(CFG_NAND_OTHER_TO); @@ -263,7 +263,7 @@ static unsigned long dfc_wait_event(unsigned long event) } /* we don't always wan't to do this */ -static void dfc_new_cmd() +static void dfc_new_cmd(void) { int retry = 0; unsigned long status; @@ -398,7 +398,7 @@ static void dfc_cmdfunc(struct mtd_info *mtd, unsigned command, return; } -static void dfc_gpio_init() +static void dfc_gpio_init(void) { DFC_DEBUG2("Setting up DFC GPIO's.\n"); diff --git a/board/lart/flash.c b/board/lart/flash.c index 5232ed2586..28c4531c02 100644 --- a/board/lart/flash.c +++ b/board/lart/flash.c @@ -348,7 +348,7 @@ outahere: * Copy memory to flash */ -volatile static int write_word (flash_info_t *info, ulong dest, ulong data) +static int write_word (flash_info_t *info, ulong dest, ulong data) { vu_long *addr = (vu_long *)dest; ulong result; diff --git a/board/lpd7a40x/flash.c b/board/lpd7a40x/flash.c index 2dfe37656f..d18720e5b2 100644 --- a/board/lpd7a40x/flash.c +++ b/board/lpd7a40x/flash.c @@ -351,8 +351,7 @@ outahere: * Copy memory to flash */ -volatile static int write_word (flash_info_t * info, ulong dest, - ulong data) +static int write_word (flash_info_t * info, ulong dest, ulong data) { vu_long *addr = (vu_long *) dest; ulong result; diff --git a/board/netstar/crcek b/board/netstar/crcek index 9593f893c816f4a2db8e3ec8db9eca91d04c2edb..491cceb2ed1cd8bf38ee7531dcee46fcf99bc3e3 100755 GIT binary patch delta 619 zcmX>xi>Y}g(*yQV>cJJK4%mvPti}$EYUC3 zP0G(N(J#+0%ATCwZa;ZVyY=K3?IDv>I#e`ufCexEF$`q1GBE4`3a~;2Sb#JS5F1V2 z*dfdqJNambGHWByR_n=cJCu13v1fGQ*>%XUh$x^y!z*iW|Y3fx>WQV{tF*0NT`2k4$QXoGDiC+igCm`{=fcyd= zh5*KThRHxy1d@WqK)w$We+@__5`R08>w&~S0OTjYf&-}V6p){S#J>sT%OI(L0_4LS z%*X)r|8t-KC|E&202l(FfHX26WH~aQ2W}WhJtKn-A3A& qi9tUpKd~r9KQFbUxFoSiKe;G5HCr#3K_zi=RL?Xfm6XZvdm;fywrCds delta 760 zcmZpk$#h~C(*yQqc#_|K4;`FDJ{~^OUz5r zFV#)T&o7yr)o#yHoK##qd3n3-`>+n=wx6>U}9k41S*rA{INrt zbwf7;!;Hy-o#9Lwt&_7lz3P!n0UF840CEHjurPf5?+N1oX%HV>ej=Lu0yI9l`qe=B z8*nv@^$c5poDjGwMusCmegG2xB9I@0#J>gPCm`{k0r>?$3;~P`?}3a6B>De9z7Glqn@fgBIG03(A8ke$E^F%G0s4aiSH;+q2bATBXRM&n1K z@l)Y?85jgyfEHw?v|+GOpX2mp!ejC=q9 diff --git a/board/netstar/eeprom b/board/netstar/eeprom index c30c98b72ce1d09c84f4e7b821cf1f4dfeac0386..e075eb4efd3c7fea6520d703cfb10274487482a6 100755 GIT binary patch delta 4787 zcmb_fdu&_P8UN0`*N-H&bMtCLDa=U=O`Des8MNgUAhapXSjtkU7?SJQw~4{AJwIr| zGMV+giUFNz@95g~YMLfCAyHId(FBY~HTYwi*Z^%~NYqIqL5EO~CV>W9_WRDYlgo4a zV@E!Z-}gS>Iro0oPd}v{`mOR%^JQn;y?PH3y>o;}aTE1WkOZ~S5^BJVb{`MDI`>I0 z(WLi@o1ZQykBigFebuhQ{lSy7q2A7Sm5?susON(;v>y zFT?sg(a?+_t08pXvw>!pZk3wp1_oc@r;O=QV^cQ4!Zbx{x!PfC|c*+-qrxF!pe3PM* zP1r*n2+MK^!i_Mm;XvR(ZL>-WZJTNBw@TF^OWhE%8s>Fvy0yb94M6sCmZLjnpj*8! zWR*^bj+ImzDv9)g1~IsAT7|CIv48sa$cLa^(?r(gb9tM94IVdfk=k02t-RFGBnM${o{y9ItAuwl^ zCZWl_IDTwhaqw7M@zk+cmAr1$Lb22N<1dN&U9s+wc&NX61?FSS~#soC5>t7Tn3P9MQTkC*u6w)seYo%MFIv1^N zVEgqoVjHH09$=!zMGc~+;y114!V)2PFC^-O?ykr9zi)pr^y_?A`-t3Kbe*q~fXeng zyr<8Tz2&SFkUWL6v=|vf`ZJzG{LnOcYRhrUe6C*oO;E%-3=`-I^MqG%v6x3$$|R3e z*F0)GnIp}m;5zceHZ_l?-N`b3TWt;21+PnSGjuD@Fv}&KdOfcE+ABzD#gjtrV;ES^ zvjKyPyl-RLiY~4c*JI+aoCN`4ce=)@fLdB9Q@NBQ1CF~l6=e~VtWlP>(RxybSeCBw2K}2hx0qJWWGOPB(Y={ zjZvgpOvq)L#Jw!pn9Pr1`Bz9b#$zPDdkKi7X*{{#1+|<|_*cl+f~y`dQI@ni}-i z%jiMDK|N$=#xu)uJxo6;n8raPV_un}Ba%B<6~(?y&a$|*ymOiYQfPoj@o}IUz66Yr z=pHSk#*FUIzlgiz$!H=UGrA*LJW_^{&ZNe=qEMmSMB2!9joP0ME`=XHb-ifoYCCXg z$L9WyH66Rx#MXR2wpaE4y1iT7@)PyzQFWkQ?P53@rzbf{eg2u~H%U7OVE z_V58U_-1v2% zL#Qv%{D3&598mXb`&@h7)M&Gb@AY=9`vTenoN~OTX&z0Gm<;&*630N}Q_hw7jQMoi zFmr2`uPGX2pM&Uv28S@Q7?v0p8b0Dc+RDy3U_sj|EQU`?(jZS$h(*vH748`<-jm#+ zL2zs?`;hG|_J0mbLEkEqq{#Eq$U*?Dbw-l-c{SDI{==N2TB;KAP8SMHb zdMrOSHbJMcilo!wY%Y??<NYaP}xqxLyac6@0WHCNp<6o2k%e<>uTv;7SpIG|;z&2{v&xWsMxG&_a~aQCLk!GFc;RB-)KJ1E$MKhRG=9;$ucCpZiosWuCt@ zU}HQomQEO13LDAT!Xp$84`;LXnV{g^c;kj(8=_tPmBIdZITvqrwYlCWj;e`N)O^_| zR+(pg;=;qjZDx;OG%8ab^Jc%e*v+rHsRL%xFIpYzCFWy(;ah7niC(N6CuY6}IA|{N za^|O2ew7}?!i)q&gZT+`t3E?p84$WMdC?TFEd+oabevnCy-dD)x(jC%)4|ExPjBoHr4W@xrjO0c1`6O|5A98 z>E~I+R~)xVulXBYoab7#&{Vi~ID_T~^Y&ZE_N9Q!)!Zxpva*_>Fvd?DI0gI<2cDE- zwm!@61J=X>E)dR$CLId=#rcr~{|fl$4*V4Gdk*{@@SFp`46NY|g$Yf_1MoWVSx}!} zkjFOw{thlgjM6~w16LYn;6ng@P%rcBw-zsC)_acRr(o~UW?38~LrHL`V zfoy|ZtDFLQ`FPpjQpcH8j)dQ_PWe*~`L98~uZ(r*UkY5Qh4sLlz$?rA0t;LQ!qpCi zD}jd`_ivH|>~ zWhos;auB%3!T%v}rE2pI9|0b4@P7f!8OuSR`HunH_E5Xn;1gv5+kv2Gfny$X*;3K@ z#ebDAR#ryLH*dVyGa zFIHhL8X1bEppSw>C|yyyr>qdoM2)+tTnX@rn21b}vpA&l5O&t@coLN_kqD2*60j*t TysRwj2(e}3sU+>p7zX_Zq7RCq literal 72374 zcmeHw3w%`7)$cxM&N(yWHIoO35MV+A1Tsk`fQX7VNRWW2;f;!hNoMkZ$-_*-L#d*I zuL`~`ZBb(F!?tSijn76!TdRH|zAb7Vq&~lj);?@)bN~On&zVfn)_&jpe)rzq-waI7 zT6?d(*4k^Yz0cn3teLrB?!uEaO$!P8rHewL0lv&r?wgKlTDm55ONi;hkMcq>Tx7|5 zv6&6ZeSAlAg=odw&7#fxlYAvDkhDP30!a%bEs(T8(gH~fBrTA%K+*z93nVR&v_R4V zNed(`khDP30!a%bEs(T8(gH~fBrTA%K+*z93nVR&v_R4VNed(`khDP30!a%bEs(T8 z(gH~fBrTA%K+*z93nVR&v_R4VNed(`khDP30!a%bEs(T8(gH~fBrTA%K+*z93nVR& zv_R4VNed(`khDP30!a%bEs(T8(gH~fBrTA%K+*z93nVR&v_R4VNed(`khDP30!a%b zEs(T8(gH~fBrTA%K+*z93nVR&v_R4VNed(`khDP30!a%bEs(T8(gH~fBrTA%K+*z9 z3nVR&v_R4VNed(`khDP30!a%bEs(T8(gH~fBrTA%K+*z93nVS@?_~kME8n29vB!!8sWR9UlUb5u+S)d^(B27hdO&& zgS+}$%Xjs=#E3ovat+^g{f7VgeqAi;f$S8#KhRL;WgA=}e^jNhtG_a5SN|SgSC7Zn z*>^9l+OeH|T5w74-yqBP6=k0d41C}@baAie&=%-pK?NP}VPXI;0OH1=dwn33@w z4g1cKdz;)>eYU3cs2|q8f9nn5o2Op(n~WdqIk0i;`>%9g_Qw8i7cIPh*rS{7I^SKq z=iO_@{Nn1c?}0I&`ggCXJm z#>s!%n!bPSeJMZu%Wd}^72R?7iLXBM@NddLf8_SQ=<8EER=qR#h4fbsoPPX^Kf68n z#>8XA+lw|YdhJ&uLi>Jk-)Hyc``FC!3=mqZ&AKi2F9=*_WnOS}J8);7$yq|j4 zrJGtxGZ!|j{Mne$*?Ov| z`Sd?;u%hSvP#gXDXP%2z?DhWP={I&qs@{Jf>w`UyeQVQY4}S5^n73-?7r#0D_nTh2 zGP3aHzpf13eae3K=O{-p*^3!KFrN1@n9JA`Dv-L?nU+QC*_|u-5a9_iUd$zXt zhrL|);I4zA|H%0K?X!10^Ty=yJNE6q_qNx5dBpMeoPJ^Yy(P!3dh~%iq7QZXFW&Q? z_uuo2@22(M@A~fkyV{SL_sR!9U%&sR;S+yjTs-1HEGxCPZ_9Dv>rYtIlz!V8YtBu5 zA>-gp1H-PHbf-wU>t^>iE3We%+JCF((uPm9v44NUYCLO2&7YpFk8D0?M)b&ct+mbT zM!)>`?xL42KjYjtea|g;tG?x(2S5M(d7T>Tw?K#)H)Q2A&p^q<}XfAu~xQCu9Onvn3 zYtOj1$XIjFsvi%$_C(nW`|kVJ&2I$8-1+vIyPpVuZ{nx5AMLz#O-IUgP5Mu)VLQJu zBjdxZ_3pOp6~eq|!7pyeId@O*oke$@H*@s;Y2Vwv|JwA&Ug>|};{%)W-uX@H%llut zy*rGd4fxi3UVZ0Jqt{N4Wa*Op#vochE)u46(I>wo;G5v%u|GOuy|Z`L=T zuwc!LcOE$7)i>%=-zh(I-0Md#x$}{qJazNKZ(s1j-SgfbxG$Ld>7$Qc@x(*F4qkW9 zk{{iAZ-F^u-$U0~uRT9`#oJ4NQU6AM$+>m+>{$@ntB-Ct>-wUWDMvq+dhadU)1Dmt zj(NtmkM&~F{l&n$SOu=e8mI?5`-0`g?+Z_7&+g#kJ)5yU`Bwt2da_4DUAuo*Kg)Lq z_xD)Ai~Dv5pOCOFvip2kuWHLX`@&ck|0KkRm1w&=_)-t+u-c?(wC%F01_eR?7TsEHJ5{89$8s1f-%6%!g?tmVSuG&cI`b5uV zXqT6uE6doAcJ_h&5l{9+rT+VS%mm%F!*u@@bg8g)VBJ5`y};J}?gZU6^qqZhbf&J< zdjs@tgJ^8CU`#iKu@RD8&HgL`C?73UK(yf(O^yW8o_B=H(@F8jc z2%GU<(+a+aI5w^56J%cxxx9B-<()l#v89)NWk0V(JK^u_(F^g0oyWr_DZx(HvBA#l z@qx~s0iW4B6YaOKy;#w=CD_@cm2c@~KOYEQ*JFw$J=*F^vf1{%fq^%LSl$Qu+31_= z5OnB7Uv}e7KS|qnN^e@#wqCQmv(M-6>`O;Kt^{9?nA

H}#9)e%v>gz=oZgCN9dN z4`@|edw)MLaE3q|w)OkA^l}XMh-E!_xKfu(&F>87TkaESjZe`6}`g04f4CQ3*c)4{%ZxFAJnM}?V-bwatsdi3*0v~ z^xY8KdX3dvyItK|ddZjiXrkMd4Z0L@Hf-AcBz*nXB6y(R06z^^6W3EIKX_BW?!UNK zh^Nv2ZSc{TRR1BXALFP8D|)ryQ~jd#sebyq2YouU<I(ufJUuEC}S>VO- zThccjV>Jx2N1{xJj+`^tqkNb`8uUFEcqU-9$2f@(e*L$B4`+d|fUO?EIPJsxGrav> zJNm_;o&CHT_SIuw)9kCyzUJ81k@hv$zWVKJfqgBsuL1iSw6D`~<^CquzpFpjw+ns4 z-sw>54UUbmG|AKuPA}FmNo_Dj~KE=lJ+w)9C1OAIFQj7E{-* z&F~NK?7r#X^XN|+=$_>q6svoULpL3iv|U$&{y={aGKQgzVBauasNbUb4jdF++hx7T z+uTi>i+mS$lP)M`lgE}nfbXGGi{D=f|Jc-dQ-8q|yZQ@yclDQxQGNQ=ojqyYotdsG z=tn#_zgO%0b@q75Sq&fS-qw%(Y|n<>n2)0K;tkltYM}G`I$c3uXSRTk>%e`!ZLrg} z{&e(37b|*-gPr%J1-IQNTI=t23-OQvnxd}G?6j_J!(Fs9Wr5ZYd#6!G)m+TwQN0HE zz_uwqaXRMjT%ES@07gB?S6~b{E}eZj!RJk_tJ4MFO>x6!!+fww*S7w3F7cs+%R75m zz7V(v^GbBxguU@g@2>3L)|(N$vRjC%KCXoo{yF_x*Ok5hiTRZ#&g@Cs-Fa6gbTg~g zc0+Hhoy#b@7dl}bS=Q%=4{E`u53&sY_vACcsWv;`M5~{;~wR+W`AIujo4nA2)FA#npprH?DqM-^NwL^#HEIw;yw8wwgn& z-8iF(D?C`QCvd*O7jQrQU<&ld2?uM&MZKON`r3LU`nsaeSba$^eHpUu@o=1RZz`b; zy1M(|gQGMb=wTbpPZ=jl84mw+^6%=zy@C7}%e6xbUMTq+T{j-&7-8-GDg9dds{f__ zDCio*;%wpT#(hPkoCBQelNN+6p%>Qj9!U$EPJm5Q{GEMEY`gv#a&j^;ZvUUW3;zrK z_{dxCoBkE_Usd*n5BD|DK8LGgs|p)loxmdi*qNtV>%3m+5140!xgHSLf_o3jc^G^Z z>!qS$8T}^o4`|QCIEkto`>!u!d|+80)?h6S<7#659jS>ADU<`WXkvYzrxk0f@5X-27Z>*z z?x5Nmaa}b!xAiyuec(gt6QJI~8?jDb(rfq|yLq1w{)_u3p?rc|hSeQ?k{2U7ygcYGITct`V-vS&;8<| zOCEhMjI}RA6u-~=uz__M>sar@v;*$fq`|(V$LrJ!)cdyeK8rn6isEB8aM9OQnI z_b}YM<@$>l5Aanz*zcsI1z&rYXAgm^ANMxDZ*%WJcUl(92FkUpfv$|+0b#(8SM@;Z zDEi88<^6AUH}~k=qbNT@Oe)xgb$cIVt9>~7t05-!0oOCleZDQOQ${0q<=-cH9}KQ05dpd7}s93EfS9&;sy{Sp2y^K13;??c~SJg5h2 zyIs%ihAm(x?B{3`jswq5uC&gca=c|fP^R{7(w9@XKV7?*U~Q*WssbYq(y-0x)nrQc(p1-*GrS9Vor+&a*3jzUj)esTDUZkz=v$Im?m z)`Tw30VNmb8Rb9zFJv9!+ucMpE{?tq`;xwx-9xXWbUS*N2f zSSL-|_zms}U^fG0)IHvRoU^rHSB{6g#l`)cL$ndkIZ8gx0lJALZFo^5^)eG3)H(y2AO!y|2r^ zxLf)+>_J;k2$8C$5ICG$CyKexqcqve8xDk&su9|PmVK&tJOT= z9^eqhomcK3Ezaw5IX@p_ncIiC=I`uz#cs#A&nE)|DVA7@HDYTo&U`=RJ%>EBF0Rv? zWFNRjX#PW3H#E6!@LVAEL%o{Q%GY_O8HYY=+~4?dZh?HnI*!$J+>^zkGA*mK%r&*M z4C8jJuBoyMeVt_&2UVFI8&U3e`7g@51#NEud@JBQt*R$aEBEK;p&alnfNup%AI+b- zJ2Nk*E#tGWFU!s5{QF4DLO(Y9qPXVa`jG%GHv1g?;UjVVb&PwCxccM2 zcw77Q&5suH8O#LWfZto%*c55$X!kFUgu;!@_5QhYs}`SjioY#V-xzC;wD~6lr*25W zLBXM0(bm}h&*)B>J;y&g9BzxmV#oT?j_r@-p9!^MMOzCbtURfD`P{`z=AU+I2^i0A zZH+e8hT0ojn*EUtt&!UHn1A+(^Zn~0Z84Tj2&ahIwe20DsDD}Ui7hSdU#b-%ST=Rq z^rL1RJ@c5^C(fyud(ynh`3p{7c*?1#RV`Y)Wa+ZyD^{L<22@F)3)R$yBX#u+jce9M zo0?l%&uNRbcdT2#VdJ@^n|124g$qv*!sEOO`EroKYo~AM%ZR`1^4apGeZ@-=oG4%V zSG-t{E$csj9WLLN8ozvnTo(E4@~;ppi+oN6dVWOhkhrN;5V#B;th*bQ= z{!PMjgb{};g(nWr7wvI)f!Gj-PZ68q@Tp>R96k*)9G+F;vN*g*Tp5QKi>u@C5^;ST zUMhCP;bmfH99}LuRhvG$g>;&stbO=%k@Old<)Q>3)Lqph?VjY>O;Ygky*g65^ok#?|Z zD~&{2+gh5c3AdLl5n86^v$F8ll`%SFLPj=*S05o<8ONp`mpUJ(09OH!)YKDDZX6|8 zVrFYvc4{gKgs{@%v@aBa+QOKH?V$@7t&5SfY@C1qtpgIVC4eFXI~6_}UTU4EqGWy>5T>!7P*J$jjx1Ew2#j z=b}sFY(@ z9EUUp9nwtXK&`)W3M9I_YpAPJ%HWKwoMIzM03WVH;y9>cN}TN zpmQCeZgeBR>{>?-GRFB7NW!`^deF+0lAEC15YHGh)HBA~Tx>@fXX|RCew(R{<~eRS zUae926ETeDxoPUL;XJAXN zj}4;CbqD@v9^H>PfIjX-AjUivzhMA!>sKMXqWe#0@!2fC7JqcNeg&!XT3Jjc=9T!f z*)`ER0_Cm=#PodZmv#amHxGev!u7Udx&_i*6FW$C6dO!_5a2N57xH`QLxB@KFqiAW2peFh@lp05nyZ!+BWsH=it5|xZ1iR5wV^j{T;5wgjP5pjW zj+Tsm%*tFz_h<4PBS8bbHO5NtbMhRwn5}KC*Fcovm#tTlE>D6>(E(#TrRbF;$d}-c z*t$T1CsXJIN&8(&n)oBo4l`~i=ljtDwttu9lcZRN`HVsd{*DbNQv>}~a-Jf=OqK>D z!ILa4mY|zj1Uc}ojp(b#G{*w=7{{cq3q`TDB_>Ct1ORoBBccg?JbQACo7LrLXv$I6 zm!Q;4Jq@Luajf;7(7?=yva%ATx~YEy#x%WBk?YYFGgJ1q6E-ljq|%ew zdN|e7XOUpUPucoqlzQA5v6;dgOIaBmfW}cqMyzaxF!LxQql4ghGS7%jn<~r#GSBEB zIDyPFVpu!PNo1bUL9md_^&e4W$!`g6gGej=R_fkCFyk$PH=-Ms_dSAL(A4t%o?wKf znSUpk37cA3!)X6|(LpPFG{L1L$hn%Jhs=iWC+#Bqu|}NB(y=5s@)?5rSUT!uf`>>u z`W}Laya_A!F@ipdDER)V*Z?`hv7 z_$?AFkwbJfn=O?Caw*kWCPyKU1k2}vyS@x|u}+t?Q%QS<*=&`hT?|WF zq2;vXQi3%V1jA%j8zWdpFdQOyBGrjpPOySt-T4H6$PTTM98MJDf zq`jSjTP1iW!E>%hsTZrTSO}sV>pZI*owYW}5y%(T<5d5f@3B+)hDFBK`J~qKJyt&D zUZAiH;hutGPCM!Qrtr=Mz81|Z-IJ}SAj>_4C32c91HjoUNi&5$43_Z}twyQO(0xQ2 zNuuMvCx!)1f?2%Bq4a%l3#W{>9z{V)uABw=B0U^gCsM{J%&@kCE=4ZAR1sl(ks^Iw z&mWc^?Px|)ha8st6zd97<|!=IDni#%#w#o>Jz5hIDHEHhL%z=%1Jk5TlB1QMV{Jld zN+I>p^G8}e&?#l|$r77w(VbJKoGG#8)|-@2a<#-(3pa@taYSZ%(i-dnljB2g$0D$aN~aHC_YZ;8{uUsOK$ zC{NpFhhAZtFg{4_rpjq0r3iDZylkz%+--1m+ z`XuWP!0Cnd^sw%Si1f+xz>72ZVz@~96jF0~JWnP?xf1hP+2~`soNYSX{8QEyD*+>| zyJ7hBspBPOu5gb45O-ZuWXU7pFoVVJsrb`Iow+N4oJuyG#$I@zM%7*5TaZzZUK17> z6Iejkr&R0D3P!y6!4ZREXVqoSWsajty`eDw@hKV7LIJfJ5^zR>niw@cbdWq ztRhlQR|`|2buuZBQrKi`AB^Fhp|B}dDWxB+up(<7#@#!UJ<{_7)^+4^jN&=VdY*O1 zDy$sRfE}l>3hPDI%~DvU6{CdX6}HeiighO_tjhW`>%O6|rB;*@$`yv0JQIS6NH1`S z?B&3P=ADxh6W-Zx!M?*g*p(Ayxw{Uv@q5RB7;y!u4exwwBHd=5;wsXcg}0Jb@MPis zp55jM`q^J0;z8AD!SGY4*j%ENHlNIe`vsd^D&&@bFAyW$@Z7UdjZkAjdPkY?&Y|LP z$@Gq?!n=SnT=|=I>-X&W$)pCFBHSYZQDG^3z=b}cpc&orc$dq?(7Qrzj=-orR4=?M z6^5C*0faN%nD*YYmG@NJgw}ab!@JrhRK65am`8YTL9_3pna5kN_%}GsxS)C)?PhRP zWVL(@PHEnj^bNw>`Y@{5pN+zMj)FDo6pmHfK3St%ml2DpI>Y)qhoxO%rZtvz9g5OI zs2A8eRp+s8qTuxk8)g-9&TLSWDZ*O~HC_REn)iIw%?liTxpH|o+xp5?&3mE3(9O%x z?3eIJk9WJOx@t(XtL8!>ye( z^SufiVSS&TexJgQ5Z*oL&`R0Yhpkmq^AVO{^o9FZ0OB(YHR(voc?DJbJn};-t#sSapX@?HPZXr;j`G6mpD6e znj%fY`!fB1I1dBfSLoBj-=Kh3>9xb3WlvwD=M2A+hJ2mgFr0fT?;9NN;dij~O^)br z*}dOz1cx&>(%a1r4!?}{=x5)=s2A~ zH;5Y}9p180W6V?3(JeVqfw9}rj7N|LucnRBXnftS6yqYzVc~Vfn^sXHkH!{k>b{8@ z;H}m);TL%1Z20_n>tINcw-(e|UIeh7htC`cS6(%^8+o%aBxYU!RyAlJ^jlOV2Aqs|=xk7etxI1VNc`NYAqQ=RYPdr6WKyHhR@w|BZEX&+ zT;yK~Rx{b4Ua}&ad*iI?B&#a6Zg5%)t&yerHDbc~Fs9ZhPh8g+B7Xp^>MuwDUON z+6tJ1fO|Nq;){tc3NHk%{Rk_QcD>YuS}-z(ks9FmT_=T9O{}E;*GcL{lhMZ;SUy== zUx95As3gHja)55UR4O4RL%kc>2WUVor%(;)^~euhjX~7K5fEf(Jb7O^OiAAhg}CE; zh$c$LFS( zjLF&C>|{)i(Q_H!O~&MsF}Y++4vS+lCWkd)Ocf#y|94|@;~!(>EbVl-x%5y1oo=36w?#X;yS!ljD^qf^&-Y*Tu@rxhzhtWXC1TiMAgKYs zTD;u^#tDzg1oGIqQ7Vn;coM5Lrpo{hGq&Sz%6IWcOXc6g(wJCer!hSM&~q(ux1G&I zS#~xPEA>@~3>rsDP-QcHz$QbonIu0IIgxZKn@NHyn@NHyo2d|iDZ3B)8gMfFvbD-) zlAy|Fq7*xuNrEbyNrER+qY08$WixF8&tb+zRWiuI{5sqgw5tHL%z_qE19G`gP@<;j%PC+ z&5}D<;<1yO=Cfo-Qj=t$lA2_vRZ^4GeKNev98N9mq^3*RIx(qAhzGlKD`c$>vi~(=&x7a-uP-hx1=bK|Ykqd%{DfA$d=x%6pO%C7$=BFvC=N zPf{`TLghUv%*lIFSc<9go)ng9s=OzK9hUcGs=O!Jx%?b+NZykOcT$0vY7Wo2at*n$$K)Gzl6Le$vZXAk)-mT(xqI(EMgb(9Z5s-p3I?nPZsl@ zNGK&`A;&IJ@;}UbGVu%$c~6%({Y0a*s}yFKD(^{Q9#iE#DJ;$00?pE{RhZ9Ic~1(< zF;(7^!bX}Z@2OQv$Td~olfuTBD(^{QV@;L!q_A=3(7Y#$c~7izEO}Vollx0~PcFl- z^Pc2jrUxApb1>7(6gD*P$y9ky_Vh4S-V=QVyEJo1-jg{b@5xkoPl{!Zsq&r_HqsoL z_hd1_DelTc^PVgx?@9I%QY*1+d`;eysq&s2B~{*&!aSzRds0}Msq&r_<}+2^lfrUL zmG`8uk*3OfQrN$i_hi_4Po~OyQcZ=a@}3lCm@4l{VIHZtcZ$N&OqKVfFrTUNo)ng2 zs=OzKjWku>lfrUMmG`7Dzp3(`6jorWyeG9V6`CsVNnw*smG`8uDW=MMQdp5WB=5;o zc~6SxEK}t@DXbh5o9nB>DomC4q_9d;@}-c%hUPsf{tZqumG@*f`*PmX z4(<%>ye9=~rpkL_7Kxs(o0oCqVyezCRo;`rkl)X`4n=91D(^|vc}$h}q_AP8%6n3j zL-U?gH!pDX<;vyVZ0jpmHSdKA8=Ci|s;(N+>}tE&SLHo9gckYlh!cJ}@5v?{lJ{h) zyeFl;Fjd}@V<46Hq%gyLnkM;~!YoteJt>wRQ{_D=EX`DTPs%_(Q{_D=EYnnZPYTO2 zRo;`rvQ3ruq_7-Q#aI+J+*El_3L9anyeEYX&3iJ3<~>0vPz%gK9^tC?GP(-7_$fpsp|H%ad3e1$wWbMIG%Qr~37)-Wd$ zn__E_UfUEFz5w%;kcn>kSy!yu`OFtnfR!pN$80AyEhH&Nip(Ma8o8trQoB@%mI1}q zlvj?~sd2gZA5rZDD{$1u-GSzk5&o1_>?dD_zPXW#~?jpWHqJ3GILHKW*6Ta+)e zs}!=NU=*`%z{-R7gd)mW!hQ`0G@5;wcod-dXr5WD$$RjmT9FwbB>d}1?tx*o>DmV< zpi1FEwWdk6mMFERNwpR!wWdk67K_5$z~Oh)ZI!ei8{e)NAjRoS)@o-nljtlOR;z+y zBk0CRP!@wpVrAc$d+L4U4j)mItJelaUj+$vJl;Cxe&*|g2SZfMdHhvrx zP{^6%WyDM&XH2d|0u_y*U*pSvhg3F}Ho3hCcHc-n^lNhRm$2?!s-|D#p}yxyIjg2X zv?$VPp`9$j*>fYB#22jD!hco{Dqm&$N2LkakN5DUe;8VsBK3&u%jtP_O-P-3#1=7r zI$1t46%4iIfjYK+tpMLfsdB9zQ^uMsyZ?k5bSkx1mM_kio?#=CrNN$(LY7X3(Vv!s zwk)4pSM67_#Tof$P{OYzvLaua>sg7c%KtNKo|nj?Vt%Qi54x8$!Z=ek*){1+tS`Nn zJ$;SzYc$zacGH7EqjpwMcC}FsrdAb{eQnfKXN|I{vbSqBc6S>35tXgQbbOhO(D?CK ztwYnuh*3*0lg--?Yral47uIKJMDIOH%(w_mGqWTYe625->*8UYRSoTJ{3S2GkAbBJ zBcMltY8Kuu0{9*~71A_R7|bL?%|8KEn(30?WVaW&th)G{Gk&U1q%b$*r#f=z5Ogrs;qS1E@JCDGUy-Ul z2I}U=K=lBN+)=c2jo1ayx)y(Qx0{~^bsa%jZhjinHIkKX#!p>GN|5nW*Qot$qT;7+ zej3y@TJrlbD|00s=`Ebp`neLrcX^^#g!Cu4B^pX;9Zu#N_yV1c188@zI2vp9Xau z^At+mjGr2YWXJfak(#c9or<5j8(En)jwQ-*+&iI&kx|AH6+dq>R^FyJ=h!(b1@zZpCDAX8Bk?HtQs41R+Uekjz;xSk;6r>6Hu z1Q|ayeRmOL{M5{RgdpRmX4WqWGJa}izd?}kQ#0pOc7^d%bNJ;fU4%d82&U4y89z0T zyp$m0r{<_@2{L|aj%J+G&G@OA%SFu1_^DaUkBYk6Njrld4sgc^9(M%65XQqSA5W0+ zQ*&-HLB>zb1#<{8erle^50JVUKQ))od~U{1&82cc7(X?a$x&eZ)Lbqn4&$fh>5`W5 zQ}YZ-%lN5zrle*3)LbQL89y~cIpoXusac~FuTS0WSjrx425e?aBj_-A%H8wiZ_Y6WTagzdS28)q$5~$rR>s zn_w4hads_;#&evtRoS&5QgBs{0lpLPZU?Uocn_aJL1&8*EW8W_SH=sMa@F#q_y`(r zWI3Qb7|T6TBVYZxY^nO9 zY`Hm^BWo6m%$LaGcO+gRS+IFw_8^Ppi7b{Y7NahNqiD6yU zkGxhV@T*VcSD&a-qoYzCS^SMET_9Poc~=69^AlN|pQzILi7IV&RQfUb;X7Z2wnGjn zc^#7cvTCuX`L^Uxl~s!^l!6zHmYcHgaE-)BN-2@aNUHWnihD<+K5Y1_c;mN~xa=5OcRNj9V-tSVPWxCk zA-QL`>@PI@oob@G_&eFfMY8=Nr+q5c9PM4U|BKX@Z7bvLKbK_7vYR98h4xoDNJ~X- z1KZ4I8+;OmOxfTz*=P)eW@w7}*an)x#ukl3M}2n9xDdaTMN+NuO9#!8d@#pyA13o6 zww$aXS0p161nNz&3VZ38;T{_wT_^XsP73< zj8-K%o}hRv^Iy#Vm8+_yelJ_wSe3}FCdac$v08B?x7*?zt2IfmOmeJN92Y5$A)BK- zIcqjng++wM&3%k~`57#nhg9dm({qHQ>3XMwJhCW8tHzxZhZp6&4)XW#9w#UIX6(aZ6rnXq=d8geKk^3~6cJt2@N=-7{ESV}ck2{LW zW%6-NHn5pK?x-p||Dv?Gsv-a%bTgTXskR& zyLGh)a;gr~B_n#KWLt&vj}~Kxa&_5bvb;@oh&S8Ox>_p6@NR1(E5=1pGe*f+IxdPD z8(9tukzpkn&QyAm8BbMeQXZ|#p_N)5ZEHCOAO1R8>9~qI9-}MU;2ZN~r{(&D^BTV8 z*mwx+srUpjk%u{V*3T&qU-*hLU2to!Yk$p1K@kd3^VMIf*w|bf?FdK2Kdmi|Ha2%` z_!^o}tm*41O7W$QwW748wY@YF4X-VpR#H|{R@xD3gNT~a`r6uJUPEn7xI$#-tkwnkzofO&=%V0m}y5OxU$(Y|gDWSS(DAu6B#->ocU9Y~l62;(KA8o-8*j0x^ z?IBeVi?nyNDiGfy+tSuf<-j!7RC`PrUcj&$!hTifM-*KJTE&9Eq|)NRltA5P&)CXv z>6GxJs>pTjys55@MN7>%Y&Omtc0@u++_zEgbdl8E1f}eN$ z|IVo}v>i3Ee|N8`9^ykdgu`!`h3CcC4!#V{b-7ksGB1E1VA8bRa;5l+LH!?{p7!MZ zpIJlx)fGmpi?y~PoK&aAH9mVeY5$w6L3~BQY7k!;;;R7*)oK99Sq%U>s{z1&bv2+M zeC;jfKN{6?X#$9$;!?n9x@)9XQc+o4{BoeUvZT_;^sG0uxqRlkm>dWMBK%)jSrU!}N=^#Y=>@(8Qv!kT&dNYI zQdwD78QvM*xpPl=XJD%$3ofGb}M zOso$S7f+sFe4*iXZJbv*W&V`FWK8eWdGqH7TofGedaJpaOoD{Wpy$%WuiR8itt5tvrE;FBPn z24q3-+FVnAw!BfK7J>OZ;5Cf_S6Wd?VM%yFEt_?+%Qv$``4HQQLE??2S%AE@Wh)Zc2c1iO0b~T}G%D^{M@_Rb@;w|)c zTo-1fZP&KyTVU6C9Y4%}??0&H$Mh>uSCQe{u3e&Ub!{<3E^xkfqwY#vD>8DnYnSSm zxV9QwupY$u^7Hig9XQmdRb-4*V*SAR;s@kk#uXJ68UF3s75b&FON_1N7Tof4Bn9Fy zSiZxO#;D9F-~Oe(v9Aa4<}%-otAjJkI$-1c?P13j;0;ED{-c5RC;<*}TP z#MrJP!`Mz|bLjb`t1_Xy05IwKD61TPiw;y|Y}l@SOTWT(xpAp^iM3Tm{QWi^9}|6n zrK}<&w<4pEeZAausc{MN1h=?pOY-9L71B#v`L-JuYZvJkVvwAAJ~B}{_-JlZ)o(V~ z=fpme{t)e02iOs7(+!ZA5+y!cf0T z+jb6LhEt}aoPJ0;2202n{fzseL(5o*w5?6cKu0-Xr>zHPdg7G{Z5{cHPpn3rGjI#E|1jROhwJk=H^;5>aMw&!7yvK)Rq z!jYddemr|cfge7%9C{w5XxAh0mbXT6eKx*y1#fi-K(P>GWhE=ZnfQWryhE+6>Ko%b z_ykIb<&xshkgVg^K5qs^tg)#z8UayTdrL=D@QHF_QB?4usI$2cwXnav(GYxQ*cxhX zRJS0d*kACS5R@?o?`pY_1HhNOz!P*)b*vD-!kLYMXvjlLJg8-S6-aICM!|S0%Ly|u z%HmMFU`$gM17>iN#c0U5qAUi?5Fv{j+63c!042=G9biU?8HXb^VFuU$hhY=O$^gb% zn*~E)09$L?)(S?f0JpcS6^t~IBGM`%Hn=`iBN*1fm+Ih5BYZgV*3`B@X$DYGNd2Ez zU{lMwh+t@f#ZdG%1;%Pa&0+vBIpe7~kK&|&{yaoiSF7<@D~(4NQA2J>oJ)H**K_-& z>N)DFp37sWQ;Dmp=a{Q{E{A(z0_UabIXJ3bE+sI(^J;8vgt4k)jps&0qS#+SEbx@CBO+oAI6eA1nq!Ui%@O{No(=wfx?q>UB8rwzNk!w2QV#xEh-p zS&FZ)YUB@|2w7c?13N-C3Xar=s%tig7=GO$j9)DYbwt|*d;?vt6?N6^b#0M|sG(Rz z-ii~mWQjZ&vf1b*mTCl+;HA;J8mTcRKz)0I>QAUC+!$Ls#1v&SC@Ip`ShtbNOLpt= zdoqz~`}ZgK6+Pr7houd_NRwF67J+RQUk=; zL3IPzMA{%23fD*4X|lTJP*cRltK0DdIBim8#jjb8EKBXaH^$c0ha`ctFZ81g8e5e) z;02hy@U&P&IL^#p(GWG*bFQt%mzd%mt5x#xTOGABn1U0D92!JH5*$c5515Cr!c-%R zqXwGAeW@-ceXBz{DD`QV#t5%(X$uQ5S_duK8)9gHr@--6I9!Dr>)<9hW?{7IV~+Ls zooO%)MwCuz`{%ljYQ?@S0`;p~>gq&WY@PDbs>;)=7tTI)=CnCwGlTSgIZEK%*i5%U z0bIFeV>_Iu6$a-JR5u8OsKT6nL(SnRVGm(LV|@b|;IP&zn%k=7a0+-CT}a76ukb+n zF!t+22VEAOQ?pi1R=BR5t%>?hgF)~_oW9i%fiSo%e~L){VI%%d3cqibUXEn|i%dgk zT?G0x$6DZU;iixrZ3s$;Jc&kh9tTQl&Jm+qfI$N5_<}(h@Cx`JiTDF7=p*_UV{hrR zF@dk91r;QyS&Y$#_^7i6Y!vmF=FQ3$3gpUxUg42GPRJP7P`EB8qj%tie%6HGk??u= zTuk|AbtD?$;)?l!MH1^BzJ;tsPUr}J2S&OAr@U=_nwst9@)CEa#@5>ER_TZHPF?1o zl?#>;w+uJQ5)_FiMJ`TBm|ngWcnz3}Fy6v^RCwh+u|dsTnfnwmG4PbKl^cP&)7yF1rY3_&&G}EV2z; z+~pmIrVC+|ng>Or zC~vwVJIcY8HB?C54-YdFs31vNpKGt`l3e*^=j>wum#$C;?*3RAu+oJ^xTC3QBlejp zh_u_4Dny@2A;BDYtfADNUdmy zL|X@sG~7fwH+-;;t>w0%y`@o{gCDeOgo^ZHKAcPJUQ{^B#6(AoyE&!5yxlj2HsC%I zi%00V$;SbM3l}!{9kC`(8qt8i4PobO0U8xV!%hTBsAEALwhfXtR)gRAYi6-L!0;*$ zPXNf0oN-s~h?DaWg#whz0|-UM#9FvWZ40=gm~*JkR)no_VgWCnh{)SUc~+7r#%1tG z5~Ejz+9J&%R#FVd6+1i_3I+1~q>e+B!-Eb=V>~nQ93a;iwo?*$z5^zE5vr}l0xZP5 zIdhKn7vkPE`D<@o|8BH=T3dj#+$_Ay@t%%1lf&Y#lGw&3>={J~jH0d$4kV8wCH1^N z9xd!^yC}iljZfG>Rfga8DUqvs31%l*C`O?gRH7zQ(}A_FriQyp8HC__KW<8&bF^ScQbo9`aQb<7rvY(^8oW~ zE$Q&oI=XXEC(=3kEd=beVL9n`pujnolMe9#u^8`!v%WBHMoM%>FYfOMix8lc$l~oc_FNa45PzPpB%f~|e?JM|Qco<#u&xrdaDD3o?UmcOiZ`Bt< z{63+;0ipH~y3_tH#AcK^FNf|96cA=ilCKv)*FuBYFV^wB$G+Od;)GO9#*iJ{;rIAq zbfXZY^*clfb%>Y^8INN@$LB82%i+gs;>2F+)5JamRS+{1Gw`Nee0U?!G=yIP@?ft` zu%E*ZWMA>ZJi*IlTa5mza3y&VR}2SnH7YU-UbbfxA3g|w<<(`+Lc)Bx1j1_xFIU`4 zRiR7vVvxXvpF~c4xdeh?2``uQ?7;$;K+G%Q<-(U8C%#<5n}|Xmsb;*)B{(XBFPA_N zGvS4gf+k?>PtFh@GsGtYRS6Wt6YWlX$6@uDHu2Y2(cg_)kNumV^u&jOf02Mc3;eSL z{B?5El>JHH1Jp>s{}cG81o}S$|8oLvLE#@H;QZ0Ij}mbFh_?D&QnVxgeBcHGi4q0Q zL~Bn1J_~qPLVNyvkMolD0`5Fx!gDCG8o2XZi8xcgoo7kJHvxB^9})i+aOZguaei3X zc}7J17U0f{^7yH1=eZB-e|}g!zbM;zZo~S$z@6tc#GgHk{-wk41HheUBzWv9`hYtz zdg31f&q3gnI{AR}8>yY=JgomKa3|(Z+{HV){d|ddCUEEZ7V(k5KSQ9_;Wq}j^9+IY z+$G4YClF*}KJwSC(h}rP1747T9}hf`fL8!#>J|N#{Fry{Jkub)9C$?n{c7OO^B2}P z0C%3<5N`#(G=Y92@Glbd=dU3-&yYyJ6?prR$Q-uiUj=+&Li=w6cb;jG{$}8Y?QgX2 z4}gmVoS$rPo{^CLZs5){DB=$Rcb;hxe}eQ0@}2?iJX2%+3&5RcIK*E8?mR0ZegL@h z%!YU$aOasAaek@0Tt6}HNIems0(YKQvHo+`+v}+h{%c|hcAg=zJ`MPEtk(>_6XzEp z7zz501m0yob7TED;LbBc;*)?o&##D=0C%2)5{{A%E> z3HpYCbG~sDI3BIQoo8<3w;s6j{Ej%k9^HBNM|>-A=UE)_ZNR4|$p3E~;r{8*A^+D; zghSaOcoSKR{DWC`GK!zu;SEM}D z21o}ZI`Ice9pT1xvBqif6DC^Q4-24!b5xdx%lLB;8D*q~@=(jzG#NPYCrZYFT6%-9 z0~{d6f69=DYI#NX?B`o5%ApRtsNy3-GQqJ}5>kqK4hod#>%`CrEhK|k=tfY;Cl8>K xZEd3g<&($6*bCXp!~c*#TcR-$dy%0ZTEmH-k`ZDMxY(z9b`zL9uFLrG{{l7M!f*fp diff --git a/board/netstar/flash.c b/board/netstar/flash.c index f555c0c006..692c416780 100644 --- a/board/netstar/flash.c +++ b/board/netstar/flash.c @@ -230,7 +230,7 @@ out: * Copy memory to flash */ -volatile static int write_hword(flash_info_t *info, ulong dest, ushort data) +static int write_hword(flash_info_t *info, ulong dest, ushort data) { vu_short *addr = (vu_short *) dest; ushort result; diff --git a/board/netstar/nand.c b/board/netstar/nand.c index e5b7f3346e..f470c1a01e 100644 --- a/board/netstar/nand.c +++ b/board/netstar/nand.c @@ -48,10 +48,12 @@ static void netstar_nand_hwcontrol(struct mtd_info *mtd, int cmd) /* * chip R/B detection */ +/*** static int netstar_nand_ready(struct mtd_info *mtd) { return (*(volatile ushort *)GPIO_DATA_INPUT_REG) & 0x02; } +***/ void board_nand_init(struct nand_chip *nand) { diff --git a/board/shannon/flash.c b/board/shannon/flash.c index 13c01d8351..475b76b30b 100644 --- a/board/shannon/flash.c +++ b/board/shannon/flash.c @@ -315,7 +315,7 @@ outahere: * Copy memory to flash */ -volatile static int write_word (flash_info_t *info, ulong dest, ulong data) +static int write_word (flash_info_t *info, ulong dest, ulong data) { vu_long *addr = (vu_long *)dest; ulong result; diff --git a/common/env_nand.c b/common/env_nand.c index 4ae68c5a23..dd27f7b629 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -112,7 +112,8 @@ int env_init(void) */ int saveenv(void) { - int total, ret = 0; + ulong total; + int ret = 0; puts ("Erasing Nand..."); if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE)) @@ -120,8 +121,7 @@ int saveenv(void) puts ("Writing to Nand... "); total = CFG_ENV_SIZE; - ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, - (u_char*) env_ptr); + ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr); if (ret || total != CFG_ENV_SIZE) return 1; @@ -138,11 +138,11 @@ int saveenv(void) void env_relocate_spec (void) { #if !defined(ENV_IS_EMBEDDED) - int ret, total; + ulong total; + int ret; total = CFG_ENV_SIZE; - ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, - (u_char*) env_ptr); + ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr); if (ret || total != CFG_ENV_SIZE) return use_default(); diff --git a/cpu/arm920t/at91rm9200/i2c.c b/cpu/arm920t/at91rm9200/i2c.c index 2565998e48..826cea8e26 100644 --- a/cpu/arm920t/at91rm9200/i2c.c +++ b/cpu/arm920t/at91rm9200/i2c.c @@ -111,7 +111,7 @@ at91_xfer(unsigned char chip, unsigned int addr, int alen, int i2c_probe(unsigned char chip) { - char buffer[1]; + unsigned char buffer[1]; return at91_xfer(chip, 0, 0, buffer, 1, 1); } @@ -191,7 +191,7 @@ i2c_init(int speed, int slaveaddr) uchar i2c_reg_read(uchar i2c_addr, uchar reg) { - char buf; + unsigned char buf; i2c_read(i2c_addr, reg, 1, &buf, 1); diff --git a/drivers/dataflash.c b/drivers/dataflash.c index ded039578a..17eb8597f8 100644 --- a/drivers/dataflash.c +++ b/drivers/dataflash.c @@ -174,8 +174,7 @@ void dataflash_print_info (void) /* Function Name : AT91F_DataflashSelect */ /* Object : Select the correct device */ /*------------------------------------------------------------------------------*/ -AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash, - unsigned int *addr) +AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash, unsigned long *addr) { char addr_valid = 0; int i; @@ -291,7 +290,7 @@ int i,j, area1, area2, addr_valid = 0; /*------------------------------------------------------------------------------*/ int read_dataflash (unsigned long addr, unsigned long size, char *result) { - int AddrToRead = addr; + unsigned long AddrToRead = addr; AT91PS_DataFlash pFlash = &DataFlashInst; pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead); @@ -313,7 +312,7 @@ int read_dataflash (unsigned long addr, unsigned long size, char *result) int write_dataflash (unsigned long addr_dest, unsigned long addr_src, unsigned long size) { - int AddrToWrite = addr_dest; + unsigned long AddrToWrite = addr_dest; AT91PS_DataFlash pFlash = &DataFlashInst; pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite); @@ -330,7 +329,7 @@ int write_dataflash (unsigned long addr_dest, unsigned long addr_src, if (AddrToWrite == -1) return -1; - return AT91F_DataFlashWrite (pFlash, (char *) addr_src, AddrToWrite, size); + return AT91F_DataFlashWrite (pFlash, (uchar *)addr_src, AddrToWrite, size); } diff --git a/drivers/lan91c96.c b/drivers/lan91c96.c index bb03dae39c..a50c5f0abe 100644 --- a/drivers/lan91c96.c +++ b/drivers/lan91c96.c @@ -185,21 +185,21 @@ static int smc_rcv (void); . If an EEPROM is present it really should be consulted. */ int smc_get_ethaddr(bd_t *bd); -int get_rom_mac(char *v_rom_mac); +int get_rom_mac(unsigned char *v_rom_mac); /* ------------------------------------------------------------ * Internal routines * ------------------------------------------------------------ */ -static char smc_mac_addr[] = { 0xc0, 0x00, 0x00, 0x1b, 0x62, 0x9c }; +static unsigned char smc_mac_addr[] = { 0xc0, 0x00, 0x00, 0x1b, 0x62, 0x9c }; /* * This function must be called before smc_open() if you want to override * the default mac address. */ -void smc_set_mac_addr (const char *addr) +void smc_set_mac_addr (const unsigned char *addr) { int i; @@ -883,7 +883,7 @@ int smc_get_ethaddr (bd_t * bd) char *s = NULL; char *e = NULL; char *v_mac, es[] = "11:22:33:44:55:66"; - uchar s_env_mac[64]; + char s_env_mac[64]; uchar v_env_mac[6]; uchar v_rom_mac[6]; @@ -905,7 +905,7 @@ int smc_get_ethaddr (bd_t * bd) if (!env_present) { /* if NO env */ if (rom_valid) { /* but ROM is valid */ - v_mac = v_rom_mac; + v_mac = (char *)v_rom_mac; sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X", v_mac[0], v_mac[1], v_mac[2], v_mac[3], v_mac[4], v_mac[5]); @@ -915,7 +915,7 @@ int smc_get_ethaddr (bd_t * bd) return (-1); } } else { /* good env, don't care ROM */ - v_mac = v_env_mac; /* always use a good env over a ROM */ + v_mac = (char *)v_env_mac; /* always use a good env over a ROM */ } if (env_present && rom_valid) { /* if both env and ROM are good */ @@ -935,7 +935,7 @@ int smc_get_ethaddr (bd_t * bd) } } memcpy (bd->bi_enetaddr, v_mac, 6); /* update global address to match env (allows env changing) */ - smc_set_mac_addr (v_mac); /* use old function to update smc default */ + smc_set_mac_addr ((unsigned char *)v_mac); /* use old function to update smc default */ PRINTK("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n", v_mac[0], v_mac[1], v_mac[2], v_mac[3], v_mac[4], v_mac[5]); return (0); @@ -946,7 +946,7 @@ int smc_get_ethaddr (bd_t * bd) * Note, this has omly been tested for the OMAP730 P2. */ -int get_rom_mac (char *v_rom_mac) +int get_rom_mac (unsigned char *v_rom_mac) { #ifdef HARDCODE_MAC /* used for testing or to supress run time warnings */ char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 }; diff --git a/drivers/lan91c96.h b/drivers/lan91c96.h index b7d7455b9d..7d33a821f3 100644 --- a/drivers/lan91c96.h +++ b/drivers/lan91c96.h @@ -51,7 +51,7 @@ * in order to override the default mac address. */ -void smc_set_mac_addr(const char *addr); +void smc_set_mac_addr(const unsigned char *addr); /* I want some simple types */ diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c index d91d90bfec..e0b406041f 100644 --- a/drivers/nand/nand_base.c +++ b/drivers/nand/nand_base.c @@ -897,7 +897,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa int i, status; u_char ecc_code[32]; int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; - int *oob_config = oobsel->eccpos; + uint *oob_config = oobsel->eccpos; int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; int eccbytes = 0; @@ -1119,7 +1119,8 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, u_char ecc_calc[32]; u_char ecc_code[32]; int eccmode, eccsteps; - int *oob_config, datidx; + unsigned *oob_config; + int datidx; int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; int eccbytes; int compareecc = 1; diff --git a/drivers/smc91111.c b/drivers/smc91111.c index 060da8ff2a..84e243ddd5 100644 --- a/drivers/smc91111.c +++ b/drivers/smc91111.c @@ -210,7 +210,7 @@ static int smc_rcv(void); . If an EEPROM is present it really should be consulted. */ int smc_get_ethaddr(bd_t *bd); -int get_rom_mac(char *v_rom_mac); +int get_rom_mac(uchar *v_rom_mac); /* ------------------------------------------------------------ @@ -276,17 +276,23 @@ static inline void SMC_outb(byte value, dword offset) static inline void SMC_insw(dword offset, volatile uchar* buf, dword len) { + volatile word *p = (volatile word *)buf; + while (len-- > 0) { - *((word*)buf)++ = SMC_inw(offset); - barrier(); *((volatile u32*)(0xc0000000)); + *p++ = SMC_inw(offset); + barrier(); + *((volatile u32*)(0xc0000000)); } } static inline void SMC_outsw(dword offset, uchar* buf, dword len) { + volatile word *p = (volatile word *)buf; + while (len-- > 0) { - SMC_outw(*((word*)buf)++, offset); - barrier(); *(volatile u32*)(0xc0000000); + SMC_outw(*p++, offset); + barrier(); + *(volatile u32*)(0xc0000000); } } #endif /* CONFIG_SMC_USE_IOFUNCS */ @@ -298,7 +304,7 @@ static char unsigned smc_mac_addr[6] = {0x02, 0x80, 0xad, 0x20, 0x31, 0xb8}; * the default mac address. */ -void smc_set_mac_addr(const char *addr) { +void smc_set_mac_addr(const unsigned char *addr) { int i; for (i=0; i < sizeof(smc_mac_addr); i++){ @@ -1524,7 +1530,8 @@ int smc_get_ethaddr (bd_t * bd) { int env_size, rom_valid, env_present = 0, reg; char *s = NULL, *e, *v_mac, es[] = "11:22:33:44:55:66"; - uchar s_env_mac[64], v_env_mac[6], v_rom_mac[6]; + char s_env_mac[64]; + uchar v_env_mac[6], v_rom_mac[6]; env_size = getenv_r ("ethaddr", s_env_mac, sizeof (s_env_mac)); if ((env_size > 0) && (env_size < sizeof (es))) { /* exit if env is bad */ @@ -1547,7 +1554,7 @@ int smc_get_ethaddr (bd_t * bd) if (!env_present) { /* if NO env */ if (rom_valid) { /* but ROM is valid */ - v_mac = v_rom_mac; + v_mac = (char *)v_rom_mac; sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X", v_mac[0], v_mac[1], v_mac[2], v_mac[3], v_mac[4], v_mac[5]); @@ -1557,7 +1564,7 @@ int smc_get_ethaddr (bd_t * bd) return (-1); } } else { /* good env, don't care ROM */ - v_mac = v_env_mac; /* always use a good env over a ROM */ + v_mac = (char *)v_env_mac; /* always use a good env over a ROM */ } if (env_present && rom_valid) { /* if both env and ROM are good */ @@ -1577,13 +1584,13 @@ int smc_get_ethaddr (bd_t * bd) } } memcpy (bd->bi_enetaddr, v_mac, 6); /* update global address to match env (allows env changing) */ - smc_set_mac_addr (v_mac); /* use old function to update smc default */ + smc_set_mac_addr ((uchar *)v_mac); /* use old function to update smc default */ PRINTK("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n", v_mac[0], v_mac[1], v_mac[2], v_mac[3], v_mac[4], v_mac[5]); return (0); } -int get_rom_mac (char *v_rom_mac) +int get_rom_mac (uchar *v_rom_mac) { #ifdef HARDCODE_MAC /* used for testing or to supress run time warnings */ char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 }; diff --git a/drivers/smc91111.h b/drivers/smc91111.h index cf08582fbf..c3c33672ab 100644 --- a/drivers/smc91111.h +++ b/drivers/smc91111.h @@ -49,7 +49,7 @@ * in order to override the default mac address. */ -void smc_set_mac_addr(const char *addr); +void smc_set_mac_addr (const unsigned char *addr); /* I want some simple types */ diff --git a/include/asm-arm/arch-arm720t/s3c4510b.h b/include/asm-arm/arch-arm720t/s3c4510b.h index 517b1ada99..73a3b6d856 100644 --- a/include/asm-arm/arch-arm720t/s3c4510b.h +++ b/include/asm-arm/arch-arm720t/s3c4510b.h @@ -267,8 +267,6 @@ struct _irq_handler { void (*m_func)( void *data); }; -extern struct _irq_handler IRQ_HANDLER[]; - #endif #endif /* __S3C4510_h */ diff --git a/lib_arm/armlinux.c b/lib_arm/armlinux.c index ca630b377e..dba2ff7085 100644 --- a/lib_arm/armlinux.c +++ b/lib_arm/armlinux.c @@ -124,7 +124,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], checksum = ntohl (hdr->ih_hcrc); hdr->ih_hcrc = 0; - if (crc32 (0, (char *) data, len) != checksum) { + if (crc32 (0, (unsigned char *) data, len) != checksum) { printf ("Bad Header Checksum\n"); SHOW_BOOT_PROGRESS (-11); do_reset (cmdtp, flag, argc, argv); @@ -148,7 +148,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong csum = 0; printf (" Verifying Checksum ... "); - csum = crc32 (0, (char *) data, len); + csum = crc32 (0, (unsigned char *) data, len); if (csum != ntohl (hdr->ih_dcrc)) { printf ("Bad Data CRC\n"); SHOW_BOOT_PROGRESS (-12); diff --git a/lib_arm/board.c b/lib_arm/board.c index c73cf0c38f..76639081ed 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -121,7 +121,7 @@ void *sbrk (ptrdiff_t increment) static int init_baudrate (void) { - uchar tmp[64]; /* long enough for environment variables */ + char tmp[64]; /* long enough for environment variables */ int i = getenv_r ("baudrate", tmp, sizeof (tmp)); gd->bd->bi_baudrate = gd->baudrate = (i > 0) ? (int) simple_strtoul (tmp, NULL, 10) @@ -235,9 +235,11 @@ init_fnc_t *init_sequence[] = { void start_armboot (void) { - ulong size; init_fnc_t **init_fnc_ptr; char *s; +#ifndef CFG_NO_FLASH + ulong size; +#endif #if defined(CONFIG_VFD) || defined(CONFIG_LCD) unsigned long addr; #endif @@ -320,7 +322,7 @@ void start_armboot (void) int i; ulong reg; char *s, *e; - uchar tmp[64]; + char tmp[64]; i = getenv_r ("ethaddr", tmp, sizeof (tmp)); s = (i > 0) ? tmp : NULL; diff --git a/rtc/rs5c372.c b/rtc/rs5c372.c index 87f38c42bb..b56808b8ba 100644 --- a/rtc/rs5c372.c +++ b/rtc/rs5c372.c @@ -73,7 +73,7 @@ static unsigned bcd2bin (uchar c); static int setup_done = 0; static int -rs5c372_readram(char *buf, int len) +rs5c372_readram(unsigned char *buf, int len) { int ret; @@ -128,7 +128,7 @@ rs5c372_enable(void) } static void -rs5c372_convert_to_time(struct rtc_time *dt, char *buf) +rs5c372_convert_to_time(struct rtc_time *dt, unsigned char *buf) { /* buf[0] is register 15 */ dt->tm_sec = bcd2bin(buf[1]); From 8de7ed3abe2b972fd3cc2eda3953fa2c0b554e3e Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sat, 11 Mar 2006 22:56:07 +0100 Subject: [PATCH 049/102] More GCC 4.x code cleanup --- board/cobra5272/flash.c | 3 +-- board/m5272c3/flash.c | 3 +-- board/m5282evb/flash.c | 3 +-- board/smdk2400/flash.c | 3 +-- board/trab/flash.c | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/board/cobra5272/flash.c b/board/cobra5272/flash.c index 6f5874a671..73cc2f2c10 100644 --- a/board/cobra5272/flash.c +++ b/board/cobra5272/flash.c @@ -256,8 +256,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last) return rc; } - -volatile static int write_word (flash_info_t * info, ulong dest, ulong data) +static int write_word (flash_info_t * info, ulong dest, ulong data) { volatile u16 *addr = (volatile u16 *) dest; ulong result; diff --git a/board/m5272c3/flash.c b/board/m5272c3/flash.c index fb918435c8..f156342291 100644 --- a/board/m5272c3/flash.c +++ b/board/m5272c3/flash.c @@ -256,8 +256,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last) return rc; } - -volatile static int write_word (flash_info_t * info, ulong dest, ulong data) +static int write_word (flash_info_t * info, ulong dest, ulong data) { volatile u16 *addr = (volatile u16 *) dest; ulong result; diff --git a/board/m5282evb/flash.c b/board/m5282evb/flash.c index ff70783bda..95f35ad84f 100644 --- a/board/m5282evb/flash.c +++ b/board/m5282evb/flash.c @@ -256,8 +256,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last) return rc; } - -volatile static int write_word (flash_info_t * info, ulong dest, ulong data) +static int write_word (flash_info_t * info, ulong dest, ulong data) { volatile u16 *addr = (volatile u16 *) dest; ulong result; diff --git a/board/smdk2400/flash.c b/board/smdk2400/flash.c index a108af7c72..fd9992d366 100644 --- a/board/smdk2400/flash.c +++ b/board/smdk2400/flash.c @@ -353,8 +353,7 @@ outahere: * Copy memory to flash */ -volatile static int write_word (flash_info_t * info, ulong dest, - ulong data) +static int write_word (flash_info_t * info, ulong dest, ulong data) { vu_long *addr = (vu_long *) dest; ulong result; diff --git a/board/trab/flash.c b/board/trab/flash.c index b4435e390f..8cdd82400b 100644 --- a/board/trab/flash.c +++ b/board/trab/flash.c @@ -308,8 +308,7 @@ outahere: * Copy memory to flash */ -volatile static int write_word (flash_info_t * info, ulong dest, - ulong data) +static int write_word (flash_info_t * info, ulong dest, ulong data) { vu_long *addr = (vu_long *) dest; ulong result; From d2ed2f661b6f74b68105d27a399801bdef287ef5 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sat, 11 Mar 2006 23:07:09 +0100 Subject: [PATCH 050/102] More GCC 4.x woes --- board/trab/Makefile | 2 +- cpu/arm920t/s3c24x0/usb_ohci.c | 3 ++- lib_arm/board.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/board/trab/Makefile b/board/trab/Makefile index ced9bc5bc8..159404b269 100644 --- a/board/trab/Makefile +++ b/board/trab/Makefile @@ -47,7 +47,7 @@ trab_fkt.srec: trab_fkt.o rs485.o tsc2000.o $(LIB) $(OBJCOPY) -O srec $(<:.o=) $@ trab_fkt.bin: trab_fkt.srec - $(OBJCOPY) -O binary $< $@ 2>/dev/null + $(OBJCOPY) -I srec -O binary $< $@ clean: rm -f $(SOBJS) $(OBJS) diff --git a/cpu/arm920t/s3c24x0/usb_ohci.c b/cpu/arm920t/s3c24x0/usb_ohci.c index b4cc74476b..869ca79d03 100644 --- a/cpu/arm920t/s3c24x0/usb_ohci.c +++ b/cpu/arm920t/s3c24x0/usb_ohci.c @@ -1647,7 +1647,8 @@ int usb_lowlevel_init(void) } /* FIXME this is a second HC reset; why?? */ - writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control); + gohci.hc_control = OHCI_USB_RESET; + writel (gohci.hc_control, &gohci.regs->control); wait_ms (10); if (hc_start (&gohci) < 0) { diff --git a/lib_arm/board.c b/lib_arm/board.c index 76639081ed..1028b046d8 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -408,6 +408,8 @@ void hang (void) } #ifdef CONFIG_MODEM_SUPPORT +static inline void mdm_readline(char *buf, int bufsiz); + /* called from main loop (common/main.c) */ extern void dbg(const char *fmt, ...); int mdm_init (void) @@ -416,7 +418,6 @@ int mdm_init (void) char *init_str; int i; extern char console_buffer[]; - static inline void mdm_readline(char *buf, int bufsiz); extern void enable_putc(void); extern int hwflow_onoff(int); From 84ef51a632063e8cb57b2e9a4252497512831ffe Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 00:04:20 +0100 Subject: [PATCH 051/102] Fix cleanup for netstart board. Remove build results from repository --- CHANGELOG | 3 +++ Makefile | 2 ++ board/netstar/Makefile | 2 +- board/netstar/crcek | Bin 35971 -> 0 bytes board/netstar/eeprom | Bin 40842 -> 0 bytes 5 files changed, 6 insertions(+), 1 deletion(-) delete mode 100755 board/netstar/crcek delete mode 100755 board/netstar/eeprom diff --git a/CHANGELOG b/CHANGELOG index 964e2b1f55..fa3f7450b0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix cleanup for netstart board. + Remove build results from repository + * Some code cleanup for GCC 4.x * Fixes to support environment in NAND flash; diff --git a/Makefile b/Makefile index 29d323a0ce..af046b930b 100644 --- a/Makefile +++ b/Makefile @@ -1876,6 +1876,8 @@ clean: rm -f tools/gdb/astest tools/gdb/gdbcont tools/gdb/gdbsend rm -f tools/env/fw_printenv tools/env/fw_setenv rm -f board/cray/L1/bootscript.c board/cray/L1/bootscript.image + rm -f board/netstar/eeprom board/netstar/crcek + rm -f board/netstar/*.srec board/netstar/*.bin rm -f board/trab/trab_fkt board/voiceblue/eeprom rm -f board/integratorap/u-boot.lds board/integratorcp/u-boot.lds diff --git a/board/netstar/Makefile b/board/netstar/Makefile index 8ef21893ee..3a205017f2 100644 --- a/board/netstar/Makefile +++ b/board/netstar/Makefile @@ -80,6 +80,6 @@ distclean: clean .depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ --include .depend +sinclude .depend ######################################################################### diff --git a/board/netstar/crcek b/board/netstar/crcek deleted file mode 100755 index 491cceb2ed1cd8bf38ee7531dcee46fcf99bc3e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35971 zcmeH}c~q3u8^@nvhJ72&NJVNaLJL_XGKmD)1W{H+5glfjfdPgYfk6~;3vn&YkfIGJ zqNt2OKz1;q1zXtneM>P5B`PUxy6?dI{?Ow&o!>dXKYo8a_niAa-|u~%_ult@nD_D? za`Sd)u~-6_Yih6(SaaHr#H!=uq5)tBJfL#g#HjLz=ZZ*>sLys101ksHFG(e1bDbKd z8kt6wrvf%4fCP{L5Uh5$=VZL-GMWK0j>6o-3cgy)wv zt`58*k9B89SWeAj;AA?abmEL~oYSuIIHp4^p8v>grE)1%1Ke}tEbtvBdtS;4J*HZx zkNepr%FH)pI7buZXy%CR4nEs132@zYaLp96iw1v-GF2{usZK zw&|}^TT`}XNFTbK7cEMf5#GJgAU@?2!dlcV)d&l7H2m{7eXW;@-NNI^ za;pX2l5L-u2tIeT2*31-bKf3~*j`o@uO;JYZu{iP)WX=uN-k;Sj@4$ZZY#U?UW4Xd zyBRP%lc)XK;tYe~O8uxq7LGAmuS-SeSRr9QPWwei3kA|;UDo2%%^;lmIbB1#KbK|v z`Lx!HLG^~eebrqc_MIqQc)hIVbn=PvJA)?uLQjjHhks3OeM#)y_SZJS#Z5o>m8?}j zRnCZYWt(&EpjT&lmt#zQ^ZS2IceF-LM7rGRmf5+Vi1@UrEVL)yg5x@F!d}hy*7>+0 zS-=1JSasizoz+%wxw*b^v^~EpL z4I4e`AUgj-RE&OJa8#0RqruoaO6{~2`Jhvnsd>OP&G2SRj@EI>6zkEy>og*F1_}T8 zHbQ(j)?T{gsz$VIk8#`IL*}g~gOhr=-+A>%$Op@3W+rRSxYU$B(tf5O^jc0w$HBDb zckAoA*7#2i`rL}BY>o)3`k-HJ z8JW$#nn?GTiUi*-O$o2cZjnD}KO*r@Pt^O4?V(#)Zlw0Om6`gM8i$H6SL#+@d^Nb( zoD)?P@}aV`&Ze=ct&a}L$U(-HbI@y=Je6Uxyt)=zY`jNId7?+@;va*xPV9~{R9st*D6f)JfJGeyU0l19!TII2>! z7gum$oGZ8jIk!~J72H6J(e5B&vED)lDL5tBlK#$Qofy?M!u!zxo zSj=bvEMv3~c#IAMQ$~xxn$cpgV{|yIVRQtzGCC4AFghB%DZM{lA&`j#aUx!%YC9{PBAt{+7 z`|rV+lu+BC{xhlCVE~ExoF;+(jV&jds$-KbNuBLPGL6bnZ3XGnZ}H#iR*@R|9wJq9 zR*?aEX=+{aO#!x~Q*+VH^f;*A6WY^rkZ+QE>W+{)2fBzvx{iv}e_*@$@@R?Si~{5XjubQk@;X^Lzryhs^T_i4UFUPZ3X_ zE7W{x#BZCI&mms*o{&i8FU$s&qkJh*^gBiQ%fyE=+h)NP;zjd(H}Uj)P1RFp5&gU@ z;;#}<^W~ELPu=H9$vt`cOd(~!CCP>N%DhqWMy}d^ebq$00`$Un~>x j`M_6c>Ks!rZZ@Mj*5>Dlp1Vh^I>;zT#wg8KO#uG@#ombS diff --git a/board/netstar/eeprom b/board/netstar/eeprom deleted file mode 100755 index e075eb4efd3c7fea6520d703cfb10274487482a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40842 zcmeHMd3;k<_CGH#Nz*;hg2*xk1gvxmP!U12g%(;UP};JHXqqNz8%UFoq_kiikWxWM zQLG>;(99qXIt~`fQnrHFQJ8ULEBjK?Wn^)rGR!D$opavHOCRWOW`6UT`C~qxdq2JR zp6@;9-gEBvy?5Wq>%z3mu^h)4!Cw>*102c?>SS#a_Lo-zDAWK+pu_PP=nheW9v0Dr zWG&Tl4FJ_38d^jRD~tig0AqkLz!+c*Fa{U{i~+^~V}LQh7+?%A1{ed30mcAhfHA-r zU<@z@7z2y}#sFi0F~AsL3@`>51B?O20AqkLz!+c*Fa{U{i~+^~V}LQh7+?%A1{ed3 z0mcAhfHA-rU<@z@7z2y}#sFi0F~AsL3@`>51B?O20AqkLz!+c*Fa{U{i~+^~V}LQh z7+?%A1{ed30mcAhfHA-rU<@z@7z2y}#sFi0F~AsL3@`>51B?O20AqkLz!+c*Fa{U{ zi~+^~V}LQh7+?%A1{ed30mcAhfHA-rU<@z@7z2y}#sFi0F~Au3-(ui>4z5C;x8-wf zbsOkbv;kzdbOQ+CoZc25y0&x$=&3-t0ZFYeHyK|Wh?gF z2yY9g&uRW1eQAGU>}E&DRZV+Ev!;Cs#-qj%6j+0y0}BeUN*`1jXN>q_*OcJb?`|j# zdgX$s-c(&)Y)(gc`wl&`Txbk?#wAHq#{Tt_)7u?GK{_{hY=O@qN zqR-gWCex_MZ~hvtdGVmmKJrPeHM2D(?}Te^;jfOi@(+(|R8IK5GW^(_Z6O=J*|_Zi z+v+W&PafKRF8S7;_gZYHhm_1}N;@2W^890?j{fF7{h5Iy;Np};Q%)W1ZalJY+s&8h|w%l8Md4W`>6kw(9KKB9f@5si)Q?$kMV<1@devoPB}kM zJ@*{9M|W)XAnl3k&sA=od(XD*>J6>?s)sh#UH;Xfpt7V}5V?F~@TwlGBYeBVXD^H& zRjhfkbmRPE7i8AHgLT@xT#q@y&>|iADyYOWL??O z^=e)HFUptg{I03bh5U^8v)%que*6VXX5+Urj9VstI%V4k5A0drtl!<3vY~1Gsg)V?rkI%kh9rN88d(zltg}*&gmv`13uS{+0!w)rNhP->IJp97Lb5&XIrYP>y zYD4Rv)rB1zu&ro%ZKXpO+*q))y4Cn;#I1`@u0C|;{(h^E)NI{&>f^gc)jsx2_|}Ax zv-a-zt!>wST}9oWx7Y4_BdmEl|HiS+o`=SrxcYwSv9;X>o>NwIKkx1uYHC?B(){Wp zvx~zw&YZm<^l(J$+K%9=`!+$y=5;|&r&dL_A6u_kT6BZ^*$)TQ)+eUtfAxn#%c8l% zY#bv7s5SnfXGOst?=i=KVa-L^D@(&Z;m3vU-q~HzFL9u1YW>Jvzl#aoyXBRc zTVs{8YiIqsUfaXoTz>48@cI*NJFcHE@7r`PwDH*SXGb?Te))Cn zg(7>!*?a!jz5bcU2k!ivue8QdI&MdgKh4xEbIy+J`29$A!K_fOOUF9POV&;KUmx$7 zV@x}2>t5Cz;{D=S_^I3q<)j0({6ofpg}?r)d)|?W*!KEqSs1zmNU zJ~{r1LXT%j53jH946hF~UY`!DIoaD%qd(xY;dxb)^`VbL8^U>r6}r*QHSnRYMt{tw z(pL!Mc%)oi3~()#?DfZe97MI4@w~)SCxlDRZT{1Z82IdES;rEyaVe=|1qO zhkJboaZmSRPq9+WYTe>yaW5YT@v3F$_ul4uQ{=SF5@9pn({=UDzkMZ|${$B6zldz}vVGo@U z_f_IjsbAb0hS!6~_wF|x9V19zj&V`VwH8|(B_7>$m(^pn7wXc|va%;n)VVB$R=3CE z(hblLDGR}yaAL|BU5eT4vbfzNbcm&S*%qVuAI+orBd8f*g6S>?dYCcRFfA=RCu8!Y z1Y9`9>9ko*Mvv8D*ICM(7L&)VOBtP^n`d#kX>5Qw1X4_%5~EEwHGZ_i;rWpk0Iv_0 zzF@|dWaAZNqN0XYX=4am8$Iv`JlH34}Vcmwhbcq<@31{(wNOn5IKKMpkk`3cw> zke`IQfNX$00oe%q19Cnz1Y{E&49I3^49FHZ9gqv)d_XRQ%K_O6p9kbQ&`$DGZjaG! zHoD9@tKC`Rc^VQEj3pjNv7^N9Ni-SV9)~M_p3Rt_=)wz|SmY?SB$k>J3$32SlK6ZY zDs{N#B<4GCg+#l>gR8j`Ef%NCQEVXDlaK>k7f!40itT`is8Bwl7e0fE{=i3shCYH9 zn@3S2ipod`4b6xGP<6+#5uqampyoI(ibjL_LPk^~PSGUb2p>TP_l0Fdb>X^l$#|az zt8h_qmIAZB5QP3k2!=q*m-9jY{yT2~w2|9tMhjLvc*~1~xP;XaqJY&@^E; z1uOR;mx3KdwH2%4X$UT+;b9B0r4oXNqaWUnFf@)F4W~H}7KAcMTtAM?xp2X@FUg|a zy@H))KH7am2Gay*kFnu~rw_uI50yjfgerlw}<&wa3Z4)Yw z;2P(#c490Uo1vgP7tZM#qErjLbynMo${&_-p6KGfrZ-OvaAZ8*Fg8@+2?I2okI*fvQRhUV9((OeT z@ID%@qKT`p2A{x&tD*_-pcIV(trQj&wl9h<3vOQ&g#cE4iq_G{#3~{ReNy1vY3IWI z^AO-kh&LMaMXi#fn~pLp@-N)l&*AV`tpB}RTd9mgr>Yg`gsUQv<5WvzK+Po+dWoZ$ zUKV)?Y9qTO8ehfH7{!cyX#|2+3fin-6YlyoqL|C}?;GDLwAV~(xo;yv&=-e`0QY~M z;a0oJR${g!8r}FTiAQ*X31@(3zSH7PC=%b{Dg`}t{6kz!Ld?>EaT)1xgW?tsG7oyj zyo3+m5u36pxZt=liWgFjsN7JW}LJ1*jB6Y-GB;C^^1@ z8>i14%LkkA94C(OI2FDXaKM#EgoQ&7#8hbG8?jH12wTooDwbeg3%yB!g-!=8&P|Qz zv7CEev6O#SS*cp0hG+d`v<)bHE@*SJP$O!|hfvOA+lrNg z9C1Lj*e|RR@K2K(gdsYpg>pBx_+(-^huuu9;@u?-(dHC_f;?AaHJ20@&xcx+j83PR zM3guYiDZilDFsXyL@N%+^yEa;6ParSjo8rsj$oyoq+*PX*q_EK6&vNgLQ`UQTMO+L zN{T$-F2dVLciT{>B^d-B78hpP27mTLr(Y>%?3N!7n2jDI%rn|bEPxZtuKz&Jt+@z_xF}kD#eS%&WlbSYZhAu5Lbpj2DgZG2m;-M)J*rut- z=mMwF<;D%zEX9_FOcCusmB4AgRUIe4^Bve z1mQ9!V1%@UxR5a)m8h}gmlPU|`S~u(JPBFt1rABJS?v}{E^rx(1Hk4mN#o9vd^>7z zasO&AqrI>b-i`#XCP%SwnWWqKpY^@a0G|TDv=s~f7Fa}YL;(nm_z(f~MI_nL+ox`6 zrwvJx9c5boiro;u9re>a}p+Z@h2J1hw%S0P#4vJ8Y z>#fECnoEWJ(m9-smDZ9H}*i0L@SO+GAZwS0pMeq14&nM zhus%10SuRvGTk#W8AXU$0r-2hvq;xtIS$FD!ydHT(`gpay?%#X*((4UKVe6Sn0&nt z&@TBW?CS2Y-wVITA2e9sUG$Belw`Y%?92#GF=yxWwb)XN&w32 zq#`X%z3i<4Gmro$lGY8!>7FG1v{-|&%GW!%7T|!i2bb;r_W08`;bl`*wgox&cX{%fEAMQy zdc?xF73>LrjI9z=6#*iq`&lEymk{rlt$z)%6ffqW@C9P2(Eh(dAmyU8f8v8M*$}4r zUO%S!8oW`Z{8X|hEVti?`6*$tr}ZdbmFuhg z*%9N(ChUiB31XYfzMSU!pHD4bk7bCHWcn8oOL;r(?{&nPGX2|#i7yX&A^m%ZnRHIzZbDtHvd16F5dZxuD=mXF4JH`zR?VZ%*iRKY1u;zlgEzDNz0Y6Atz&I8jST9 z7?V9_=nzA0%IM5AnmR;2b+9zmVYe8pZb3!g3JrtZ9uR~fnB Date: Sun, 12 Mar 2006 01:13:30 +0100 Subject: [PATCH 052/102] Fix behaviour if gatewayip is not set Patch by Robin Gilks, 23 Dec 2004 --- CHANGELOG | 3 +++ net/net.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index fa3f7450b0..db50b57e85 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix behaviour if gatewayip is not set + Patch by Robin Gilks, 23 Dec 2004 + * Fix cleanup for netstart board. Remove build results from repository diff --git a/net/net.c b/net/net.c index 37c5fb698e..506203761f 100644 --- a/net/net.c +++ b/net/net.c @@ -222,8 +222,10 @@ void ArpRequest (void) (NetOurIP & NetOurSubnetMask)) { if (NetOurGatewayIP == 0) { puts ("## Warning: gatewayip needed but not set\n"); + NetArpWaitReplyIP = NetArpWaitPacketIP; + } else { + NetArpWaitReplyIP = NetOurGatewayIP; } - NetArpWaitReplyIP = NetOurGatewayIP; } else { NetArpWaitReplyIP = NetArpWaitPacketIP; } From 2281490485ef2c76f93bf37a5014f5e630d5a3d0 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 01:21:19 +0100 Subject: [PATCH 053/102] Word alignment fixes for word aligned NS16550 UART Patch by Jean-Paul Saman, 01 Mar 2005 --- CHANGELOG | 12 ++++++++++++ include/ns16550.h | 20 ++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index db50b57e85..e3003e0dda 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,18 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Word alignment fixes for word aligned NS16550 UART + Patch by Jean-Paul Saman, 01 Mar 2005 + + Fixes bug with UART that only supports word aligned access: removed + "__attribute__ ((packed));" for "(CFG_NS16550_REG_SIZE == 4)" some + (broken!) versions of GCC generate byte accesses when encountering + the packed attribute regardless if the struct is already correctly + aligned for a platform. Peripherals that can only handle word + aligned access won't work properly when accessed with byte access. + The struct NS16550 is already word aligned for REG_SIZE = 4, so + there is no need to packed the struct in that case. + * Fix behaviour if gatewayip is not set Patch by Robin Gilks, 23 Dec 2004 diff --git a/include/ns16550.h b/include/ns16550.h index e17a11edca..d987a8b7ed 100644 --- a/include/ns16550.h +++ b/include/ns16550.h @@ -45,15 +45,15 @@ struct NS16550 { } __attribute__ ((packed)); #elif (CFG_NS16550_REG_SIZE == 4) struct NS16550 { - unsigned long rbr; /* 0 */ - unsigned long ier; /* 1 */ - unsigned long fcr; /* 2 */ - unsigned long lcr; /* 3 */ - unsigned long mcr; /* 4 */ - unsigned long lsr; /* 5 */ - unsigned long msr; /* 6 */ - unsigned long scr; /* 7 */ -} __attribute__ ((packed)); + unsigned long rbr; /* 0 r */ + unsigned long ier; /* 1 rw */ + unsigned long fcr; /* 2 w */ + unsigned long lcr; /* 3 rw */ + unsigned long mcr; /* 4 rw */ + unsigned long lsr; /* 5 r */ + unsigned long msr; /* 6 r */ + unsigned long scr; /* 7 rw */ +}; /* No need to pack an already aligned struct */ #elif (CFG_NS16550_REG_SIZE == -4) struct NS16550 { unsigned char rbr; /* 0 */ @@ -102,7 +102,7 @@ typedef volatile struct NS16550 *NS16550_t; #define MCR_DMA_EN 0x04 #define MCR_TX_DFR 0x08 -#define LCR_WLS_MSK 0x03 /* character length slect mask */ +#define LCR_WLS_MSK 0x03 /* character length select mask */ #define LCR_WLS_5 0x00 /* 5 bit character length */ #define LCR_WLS_6 0x01 /* 6 bit character length */ #define LCR_WLS_7 0x02 /* 7 bit character length */ From 611125a2925632c3281885e02836725ac1f6d8b0 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 01:23:43 +0100 Subject: [PATCH 054/102] Cleanup compiler warnings. Patch by Greg Ungerer, 21 May 2005 --- CHANGELOG | 3 +++ drivers/ks8695eth.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e3003e0dda..b2adb3167b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Cleanup compiler warnings. + Patch by Greg Ungerer, 21 May 2005 + * Word alignment fixes for word aligned NS16550 UART Patch by Jean-Paul Saman, 01 Mar 2005 diff --git a/drivers/ks8695eth.c b/drivers/ks8695eth.c index a4b03aee8c..a1bec1cc29 100644 --- a/drivers/ks8695eth.c +++ b/drivers/ks8695eth.c @@ -216,10 +216,10 @@ int eth_send(volatile void *packet, int len) packet, len); dp = &ks8695_tx[next]; - memcpy((void *) dp->addr, packet, len); + memcpy((void *) dp->addr, (void *) packet, len); if (len < 64) { - memset(dp->addr+len, 0, 64-len); + memset((void *) (dp->addr + len), 0, 64-len); len = 64; } From 82d716fd0d057db300cf2b1ab59194858f9b2e6d Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 01:30:45 +0100 Subject: [PATCH 055/102] Fix comment in common/soft_i2c.c Patches by Peter Korsgaard/Tolunay Orkun, 26 May 2005 --- CHANGELOG | 3 +++ common/soft_i2c.c | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index b2adb3167b..8afc11b611 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix comment in common/soft_i2c.c + Patches by Peter Korsgaard/Tolunay Orkun, 26 May 2005 + * Cleanup compiler warnings. Patch by Greg Ungerer, 21 May 2005 diff --git a/common/soft_i2c.c b/common/soft_i2c.c index 3d0e08c6ff..268da2cdc4 100644 --- a/common/soft_i2c.c +++ b/common/soft_i2c.c @@ -288,7 +288,10 @@ int i2c_probe(uchar addr) { int rc; - /* perform 1 byte read transaction */ + /* + * perform 1 byte write transaction with just address byte + * (fake write) + */ send_start(); rc = write_byte ((addr << 1) | 0); send_stop(); From 92b197f0da45ae086b7c457184ae67a432ef1c5e Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 01:37:50 +0100 Subject: [PATCH 056/102] Fix Makefile: include config.mk only after CROSS_COMPILE is defined Patch by Friedrich Lobenstock, 02 Jun 2005 --- CHANGELOG | 3 +++ Makefile | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8afc11b611..7e38f4de89 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix Makefile: include config.mk only after CROSS_COMPILE is defined + Patch by Friedrich Lobenstock, 02 Jun 2005 + * Fix comment in common/soft_i2c.c Patches by Peter Korsgaard/Tolunay Orkun, 26 May 2005 diff --git a/Makefile b/Makefile index af046b930b..fefcbbac0a 100644 --- a/Makefile +++ b/Makefile @@ -53,9 +53,6 @@ ifeq (include/config.mk,$(wildcard include/config.mk)) # load ARCH, BOARD, and CPU configuration include include/config.mk export ARCH CPU BOARD VENDOR SOC -# load other configuration -include $(TOPDIR)/config.mk - ifndef CROSS_COMPILE ifeq ($(HOSTARCH),ppc) CROSS_COMPILE = @@ -93,6 +90,10 @@ endif export CROSS_COMPILE +# load other configuration +include $(TOPDIR)/config.mk + + ######################################################################### # U-Boot objects....order is important (i.e. start must be first) From 7c54c7018e9c6f50931c07afe1805bef1be0def9 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 01:40:01 +0100 Subject: [PATCH 057/102] Fix conditional for including ks8695eth driver Patch by Greg Ungerer, 04 Jun 2005 --- CHANGELOG | 3 +++ drivers/ks8695eth.c | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7e38f4de89..8999b153bc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix conditional for including ks8695eth driver + Patch by Greg Ungerer, 04 Jun 2005 + * Fix Makefile: include config.mk only after CROSS_COMPILE is defined Patch by Friedrich Lobenstock, 02 Jun 2005 diff --git a/drivers/ks8695eth.c b/drivers/ks8695eth.c index a1bec1cc29..a0f5be81dd 100644 --- a/drivers/ks8695eth.c +++ b/drivers/ks8695eth.c @@ -18,8 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef CONFIG_DRIVER_KS8695ETH - /****************************************************************************/ #include @@ -28,6 +26,7 @@ #include #include +#ifdef CONFIG_DRIVER_KS8695ETH /****************************************************************************/ /* From 5797b821dcd245af36f9d44eb05b256f1e1ccfc3 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 01:43:03 +0100 Subject: [PATCH 058/102] Add support for Adder boards with 16MB SDRAM; add support for second FEC on Adder87x board. Patch by Yuli Barcohen, 05 Jun 2005 --- CHANGELOG | 4 ++++ board/adder/adder.c | 24 +++++++++++++++--------- include/configs/Adder.h | 33 +++++++++++++++++---------------- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8999b153bc..41b266fdb7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,10 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add support for Adder boards with 16MB SDRAM; + add support for second FEC on Adder87x board. + Patch by Yuli Barcohen, 05 Jun 2005 + * Fix conditional for including ks8695eth driver Patch by Greg Ungerer, 04 Jun 2005 diff --git a/board/adder/adder.c b/board/adder/adder.c index cab6e2f66a..aa7815848c 100644 --- a/board/adder/adder.c +++ b/board/adder/adder.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Arabella Software Ltd. + * Copyright (C) 2004-2005 Arabella Software Ltd. * Yuli Barcohen * * Support for Analogue&Micro Adder boards family. @@ -28,7 +28,8 @@ #include /* - * SDRAM is single Samsung K4S643232F-T70 chip. + * SDRAM is single Samsung K4S643232F-T70 chip (8MB) + * or single Micron MT48LC4M32B2TG-7 chip (16MB). * Minimal CPU frequency is 40MHz. */ static uint sdram_table[] = { @@ -53,7 +54,7 @@ static uint sdram_table[] = { 0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04, /* Refresh (offset 0x30 in UPM RAM) */ - 0x1ff5fca4, 0xfffffc04, 0xfffffc04, 0xfffffc04, + 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc84, 0xfffffc07, 0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04, @@ -63,7 +64,7 @@ static uint sdram_table[] = { long int initdram (int board_type) { - long int msize = CFG_SDRAM_SIZE; + long int msize; volatile immap_t *immap = (volatile immap_t *)CFG_IMMR; volatile memctl8xx_t *memctl = &immap->im_memctl; @@ -72,11 +73,11 @@ long int initdram (int board_type) /* Configure SDRAM refresh */ memctl->memc_mptpr = MPTPR_PTP_DIV32; /* BRGCLK/32 */ - memctl->memc_mamr = (94 << 24) | CFG_MAMR; - memctl->memc_mar = 0x0; + memctl->memc_mamr = (94 << 24) | CFG_MAMR; /* No refresh */ udelay(200); /* Run precharge from location 0x15 */ + memctl->memc_mar = 0x0; memctl->memc_mcr = 0x80002115; udelay(200); @@ -84,13 +85,18 @@ long int initdram (int board_type) memctl->memc_mcr = 0x80002830; udelay(200); - memctl->memc_mar = 0x88; - udelay(200); - /* Run MRS pattern from location 0x16 */ + memctl->memc_mar = 0x88; memctl->memc_mcr = 0x80002116; udelay(200); + memctl->memc_mamr |= MAMR_PTAE; /* Enable refresh */ + memctl->memc_or1 = ~(CFG_SDRAM_MAX_SIZE - 1) | OR_CSNT_SAM; + memctl->memc_br1 = CFG_SDRAM_BASE | BR_PS_32 | BR_MS_UPMA | BR_V; + + msize = get_ram_size(CFG_SDRAM_BASE, CFG_SDRAM_MAX_SIZE); + memctl->memc_or1 |= ~(msize - 1); + return msize; } diff --git a/include/configs/Adder.h b/include/configs/Adder.h index f8075466c4..0e6b50f8b0 100644 --- a/include/configs/Adder.h +++ b/include/configs/Adder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Arabella Software Ltd. + * Copyright (C) 2004-2005 Arabella Software Ltd. * Yuli Barcohen * * Support for Analogue&Micro Adder boards family. @@ -35,11 +35,13 @@ #define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */ #define CONFIG_BAUDRATE 38400 -#define CONFIG_FEC_ENET /* Ethernet is on FEC */ -#ifdef CONFIG_FEC_ENET +#define CONFIG_ETHER_ON_FEC1 +#define CONFIG_ETHER_ON_FEC2 + +#if defined(CONFIG_ETHER_ON_FEC1) || defined(CONFIG_ETHER_ON_FEC2) #define CFG_DISCOVER_PHY #define FEC_ENET -#endif /* CONFIG_FEC_ENET */ +#endif /* CONFIG_ETHER_ON_FEC || CONFIG_ETHER_ON_FEC2 */ #define CONFIG_8xx_OSCLK 10000000 /* 10 MHz oscillator on EXTCLK */ #define CONFIG_8xx_CPUCLK_DEFAULT 50000000 @@ -47,7 +49,7 @@ #ifdef CONFIG_MPC852T #define CFG_8xx_CPUCLK_MAX 50000000 #else -#define CFG_8xx_CPUCLK_MAX 120000000 +#define CFG_8xx_CPUCLK_MAX 133000000 #endif /* CONFIG_MPC852T */ #define CONFIG_COMMANDS (CONFIG_CMD_DFL \ @@ -62,7 +64,7 @@ #define CONFIG_BOOTDELAY 5 /* Autoboot after 5 seconds */ #define CONFIG_BOOTCOMMAND "bootm fe040000" /* Autoboot command */ -#define CONFIG_BOOTARGS "root=/dev/mtdblock2 rw" +#define CONFIG_BOOTARGS "root=/dev/mtdblock1 rw mtdparts=1M(ROM)ro,-(root)" #define CONFIG_BZIP2 /* Include support for bzip2 compressed images */ #undef CONFIG_WATCHDOG /* Disable platform specific watchdog */ @@ -79,7 +81,7 @@ #define CFG_MAXARGS 16 /* Max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ -#define CFG_LOAD_ADDR 0x100000 /* Default load address */ +#define CFG_LOAD_ADDR 0x400000 /* Default load address */ #define CFG_HZ 1000 /* Decrementer freq: 1 ms ticks */ @@ -89,24 +91,21 @@ * RAM configuration (note that CFG_SDRAM_BASE must be zero) */ #define CFG_SDRAM_BASE 0x00000000 -#define CFG_SDRAM_SIZE 0x00800000 /* 8 Mbyte */ +#define CFG_SDRAM_MAX_SIZE 0x01000000 /* Up to 16 Mbyte */ -#define CFG_OR1_PRELIM (0xFF800000 | OR_CSNT_SAM | OR_ACS_DIV2) -#define CFG_BR1_PRELIM (CFG_SDRAM_BASE | BR_PS_32 | BR_MS_UPMA | BR_V) - -#define CFG_MAMR 0x00802114 +#define CFG_MAMR 0x00002114 /* - * 2048 SDRAM rows + * 4096 Up to 4096 SDRAM rows * 1000 factor s -> ms - * 64 PTP (pre-divider from MPTPR) from SDRAM example configuration + * 32 PTP (pre-divider from MPTPR) * 4 Number of refresh cycles per period * 64 Refresh cycle in ms per number of rows */ -#define CFG_PTA_PER_CLK ((2048 * 64 * 1000) / (4 * 64)) +#define CFG_PTA_PER_CLK ((4096 * 32 * 1000) / (4 * 64)) #define CFG_MEMTEST_START 0x00100000 /* memtest works on */ -#define CFG_MEMTEST_END 0x00700000 /* 1 ... 7 MB in SDRAM */ +#define CFG_MEMTEST_END 0x00500000 /* 1 ... 5 MB in SDRAM */ #define CFG_RESET_ADDRESS 0x09900000 @@ -139,6 +138,8 @@ #define CFG_ENV_SECT_SIZE 0x10000 /* We use one complete sector */ #define CFG_ENV_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN) +#define CONFIG_ENV_OVERWRITE + #define CFG_OR0_PRELIM 0xFF000774 #define CFG_BR0_PRELIM (CFG_FLASH_BASE | BR_PS_16 | BR_MS_GPCM | BR_V) From aba9f1af6001b124f4e3e56ebd1a296bd63531f4 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 01:45:44 +0100 Subject: [PATCH 059/102] Memory configuration changes for ZPC.1900 board - Fix SDRAM timing on both local bus and 60x bus - Add support for second flash bank (SIMM) - Change boot flash base Patch by Yuli Barcohen, 05 Jun 2005 --- CHANGELOG | 6 ++++ board/zpc1900/config.mk | 2 +- board/zpc1900/zpc1900.c | 32 ++++++++---------- include/configs/ZPC1900.h | 69 +++++++++++++++++++-------------------- 4 files changed, 55 insertions(+), 54 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 41b266fdb7..e2730cf01c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,12 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Memory configuration changes for ZPC.1900 board + - Fix SDRAM timing on both local bus and 60x bus + - Add support for second flash bank (SIMM) + - Change boot flash base + Patch by Yuli Barcohen, 05 Jun 2005 + * Add support for Adder boards with 16MB SDRAM; add support for second FEC on Adder87x board. Patch by Yuli Barcohen, 05 Jun 2005 diff --git a/board/zpc1900/config.mk b/board/zpc1900/config.mk index 1072dc7905..3e53b2be05 100644 --- a/board/zpc1900/config.mk +++ b/board/zpc1900/config.mk @@ -27,4 +27,4 @@ # ZPC.1900 board # -TEXT_BASE = 0xFFE00000 +TEXT_BASE = 0xFE000000 diff --git a/board/zpc1900/zpc1900.c b/board/zpc1900/zpc1900.c index 6d16a0d192..7db535e8a4 100644 --- a/board/zpc1900/zpc1900.c +++ b/board/zpc1900/zpc1900.c @@ -2,7 +2,7 @@ * (C) Copyright 2001-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2003 Arabella Software Ltd. + * (C) Copyright 2003-2005 Arabella Software Ltd. * Yuli Barcohen * * See file CREDITS for list of people who contributed to this @@ -27,9 +27,6 @@ #include #include #include -#include -#include -#include #include /* @@ -167,8 +164,8 @@ const iop_conf_t iop_conf_tab[4][32] = { /* PD18 */ { 0, 0, 0, 0, 0, 0 }, /* PD18 */ /* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */ /* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */ - /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */ - /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */ + /* PD15 */ { 0, 1, 1, 0, 1, 0 }, /* I2C SDA */ + /* PD14 */ { 0, 1, 1, 0, 1, 0 }, /* I2C SCL */ /* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */ /* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */ /* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */ @@ -231,11 +228,10 @@ long int initdram(int board_type) vu_char *ramaddr; uchar c = 0xFF; long int msize = CFG_SDRAM_SIZE; - uint psdmr = CFG_PSDMR; int i; if (bcsr[4] & BCSR_PCI_MODE) { /* PCI mode selected by JP9 */ - immap->im_clkrst.car_sccr |= M826X_SCCR_PCI_MODE_EN; + immap->im_clkrst.car_sccr |= SCCR_PCI_MODE; immap->im_siu_conf.sc_siumcr = (immap->im_siu_conf.sc_siumcr & ~SIUMCR_LBPC11) | SIUMCR_LBPC01; @@ -255,10 +251,10 @@ long int initdram(int board_type) */ if ((immap->im_siu_conf.sc_siumcr & SIUMCR_LBPC11) == SIUMCR_LBPC00) { memctl->memc_lsrt = CFG_LSRT; - memctl->memc_or4 = 0xFFC01480; - memctl->memc_br4 = CFG_LSDRAM_BASE | 0x00001861; - memctl->memc_lsdmr = CFG_LSDMR | PSDMR_OP_PREA; + memctl->memc_or4 = CFG_LSDRAM_OR; + memctl->memc_br4 = CFG_LSDRAM_BR; ramaddr = (vu_char *)CFG_LSDRAM_BASE; + memctl->memc_lsdmr = CFG_LSDMR | PSDMR_OP_PREA; *ramaddr = c; memctl->memc_lsdmr = CFG_LSDMR | PSDMR_OP_CBRR; for (i = 0; i < 8; i++) @@ -271,8 +267,8 @@ long int initdram(int board_type) /* Initialise 60x bus SDRAM */ memctl->memc_psrt = CFG_PSRT; - memctl->memc_or2 = 0xFC0028C0; - memctl->memc_br2 = CFG_SDRAM_BASE | 0x00000041; + memctl->memc_or2 = CFG_PSDRAM_OR; + memctl->memc_br2 = CFG_PSDRAM_BR; /* * The mode data for Mode Register Write command must appear on * the address lines during a mode-set cycle. It is driven by @@ -283,15 +279,15 @@ long int initdram(int board_type) * length must be 4. */ ramaddr = (vu_char *)(CFG_SDRAM_BASE | - ((psdmr & PSDMR_CL_MSK) << 7) | 0x10); - memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; /* Precharge all banks */ + ((CFG_PSDMR & PSDMR_CL_MSK) << 7) | 0x10); + memctl->memc_psdmr = CFG_PSDMR | PSDMR_OP_PREA; /* Precharge all banks */ *ramaddr = c; - memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; /* CBR refresh */ + memctl->memc_psdmr = CFG_PSDMR | PSDMR_OP_CBRR; /* CBR refresh */ for (i = 0; i < 8; i++) *ramaddr = c; - memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; /* Mode Register write */ + memctl->memc_psdmr = CFG_PSDMR | PSDMR_OP_MRW; /* Mode Register write */ *ramaddr = c; - memctl->memc_psdmr = psdmr | PSDMR_RFEN; /* Refresh enable */ + memctl->memc_psdmr = CFG_PSDMR | PSDMR_RFEN; /* Refresh enable */ *ramaddr = c; #endif /* CFG_RAMBOOT */ diff --git a/include/configs/ZPC1900.h b/include/configs/ZPC1900.h index f71e691b26..a5085cfb79 100644 --- a/include/configs/ZPC1900.h +++ b/include/configs/ZPC1900.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2004 Arabella Software Ltd. + * Copyright (C) 2003-2005 Arabella Software Ltd. * Yuli Barcohen * * U-Boot configuration for Zephyr Engineering ZPC.1900 board. @@ -32,11 +32,7 @@ #define CPU_ID_STR "MPC8265" #define CONFIG_CPM2 1 /* Has a CPM2 */ -#undef DEBUG - -#undef CONFIG_BOARD_EARLY_INIT_F /* Don't call board_early_init_f */ - -/* Allow serial number (serial) and MAC address (ethaddr) to be overwritten */ +/* Allow serial number (serial#) and MAC address (ethaddr) to be overwritten */ #define CONFIG_ENV_OVERWRITE /* @@ -113,7 +109,6 @@ #define CONFIG_COMMANDS (CONFIG_CMD_DFL \ | CFG_CMD_ASKENV \ | CFG_CMD_DHCP \ - | CFG_CMD_ECHO \ | CFG_CMD_IMMAP \ | CFG_CMD_MII \ | CFG_CMD_PING \ @@ -154,31 +149,30 @@ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CFG_MEMTEST_START 0x00100000 /* memtest works on */ -#define CFG_MEMTEST_END 0x00f00000 /* 1 ... 15 MB in DRAM */ +#define CFG_MEMTEST_END 0x03800000 /* 1 ... 56 MB in DRAM */ -#define CFG_LOAD_ADDR 0x100000 /* default load address */ +#define CFG_LOAD_ADDR 0x400000 /* default load address */ #define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 230400 } -#define CFG_FLASH_BASE 0xFFE00000 -#define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER -#define CFG_MAX_FLASH_BANKS 1 /* max num of flash banks */ -#define CFG_MAX_FLASH_SECT 32 /* max num of sects on one chip */ - -#define CFG_DEFAULT_IMMR 0x0F010000 - -#define CFG_IMMR 0xF0000000 #define CFG_SDRAM_BASE 0x00000000 #define CFG_SDRAM_SIZE 64 -#define CFG_FLSIMM_BASE 0xFC000000 -#define CFG_LSDRAM_BASE 0xFE000000 + +#define CFG_IMMR 0xF0000000 +#define CFG_LSDRAM_BASE 0xFC000000 +#define CFG_FLASH_BASE 0xFE000000 #define CFG_BCSR 0xFEA00000 #define CFG_EEPROM 0xFEB00000 +#define CFG_FLSIMM_BASE 0xFF000000 -#define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } +#define CFG_FLASH_CFI +#define CFG_FLASH_CFI_DRIVER +#define CFG_MAX_FLASH_BANKS 2 /* max num of flash banks */ +#define CFG_MAX_FLASH_SECT 32 /* max num of sects on one chip */ + +#define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, CFG_FLSIMM_BASE } #define BCSR_PCI_MODE 0x01 @@ -190,10 +184,10 @@ /* Hard reset configuration word */ #define CFG_HRCW_MASTER (HRCW_EBM | HRCW_BPS01| HRCW_CIP |\ - HRCW_L2CPC10 | HRCW_DPPC00 | HRCW_ISB010 |\ - HRCW_BMS | HRCW_LBPC01 | HRCW_APPC10 |\ - HRCW_MODCK_H0101 \ - ) /* 0x16828605 */ + HRCW_L2CPC10 | HRCW_DPPC00 | HRCW_ISB100 |\ + HRCW_BMS | HRCW_LBPC00 | HRCW_APPC10 |\ + HRCW_MODCK_H0111 \ + ) /* 0x16848207 */ /* No slaves */ #define CFG_HRCW_SLAVE1 0 #define CFG_HRCW_SLAVE2 0 @@ -211,7 +205,7 @@ #define CFG_RAMBOOT #endif -#define CFG_MONITOR_LEN (192 << 10) /* Reserve 192 kB for Monitor */ +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ #define CFG_MALLOC_LEN (4096 << 10) /* Reserve 4 MB for malloc() */ #define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ @@ -233,14 +227,14 @@ # define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ #endif -#define CFG_HID0_INIT 0 -#define CFG_HID0_FINAL (HID0_ICE | HID0_IFEM | HID0_ABE ) +#define CFG_HID0_INIT (HID0_ICFI) +#define CFG_HID0_FINAL (HID0_ICE | HID0_IFEM | HID0_ABE) #define CFG_HID2 0 #define CFG_SIUMCR 0x42200000 #define CFG_SYPCR 0xFFFFFFC3 -#define CFG_BCR 0x90400000 +#define CFG_BCR 0x90000000 #define CFG_SCCR SCCR_DFBRG01 #define CFG_RMR RMR_CSRE @@ -248,18 +242,23 @@ #define CFG_PISCR (PISCR_PS|PISCR_PTF|PISCR_PTE) #define CFG_RCCR 0 -#define CFG_PSDMR 0x014EB45A -#define CFG_PSRT 0x0C -#define CFG_LSDMR 0x008AB552 -#define CFG_LSRT 0x0E +#define CFG_PSDMR /* 0x834DA43B */0x014DA43A +#define CFG_PSRT 0x0F/* 0x0C */ +#define CFG_LSDMR 0x0085A562 +#define CFG_LSRT 0x0F #define CFG_MPTPR 0x4000 +#define CFG_PSDRAM_BR CFG_SDRAM_BASE | 0x00000041 +#define CFG_PSDRAM_OR 0xFC0028C0 +#define CFG_LSDRAM_BR CFG_LSDRAM_BASE | 0x00001861 +#define CFG_LSDRAM_OR 0xFF803480 + #define CFG_BR0_PRELIM CFG_FLASH_BASE | 0x00000801 #define CFG_OR0_PRELIM 0xFFE00856 #define CFG_BR5_PRELIM CFG_EEPROM | 0x00000801 #define CFG_OR5_PRELIM 0xFFFF03F6 -#define CFG_BR6_PRELIM CFG_FLSIMM_BASE | 0x00000801 -#define CFG_OR6_PRELIM 0xFE000856 +#define CFG_BR6_PRELIM CFG_FLSIMM_BASE | 0x00001801 +#define CFG_OR6_PRELIM 0xFF000856 #define CFG_BR7_PRELIM CFG_BCSR | 0x00000801 #define CFG_OR7_PRELIM 0xFFFF83F6 From f47b6611419bf81a128869fa78f9772cfada9af0 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 01:48:55 +0100 Subject: [PATCH 060/102] RPXlite configuration fixes - Use correct flash sector size - Use correct memory test end address - Add support for bzip2 compression - Various small fixes Patch by Yuli Barcohen, 05 Jun 2005 --- CHANGELOG | 7 ++++ include/configs/RPXlite.h | 68 +++++++++++++++++---------------------- 2 files changed, 36 insertions(+), 39 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e2730cf01c..a1a768d585 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,13 @@ Changes since U-Boot 1.1.4: ====================================================================== +* RPXlite configuration fixes + - Use correct flash sector size + - Use correct memory test end address + - Add support for bzip2 compression + - Various small fixes + Patch by Yuli Barcohen, 05 Jun 2005 + * Memory configuration changes for ZPC.1900 board - Fix SDRAM timing on both local bus and 60x bus - Add support for second flash bank (SIMM) diff --git a/include/configs/RPXlite.h b/include/configs/RPXlite.h index 6b65031099..48ada0ed9b 100644 --- a/include/configs/RPXlite.h +++ b/include/configs/RPXlite.h @@ -21,10 +21,6 @@ * MA 02111-1307 USA */ -/* - * board/config.h - configuration options, board specific - */ - /* Yoo. Jonghoon, IPone, yooth@ipone.co.kr * U-Boot port on RPXlite board */ @@ -53,8 +49,6 @@ #define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ #endif -#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */ - #undef CONFIG_BOOTARGS #define CONFIG_BOOTCOMMAND \ "bootp; " \ @@ -65,6 +59,7 @@ #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ #undef CFG_LOADS_BAUD_CHANGE /* don't allow baudrate change */ +#define CONFIG_BZIP2 /* Include support for bzip2 compressed images */ #undef CONFIG_WATCHDOG /* watchdog disabled */ #define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE) @@ -86,12 +81,14 @@ #define CFG_MAXARGS 16 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ -#define CFG_MEMTEST_START 0x0040000 /* memtest works on */ -#define CFG_MEMTEST_END 0x00C0000 /* 4 ... 12 MB in DRAM */ +#define CFG_MEMTEST_START 0x00400000 /* memtest works on */ +#define CFG_MEMTEST_END 0x00C00000 /* 4 ... 12 MB in DRAM */ -#define CFG_LOAD_ADDR 0x100000 /* default load address */ +#define CFG_RESET_ADDRESS 0x09900000 -#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ +#define CFG_LOAD_ADDR 0x400000 /* default load address */ + +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } @@ -120,16 +117,14 @@ * Please note that CFG_SDRAM_BASE _must_ start at 0 */ #define CFG_SDRAM_BASE 0x00000000 -#define CFG_FLASH_BASE 0xFFC00000 -/*%%% #define CFG_FLASH_BASE 0xFFF00000 */ -#if defined(DEBUG) || (CONFIG_COMMANDS & CFG_CMD_IDE) +#define CFG_FLASH_BASE 0xFFC00000 +#define CFG_MONITOR_BASE TEXT_BASE #define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#ifdef CONFIG_BZIP2 +#define CFG_MALLOC_LEN (4096 << 10) /* Reserve ~4 MB for malloc() */ #else -#define CFG_MONITOR_LEN (128 << 10) /* Reserve 128 kB for Monitor */ -#endif -#define CFG_MONITOR_BASE 0xFFF00000 -/*%%% #define CFG_MONITOR_BASE CFG_FLASH_BASE */ -#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 KB for malloc() */ +#endif /* CONFIG_BZIP2 */ /* * For booting Linux, the board info and command line data @@ -147,9 +142,13 @@ #define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ #define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ +#define CFG_DIRECT_FLASH_TFTP + #define CFG_ENV_IS_IN_FLASH 1 -#define CFG_ENV_OFFSET 0x8000 /* Offset of Environment Sector */ -#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */ +#define CFG_ENV_SECT_SIZE 0x40000 /* We use one complete sector */ +#define CFG_ENV_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN) + +#define CONFIG_ENV_OVERWRITE /*----------------------------------------------------------------------- * Cache Configuration @@ -352,12 +351,12 @@ #define BCSR0_ENMONXCVR 0x01 /* Monitor XVCR Control */ #define BCSR0_ENNVRAM 0x02 /* CS4# Control */ -#define BCSR0_LED5 0x04 /* LED5 control 0='on' 1='off' */ -#define BCSR0_LED4 0x08 /* LED4 control 0='on' 1='off' */ +#define BCSR0_LED5 0x04 /* LED5 control 0='on' 1='off' */ +#define BCSR0_LED4 0x08 /* LED4 control 0='on' 1='off' */ #define BCSR0_FULLDPLX 0x10 /* Ethernet XCVR Control */ #define BCSR0_COLTEST 0x20 #define BCSR0_ETHLPBK 0x40 -#define BCSR0_ETHEN 0x80 +#define BCSR0_ETHEN 0x80 #define BCSR1_PCVCTL7 0x01 /* PC Slot B Control */ #define BCSR1_PCVCTL6 0x02 @@ -371,22 +370,13 @@ #define BCSR2_USBSPD 0x40 #define BCSR2_USBSUSP 0x80 -#define BCSR3_BWRTC 0x01 /* Real Time Clock Battery */ -#define BCSR3_BWNVR 0x02 /* NVRAM Battery */ +#define BCSR3_BWRTC 0x01 /* Real Time Clock Battery */ +#define BCSR3_BWNVR 0x02 /* NVRAM Battery */ #define BCSR3_RDY_BSY 0x04 /* Flash Operation */ -#define BCSR3_RPXL 0x08 /* Reserved (reads back '1') */ -#define BCSR3_D27 0x10 /* Dip Switch settings */ -#define BCSR3_D26 0x20 -#define BCSR3_D25 0x40 -#define BCSR3_D24 0x80 - - -/* - * Environment setting - */ - -#define CONFIG_ETHADDR 00:10:EC:00:1D:0B -#define CONFIG_IPADDR 192.168.1.65 -#define CONFIG_SERVERIP 192.168.1.27 +#define BCSR3_RPXL 0x08 /* Reserved (reads back '1') */ +#define BCSR3_D27 0x10 /* Dip Switch settings */ +#define BCSR3_D26 0x20 +#define BCSR3_D25 0x40 +#define BCSR3_D24 0x80 #endif /* __CONFIG_H */ From 8ff0208d31223e36f7c038982589b448d7fdd217 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 01:55:43 +0100 Subject: [PATCH 061/102] Switch MPC86xADS and MPC885ADS boards to use cpuclk environment variable to set clock Patch by Yuli Barcohen, 05 Jun 2005 --- CHANGELOG | 4 ++ board/fads/fads.c | 28 ++++---- board/fads/fads.h | 135 +++++++++++++++--------------------- include/configs/MPC86xADS.h | 7 +- include/configs/MPC885ADS.h | 28 +++----- 5 files changed, 85 insertions(+), 117 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a1a768d585..c4c4124196 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,10 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Switch MPC86xADS and MPC885ADS boards to use cpuclk environment + variable to set clock + Patch by Yuli Barcohen, 05 Jun 2005 + * RPXlite configuration fixes - Use correct flash sector size - Use correct memory test end address diff --git a/board/fads/fads.c b/board/fads/fads.c index 013b3cb155..7b04af56c9 100644 --- a/board/fads/fads.c +++ b/board/fads/fads.c @@ -726,24 +726,23 @@ static void checkdboard(void) int checkboard (void) { - /* get revision from BCSR 3 */ +#if defined(CONFIG_MPC86xADS) + puts ("Board: MPC86xADS\n"); +#elif defined(CONFIG_MPC885ADS) + puts ("Board: MPC885ADS\n"); +#else /* Only old ADS/FADS have got revision ID in BCSR3 */ uint r = (((*((uint *) BCSR3) >> 23) & 1) << 3) | (((*((uint *) BCSR3) >> 19) & 1) << 2) | (((*((uint *) BCSR3) >> 16) & 3)); puts ("Board: "); - -#if defined(CONFIG_MPC86xADS) - puts ("MPC86xADS"); -#elif defined(CONFIG_MPC885ADS) - puts ("MPC885ADS"); - r = 0; /* I've got NR (No Revision) board */ -#elif defined(CONFIG_FADS) +#if defined(CONFIG_FADS) puts ("FADS"); checkdboard (); #else puts ("ADS"); #endif + puts (" rev "); switch (r) { @@ -758,13 +757,9 @@ int checkboard (void) puts ("A - warning, read errata \n"); break; case 0x03: - puts ("B \n"); + puts ("B\n"); break; -#elif defined(CONFIG_MPC885ADS) - case 0x00: - puts ("NR\n"); - break; -#else /* FADS and newer */ +#else /* FADS */ case 0x00: puts ("ENG\n"); break; @@ -776,6 +771,7 @@ int checkboard (void) printf ("unknown (0x%x)\n", r); return -1; } +#endif /* CONFIG_MPC86xADS */ return 0; } @@ -848,7 +844,7 @@ int pcmcia_init(void) switch ((pcmp->pcmc_pipr >> 14) & 3) #endif { - case 0x00 : + case 0x03 : printf("5V"); v = 5; break; @@ -860,7 +856,7 @@ int pcmcia_init(void) v = 5; #endif break; - case 0x03 : + case 0x00 : printf("5V, 3V and x.xV"); #ifdef CONFIG_FADS v = 3; /* User lower voltage if supported! */ diff --git a/board/fads/fads.h b/board/fads/fads.h index 1127c7ff72..e981be03b5 100644 --- a/board/fads/fads.h +++ b/board/fads/fads.h @@ -55,18 +55,26 @@ #define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ #endif -#undef CONFIG_BOOTARGS -#define CONFIG_BOOTCOMMAND \ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_NFSBOOTCOMMAND \ "dhcp;" \ - "setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} " \ - "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off;" \ + "setenv bootargs root=/dev/nfs rw nfsroot=$rootpath " \ + "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:eth0:off;" \ "bootm" +#define CONFIG_BOOTCOMMAND \ + "setenv bootargs root=/dev/mtdblock2 rw mtdparts=phys:1280K(ROM)ro,-(root) "\ + "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:eth0:off;" \ + "bootm fe080000" + +#undef CONFIG_BOOTARGS + #undef CONFIG_WATCHDOG /* watchdog disabled */ #define CONFIG_BZIP2 /* include support for bzip2 compressed images */ /* - * New MPC86xADS and Duet provide two Ethernet connectivity options: + * New MPC86xADS and MPC885ADS provide two Ethernet connectivity options: * 10Mbit/s on SCC and 100Mbit/s on FEC. FADS provides SCC Ethernet on * motherboard and FEC Ethernet on daughterboard. All new PQ1 chips have * got FEC so FEC is the default. @@ -89,7 +97,9 @@ #ifndef CONFIG_COMMANDS #define CONFIG_COMMANDS (CONFIG_CMD_DFL \ + | CFG_CMD_ASKENV \ | CFG_CMD_DHCP \ + | CFG_CMD_ECHO \ | CFG_CMD_IMMAP \ | CFG_CMD_JFFS2 \ | CFG_CMD_MII \ @@ -104,16 +114,18 @@ /* * Miscellaneous configurable options */ -#undef CFG_LONGHELP /* undef to save memory */ -#define CFG_PROMPT "=>" /* Monitor Command Prompt */ +#define CFG_PROMPT "=>" /* Monitor Command Prompt */ +#define CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#define CFG_LONGHELP /* #undef to save memory */ #if (CONFIG_COMMANDS & CFG_CMD_KGDB) -#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ #else -#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ #endif -#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ -#define CFG_MAXARGS 16 /* max number of command args */ -#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CFG_LOAD_ADDR 0x00100000 @@ -126,6 +138,7 @@ * (address mappings, register initial values, etc.) * You should know what you are doing if you make changes here. */ + /*----------------------------------------------------------------------- * Internal Memory Mapped Register */ @@ -148,6 +161,14 @@ #define CFG_SDRAM_BASE 0x00000000 #if defined(CONFIG_MPC86xADS) || defined(CONFIG_MPC885ADS) /* New ADS or Duet */ #define CFG_SDRAM_SIZE 0x00800000 /* 8 Mbyte */ +/* + * 2048 SDRAM rows + * 1000 factor s -> ms + * 64 PTP (pre-divider from MPTPR) from SDRAM example configuration + * 4 Number of refresh cycles per period + * 64 Refresh cycle in ms per number of rows + */ +#define CFG_PTA_PER_CLK ((2048 * 64 * 1000) / (4 * 64)) #elif defined(CONFIG_FADS) /* Old/new FADS */ #define CFG_SDRAM_SIZE 0x00400000 /* 4 Mbyte */ #else /* Old ADS */ @@ -223,9 +244,7 @@ * Cache Configuration */ #define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */ -#if (CONFIG_COMMANDS & CFG_CMD_KGDB) #define CFG_CACHELINE_SHIFT 4 /* log base 2 of the above value */ -#endif /*----------------------------------------------------------------------- * I2C configuration @@ -277,31 +296,21 @@ * power management and some other internal clocks */ #define SCCR_MASK SCCR_EBDF11 -#define CFG_SCCR (SCCR_TBS|SCCR_COM00|SCCR_DFSYNC00|SCCR_DFBRG00|SCCR_DFNL000|SCCR_DFNH000|SCCR_DFLCD000|SCCR_DFALCD00) +#define CFG_SCCR SCCR_TBS /*----------------------------------------------------------------------- - * PLPRCR - PLL, Low-Power, and Reset Control Register 14-22 + * DER - Debug Enable Register *----------------------------------------------------------------------- - * set the PLL, the low-power modes and the reset control - */ -#ifndef CFG_PLPRCR -#define CFG_PLPRCR PLPRCR_TEXPS -#endif - -/*----------------------------------------------------------------------- - * - *----------------------------------------------------------------------- - * + * Set to zero to prevent the processor from entering debug mode */ #define CFG_DER 0 -/* Because of the way the 860 starts up and assigns CS0 the -* entire address space, we have to set the memory controller -* differently. Normally, you write the option register -* first, and then enable the chip select by writing the -* base register. For CS0, you must write the base register -* first, followed by the option register. -*/ +/* Because of the way the 860 starts up and assigns CS0 the entire + * address space, we have to set the memory controller differently. + * Normally, you write the option register first, and then enable the + * chip select by writing the base register. For CS0, you must write + * the base register first, followed by the option register. + */ /* * Init Memory Controller: @@ -335,9 +344,6 @@ /* values according to the manual */ -#define PCMCIA_MEM_ADDR ((uint)0xFF020000) -#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) - #define BCSR0 ((uint) (BCSR_ADDR + 0x00)) #define BCSR1 ((uint) (BCSR_ADDR + 0x04)) #define BCSR2 ((uint) (BCSR_ADDR + 0x08)) @@ -396,59 +402,28 @@ #define BCSR4_TFPLDL ((uint)0x40000000) #define BCSR4_TPSQEL ((uint)0x20000000) #define BCSR4_SIGNAL_LAMP ((uint)0x10000000) -#define BCSR4_FETH_EN ((uint)0x08000000) -#define BCSR4_FETHCFG0 ((uint)0x04000000) -#define BCSR4_FETHFDE ((uint)0x02000000) -#define BCSR4_FETHCFG1 ((uint)0x00400000) -#define BCSR4_FETHRST ((uint)0x00200000) - -#ifdef CONFIG_MPC823 +#if defined(CONFIG_MPC823) #define BCSR4_USB_EN ((uint)0x08000000) -#endif /* CONFIG_MPC823 */ -#ifdef CONFIG_MPC860SAR -#define BCSR4_UTOPIA_EN ((uint)0x08000000) -#endif /* CONFIG_MPC860SAR */ -#ifdef CONFIG_MPC860T -#define BCSR4_FETH_EN ((uint)0x08000000) -#endif /* CONFIG_MPC860T */ -#ifdef CONFIG_MPC823 #define BCSR4_USB_SPEED ((uint)0x04000000) -#endif /* CONFIG_MPC823 */ -#ifdef CONFIG_MPC860T -#define BCSR4_FETHCFG0 ((uint)0x04000000) -#endif /* CONFIG_MPC860T */ -#ifdef CONFIG_MPC823 #define BCSR4_VCCO ((uint)0x02000000) -#endif /* CONFIG_MPC823 */ -#ifdef CONFIG_MPC860T -#define BCSR4_FETHFDE ((uint)0x02000000) -#endif /* CONFIG_MPC860T */ -#ifdef CONFIG_MPC823 #define BCSR4_VIDEO_ON ((uint)0x00800000) -#endif /* CONFIG_MPC823 */ -#ifdef CONFIG_MPC823 #define BCSR4_VDO_EKT_CLK_EN ((uint)0x00400000) -#endif /* CONFIG_MPC823 */ -#ifdef CONFIG_MPC860T -#define BCSR4_FETHCFG1 ((uint)0x00400000) -#endif /* CONFIG_MPC860T */ -#ifdef CONFIG_MPC823 #define BCSR4_VIDEO_RST ((uint)0x00200000) -#endif /* CONFIG_MPC823 */ -#ifdef CONFIG_MPC860T -#define BCSR4_FETHRST ((uint)0x00200000) -#endif /* CONFIG_MPC860T */ -#ifdef CONFIG_MPC823 #define BCSR4_MODEM_EN ((uint)0x00100000) -#endif /* CONFIG_MPC823 */ -#ifdef CONFIG_MPC823 #define BCSR4_DATA_VOICE ((uint)0x00080000) -#endif /* CONFIG_MPC823 */ -#ifdef CONFIG_MPC850 +#elif defined(CONFIG_MPC850) #define BCSR4_DATA_VOICE ((uint)0x00080000) -#endif /* CONFIG_MPC850 */ +#elif defined(CONFIG_MPC860SAR) +#define BCSR4_UTOPIA_EN ((uint)0x08000000) +#else /* MPC860T and other chips with FEC */ +#define BCSR4_FETH_EN ((uint)0x08000000) +#define BCSR4_FETHCFG0 ((uint)0x04000000) +#define BCSR4_FETHFDE ((uint)0x02000000) +#define BCSR4_FETHCFG1 ((uint)0x00400000) +#define BCSR4_FETHRST ((uint)0x00200000) +#endif -/* BSCR5 exists on MPC86xADS and Duet ADS only */ +/* BSCR5 exists on MPC86xADS and MPC885ADS only */ #define CFG_PHYDEV_ADDR (BCSR_ADDR + 0x20000) @@ -511,4 +486,4 @@ #define CFG_ATA_ALT_OFFSET 0x0000 #define CONFIG_DISK_SPINUP_TIME 1000000 -#undef CONFIG_DISK_SPINUP_TIME /* usin´ Compact Flash */ +/* #undef CONFIG_DISK_SPINUP_TIME */ /* usin Compact Flash */ diff --git a/include/configs/MPC86xADS.h b/include/configs/MPC86xADS.h index 565f9bb5c0..831cc5ecd3 100644 --- a/include/configs/MPC86xADS.h +++ b/include/configs/MPC86xADS.h @@ -21,7 +21,7 @@ #define CONFIG_MPC86xADS 1 /* new ADS */ #define CONFIG_FADS 1 /* We are FADS compatible (more or less) */ -/* New MPC86xADS - pick one of these */ +/* CPU type - pick one of these */ #define CONFIG_MPC866T 1 #undef CONFIG_MPC866P #undef CONFIG_MPC859T @@ -33,7 +33,10 @@ #undef CONFIG_8xx_CONS_NONE #define CONFIG_BAUDRATE 38400 -#define CONFIG_8xx_OSCLK 10000000 /* 10MHz oscillator on EXTCLK */ +#define CONFIG_8xx_OSCLK 10000000 /* 10MHz oscillator on EXTCLK */ +#define CONFIG_8xx_CPUCLK_DEFAULT 50000000 +#define CFG_8xx_CPUCLK_MIN 40000000 +#define CFG_8xx_CPUCLK_MAX 80000000 #define CONFIG_DRAM_50MHZ 1 #define CONFIG_SDRAM_50MHZ 1 diff --git a/include/configs/MPC885ADS.h b/include/configs/MPC885ADS.h index 74318e5545..1867c5bf0a 100644 --- a/include/configs/MPC885ADS.h +++ b/include/configs/MPC885ADS.h @@ -1,44 +1,34 @@ /* * A collection of structures, addresses, and values associated with - * the Motorola DUET ADS board. Values common to all FADS family boards + * the Motorola MPC885ADS board. Values common to all FADS family boards * are in board/fads/fads.h * - * Copyright (C) 2003 Arabella Software Ltd. + * Copyright (C) 2003-2004 Arabella Software Ltd. * Yuli Barcohen */ #ifndef __CONFIG_H #define __CONFIG_H -/* Board type */ -#define CONFIG_MPC885ADS 1 /* Duet (MPC87x/88x) ADS */ +#define CONFIG_MPC885ADS 1 /* MPC885ADS board */ #define CONFIG_FADS 1 /* We are FADS compatible (more or less) */ -#define CONFIG_MPC885 1 /* MPC885 CPU (Duet family) */ +#define CONFIG_MPC885 1 /* MPC885 CPU (Duet family) */ -#define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */ +#define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */ #undef CONFIG_8xx_CONS_SMC2 #undef CONFIG_8xx_CONS_NONE #define CONFIG_BAUDRATE 38400 -#define CONFIG_8xx_OSCLK 10000000 /* 10 MHz oscillator on EXTCLK */ - -#define CFG_PLPRCR ((1 << PLPRCR_MFD_SHIFT) | (12 << PLPRCR_MFI_SHIFT) | PLPRCR_TEXPS) +#define CONFIG_8xx_OSCLK 10000000 /* 10 MHz oscillator on EXTCLK */ +#define CONFIG_8xx_CPUCLK_DEFAULT 50000000 +#define CFG_8xx_CPUCLK_MIN 40000000 +#define CFG_8xx_CPUCLK_MAX 133000000 #define CONFIG_SDRAM_50MHZ 1 -#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ - | CFG_CMD_DHCP \ - | CFG_CMD_IMMAP \ - | CFG_CMD_MII \ - | CFG_CMD_PING \ - ) - #include "fads.h" -#undef CFG_SCCR -#define CFG_SCCR (SCCR_TBS|SCCR_EBDF11) - #define CFG_OR5_PRELIM 0xFFFF8110 /* 64Kbyte address space */ #define CFG_BR5_PRELIM (CFG_PHYDEV_ADDR | BR_PS_8 | BR_V) From dc013d464000635a5b8ae841c6e683f94a6bee3d Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 01:59:35 +0100 Subject: [PATCH 062/102] Add loads of ntohl() in image header handling Patch by Steven Scholz, 10 Jun 2005 --- CHANGELOG | 3 +++ common/cmd_bootm.c | 18 +++++++++--------- common/cmd_doc.c | 2 +- common/cmd_fdc.c | 4 ++-- common/cmd_nand.c | 2 +- common/lynxkdi.c | 8 ++++---- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c4c4124196..a11dd4d740 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add loads of ntohl() in image header handling + Patch by Steven Scholz, 10 Jun 2005 + * Switch MPC86xADS and MPC885ADS boards to use cpuclk environment variable to set clock Patch by Yuli Barcohen, 05 Jun 2005 diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 8599a49d05..8bb524bfe1 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -606,7 +606,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #endif /* CONFIG_MPC5xxx */ } - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))hdr->ih_ep; + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong)) ntohl(hdr->ih_ep); /* * Check if there is an initrd image @@ -621,7 +621,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, /* Copy header so we can blank CRC field for re-calculation */ memmove (&header, (char *)addr, sizeof(image_header_t)); - if (hdr->ih_magic != IH_MAGIC) { + if (ntohl(hdr->ih_magic) != IH_MAGIC) { puts ("Bad Magic Number\n"); SHOW_BOOT_PROGRESS (-10); do_reset (cmdtp, flag, argc, argv); @@ -630,7 +630,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, data = (ulong)&header; len = sizeof(image_header_t); - checksum = hdr->ih_hcrc; + checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; if (crc32 (0, (uchar *)data, len) != checksum) { @@ -644,7 +644,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, print_image_hdr (hdr); data = addr + sizeof(image_header_t); - len = hdr->ih_size; + len = ntohl(hdr->ih_size); if (verify) { ulong csum = 0; @@ -670,7 +670,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, csum = crc32 (0, (uchar *)data, len); #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - if (csum != hdr->ih_dcrc) { + if (csum != ntohl(hdr->ih_dcrc)) { puts ("Bad Data CRC\n"); SHOW_BOOT_PROGRESS (-12); do_reset (cmdtp, flag, argc, argv); @@ -902,7 +902,7 @@ do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, cmdline = ""; } - loader = (void (*)(bd_t *, image_header_t *, char *, char *)) hdr->ih_ep; + loader = (void (*)(bd_t *, image_header_t *, char *, char *)) ntohl(hdr->ih_ep); printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n", (ulong)loader); @@ -1364,7 +1364,7 @@ do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], image_header_t *hdr = &header; void (*entry_point)(bd_t *); - entry_point = (void (*)(bd_t *)) hdr->ih_ep; + entry_point = (void (*)(bd_t *)) ntohl(hdr->ih_ep); printf ("## Transferring control to RTEMS (at address %08lx) ...\n", (ulong)entry_point); @@ -1387,7 +1387,7 @@ do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], image_header_t *hdr = &header; char str[80]; - sprintf(str, "%x", hdr->ih_ep); /* write entry-point into string */ + sprintf(str, "%x", ntohl(hdr->ih_ep)); /* write entry-point into string */ setenv("loadaddr", str); do_bootvx(cmdtp, 0, 0, NULL); } @@ -1400,7 +1400,7 @@ do_bootm_qnxelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char *local_args[2]; char str[16]; - sprintf(str, "%x", hdr->ih_ep); /* write entry-point into string */ + sprintf(str, "%x", ntohl(hdr->ih_ep)); /* write entry-point into string */ local_args[0] = argv[0]; local_args[1] = str; /* and provide it via the arguments */ do_bootelf(cmdtp, 0, 2, local_args); diff --git a/common/cmd_doc.c b/common/cmd_doc.c index c726957cac..37b7325be6 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -250,7 +250,7 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) print_image_hdr (hdr); - cnt = (hdr->ih_size + sizeof(image_header_t)); + cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); cnt -= SECTORSIZE; } else { puts ("\n** Bad Magic Number **\n"); diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index 02dffa38e5..03f4ce6d34 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -836,13 +836,13 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } hdr = (image_header_t *)addr; - if (hdr->ih_magic != IH_MAGIC) { + if (ntohl(hdr->ih_magic) != IH_MAGIC) { printf ("Bad Magic Number\n"); return 1; } print_image_hdr(hdr); - imsize= hdr->ih_size+sizeof(image_header_t); + imsize= ntohl(hdr->ih_size)+sizeof(image_header_t); nrofblk=imsize/512; if((imsize%512)>0) nrofblk++; diff --git a/common/cmd_nand.c b/common/cmd_nand.c index bb51d91fb3..21adb1b478 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -717,7 +717,7 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); cnt -= SECTORSIZE; } else { - printf ("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); + printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr->ih_magic)); SHOW_BOOT_PROGRESS (-1); return 1; } diff --git a/common/lynxkdi.c b/common/lynxkdi.c index 797d8cc880..ed1b595b84 100644 --- a/common/lynxkdi.c +++ b/common/lynxkdi.c @@ -23,11 +23,11 @@ #if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR) void lynxkdi_boot ( image_header_t *hdr ) { - void (*lynxkdi)(void) = (void(*)(void))hdr->ih_ep; + void (*lynxkdi)(void) = (void(*)(void)) ntohl(hdr->ih_ep); lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020; bd_t *kbd; DECLARE_GLOBAL_DATA_PTR; - u32 *psz = (u32 *)(hdr->ih_load + 0x0204); + u32 *psz = (u32 *)(ntohl(hdr->ih_load) + 0x0204); memset( parms, 0, sizeof(*parms)); kbd = gd->bd; @@ -39,9 +39,9 @@ void lynxkdi_boot ( image_header_t *hdr ) /* Do a simple check for Bluecat so we can pass the * kernel command line parameters. */ - if( le32_to_cpu(*psz) == hdr->ih_size ){ + if( le32_to_cpu(*psz) == ntohl(hdr->ih_size) ){ /* FIXME: NOT SURE HERE ! */ char *args; - char *cmdline = (char *)(hdr->ih_load + 0x020c); + char *cmdline = (char *)(ntohl(hdr->ih_load) + 0x020c); int len; printf("Booting Bluecat KDI ...\n"); From 0afe519a433184fb1270ff0823971130353a807f Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 02:10:00 +0100 Subject: [PATCH 063/102] Add ADI Blackfin support - add support for Analog Devices Blackfin BF533 CPU - add support for the ADI BF533 Stamp uClinux board - add support for the ADI BF533 EZKit board Patches by Richard Klingler, June 11th 2005: --- CHANGELOG | 6 ++++++ Makefile | 21 +++++++++++++++++++++ common/cmd_bootm.c | 2 ++ config.mk | 4 ++++ drivers/cfi_flash.c | 12 ++++++++++++ drivers/smc91111.c | 9 +++++++++ drivers/smc91111.h | 4 ++++ examples/Makefile | 9 +++++++++ examples/smc91111_eeprom.c | 6 ++---- examples/stubs.c | 13 +++++++++++++ include/flash.h | 1 + include/image.h | 1 + include/linux/stat.h | 2 +- rtc/Makefile | 4 ++-- tools/mkimage.c | 1 + 15 files changed, 88 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a11dd4d740..20e875aabf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,12 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add ADI Blackfin support + - add support for Analog Devices Blackfin BF533 CPU + - add support for the ADI BF533 Stamp uClinux board + - add support for the ADI BF533 EZKit board + Patches by Richard Klingler, 11 Jun 2005 + * Add loads of ntohl() in image header handling Patch by Steven Scholz, 10 Jun 2005 diff --git a/Makefile b/Makefile index fefcbbac0a..0c8137f0eb 100644 --- a/Makefile +++ b/Makefile @@ -85,6 +85,9 @@ endif ifeq ($(ARCH),microblaze) CROSS_COMPILE = mb- endif +ifeq ($(ARCH),blackfin) +CROSS_COMPILE = bfin-elf- +endif endif endif @@ -111,6 +114,10 @@ endif ifeq ($(CPU),mpc85xx) OBJS += cpu/$(CPU)/resetvec.o endif +ifeq ($(CPU),bf533) +OBJS += cpu/$(CPU)/start1.o cpu/$(CPU)/interrupt.o cpu/$(CPU)/cache.o +OBJS += cpu/$(CPU)/cplbhdlr.o cpu/$(CPU)/cplbmgr.o cpu/$(CPU)/flush.o +endif LIBS = lib_generic/libgeneric.a LIBS += board/$(BOARDDIR)/lib$(BOARD).a @@ -1859,6 +1866,19 @@ suzaku_config: unconfig @echo "#define CONFIG_SUZAKU 1" >> include/config.h @./mkconfig -a $(@:_config=) microblaze microblaze suzaku AtmarkTechno +######################################################################### +## Blackfin +######################################################################### +ezkit533_config : unconfig + @./mkconfig $(@:_config=) blackfin bf533 ezkit533 + +stamp_config : unconfig + @./mkconfig $(@:_config=) blackfin bf533 stamp + +dspstamp_config : unconfig + @./mkconfig $(@:_config=) blackfin bf533 dsp_stamp + +######################################################################### ######################################################################### ######################################################################### @@ -1870,6 +1890,7 @@ clean: rm -f examples/hello_world examples/timer \ examples/eepro100_eeprom examples/sched \ examples/mem_to_mem_idma2intr examples/82559_eeprom \ + examples/smc91111_eeprom \ examples/test_burst rm -f tools/img2srec tools/mkimage tools/envcrc tools/gen_eth_addr rm -f tools/mpc86x_clk tools/ncb diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 8bb524bfe1..5b93bddf98 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -252,6 +252,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (hdr->ih_arch != IH_CPU_MICROBLAZE) #elif defined(__nios2__) if (hdr->ih_arch != IH_CPU_NIOS2) +#elif defined(__blackfin__) + if (hdr->ih_arch != IH_CPU_BLACKFIN) #else # error Unknown CPU type #endif diff --git a/config.mk b/config.mk index d85ac36b5e..dfbb1b7c6f 100644 --- a/config.mk +++ b/config.mk @@ -53,6 +53,10 @@ PLATFORM_CPPFLAGS+= -D__ARM__ endif endif +ifeq ($(ARCH),blackfin) +PLATFORM_CPPFLAGS+= -D__BLACKFIN__ -mno-underscore +endif + ifdef ARCH sinclude $(TOPDIR)/$(ARCH)_config.mk # include architecture dependend rules endif diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c index ff4d85f3f0..a989d34662 100644 --- a/drivers/cfi_flash.c +++ b/drivers/cfi_flash.c @@ -878,18 +878,27 @@ static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr.cp, cmd, cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH); *addr.cp = cword.c; +#ifdef CONFIG_BLACKFIN + asm("ssync;"); +#endif break; case FLASH_CFI_16BIT: debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr.wp, cmd, cword.w, info->chipwidth << CFI_FLASH_SHIFT_WIDTH); *addr.wp = cword.w; +#ifdef CONFIG_BLACKFIN + asm("ssync;"); +#endif break; case FLASH_CFI_32BIT: debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr.lp, cmd, cword.l, info->chipwidth << CFI_FLASH_SHIFT_WIDTH); *addr.lp = cword.l; +#ifdef CONFIG_BLACKFIN + asm("ssync;"); +#endif break; case FLASH_CFI_64BIT: #ifdef DEBUG @@ -904,6 +913,9 @@ static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset } #endif *addr.llp = cword.ll; +#ifdef CONFIG_BLACKFIN + asm("ssync;"); +#endif break; } } diff --git a/drivers/smc91111.c b/drivers/smc91111.c index 84e243ddd5..f91e4b9843 100644 --- a/drivers/smc91111.c +++ b/drivers/smc91111.c @@ -160,6 +160,9 @@ extern void eth_halt(void); extern int eth_rx(void); extern int eth_send(volatile void *packet, int length); +#ifdef SHARED_RESOURCES + extern void swap_to(int device_id); +#endif /* . This is called by register_netdev(). It is responsible for @@ -533,6 +536,9 @@ static void smc_shutdown() SMC_SELECT_BANK( 0 ); SMC_outb( RCR_CLEAR, RCR_REG ); SMC_outb( TCR_CLEAR, TCR_REG ); +#ifdef SHARED_RESOURCES + swap_to(FLASH); +#endif } @@ -1511,6 +1517,9 @@ static void print_packet( byte * buf, int length ) #endif int eth_init(bd_t *bd) { +#ifdef SHARED_RESOURCES + swap_to(ETHERNET); +#endif return (smc_open(bd)); } diff --git a/drivers/smc91111.h b/drivers/smc91111.h index c3c33672ab..d03cbc320b 100644 --- a/drivers/smc91111.h +++ b/drivers/smc91111.h @@ -185,6 +185,8 @@ typedef unsigned long int dword; #ifdef CONFIG_ADNPESC1 #define SMC_inw(r) (*((volatile word *)(SMC_BASE_ADDRESS+((r)<<1)))) +#elif CONFIG_BLACKFIN +#define SMC_inw(r) ({ word __v = (*((volatile word *)(SMC_BASE_ADDRESS+(r)))); asm("ssync;"); __v;}) #else #define SMC_inw(r) (*((volatile word *)(SMC_BASE_ADDRESS+(r)))) #endif @@ -192,6 +194,8 @@ typedef unsigned long int dword; #ifdef CONFIG_ADNPESC1 #define SMC_outw(d,r) (*((volatile word *)(SMC_BASE_ADDRESS+((r)<<1))) = d) +#elif CONFIG_BLACKFIN +#define SMC_outw(d,r) {(*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d);asm("ssync;");} #else #define SMC_outw(d,r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d) #endif diff --git a/examples/Makefile b/examples/Makefile index 2f8c4c4035..fee26741d0 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -53,6 +53,10 @@ ifeq ($(ARCH),microblaze) LOAD_ADDR = 0x80F00000 endif +ifeq ($(ARCH),blackfin) +LOAD_ADDR = 0x1000 +endif + include $(TOPDIR)/config.mk SREC = hello_world.srec @@ -73,6 +77,11 @@ SREC += sched.srec BIN += sched.bin sched endif +ifeq ($(ARCH),blackfin) +SREC += smc91111_eeprom.srec +BIN += smc91111_eeprom.bin smc91111_eeprom +endif + # The following example is pretty 8xx specific... ifeq ($(CPU),mpc8xx) SREC += timer.srec diff --git a/examples/smc91111_eeprom.c b/examples/smc91111_eeprom.c index 885f9336cd..98e3e86ffa 100644 --- a/examples/smc91111_eeprom.c +++ b/examples/smc91111_eeprom.c @@ -214,13 +214,11 @@ int smc91111_eeprom (int argc, char *argv[]) switch (what) { case 1: - printf ("Writing EEPROM register %02x with %04x\n", - reg, value); + printf ("Writing EEPROM register %02x with %04x\n", reg, value); write_eeprom_reg (value, reg); break; case 2: - printf ("Writing MAC register bank %i, - reg %02x with %04x\n", reg >> 4, reg & 0xE, value); + printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value); SMC_SELECT_BANK (reg >> 4); SMC_outw (value, reg & 0xE); break; diff --git a/examples/stubs.c b/examples/stubs.c index d4c6e063e3..1797274eb4 100644 --- a/examples/stubs.c +++ b/examples/stubs.c @@ -125,6 +125,19 @@ gd_t *global_data; " lwi r5, r5, %1\n" \ " bra r5\n" \ : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r5"); +#elif defined(CONFIG_BLACKFIN) +/* + * P5 holds the pointer to the global_data, P0 is a call-clobbered + * register + */ +#define EXPORT_FUNC(x) \ + asm volatile ( \ +" .globl " #x "\n" \ +#x ":\n" \ +" P0 = [P5 + %0]\n" \ +" P0 = [P0 + %1]\n" \ +" JUMP (P0)\n" \ + : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "P0"); #else #error stubs definition missing for this architecture #endif diff --git a/include/flash.h b/include/flash.h index 8493191789..4c68c6832f 100644 --- a/include/flash.h +++ b/include/flash.h @@ -242,6 +242,7 @@ extern void flash_read_factory_serial(flash_info_t * info, void * buffer, int of #define STM_ID_29W320DT 0x22CA22CA /* M29W320DT ID (32 M, top boot sector) */ #define STM_ID_29W320DB 0x22CB22CB /* M29W320DB ID (32 M, bottom boot sect) */ #define STM_ID_29W040B 0x00E300E3 /* M29W040B ID (4M = 512K x 8) */ +#define FLASH_PSD4256GV 0x00E9 /* PSD4256 Flash and CPLD combination */ #define INTEL_ID_28F016S 0x66a066a0 /* 28F016S[VS] ID (16M = 512k x 16) */ #define INTEL_ID_28F800B3T 0x88928892 /* 8M = 512K x 16 top boot sector */ diff --git a/include/image.h b/include/image.h index af37bcad5a..139df0b2d1 100644 --- a/include/image.h +++ b/include/image.h @@ -75,6 +75,7 @@ #define IH_CPU_NIOS 13 /* Nios-32 */ #define IH_CPU_MICROBLAZE 14 /* MicroBlaze */ #define IH_CPU_NIOS2 15 /* Nios-II */ +#define IH_CPU_BLACKFIN 16 /* Blackfin */ /* * Image Types diff --git a/include/linux/stat.h b/include/linux/stat.h index 2f7a3b36ac..f9422cb1fa 100644 --- a/include/linux/stat.h +++ b/include/linux/stat.h @@ -67,7 +67,7 @@ struct stat { #endif /* __PPC__ */ -#if defined (__ARM__) || defined (__I386__) || defined (__M68K__) +#if defined (__ARM__) || defined (__I386__) || defined (__M68K__) || defined (__blackfin__) struct stat { unsigned short st_dev; diff --git a/rtc/Makefile b/rtc/Makefile index 4ceac76933..b08057e2f1 100644 --- a/rtc/Makefile +++ b/rtc/Makefile @@ -28,8 +28,8 @@ include $(TOPDIR)/config.mk LIB = librtc.a OBJS = date.o \ - ds12887.o ds1302.o ds1306.o ds1307.o ds1337.o \ - ds1556.o ds164x.o ds174x.o \ + bf533_rtc.o ds12887.o ds1302.o ds1306.o ds1307.o \ + ds1337.o ds1556.o ds164x.o ds174x.o \ m41t11.o max6900.o m48t35ax.o mc146818.o mk48t59.o \ mpc5xxx.o mpc8xx.o pcf8563.o s3c24x0_rtc.o rs5c372.o diff --git a/tools/mkimage.c b/tools/mkimage.c index 70452db1c0..5222bb21a5 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -93,6 +93,7 @@ table_entry_t arch_name[] = { { IH_CPU_SH, "sh", "SuperH", }, { IH_CPU_SPARC, "sparc", "SPARC", }, { IH_CPU_SPARC64, "sparc64", "SPARC 64 Bit", }, + { IH_CPU_BLACKFIN, "blackfin", "Blackfin", }, { -1, "", "", }, }; From 6cb142fa3b732a2cea257ca39ef4a7dbe81a32e1 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 02:12:27 +0100 Subject: [PATCH 064/102] Add missing Blackfin files. --- blackfin_config.mk | 24 + board/ezkit533/Makefile | 44 + board/ezkit533/config.mk | 26 + board/ezkit533/ezkit533.c | 71 ++ board/ezkit533/flash-defines.h | 130 +++ board/ezkit533/flash.c | 476 ++++++++ board/ezkit533/psd4256.h | 68 ++ board/ezkit533/u-boot.lds | 149 +++ board/stamp/Makefile | 68 ++ board/stamp/config.mk | 26 + board/stamp/stamp.c | 278 +++++ board/stamp/stamp.h | 57 + board/stamp/u-boot.lds | 148 +++ cpu/bf533/Makefile | 46 + cpu/bf533/bf533_serial.h | 78 ++ cpu/bf533/cache.S | 125 +++ cpu/bf533/config.mk | 27 + cpu/bf533/cplbhdlr.S | 194 ++++ cpu/bf533/cplbmgr.S | 601 ++++++++++ cpu/bf533/cpu.c | 194 ++++ cpu/bf533/cpu.h | 65 ++ cpu/bf533/flush.S | 402 +++++++ cpu/bf533/interrupt.S | 391 +++++++ cpu/bf533/interrupts.c | 165 +++ cpu/bf533/ints.c | 107 ++ cpu/bf533/serial.c | 194 ++++ cpu/bf533/start.S | 435 ++++++++ cpu/bf533/start1.S | 38 + cpu/bf533/traps.c | 73 ++ include/asm-blackfin/bitops.h | 380 +++++++ include/asm-blackfin/blackfin.h | 46 + include/asm-blackfin/blackfin_defs.h | 83 ++ include/asm-blackfin/byteorder.h | 40 + include/asm-blackfin/cplb.h | 48 + include/asm-blackfin/cplbtab.h | 572 ++++++++++ include/asm-blackfin/cpu/bf533_irq.h | 137 +++ include/asm-blackfin/cpu/bf533_rtc.h | 46 + include/asm-blackfin/cpu/bf533_serial.h | 79 ++ include/asm-blackfin/cpu/cdefBF531.h | 24 + include/asm-blackfin/cpu/cdefBF532.h | 398 +++++++ include/asm-blackfin/cpu/cdefBF533.h | 24 + include/asm-blackfin/cpu/cdefBF53x.h | 32 + include/asm-blackfin/cpu/cdef_LPBlackfin.h | 185 ++++ include/asm-blackfin/cpu/defBF531.h | 24 + include/asm-blackfin/cpu/defBF532.h | 1159 ++++++++++++++++++++ include/asm-blackfin/cpu/defBF533.h | 24 + include/asm-blackfin/cpu/defBF533_extn.h | 76 ++ include/asm-blackfin/cpu/def_LPBlackfin.h | 445 ++++++++ include/asm-blackfin/current.h | 40 + include/asm-blackfin/delay.h | 55 + include/asm-blackfin/entry.h | 385 +++++++ include/asm-blackfin/errno.h | 156 +++ include/asm-blackfin/global_data.h | 64 ++ include/asm-blackfin/hw_irq.h | 37 + include/asm-blackfin/io-kernel.h | 135 +++ include/asm-blackfin/io.h | 122 +++ include/asm-blackfin/irq.h | 142 +++ include/asm-blackfin/linkage.h | 60 + include/asm-blackfin/machdep.h | 89 ++ include/asm-blackfin/mem_init.h | 287 +++++ include/asm-blackfin/page.h | 128 +++ include/asm-blackfin/page_offset.h | 35 + include/asm-blackfin/posix_types.h | 90 ++ include/asm-blackfin/processor.h | 174 +++ include/asm-blackfin/ptrace.h | 269 +++++ include/asm-blackfin/segment.h | 46 + include/asm-blackfin/setup.h | 86 ++ include/asm-blackfin/shared_resources.h | 33 + include/asm-blackfin/string.h | 79 ++ include/asm-blackfin/system.h | 182 +++ include/asm-blackfin/traps.h | 86 ++ include/asm-blackfin/types.h | 83 ++ include/asm-blackfin/u-boot.h | 47 + include/asm-blackfin/uaccess.h | 207 ++++ include/asm-blackfin/virtconvert.h | 47 + include/configs/ezkit533.h | 188 ++++ include/configs/stamp.h | 340 ++++++ lib_blackfin/Makefile | 47 + lib_blackfin/bf533_linux.c | 91 ++ lib_blackfin/bf533_string.c | 185 ++++ lib_blackfin/blackfin_board.h | 62 ++ lib_blackfin/board.c | 282 +++++ lib_blackfin/cache.c | 41 + lib_blackfin/muldi3.c | 92 ++ rtc/bf533_rtc.c | 143 +++ 85 files changed, 13157 insertions(+) create mode 100644 blackfin_config.mk create mode 100644 board/ezkit533/Makefile create mode 100644 board/ezkit533/config.mk create mode 100644 board/ezkit533/ezkit533.c create mode 100644 board/ezkit533/flash-defines.h create mode 100644 board/ezkit533/flash.c create mode 100644 board/ezkit533/psd4256.h create mode 100644 board/ezkit533/u-boot.lds create mode 100644 board/stamp/Makefile create mode 100644 board/stamp/config.mk create mode 100644 board/stamp/stamp.c create mode 100644 board/stamp/stamp.h create mode 100644 board/stamp/u-boot.lds create mode 100644 cpu/bf533/Makefile create mode 100644 cpu/bf533/bf533_serial.h create mode 100644 cpu/bf533/cache.S create mode 100644 cpu/bf533/config.mk create mode 100644 cpu/bf533/cplbhdlr.S create mode 100644 cpu/bf533/cplbmgr.S create mode 100644 cpu/bf533/cpu.c create mode 100644 cpu/bf533/cpu.h create mode 100644 cpu/bf533/flush.S create mode 100644 cpu/bf533/interrupt.S create mode 100644 cpu/bf533/interrupts.c create mode 100644 cpu/bf533/ints.c create mode 100644 cpu/bf533/serial.c create mode 100644 cpu/bf533/start.S create mode 100644 cpu/bf533/start1.S create mode 100644 cpu/bf533/traps.c create mode 100644 include/asm-blackfin/bitops.h create mode 100644 include/asm-blackfin/blackfin.h create mode 100644 include/asm-blackfin/blackfin_defs.h create mode 100644 include/asm-blackfin/byteorder.h create mode 100644 include/asm-blackfin/cplb.h create mode 100644 include/asm-blackfin/cplbtab.h create mode 100644 include/asm-blackfin/cpu/bf533_irq.h create mode 100644 include/asm-blackfin/cpu/bf533_rtc.h create mode 100644 include/asm-blackfin/cpu/bf533_serial.h create mode 100644 include/asm-blackfin/cpu/cdefBF531.h create mode 100644 include/asm-blackfin/cpu/cdefBF532.h create mode 100644 include/asm-blackfin/cpu/cdefBF533.h create mode 100644 include/asm-blackfin/cpu/cdefBF53x.h create mode 100644 include/asm-blackfin/cpu/cdef_LPBlackfin.h create mode 100644 include/asm-blackfin/cpu/defBF531.h create mode 100644 include/asm-blackfin/cpu/defBF532.h create mode 100644 include/asm-blackfin/cpu/defBF533.h create mode 100644 include/asm-blackfin/cpu/defBF533_extn.h create mode 100644 include/asm-blackfin/cpu/def_LPBlackfin.h create mode 100644 include/asm-blackfin/current.h create mode 100644 include/asm-blackfin/delay.h create mode 100644 include/asm-blackfin/entry.h create mode 100644 include/asm-blackfin/errno.h create mode 100644 include/asm-blackfin/global_data.h create mode 100644 include/asm-blackfin/hw_irq.h create mode 100644 include/asm-blackfin/io-kernel.h create mode 100644 include/asm-blackfin/io.h create mode 100644 include/asm-blackfin/irq.h create mode 100644 include/asm-blackfin/linkage.h create mode 100644 include/asm-blackfin/machdep.h create mode 100644 include/asm-blackfin/mem_init.h create mode 100644 include/asm-blackfin/page.h create mode 100644 include/asm-blackfin/page_offset.h create mode 100644 include/asm-blackfin/posix_types.h create mode 100644 include/asm-blackfin/processor.h create mode 100644 include/asm-blackfin/ptrace.h create mode 100644 include/asm-blackfin/segment.h create mode 100644 include/asm-blackfin/setup.h create mode 100644 include/asm-blackfin/shared_resources.h create mode 100644 include/asm-blackfin/string.h create mode 100644 include/asm-blackfin/system.h create mode 100644 include/asm-blackfin/traps.h create mode 100644 include/asm-blackfin/types.h create mode 100644 include/asm-blackfin/u-boot.h create mode 100644 include/asm-blackfin/uaccess.h create mode 100644 include/asm-blackfin/virtconvert.h create mode 100644 include/configs/ezkit533.h create mode 100644 include/configs/stamp.h create mode 100644 lib_blackfin/Makefile create mode 100644 lib_blackfin/bf533_linux.c create mode 100644 lib_blackfin/bf533_string.c create mode 100644 lib_blackfin/blackfin_board.h create mode 100644 lib_blackfin/board.c create mode 100644 lib_blackfin/cache.c create mode 100644 lib_blackfin/muldi3.c create mode 100644 rtc/bf533_rtc.c diff --git a/blackfin_config.mk b/blackfin_config.mk new file mode 100644 index 0000000000..e2747aafe9 --- /dev/null +++ b/blackfin_config.mk @@ -0,0 +1,24 @@ +# +# (C) Copyright 2000-2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_CPPFLAGS += -DCONFIG_BLACKFIN -D__blackfin__ diff --git a/board/ezkit533/Makefile b/board/ezkit533/Makefile new file mode 100644 index 0000000000..c9b3c9280f --- /dev/null +++ b/board/ezkit533/Makefile @@ -0,0 +1,44 @@ +# +# U-boot - Makefile +# +# Copyright (c) 2005 blackfin.uclinux.org +# +# (C) Copyright 2000-2004 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS = $(BOARD).o flash.o ezkit533.o + +$(LIB): .depend $(OBJS) + $(AR) crv $@ $(OBJS) + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/ezkit533/config.mk b/board/ezkit533/config.mk new file mode 100644 index 0000000000..e4c089d23e --- /dev/null +++ b/board/ezkit533/config.mk @@ -0,0 +1,26 @@ +# +# (C) Copyright 2001 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +TEXT_BASE = 0x01FC0000 +PLATFORM_CPPFLAGS += -I$(TOPDIR) + diff --git a/board/ezkit533/ezkit533.c b/board/ezkit533/ezkit533.c new file mode 100644 index 0000000000..f8ee9003ad --- /dev/null +++ b/board/ezkit533/ezkit533.c @@ -0,0 +1,71 @@ +/* + * U-boot - ezkit533.c + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#if defined(CONFIG_MISC_INIT_R) +#include "psd4256.h" +#endif + +int checkboard(void) +{ + printf("CPU: ADSP BF533 Rev.: 0.%d\n", *pCHIPID >> 28); + printf("Board: ADI BF533 EZ-Kit Lite board\n"); + printf(" Support: http://blackfin.uclinux.org/\n"); + printf(" Richard Klingler \n"); + return 0; +} + +long int initdram(int board_type) +{ + DECLARE_GLOBAL_DATA_PTR; +#ifdef DEBUG + int brate; + char *tmp = getenv("baudrate"); + brate = simple_strtoul(tmp, NULL, 16); + printf("Serial Port initialized with Baud rate = %x\n",brate); + printf("SDRAM attributes:\n"); + printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles" + "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n", + 3, 3, 6, 2, 3); + printf("SDRAM Begin: 0x%x\n", CFG_SDRAM_BASE); + printf("Bank size = %d MB\n", CFG_MAX_RAM_SIZE >> 20); +#endif + gd->bd->bi_memstart = CFG_SDRAM_BASE; + gd->bd->bi_memsize = CFG_MAX_RAM_SIZE; + return CFG_MAX_RAM_SIZE; +} + +#if defined(CONFIG_MISC_INIT_R) +/* miscellaneous platform dependent initialisations */ +int misc_init_r(void) +{ + /* Set direction bits for Video en/decoder reset as output */ + *(volatile unsigned char *)(CFG_FLASH1_BASE + PSD_PORTA_DIR) = PSDA_VDEC_RST | PSDA_VENC_RST; + /* Deactivate Video en/decoder reset lines */ + *(volatile unsigned char *)(CFG_FLASH1_BASE + PSD_PORTA_DOUT) = PSDA_VDEC_RST | PSDA_VENC_RST; +} +#endif diff --git a/board/ezkit533/flash-defines.h b/board/ezkit533/flash-defines.h new file mode 100644 index 0000000000..8f9dff5de8 --- /dev/null +++ b/board/ezkit533/flash-defines.h @@ -0,0 +1,130 @@ +/* + * U-boot - flash-defines.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __FLASHDEFINES_H__ +#define __FLASHDEFINES_H__ + +#include + +#define V_ULONG(a) (*(volatile unsigned long *)( a )) +#define V_BYTE(a) (*(volatile unsigned char *)( a )) +#define TRUE 0x1 +#define FALSE 0x0 +#define BUFFER_SIZE 0x80000 +#define NO_COMMAND 0 +#define GET_CODES 1 +#define RESET 2 +#define WRITE 3 +#define FILL 4 +#define ERASE_ALL 5 +#define ERASE_SECT 6 +#define READ 7 +#define GET_SECTNUM 8 +#define FLASH_START_L 0x0000 +#define FLASH_START_H 0x2000 +#define FLASH_TOT_SECT 40 +#define FLASH_SIZE 0x220000 +#define FLASH_MAN_ST 2 +#define CFG_FLASH0_BASE 0x20000000 +#define RESET_VAL 0xF0 + + +asm("#define FLASH_START_L 0x0000"); +asm("#define FLASH_START_H 0x2000"); + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +int get_codes(void); +int poll_toggle_bit(long lOffset); +void reset_flash(void); +int erase_flash(void); +int erase_block_flash(int,unsigned long); +void unlock_flash(long lOffset); +int write_data(long lStart, long lCount, long lStride, int *pnData); +int FillData(long lStart, long lCount, long lStride, int *pnData); +int read_data(long lStart, long lCount, long lStride, int *pnData); +int read_flash(long nOffset, int *pnValue); +int write_flash(long nOffset, int nValue); +void get_sector_number(long lOffset, int *pnSector); +int GetSectorProtectionStatus(flash_info_t * info, int nSector); +int GetOffset(int nBlock); +int AFP_NumSectors = 40; +long AFP_SectorSize1 = 0x10000; +int AFP_SectorSize2 = 0x4000; + +#define WRITESEQ1 0x0AAA +#define WRITESEQ2 0x0554 +#define WRITESEQ3 0x0AAA +#define WRITESEQ4 0x0AAA +#define WRITESEQ5 0x0554 +#define WRITESEQ6 0x0AAA +#define WRITEDATA1 0xaa +#define WRITEDATA2 0x55 +#define WRITEDATA3 0x80 +#define WRITEDATA4 0xaa +#define WRITEDATA5 0x55 +#define WRITEDATA6 0x10 +#define PriFlashABegin 0 +#define SecFlashABegin 32 +#define SecFlashBBegin 36 +#define PriFlashAOff 0x0 +#define PriFlashBOff 0x100000 +#define SecFlashAOff 0x200000 +#define SecFlashBOff 0x280000 +#define INVALIDLOCNSTART 0x20270000 +#define INVALIDLOCNEND 0x20280000 +#define BlockEraseVal 0x30 +#define UNLOCKDATA1 0xaa +#define UNLOCKDATA2 0x55 +#define UNLOCKDATA3 0xa0 +#define GETCODEDATA1 0xaa +#define GETCODEDATA2 0x55 +#define GETCODEDATA3 0x90 +#define SecFlashASec1Off 0x200000 +#define SecFlashASec2Off 0x204000 +#define SecFlashASec3Off 0x206000 +#define SecFlashASec4Off 0x208000 +#define SecFlashAEndOff 0x210000 +#define SecFlashBSec1Off 0x280000 +#define SecFlashBSec2Off 0x284000 +#define SecFlashBSec3Off 0x286000 +#define SecFlashBSec4Off 0x288000 +#define SecFlashBEndOff 0x290000 + +#define SECT32 32 +#define SECT33 33 +#define SECT34 34 +#define SECT35 35 +#define SECT36 36 +#define SECT37 37 +#define SECT38 38 +#define SECT39 39 + +#define FLASH_SUCCESS 0 +#define FLASH_FAIL -1 + +#endif diff --git a/board/ezkit533/flash.c b/board/ezkit533/flash.c new file mode 100644 index 0000000000..0b59232644 --- /dev/null +++ b/board/ezkit533/flash.c @@ -0,0 +1,476 @@ +/* + * U-boot - flash.c Flash driver for PSD4256GV + * + * Copyright (c) 2005 blackfin.uclinux.org + * This file is based on BF533EzFlash.c originally written by Analog Devices, Inc. + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include "flash-defines.h" + +void flash_reset(void) +{ + reset_flash(); +} + +unsigned long flash_get_size(ulong baseaddr, flash_info_t * info, + int bank_flag) +{ + int id = 0, i = 0; + static int FlagDev = 1; + + id = get_codes(); + if(FlagDev) { +#ifdef DEBUG + printf("Device ID of the Flash is %x\n", id); +#endif + FlagDev = 0; + } + info->flash_id = id; + + switch (bank_flag) { + case 0: + for (i = PriFlashABegin; i < SecFlashABegin; i++) + info->start[i] = (baseaddr + (i * AFP_SectorSize1)); + info->size = 0x200000; + info->sector_count = 32; + break; + case 1: + info->start[0] = baseaddr + SecFlashASec1Off; + info->start[1] = baseaddr + SecFlashASec2Off; + info->start[2] = baseaddr + SecFlashASec3Off; + info->start[3] = baseaddr + SecFlashASec4Off; + info->size = 0x10000; + info->sector_count = 4; + break; + case 2: + info->start[0] = baseaddr + SecFlashBSec1Off; + info->start[1] = baseaddr + SecFlashBSec2Off; + info->start[2] = baseaddr + SecFlashBSec3Off; + info->start[3] = baseaddr + SecFlashBSec4Off; + info->size = 0x10000; + info->sector_count = 4; + break; + } + return (info->size); +} + +unsigned long flash_init(void) +{ + unsigned long size_b0, size_b1, size_b2; + int i; + + size_b0 = size_b1 = size_b2 = 0; +#ifdef DEBUG + printf("Flash Memory Start 0x%x\n", CFG_FLASH_BASE); + printf("Memory Map for the Flash\n"); + printf("0x20000000 - 0x200FFFFF Flash A Primary (1MB)\n"); + printf("0x20100000 - 0x201FFFFF Flash B Primary (1MB)\n"); + printf("0x20200000 - 0x2020FFFF Flash A Secondary (64KB)\n"); + printf("0x20280000 - 0x2028FFFF Flash B Secondary (64KB)\n"); + printf("Please type command flinfo for information on Sectors \n"); +#endif + for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + } + + size_b0 = flash_get_size(CFG_FLASH0_BASE, &flash_info[0], 0); + size_b1 = flash_get_size(CFG_FLASH0_BASE, &flash_info[1], 1); + size_b2 = flash_get_size(CFG_FLASH0_BASE, &flash_info[2], 2); + + if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b0 == 0) { + printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, size_b0 >> 20); + } + + (void)flash_protect(FLAG_PROTECT_SET,CFG_FLASH0_BASE,(flash_info[0].start[2] - 1),&flash_info[0]); + + return (size_b0 + size_b1 + size_b2); +} + +void flash_print_info(flash_info_t * info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id) { + case FLASH_PSD4256GV: + printf("ST Microelectronics "); + break; + default: + printf("Unknown Vendor "); + break; + } + for (i = 0; i < info->sector_count; ++i) { + if ((i % 5) == 0) + printf("\n "); + printf(" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " "); + } + printf("\n"); + return; +} + +int flash_erase(flash_info_t * info, int s_first, int s_last) +{ + int cnt = 0,i; + int prot,sect; + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) + prot++; + } + + if (prot) + printf ("- Warning: %d protected sectors will not be erased!\n", prot); + else + printf ("\n"); + + cnt = s_last - s_first + 1; + + if (cnt == FLASH_TOT_SECT) { + printf("Erasing flash, Please Wait \n"); + if(erase_flash() < 0) { + printf("Erasing flash failed \n"); + return FLASH_FAIL; + } + } else { + printf("Erasing Flash locations, Please Wait\n"); + for (i = s_first; i <= s_last; i++) { + if (info->protect[i] == 0) { /* not protected */ + if(erase_block_flash(i, info->start[i]) < 0) { + printf("Error Sector erasing \n"); + return FLASH_FAIL; + } + } + } + } + return FLASH_SUCCESS; +} + +int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + int ret; + + ret = write_data(addr, cnt, 1, (int *) src); + if(ret == FLASH_FAIL) + return ERR_NOT_ERASED; + return FLASH_SUCCESS; +} + + +int write_data(long lStart, long lCount, long lStride, int *pnData) +{ + long i = 0; + int j = 0; + unsigned long ulOffset = lStart - CFG_FLASH_BASE; + int d; + int iShift = 0; + int iNumWords = 2; + int nLeftover = lCount % 4; + int nSector = 0; + + for (i = 0; (i < lCount / 4) && (i < BUFFER_SIZE); i++) { + for (iShift = 0, j = 0; (j < iNumWords); + j++, ulOffset += (lStride * 2)) { + if ((ulOffset >= INVALIDLOCNSTART) + && (ulOffset < INVALIDLOCNEND)) { + printf("Invalid locations, Try writing to another location \n"); + return FLASH_FAIL; + } + get_sector_number(ulOffset, &nSector); + read_flash(ulOffset,&d); + if(d != 0xffff) { + printf("Flash not erased at offset 0x%x Please erase to reprogram \n",ulOffset); + return FLASH_FAIL; + } + unlock_flash(ulOffset); + if(write_flash(ulOffset, (pnData[i] >> iShift)) < 0) { + printf("Error programming the flash \n"); + return FLASH_FAIL; + } + iShift += 16; + } + } + if (nLeftover > 0) { + if ((ulOffset >= INVALIDLOCNSTART) + && (ulOffset < INVALIDLOCNEND)) + return FLASH_FAIL; + get_sector_number(ulOffset, &nSector); + read_flash(ulOffset,&d); + if(d != 0xffff) { + printf("Flash already programmed. Please erase to reprogram \n"); + printf("uloffset = 0x%x \t d = 0x%x\n",ulOffset,d); + return FLASH_FAIL; + } + unlock_flash(ulOffset); + if(write_flash(ulOffset, pnData[i]) < 0) { + printf("Error programming the flash \n"); + return FLASH_FAIL; + } + } + return FLASH_SUCCESS; +} + +int read_data(long ulStart, long lCount, long lStride, int *pnData) +{ + long i = 0; + int j = 0; + long ulOffset = ulStart; + int iShift = 0; + int iNumWords = 2; + int nLeftover = lCount % 4; + int nHi, nLow; + int nSector = 0; + + for (i = 0; (i < lCount / 4) && (i < BUFFER_SIZE); i++) { + for (iShift = 0, j = 0; j < iNumWords; j += 2) { + if ((ulOffset >= INVALIDLOCNSTART) + && (ulOffset < INVALIDLOCNEND)) + return FLASH_FAIL; + + get_sector_number(ulOffset, &nSector); + read_flash(ulOffset, &nLow); + ulOffset += (lStride * 2); + read_flash(ulOffset, &nHi); + ulOffset += (lStride * 2); + pnData[i] = (nHi << 16) | nLow; + } + } + if (nLeftover > 0) { + if ((ulOffset >= INVALIDLOCNSTART) + && (ulOffset < INVALIDLOCNEND)) + return FLASH_FAIL; + + get_sector_number(ulOffset, &nSector); + read_flash(ulOffset, &pnData[i]); + } + return FLASH_SUCCESS; +} + +int write_flash(long nOffset, int nValue) +{ + long addr; + + addr = (CFG_FLASH_BASE + nOffset); + asm("ssync;"); + *(unsigned volatile short *) addr = nValue; + asm("ssync;"); + if(poll_toggle_bit(nOffset) < 0) + return FLASH_FAIL; + return FLASH_SUCCESS; +} + +int read_flash(long nOffset, int *pnValue) +{ + int nValue = 0x0; + long addr = (CFG_FLASH_BASE + nOffset); + + if (nOffset != 0x2) + reset_flash(); + asm("ssync;"); + nValue = *(volatile unsigned short *) addr; + asm("ssync;"); + *pnValue = nValue; + return TRUE; +} + +int poll_toggle_bit(long lOffset) +{ + unsigned int u1,u2; + unsigned long timeout = 0xFFFFFFFF; + volatile unsigned long *FB = (volatile unsigned long *)(0x20000000 + lOffset); + while(1) { + if(timeout < 0) + break; + u1 = *(volatile unsigned short *)FB; + u2 = *(volatile unsigned short *)FB; + if((u1 & 0x0040) == (u2 & 0x0040)) + return FLASH_SUCCESS; + if((u2 & 0x0020) == 0x0000) + continue; + u1 = *(volatile unsigned short *)FB; + if((u2 & 0x0040) == (u1 & 0x0040)) + return FLASH_SUCCESS; + else { + reset_flash(); + return FLASH_FAIL; + } + timeout--; + } + printf("Time out occured \n"); + if(timeout <0) return FLASH_FAIL; +} + +void reset_flash(void) +{ + write_flash(WRITESEQ1, RESET_VAL); + /* Wait for 10 micro seconds */ + udelay(10); +} + +int erase_flash(void) +{ + write_flash(WRITESEQ1, WRITEDATA1); + write_flash(WRITESEQ2, WRITEDATA2); + write_flash(WRITESEQ3, WRITEDATA3); + write_flash(WRITESEQ4, WRITEDATA4); + write_flash(WRITESEQ5, WRITEDATA5); + write_flash(WRITESEQ6, WRITEDATA6); + + if(poll_toggle_bit(0x0000) < 0) + return FLASH_FAIL; + + write_flash(SecFlashAOff + WRITESEQ1, WRITEDATA1); + write_flash(SecFlashAOff + WRITESEQ2, WRITEDATA2); + write_flash(SecFlashAOff + WRITESEQ3, WRITEDATA3); + write_flash(SecFlashAOff + WRITESEQ4, WRITEDATA4); + write_flash(SecFlashAOff + WRITESEQ5, WRITEDATA5); + write_flash(SecFlashAOff + WRITESEQ6, WRITEDATA6); + + if(poll_toggle_bit(SecFlashASec1Off) < 0) + return FLASH_FAIL; + + write_flash(PriFlashBOff + WRITESEQ1, WRITEDATA1); + write_flash(PriFlashBOff + WRITESEQ2, WRITEDATA2); + write_flash(PriFlashBOff + WRITESEQ3, WRITEDATA3); + write_flash(PriFlashBOff + WRITESEQ4, WRITEDATA4); + write_flash(PriFlashBOff + WRITESEQ5, WRITEDATA5); + write_flash(PriFlashBOff + WRITESEQ6, WRITEDATA6); + + if(poll_toggle_bit(PriFlashBOff) <0) + return FLASH_FAIL; + + write_flash(SecFlashBOff + WRITESEQ1, WRITEDATA1); + write_flash(SecFlashBOff + WRITESEQ2, WRITEDATA2); + write_flash(SecFlashBOff + WRITESEQ3, WRITEDATA3); + write_flash(SecFlashBOff + WRITESEQ4, WRITEDATA4); + write_flash(SecFlashBOff + WRITESEQ5, WRITEDATA5); + write_flash(SecFlashBOff + WRITESEQ6, WRITEDATA6); + + if(poll_toggle_bit(SecFlashBOff) < 0) + return FLASH_FAIL; + + return FLASH_SUCCESS; +} + +int erase_block_flash(int nBlock, unsigned long address) +{ + long ulSectorOff = 0x0; + + if ((nBlock < 0) || (nBlock > AFP_NumSectors)) + return FALSE; + + ulSectorOff = (address - CFG_FLASH_BASE); + + write_flash((WRITESEQ1 | ulSectorOff), WRITEDATA1); + write_flash((WRITESEQ2 | ulSectorOff), WRITEDATA2); + write_flash((WRITESEQ3 | ulSectorOff), WRITEDATA3); + write_flash((WRITESEQ4 | ulSectorOff), WRITEDATA4); + write_flash((WRITESEQ5 | ulSectorOff), WRITEDATA5); + + write_flash(ulSectorOff, BlockEraseVal); + + if(poll_toggle_bit(ulSectorOff) < 0) + return FLASH_FAIL; + + return FLASH_SUCCESS; +} + +void unlock_flash(long ulOffset) +{ + unsigned long ulOffsetAddr = ulOffset; + ulOffsetAddr &= 0xFFFF0000; + + write_flash((WRITESEQ1 | ulOffsetAddr), UNLOCKDATA1); + write_flash((WRITESEQ2 | ulOffsetAddr), UNLOCKDATA2); + write_flash((WRITESEQ3 | ulOffsetAddr), UNLOCKDATA3); +} + +int get_codes() +{ + int dev_id = 0; + + write_flash(WRITESEQ1, GETCODEDATA1); + write_flash(WRITESEQ2, GETCODEDATA2); + write_flash(WRITESEQ3, GETCODEDATA3); + + read_flash(0x0002, &dev_id); + dev_id &= 0x00FF; + + reset_flash(); + + return dev_id; +} + +void get_sector_number(long ulOffset, int *pnSector) +{ + int nSector = 0; + + if (ulOffset >= SecFlashAOff) { + if ((ulOffset < SecFlashASec1Off) + && (ulOffset < SecFlashASec2Off)) { + nSector = SECT32; + } else if ((ulOffset >= SecFlashASec2Off) + && (ulOffset < SecFlashASec3Off)) { + nSector = SECT33; + } else if ((ulOffset >= SecFlashASec3Off) + && (ulOffset < SecFlashASec4Off)) { + nSector = SECT34; + } else if ((ulOffset >= SecFlashASec4Off) + && (ulOffset < SecFlashAEndOff)) { + nSector = SECT35; + } + } else if (ulOffset >= SecFlashBOff) { + if ((ulOffset < SecFlashBSec1Off) + && (ulOffset < SecFlashBSec2Off)) { + nSector = SECT36; + } + if ((ulOffset < SecFlashBSec2Off) + && (ulOffset < SecFlashBSec3Off)) { + nSector = SECT37; + } + if ((ulOffset < SecFlashBSec3Off) + && (ulOffset < SecFlashBSec4Off)) { + nSector = SECT38; + } + if ((ulOffset < SecFlashBSec4Off) + && (ulOffset < SecFlashBEndOff)) { + nSector = SECT39; + } + } else if ((ulOffset >= PriFlashAOff) && (ulOffset < SecFlashAOff)) { + nSector = ulOffset & 0xffff0000; + nSector = ulOffset >> 16; + nSector = nSector & 0x000ff; + } + + if ((nSector >= 0) && (nSector < AFP_NumSectors)) { + *pnSector = nSector; + } +} diff --git a/board/ezkit533/psd4256.h b/board/ezkit533/psd4256.h new file mode 100644 index 0000000000..9ae678babb --- /dev/null +++ b/board/ezkit533/psd4256.h @@ -0,0 +1,68 @@ +/* + * U-boot - psd4256.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Flash A/B Port A configuration registers. + * Addresses are offset values to CFG_FLASH1_BASE + * for Flash A and CFG_FLASH2_BASE for Flash B. + */ + +#define PSD_PORTA_DIN 0x070000 +#define PSD_PORTA_DOUT 0x070004 +#define PSD_PORTA_DIR 0x070006 + +/* + * Flash A/B Port B configuration registers + * Addresses are offset values to CFG_FLASH1_BASE + * for Flash A and CFG_FLASH2_BASE for Flash B. + */ + +#define PSD_PORTB_DIN 0x070001 +#define PSD_PORTB_DOUT 0x070005 +#define PSD_PORTB_DIR 0x070007 + +/* + * Flash A Port A Bit definitions + */ + +#define PSDA_PPICLK1 0x20 /* PPI Clock select bit 1 */ +#define PSDA_PPICLK0 0x10 /* PPI Clock select bit 0 */ +#define PSDA_VDEC_RST 0x08 /* Video decoder reset, 0 = RESET */ +#define PSDA_VENC_RST 0x04 /* Video encoder reset, 0 = RESET */ +#define PSDA_CODEC_RST 0x01 /* Codec reset, 0 = RESET */ + +/* + * Flash A Port B Bit definitions + */ + +#define PSDA_LED9 0x20 /* LED 9, 1 = LED ON */ +#define PSDA_LED8 0x10 /* LED 8, 1 = LED ON */ +#define PSDA_LED7 0x08 /* LED 7, 1 = LED ON */ +#define PSDA_LED6 0x04 /* LED 6, 1 = LED ON */ +#define PSDA_LED5 0x02 /* LED 5, 1 = LED ON */ +#define PSDA_LED4 0x01 /* LED 4, 1 = LED ON */ + diff --git a/board/ezkit533/u-boot.lds b/board/ezkit533/u-boot.lds new file mode 100644 index 0000000000..f58b489d80 --- /dev/null +++ b/board/ezkit533/u-boot.lds @@ -0,0 +1,149 @@ +/* + * U-boot - u-boot.lds + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(bfin) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector before the environment sector. If it throws */ + /* an error during compilation remove an object here to get */ + /* it linked after the configuration sector. */ + + cpu/bf533/start.o (.text) + cpu/bf533/start1.o (.text) + cpu/bf533/traps.o (.text) + cpu/bf533/interrupt.o (.text) + cpu/bf533/serial.o (.text) + common/dlmalloc.o (.text) + lib_generic/vsprintf.o (.text) + lib_generic/crc32.o (.text) + lib_generic/zlib.o (.text) + board/ezkit533/ezkit533.o (.text) + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} + diff --git a/board/stamp/Makefile b/board/stamp/Makefile new file mode 100644 index 0000000000..ab97e1b484 --- /dev/null +++ b/board/stamp/Makefile @@ -0,0 +1,68 @@ +# +# U-boot - Makefile +# +# Copyright (c) 2005 blackfin.uclinux.org +# +# (C) Copyright 2000-2004 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# (C) Copyright 2001 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS = $(BOARD).o stamp.o +SOBJS = + +$(LIB): .depend $(OBJS) + $(AR) crv $@ $(OBJS) + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/stamp/config.mk b/board/stamp/config.mk new file mode 100644 index 0000000000..4ec82cb776 --- /dev/null +++ b/board/stamp/config.mk @@ -0,0 +1,26 @@ +# +# (C) Copyright 2001 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +TEXT_BASE = 0x07FC0000 +PLATFORM_CPPFLAGS += -I$(TOPDIR) + diff --git a/board/stamp/stamp.c b/board/stamp/stamp.c new file mode 100644 index 0000000000..8485f58c5c --- /dev/null +++ b/board/stamp/stamp.c @@ -0,0 +1,278 @@ +/* + * U-boot - stamp.c STAMP board specific routines + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include "stamp.h" + +#define STATUS_LED_OFF 0 +#define STATUS_LED_ON 1 + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) +#else +# define SHOW_BOOT_PROGRESS(arg) +#endif + +int checkboard(void) +{ + printf("CPU: ADSP BF533 Rev.: 0.%d\n", *pCHIPID >> 28); + printf("Board: ADI BF533 Stamp board\n"); + printf(" Support: http://blackfin.uclinux.org/\n"); + printf(" Richard Klingler \n"); + return 0; +} + +long int initdram(int board_type) +{ + DECLARE_GLOBAL_DATA_PTR; +#ifdef DEBUG + printf("SDRAM attributes:\n"); + printf(" tRCD:%d Cycles; tRP:%d Cycles; tRAS:%d Cycles; tWR:%d Cycles; " + "CAS Latency:%d cycles\n", (SDRAM_tRCD >> 15), (SDRAM_tRP >> 11), + (SDRAM_tRAS >> 6), ( SDRAM_tWR >> 19), (SDRAM_CL >> 2 )); + printf("SDRAM Begin: 0x%x\n", CFG_SDRAM_BASE); + printf("Bank size = %d MB\n", 128); +#endif + gd->bd->bi_memstart = CFG_SDRAM_BASE; + gd->bd->bi_memsize = CFG_MAX_RAM_SIZE; + return (gd->bd->bi_memsize); +} + +void swap_to(int device_id) +{ + + if (device_id == ETHERNET) + { + *pFIO_DIR = PF0; + asm("ssync;"); + *pFIO_FLAG_S = PF0; + asm("ssync;"); + } + else if (device_id == FLASH) + { + *pFIO_DIR = (PF4 | PF3 | PF2 | PF1 | PF0); + *pFIO_FLAG_S = (PF4 | PF3 | PF2 ); + *pFIO_MASKA_D = (PF8 | PF6 | PF5); + *pFIO_MASKB_D = (PF7); + *pFIO_POLAR = (PF8 | PF6 | PF5 ); + *pFIO_EDGE = (PF8 | PF7 | PF6 | PF5); + *pFIO_INEN = (PF8 | PF7 | PF6 | PF5); + *pFIO_FLAG_D = (PF4 | PF3 | PF2 ); + asm("ssync;"); + } + else { + printf("Unknown bank to switch\n"); + } + + return; +} + +#if defined(CONFIG_MISC_INIT_R) +/* miscellaneous platform dependent initialisations */ +int misc_init_r(void) +{ + int i; + int cf_stat = 0; + + /* Check whether CF card is inserted */ + *pFIO_EDGE = FIO_EDGE_CF_BITS; + *pFIO_POLAR = FIO_POLAR_CF_BITS; + for (i=0; i < 0x300 ; i++) asm("nop;"); + + if ( (*pFIO_FLAG_S) & CF_STAT_BITS) + { + cf_stat = 0; + } + else + { + cf_stat = 1; + } + + *pFIO_EDGE = FIO_EDGE_BITS; + *pFIO_POLAR = FIO_POLAR_BITS; + + + if (cf_stat) + { + printf ("Booting from COMPACT flash\n"); + + /* Set cycle time for CF */ + *(volatile unsigned long *) ambctl1 = CF_AMBCTL1VAL; + + for (i=0; i < 0x1000 ; i++) asm("nop;"); + for (i=0; i < 0x1000 ; i++) asm("nop;"); + for (i=0; i < 0x1000 ; i++) asm("nop;"); + + serial_setbrg(); + ide_init(); + + setenv ("bootargs", ""); + setenv ("bootcmd", "fatload ide 0:1 0x1000000 uImage-stamp;bootm 0x1000000;bootm 0x20100000" ); + } + else + { + printf ("Booting from FLASH\n"); + } + + return 1; +} +#endif + +#ifdef CONFIG_STAMP_CF + +void cf_outb(unsigned char val, volatile unsigned char* addr) +{ + /* + * Set PF1 PF0 respectively to 0 1 to divert address + * to the expansion memory banks + */ + *pFIO_FLAG_S = CF_PF0; + *pFIO_FLAG_C = CF_PF1; + asm("ssync;"); + + *(addr) = val; + asm("ssync;"); + + /* Setback PF1 PF0 to 0 0 to address external + * memory banks */ + *(volatile unsigned short *) pFIO_FLAG_C = CF_PF1_PF0; + asm("ssync;"); +} + +unsigned char cf_inb(volatile unsigned char *addr) +{ + volatile unsigned char c; + + *pFIO_FLAG_S = CF_PF0; + *pFIO_FLAG_C = CF_PF1; + asm("ssync;"); + + c = *(addr); + asm("ssync;"); + + *pFIO_FLAG_C = CF_PF1_PF0; + asm("ssync;"); + + return c; +} + +void cf_insw(unsigned short *sect_buf, unsigned short *addr, int words) +{ + int i; + + *pFIO_FLAG_S = CF_PF0; + *pFIO_FLAG_C = CF_PF1; + asm("ssync;"); + + for (i = 0;i < words; i++) + { + *(sect_buf + i) = *(addr); + asm("ssync;"); + } + + *pFIO_FLAG_C = CF_PF1_PF0; + asm("ssync;"); +} + +void cf_outsw(unsigned short *addr, unsigned short *sect_buf, int words) +{ + int i; + + *pFIO_FLAG_S = CF_PF0; + *pFIO_FLAG_C = CF_PF1; + asm("ssync;"); + + for (i = 0;i < words; i++) + { + *(addr) = *(sect_buf + i); + asm("ssync;"); + } + + *pFIO_FLAG_C = CF_PF1_PF0; + asm("ssync;"); +} +#endif + +void stamp_led_set(int LED1, int LED2, int LED3) +{ + *pFIO_INEN &= ~( PF2 | PF3 | PF4); + *pFIO_DIR |= ( PF2 | PF3 | PF4); + + if(LED1 == STATUS_LED_OFF) + *pFIO_FLAG_S = PF2; + else + *pFIO_FLAG_C = PF2; + if(LED2 == STATUS_LED_OFF) + *pFIO_FLAG_S = PF3; + else + *pFIO_FLAG_C = PF3; + if(LED3 == STATUS_LED_OFF) + *pFIO_FLAG_S = PF4; + else + *pFIO_FLAG_C = PF4; + asm("ssync;"); +} + +void show_boot_progress(int status) +{ + switch(status){ + case 1: + stamp_led_set(STATUS_LED_OFF,STATUS_LED_OFF,STATUS_LED_ON); + break; + case 2: + stamp_led_set(STATUS_LED_OFF,STATUS_LED_ON,STATUS_LED_OFF); + break; + case 3: + stamp_led_set(STATUS_LED_OFF,STATUS_LED_ON,STATUS_LED_ON); + break; + case 4: + stamp_led_set(STATUS_LED_ON,STATUS_LED_OFF,STATUS_LED_OFF); + break; + case 5: + case 6: + stamp_led_set(STATUS_LED_ON,STATUS_LED_OFF,STATUS_LED_ON); + break; + case 7: + case 8: + stamp_led_set(STATUS_LED_ON,STATUS_LED_ON,STATUS_LED_OFF); + break; + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + stamp_led_set(STATUS_LED_OFF,STATUS_LED_OFF,STATUS_LED_OFF); + break; + default: + stamp_led_set(STATUS_LED_ON,STATUS_LED_ON,STATUS_LED_ON); + break; + } +} + diff --git a/board/stamp/stamp.h b/board/stamp/stamp.h new file mode 100644 index 0000000000..7bc33b4147 --- /dev/null +++ b/board/stamp/stamp.h @@ -0,0 +1,57 @@ +/* + * U-boot - stamp.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __STAMP_H__ +#define __STAMP_H__ + +extern void init_Flags(void); + +extern volatile unsigned long *ambctl0; +extern volatile unsigned long *ambctl1; +extern volatile unsigned long *amgctl; + +extern unsigned long pll_div_fact; +extern void serial_setbrg(void); +extern void pll_set(int vco, int crystal_frq, int pll_div); + +/* Definitions used in Compact Flash Boot support */ +#define FIO_EDGE_CF_BITS 0x0000 +#define FIO_POLAR_CF_BITS 0x0000 +#define FIO_EDGE_BITS 0x1E0 +#define FIO_POLAR_BITS 0x160 + +/* Compact flash status bits in status register */ +#define CF_STAT_BITS 0x00000060 + +/* CF Flags used to switch between expansion and external + * memory banks + */ +#define CF_PF0 0x0001 +#define CF_PF1 0x0002 +#define CF_PF1_PF0 0x0003 + +#endif diff --git a/board/stamp/u-boot.lds b/board/stamp/u-boot.lds new file mode 100644 index 0000000000..ad6886f8e1 --- /dev/null +++ b/board/stamp/u-boot.lds @@ -0,0 +1,148 @@ +/* + * U-boot - u-boot.lds + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(bfin) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector before the environment sector. If it throws */ + /* an error during compilation remove an object here to get */ + /* it linked after the configuration sector. */ + + cpu/bf533/start.o (.text) + cpu/bf533/start1.o (.text) + cpu/bf533/traps.o (.text) + cpu/bf533/interrupt.o (.text) + cpu/bf533/serial.o (.text) + common/dlmalloc.o (.text) + lib_generic/vsprintf.o (.text) + lib_generic/crc32.o (.text) + lib_generic/zlib.o (.text) + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} + diff --git a/cpu/bf533/Makefile b/cpu/bf533/Makefile new file mode 100644 index 0000000000..c63a8f6d01 --- /dev/null +++ b/cpu/bf533/Makefile @@ -0,0 +1,46 @@ +# U-boot - Makefile +# +# Copyright (c) 2005 blackfin.uclinux.org +# +# (C) Copyright 2000-2004 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(CPU).a + +START = start.o start1.o interrupt.o cache.o cplbhdlr.o cplbmgr.o flush.o +OBJS = cpu.o traps.o ints.o serial.o interrupts.o + +all: .depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) crv $@ $(OBJS) + +######################################################################### + +.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/cpu/bf533/bf533_serial.h b/cpu/bf533/bf533_serial.h new file mode 100644 index 0000000000..ec63a5e00a --- /dev/null +++ b/cpu/bf533/bf533_serial.h @@ -0,0 +1,78 @@ +/* + * U-boot - bf533_serial.h Serial Driver defines + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on + * bf533_serial.h: Definitions for the BlackFin BF533 DSP serial driver. + * Copyright (C) 2003 Bas Vermeulen + * BuyWays B.V. (www.buyways.nl) + * + * Based heavily on: + * blkfinserial.h: Definitions for the BlackFin DSP serial driver. + * + * Copyright (C) 2001 Tony Z. Kou tonyko@arcturusnetworks.com + * Copyright (C) 2001 Arcturus Networks Inc. + * + * Based on code from 68328serial.c which was: + * Copyright (C) 1995 David S. Miller + * Copyright (C) 1998 Kenneth Albanowski + * Copyright (C) 1998, 1999 D. Jeff Dionne + * Copyright (C) 1999 Vladimir Gurevich + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _Bf533_SERIAL_H +#define _Bf533_SERIAL_H + +#include +#include + +#define SYNC_ALL __asm__ __volatile__ ("ssync;\n") +#define ACCESS_LATCH *pUART_LCR |= UART_LCR_DLAB; +#define ACCESS_PORT_IER *pUART_LCR &= (~UART_LCR_DLAB); + +void serial_setbrg(void); +static void local_put_char(char ch); +void calc_baud(void); +void serial_setbrg(void); +int serial_init(void); +void serial_putc(const char c); +int serial_tstc(void); +int serial_getc(void); +void serial_puts(const char *s); +static void local_put_char(char ch); + +extern int get_clock(void); +int baud_table[5] = {9600, 19200, 38400, 57600, 115200}; + +struct { + unsigned char dl_high; + unsigned char dl_low; +} hw_baud_table[5]; + +#ifdef CONFIG_STAMP +extern unsigned long pll_div_fact; +#endif + +#endif diff --git a/cpu/bf533/cache.S b/cpu/bf533/cache.S new file mode 100644 index 0000000000..1822d1f329 --- /dev/null +++ b/cpu/bf533/cache.S @@ -0,0 +1,125 @@ + + +#define ASSEMBLY +#include +#include + +.text +.align 2 +ENTRY(blackfin_icache_flush_range) + R2 = -32; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC; +1: + IFLUSH[P0++]; + CC = P0 < P1(iu); + IF CC JUMP 1b(bp); + IFLUSH[P0]; + SSYNC; + RTS; + +ENTRY(blackfin_dcache_flush_range) + R2 = -32; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC; +1: + FLUSH[P0++]; + CC = P0 < P1(iu); + IF CC JUMP 1b(bp); + FLUSH[P0]; + SSYNC; + RTS; + +ENTRY(_icache_invalidate) +ENTRY(invalidate_entire_icache) + [--SP] = ( R7:5); + + P0.L = (IMEM_CONTROL & 0xFFFF); + P0.H = (IMEM_CONTROL >> 16); + R7 = [P0]; + + /* Clear the IMC bit , All valid bits in the instruction + * cache are set to the invalid state + */ + BITCLR(R7,IMC_P); + CLI R6; + SSYNC; /* SSYNC required before invalidating cache. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + /* Configures the instruction cache agian */ + R6 = (IMC | ENICPLB); + R7 = R7 | R6; + + CLI R6; + SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + ( R7:5) = [SP++]; + RTS; + +/* Invalidate the Entire Data cache by + * clearing DMC[1:0] bits + */ +ENTRY(invalidate_entire_dcache) +ENTRY(_dcache_invalidate) + [--SP] = ( R7:6); + + P0.L = (DMEM_CONTROL & 0xFFFF); + P0.H = (DMEM_CONTROL >> 16); + R7 = [P0]; + + /* Clear the DMC[1:0] bits, All valid bits in the data + * cache are set to the invalid state + */ + BITCLR(R7,DMC0_P); + BITCLR(R7,DMC1_P); + CLI R6; + SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + /* Configures the data cache again */ + + R6 = (ACACHE_BCACHE | ENDCPLB | PORT_PREF0); + R7 = R7 | R6; + + CLI R6; + SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + ( R7:6) = [SP++]; + RTS; + +ENTRY(blackfin_dcache_invalidate_range) + R2 = -32; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC; +1: + FLUSHINV[P0++]; + CC = P0 < P1 (iu); + IF CC JUMP 1b (bp); + + /* If the data crosses a cache line, then we'll be pointing to + ** the last cache line, but won't have flushed/invalidated it yet, so do + ** one more. + */ + FLUSHINV[P0]; + SSYNC; + RTS; diff --git a/cpu/bf533/config.mk b/cpu/bf533/config.mk new file mode 100644 index 0000000000..a9d529ecd8 --- /dev/null +++ b/cpu/bf533/config.mk @@ -0,0 +1,27 @@ +# U-boot - config.mk +# +# Copyright (c) 2005 blackfin.uclinux.org +# +# (C) Copyright 2000-2004 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -ffixed-P5 diff --git a/cpu/bf533/cplbhdlr.S b/cpu/bf533/cplbhdlr.S new file mode 100644 index 0000000000..b5abbbcbb6 --- /dev/null +++ b/cpu/bf533/cplbhdlr.S @@ -0,0 +1,194 @@ +/* Copyright (C) 2003 Analog Devices, Inc. All Rights Reserved. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. + * + * Blackfin BF533/2.6 support : LG Soft India + */ + + +/* Include an exception handler to invoke the CPLB manager + */ + +#include +#include +#include + + +.text + +.globl _cplb_hdr; +.type _cplb_hdr, STT_FUNC; +.extern _cplb_mgr; +.type _cplb_mgr, STT_FUNC; +.extern __unknown_exception_occurred; +.type __unknown_exception_occurred, STT_FUNC; +.extern __cplb_miss_all_locked; +.type __cplb_miss_all_locked, STT_FUNC; +.extern __cplb_miss_without_replacement; +.type __cplb_miss_without_replacement, STT_FUNC; +.extern __cplb_protection_violation; +.type __cplb_protection_violation, STT_FUNC; +.extern panic_pv; + +.align 2; + +ENTRY(_cplb_hdr) + SSYNC; + [--SP] = ( R7:0, P5:0 ); + [--SP] = ASTAT; + [--SP] = SEQSTAT; + [--SP] = I0; + [--SP] = I1; + [--SP] = I2; + [--SP] = I3; + [--SP] = LT0; + [--SP] = LB0; + [--SP] = LC0; + [--SP] = LT1; + [--SP] = LB1; + [--SP] = LC1; + R2 = SEQSTAT; + + /*Mask the contents of SEQSTAT and leave only EXCAUSE in R2*/ + R2 <<= 26; + R2 >>= 26; + + R1 = 0x23; /* Data access CPLB protection violation */ + CC = R2 == R1; + IF !CC JUMP not_data_write; + R0 = 2; /* is a write to data space*/ + JUMP is_icplb_miss; + +not_data_write: + R1 = 0x2C; /* CPLB miss on an instruction fetch */ + CC = R2 == R1; + R0 = 0; /* is_data_miss == False*/ + IF CC JUMP is_icplb_miss; + + R1 = 0x26; + CC = R2 == R1; + IF !CC JUMP unknown; + + R0 = 1; /* is_data_miss == True*/ + +is_icplb_miss: + +#if ( defined (CONFIG_BLKFIN_CACHE) || defined (CONFIG_BLKFIN_DCACHE)) +#if ( defined (CONFIG_BLKFIN_CACHE) && !defined (CONFIG_BLKFIN_DCACHE)) + R1 = CPLB_ENABLE_ICACHE; +#endif +#if ( !defined (CONFIG_BLKFIN_CACHE) && defined (CONFIG_BLKFIN_DCACHE)) + R1 = CPLB_ENABLE_DCACHE; +#endif +#if ( defined (CONFIG_BLKFIN_CACHE) && defined (CONFIG_BLKFIN_DCACHE)) + R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE; +#endif +#else + R1 = 0; +#endif + + [--SP] = RETS; + CALL _cplb_mgr; + RETS = [SP++]; + CC = R0 == 0; + IF !CC JUMP not_replaced; + LC1 = [SP++]; + LB1 = [SP++]; + LT1 = [SP++]; + LC0 = [SP++]; + LB0 = [SP++]; + LT0 = [SP++]; + I3 = [SP++]; + I2 = [SP++]; + I1 = [SP++]; + I0 = [SP++]; + SEQSTAT = [SP++]; + ASTAT = [SP++]; + ( R7:0, P5:0 ) = [SP++]; + RTS; + +unknown: + [--SP] = RETS; + CALL __unknown_exception_occurred; + RETS = [SP++]; + JUMP unknown; +not_replaced: + CC = R0 == CPLB_NO_UNLOCKED; + IF !CC JUMP next_check; + [--SP] = RETS; + CALL __cplb_miss_all_locked; + RETS = [SP++]; +next_check: + CC = R0 == CPLB_NO_ADDR_MATCH; + IF !CC JUMP next_check2; + [--SP] = RETS; + CALL __cplb_miss_without_replacement; + RETS = [SP++]; + JUMP not_replaced; +next_check2: + CC = R0 == CPLB_PROT_VIOL; + IF !CC JUMP strange_return_from_cplb_mgr; + [--SP] = RETS; + CALL __cplb_protection_violation; + RETS = [SP++]; + JUMP not_replaced; +strange_return_from_cplb_mgr: + IDLE; + CSYNC; + JUMP strange_return_from_cplb_mgr; + +/************************************ + * Diagnostic exception handlers + */ + +__cplb_miss_all_locked: + sp += -12; + R0 = CPLB_NO_UNLOCKED; + call panic_bfin; + SP += 12; + RTS; + + __cplb_miss_without_replacement: + sp += -12; + R0 = CPLB_NO_ADDR_MATCH; + call panic_bfin; + SP += 12; + RTS; + +__cplb_protection_violation: + sp += -12; + R0 = CPLB_PROT_VIOL; + call panic_bfin; + SP += 12; + RTS; + +__unknown_exception_occurred: + + /* This function is invoked by the default exception + * handler, if it does not recognise the kind of + * exception that has occurred. In other words, the + * default handler only handles some of the system's + * exception types, and it does not expect any others + * to occur. If your application is going to be using + * other kinds of exceptions, you must replace the + * default handler with your own, that handles all the + * exceptions you will use. + * + * Since there's nothing we can do, we just loop here + * at what we hope is a suitably informative label. + */ + + IDLE; +do_not_know_what_to_do: + CSYNC; + JUMP __unknown_exception_occurred; + + RTS; +.__unknown_exception_occurred.end: +.global __unknown_exception_occurred; +.type __unknown_exception_occurred, STT_FUNC; + +panic_bfin: + RTS; + diff --git a/cpu/bf533/cplbmgr.S b/cpu/bf533/cplbmgr.S new file mode 100644 index 0000000000..fc3e3a8832 --- /dev/null +++ b/cpu/bf533/cplbmgr.S @@ -0,0 +1,601 @@ +/*This file is subject to the terms and conditions of the GNU General Public + * License. + * + * Blackfin BF533/2.6 support : LG Soft India + * Modification: Dec 07 2004 + * 1. Correction in icheck_lock. Valid lock entries were + * geting victimized, for instruction cplb replacement. + * 2. Setup loop's are modified as now toolchain support's P Indexed + * addressing + * :LG Soft India + * + */ + +/* Usage: int _cplb_mgr(is_data_miss,int enable_cache) + * is_data_miss==2 => Mark as Dirty, write to the clean data page + * is_data_miss==1 => Replace a data CPLB. + * is_data_miss==0 => Replace an instruction CPLB. + * + * Returns: + * CPLB_RELOADED => Successfully updated CPLB table. + * CPLB_NO_UNLOCKED => All CPLBs are locked, so cannot be evicted.This indicates + * that the CPLBs in the configuration tablei are badly + * configured, as this should never occur. + * CPLB_NO_ADDR_MATCH => The address being accessed, that triggered the exception, + * is not covered by any of the CPLBs in the configuration + * table. The application isi presumably misbehaving. + * CPLB_PROT_VIOL => The address being accessed, that triggered thei exception, + * was not a first-write to a clean Write Back Data page, + * and so presumably is a genuine violation of the page's + * protection attributes. The application is misbehaving. + */ +#define ASSEMBLY + +#include +#include +#include +#include + +.text + +.align 2; +ENTRY(_cplb_mgr) + + [--SP]=( R7:0,P5:0 ); + + CC = R0 == 2; + IF CC JUMP dcplb_write; + + CC = R0 == 0; + IF !CC JUMP dcplb_miss_compare; + + /* ICPLB Miss Exception. We need to choose one of the + * currently-installed CPLBs, and replace it with one + * from the configuration table. + */ + + P4.L = (ICPLB_FAULT_ADDR & 0xFFFF); + P4.H = (ICPLB_FAULT_ADDR >> 16); + + P1 = 16; + P5.L = page_size_table; + P5.H = page_size_table; + + P0.L = (ICPLB_DATA0 & 0xFFFF); + P0.H = (ICPLB_DATA0 >> 16); + R4 = [P4]; /* Get faulting address*/ + R6 = 64; /* Advance past the fault address, which*/ + R6 = R6 + R4; /* we'll use if we find a match*/ + R3 = ((16 << 8) | 2); /* Extract mask, bits 16 and 17.*/ + + R5 = 0; +isearch: + + R1 = [P0-0x100]; /* Address for this CPLB */ + + R0 = [P0++]; /* Info for this CPLB*/ + CC = BITTST(R0,0); /* Is the CPLB valid?*/ + IF !CC JUMP nomatch; /* Skip it, if not.*/ + CC = R4 < R1(IU); /* If fault address less than page start*/ + IF CC JUMP nomatch; /* then skip this one.*/ + R2 = EXTRACT(R0,R3.L) (Z); /* Get page size*/ + P1 = R2; + P1 = P5 + (P1<<2); /* index into page-size table*/ + R2 = [P1]; /* Get the page size*/ + R1 = R1 + R2; /* and add to page start, to get page end*/ + CC = R4 < R1(IU); /* and see whether fault addr is in page.*/ + IF !CC R4 = R6; /* If so, advance the address and finish loop.*/ + IF !CC JUMP isearch_done; +nomatch: + /* Go around again*/ + R5 += 1; + CC = BITTST(R5, 4); /* i.e CC = R5 >= 16*/ + IF !CC JUMP isearch; + +isearch_done: + I0 = R4; /* Fault address we'll search for*/ + + /* set up pointers */ + P0.L = (ICPLB_DATA0 & 0xFFFF); + P0.H = (ICPLB_DATA0 >> 16); + + /* The replacement procedure for ICPLBs */ + + P4.L = (IMEM_CONTROL & 0xFFFF); + P4.H = (IMEM_CONTROL >> 16); + + /* disable cplbs */ + R5 = [P4]; /* Control Register*/ + BITCLR(R5,ENICPLB_P); + CLI R1; + SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ + .align 8; + [P4] = R5; + SSYNC; + STI R1; + + R1 = -1; /* end point comparison */ + R3 = 16; /* counter */ + + /* Search through CPLBs for first non-locked entry */ + /* Overwrite it by moving everyone else up by 1 */ +icheck_lock: + R0 = [P0++]; + R3 = R3 + R1; + CC = R3 == R1; + IF CC JUMP all_locked; + CC = BITTST(R0, 0); /* an invalid entry is good */ + IF !CC JUMP ifound_victim; + CC = BITTST(R0,1); /* but a locked entry isn't */ + IF CC JUMP icheck_lock; + +ifound_victim: +#ifdef CONFIG_CPLB_INFO + R7 = [P0 - 0x104]; + P2.L = ipdt_table; + P2.H = ipdt_table; + P3.L = ipdt_swapcount_table; + P3.H = ipdt_swapcount_table; + P3 += -4; +icount: + R2 = [P2]; /* address from config table */ + P2 += 8; + P3 += 8; + CC = R2==-1; + IF CC JUMP icount_done; + CC = R7==R2; + IF !CC JUMP icount; + R7 = [P3]; + R7 += 1; + [P3] = R7; + CSYNC; +icount_done: +#endif + LC0=R3; + LSETUP(is_move,ie_move) LC0; +is_move: + R0 = [P0]; + [P0 - 4] = R0; + R0 = [P0 - 0x100]; + [P0-0x104] = R0; +ie_move:P0+=4; + + /* We've made space in the ICPLB table, so that ICPLB15 + * is now free to be overwritten. Next, we have to determine + * which CPLB we need to install, from the configuration + * table. This is a matter of getting the start-of-page + * addresses and page-lengths from the config table, and + * determining whether the fault address falls within that + * range. + */ + + P2.L = ipdt_table; + P2.H = ipdt_table; +#ifdef CONFIG_CPLB_INFO + P3.L = ipdt_swapcount_table; + P3.H = ipdt_swapcount_table; + P3 += -8; +#endif + P0.L = page_size_table; + P0.H = page_size_table; + + /* Retrieve our fault address (which may have been advanced + * because the faulting instruction crossed a page boundary). + */ + + R0 = I0; + + /* An extraction pattern, to get the page-size bits from + * the CPLB data entry. Bits 16-17, so two bits at posn 16. + */ + + R1 = ((16<<8)|2); +inext: R4 = [P2++]; /* address from config table */ + R2 = [P2++]; /* data from config table */ +#ifdef CONFIG_CPLB_INFO + P3 += 8; +#endif + + CC = R4 == -1; /* End of config table*/ + IF CC JUMP no_page_in_table; + + /* See if failed address > start address */ + CC = R4 <= R0(IU); + IF !CC JUMP inext; + + /* extract page size (17:16)*/ + R3 = EXTRACT(R2, R1.L) (Z); + + /* add page size to addr to get range */ + + P5 = R3; + P5 = P0 + (P5 << 2); /* scaled, for int access*/ + R3 = [P5]; + R3 = R3 + R4; + + /* See if failed address < (start address + page size) */ + CC = R0 < R3(IU); + IF !CC JUMP inext; + + /* We've found a CPLB in the config table that covers + * the faulting address, so install this CPLB into the + * last entry of the table. + */ + + P1.L = (ICPLB_DATA15 & 0xFFFF); /*ICPLB_DATA15*/ + P1.H = (ICPLB_DATA15 >> 16); + [P1] = R2; + [P1-0x100] = R4; +#ifdef CONFIG_CPLB_INFO + R3 = [P3]; + R3 += 1; + [P3] = R3; +#endif + + /* P4 points to IMEM_CONTROL, and R5 contains its old + * value, after we disabled ICPLBS. Re-enable them. + */ + + BITSET(R5,ENICPLB_P); + CLI R2; + SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ + .align 8; + [P4] = R5; + SSYNC; + STI R2; + + ( R7:0,P5:0 ) = [SP++]; + R0 = CPLB_RELOADED; + RTS; + +/* FAILED CASES*/ +no_page_in_table: + ( R7:0,P5:0 ) = [SP++]; + R0 = CPLB_NO_ADDR_MATCH; + RTS; +all_locked: + ( R7:0,P5:0 ) = [SP++]; + R0 = CPLB_NO_UNLOCKED; + RTS; +prot_violation: + ( R7:0,P5:0 ) = [SP++]; + R0 = CPLB_PROT_VIOL; + RTS; + +dcplb_write: + + /* if a DCPLB is marked as write-back (CPLB_WT==0), and + * it is clean (CPLB_DIRTY==0), then a write to the + * CPLB's page triggers a protection violation. We have to + * mark the CPLB as dirty, to indicate that there are + * pending writes associated with the CPLB. + */ + + P4.L = (DCPLB_STATUS & 0xFFFF); + P4.H = (DCPLB_STATUS >> 16); + P3.L = (DCPLB_DATA0 & 0xFFFF); + P3.H = (DCPLB_DATA0 >> 16); + R5 = [P4]; + + /* A protection violation can be caused by more than just writes + * to a clean WB page, so we have to ensure that: + * - It's a write + * - to a clean WB page + * - and is allowed in the mode the access occurred. + */ + + CC = BITTST(R5, 16); /* ensure it was a write*/ + IF !CC JUMP prot_violation; + + /* to check the rest, we have to retrieve the DCPLB.*/ + + /* The low half of DCPLB_STATUS is a bit mask*/ + + R2 = R5.L (Z); /* indicating which CPLB triggered the event.*/ + R3 = 30; /* so we can use this to determine the offset*/ + R2.L = SIGNBITS R2; + R2 = R2.L (Z); /* into the DCPLB table.*/ + R3 = R3 - R2; + P4 = R3; + P3 = P3 + (P4<<2); + R3 = [P3]; /* Retrieve the CPLB*/ + + /* Now we can check whether it's a clean WB page*/ + + CC = BITTST(R3, 14); /* 0==WB, 1==WT*/ + IF CC JUMP prot_violation; + CC = BITTST(R3, 7); /* 0 == clean, 1 == dirty*/ + IF CC JUMP prot_violation; + + /* Check whether the write is allowed in the mode that was active.*/ + + R2 = 1<<3; /* checking write in user mode*/ + CC = BITTST(R5, 17); /* 0==was user, 1==was super*/ + R5 = CC; + R2 <<= R5; /* if was super, check write in super mode*/ + R2 = R3 & R2; + CC = R2 == 0; + IF CC JUMP prot_violation; + + /* It's a genuine write-to-clean-page.*/ + + BITSET(R3, 7); /* mark as dirty*/ + [P3] = R3; /* and write back.*/ + CSYNC; + ( R7:0,P5:0 ) = [SP++]; + R0 = CPLB_RELOADED; + RTS; + +dcplb_miss_compare: + + /* Data CPLB Miss event. We need to choose a CPLB to + * evict, and then locate a new CPLB to install from the + * config table, that covers the faulting address. + */ + + P1.L = (DCPLB_DATA15 & 0xFFFF); + P1.H = (DCPLB_DATA15 >> 16); + + P4.L = (DCPLB_FAULT_ADDR & 0xFFFF); + P4.H = (DCPLB_FAULT_ADDR >> 16); + R4 = [P4]; + I0 = R4; + + /* The replacement procedure for DCPLBs*/ + + R6 = R1; /* Save for later*/ + + /* Turn off CPLBs while we work.*/ + P4.L = (DMEM_CONTROL & 0xFFFF); + P4.H = (DMEM_CONTROL >> 16); + R5 = [P4]; + BITCLR(R5,ENDCPLB_P); + CLI R0; + SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ + .align 8; + [P4] = R5; + SSYNC; + STI R0; + + /* Start looking for a CPLB to evict. Our order of preference + * is: invalid CPLBs, clean CPLBs, dirty CPLBs. Locked CPLBs + * are no good. + */ + + I1.L = (DCPLB_DATA0 & 0xFFFF); + I1.H = (DCPLB_DATA0 >> 16); + P1 = 3; + P2 = 16; + I2.L = dcplb_preference; + I2.H = dcplb_preference; + LSETUP(sdsearch1, edsearch1) LC0 = P1; +sdsearch1: + R0 = [I2++]; /* Get the bits we're interested in*/ + P0 = I1; /* Go back to start of table*/ + LSETUP (sdsearch2, edsearch2) LC1 = P2; +sdsearch2: + R1 = [P0++]; /* Fetch each installed CPLB in turn*/ + R2 = R1 & R0; /* and test for interesting bits.*/ + CC = R2 == 0; /* If none are set, it'll do.*/ + IF !CC JUMP skip_stack_check; + + R2 = [P0 - 0x104]; /* R2 - PageStart */ + P3.L = page_size_table; /* retrive end address */ + P3.H = page_size_table; /* retrive end address */ + R3 = 0x2; /* 0th - position, 2 bits -length */ + nop; /*Anamoly 05000209*/ + R7 = EXTRACT(R1,R3.l); + R7 = R7 << 2; /* Page size index offset */ + P5 = R7; + P3 = P3 + P5; + R7 = [P3]; /* page size in 1K bytes */ + + R7 = R7 << 0xA; /* in bytes * 1024*/ + R7 = R2 + R7; /* R7 - PageEnd */ + R4 = SP; /* Test SP is in range */ + + CC = R7 < R4; /* if PageEnd < SP */ + IF CC JUMP dfound_victim; + R3 = 0x284; /* stack length from start of trap till the point */ + /* 20 stack locations for future modifications */ + R4 = R4 + R3; + CC = R4 < R2; /* if SP + stacklen < PageStart */ + IF CC JUMP dfound_victim; +skip_stack_check: + +edsearch2: NOP; +edsearch1: NOP; + + /* If we got here, we didn't find a DCPLB we considered + * replacable, which means all of them were locked. + */ + + JUMP all_locked; +dfound_victim: + +#ifdef CONFIG_CPLB_INFO + R1 = [P0 - 0x104]; + P2.L = dpdt_table; + P2.H = dpdt_table; + P3.L = dpdt_swapcount_table; + P3.H = dpdt_swapcount_table; + P3 += -4; +dicount: + R2 = [P2]; + P2 += 8; + P3 += 8; + CC = R2==-1; + IF CC JUMP dicount_done; + CC = R1==R2; + IF !CC JUMP dicount; + R1 = [P3]; + R1 += 1; + [P3] = R1; + CSYNC; +dicount_done: +#endif + + /* Clean down the hardware loops*/ + R2 = 0; + LC1 = R2; + LC0 = R2; + + /* There's a suitable victim in [P0-4] (because we've + * advanced already). If it's a valid dirty write-back + * CPLB, we need to flush the pending writes first. + */ + + CC = BITTST(R1, 0); /* Is it valid?*/ + IF !CC JUMP Ddoverwrite;/* nope.*/ + CC = BITTST(R1, 7); /* Is it dirty?*/ + IF !CC JUMP Ddoverwrite (BP); /* Nope.*/ + CC = BITTST(R1, 14); /* Is it Write-Through?*/ + IF CC JUMP Ddoverwrite; /* Yep*/ + + /* This is a dirty page, so we need to flush all writes + * that are pending on the page. + */ + + /* Retrieve the page start address*/ + R0 = [P0 - 0x104]; + [--sp] = rets; + CALL dcplb_flush; /* R0==CPLB addr, R1==CPLB data*/ + rets = [sp++]; +Ddoverwrite: + + /* [P0-4] is a suitable victim CPLB, so we want to + * overwrite it by moving all the following CPLBs + * one space closer to the start. + */ + + R1.L = ((DCPLB_DATA15+4) & 0xFFFF); /*DCPLB_DATA15+4*/ + R1.H = ((DCPLB_DATA15+4) >> 16); + R0 = P0; + + /* If the victim happens to be in DCPLB15, + * we don't need to move anything. + */ + + CC = R1 == R0; + IF CC JUMP de_moved; + R1 = R1 - R0; + R1 >>= 2; + P1 = R1; + LSETUP(ds_move, de_move) LC0=P1; +ds_move: + R0 = [P0++]; /* move data */ + [P0 - 8] = R0; + R0 = [P0-0x104] /* move address */ +de_move: [P0-0x108] = R0; + + /* We've now made space in DCPLB15 for the new CPLB to be + * installed. The next stage is to locate a CPLB in the + * config table that covers the faulting address. + */ + +de_moved:NOP; + R0 = I0; /* Our faulting address */ + + P2.L = dpdt_table; + P2.H = dpdt_table; +#ifdef CONFIG_CPLB_INFO + P3.L = dpdt_swapcount_table; + P3.H = dpdt_swapcount_table; + P3 += -8; +#endif + + P1.L = page_size_table; + P1.H = page_size_table; + + /* An extraction pattern, to retrieve bits 17:16.*/ + + R1 = (16<<8)|2; +dnext: R4 = [P2++]; /* address */ + R2 = [P2++]; /* data */ +#ifdef CONFIG_CPLB_INFO + P3 += 8; +#endif + + CC = R4 == -1; + IF CC JUMP no_page_in_table; + + /* See if failed address > start address */ + CC = R4 <= R0(IU); + IF !CC JUMP dnext; + + /* extract page size (17:16)*/ + R3 = EXTRACT(R2, R1.L) (Z); + + /* add page size to addr to get range */ + + P5 = R3; + P5 = P1 + (P5 << 2); + R3 = [P5]; + R3 = R3 + R4; + + /* See if failed address < (start address + page size) */ + CC = R0 < R3(IU); + IF !CC JUMP dnext; + + /* We've found the CPLB that should be installed, so + * write it into CPLB15, masking off any caching bits + * if necessary. + */ + + P1.L = (DCPLB_DATA15 & 0xFFFF); + P1.H = (DCPLB_DATA15 >> 16); + + /* If the DCPLB has cache bits set, but caching hasn't + * been enabled, then we want to mask off the cache-in-L1 + * bit before installing. Moreover, if caching is off, we + * also want to ensure that the DCPLB has WT mode set, rather + * than WB, since WB pages still trigger first-write exceptions + * even when not caching is off, and the page isn't marked as + * cachable. Finally, we could mark the page as clean, not dirty, + * but we choose to leave that decision to the user; if the user + * chooses to have a CPLB pre-defined as dirty, then they always + * pay the cost of flushing during eviction, but don't pay the + * cost of first-write exceptions to mark the page as dirty. + */ + +#ifdef CONFIG_BLKFIN_WT + BITSET(R6, 14); /* Set WT*/ +#endif + + [P1] = R2; + [P1-0x100] = R4; +#ifdef CONFIG_CPLB_INFO + R3 = [P3]; + R3 += 1; + [P3] = R3; +#endif + + /* We've installed the CPLB, so re-enable CPLBs. P4 + * points to DMEM_CONTROL, and R5 is the value we + * last wrote to it, when we were disabling CPLBs. + */ + + BITSET(R5,ENDCPLB_P); + CLI R2; + .align 8; + [P4] = R5; + SSYNC; + STI R2; + + ( R7:0,P5:0 ) = [SP++]; + R0 = CPLB_RELOADED; + RTS; + +.data +.align 4; +page_size_table: +.byte4 0x00000400; /* 1K */ +.byte4 0x00001000; /* 4K */ +.byte4 0x00100000; /* 1M */ +.byte4 0x00400000; /* 4M */ + +.align 4; +dcplb_preference: +.byte4 0x00000001; /* valid bit */ +.byte4 0x00000082; /* dirty+lock bits */ +.byte4 0x00000002; /* lock bit */ diff --git a/cpu/bf533/cpu.c b/cpu/bf533/cpu.c new file mode 100644 index 0000000000..2c139f547d --- /dev/null +++ b/cpu/bf533/cpu.c @@ -0,0 +1,194 @@ +/* + * U-boot - cpu.c CPU specific functions + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#define SSYNC() asm("ssync;") +#define CACHE_ON 1 +#define CACHE_OFF 0 + +/* Data Attibutes*/ + +#define SDRAM_IGENERIC (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID) +#define SDRAM_IKERNEL (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_LOCK) +#define L1_IMEMORY (PAGE_SIZE_1MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_LOCK) +#define SDRAM_INON_CHBL (PAGE_SIZE_4MB | CPLB_USER_RD | CPLB_VALID) + +#define ANOMALY_05000158 0x200 +#define SDRAM_DGENERIC (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_SUPV_WR | CPLB_USER_RD | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158) +#define SDRAM_DNON_CHBL (PAGE_SIZE_4MB | CPLB_WT | CPLB_L1_AOW | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158) +#define SDRAM_DKERNEL (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_USER_RD | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_VALID | CPLB_LOCK | ANOMALY_05000158) +#define L1_DMEMORY (PAGE_SIZE_4KB | CPLB_L1_CHBL | CPLB_L1_AOW | CPLB_WT | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158) +#define SDRAM_EBIU (PAGE_SIZE_4MB | CPLB_WT | CPLB_L1_AOW | CPLB_USER_RD | CPLB_USER_WR | CPLB_SUPV_WR | CPLB_VALID | ANOMALY_05000158) + +static unsigned int icplb_table[16][2]={ + {0xFFA00000, L1_IMEMORY}, + {0x00000000, SDRAM_IKERNEL}, /*SDRAM_Page1*/ + {0x00400000, SDRAM_IKERNEL}, /*SDRAM_Page1*/ + {0x07C00000, SDRAM_IKERNEL}, /*SDRAM_Page14*/ + {0x00800000, SDRAM_IGENERIC}, /*SDRAM_Page2*/ + {0x00C00000, SDRAM_IGENERIC}, /*SDRAM_Page2*/ + {0x01000000, SDRAM_IGENERIC}, /*SDRAM_Page4*/ + {0x01400000, SDRAM_IGENERIC}, /*SDRAM_Page5*/ + {0x01800000, SDRAM_IGENERIC}, /*SDRAM_Page6*/ + {0x01C00000, SDRAM_IGENERIC}, /*SDRAM_Page7*/ + {0x02000000, SDRAM_IGENERIC}, /*SDRAM_Page8*/ + {0x02400000, SDRAM_IGENERIC}, /*SDRAM_Page9*/ + {0x02800000, SDRAM_IGENERIC}, /*SDRAM_Page10*/ + {0x02C00000, SDRAM_IGENERIC}, /*SDRAM_Page11*/ + {0x03000000, SDRAM_IGENERIC}, /*SDRAM_Page12*/ + {0x03400000, SDRAM_IGENERIC}, /*SDRAM_Page13*/ +}; + +static unsigned int dcplb_table[16][2]={ + {0xFFA00000,L1_DMEMORY}, + {0x00000000,SDRAM_DKERNEL}, /*SDRAM_Page1*/ + {0x00400000,SDRAM_DKERNEL}, /*SDRAM_Page1*/ + {0x07C00000,SDRAM_DKERNEL}, /*SDRAM_Page15*/ + {0x00800000,SDRAM_DGENERIC}, /*SDRAM_Page2*/ + {0x00C00000,SDRAM_DGENERIC}, /*SDRAM_Page3*/ + {0x01000000,SDRAM_DGENERIC}, /*SDRAM_Page4*/ + {0x01400000,SDRAM_DGENERIC}, /*SDRAM_Page5*/ + {0x01800000,SDRAM_DGENERIC}, /*SDRAM_Page6*/ + {0x01C00000,SDRAM_DGENERIC}, /*SDRAM_Page7*/ + {0x02000000,SDRAM_DGENERIC}, /*SDRAM_Page8*/ + {0x02400000,SDRAM_DGENERIC}, /*SDRAM_Page9*/ + {0x02800000,SDRAM_DGENERIC}, /*SDRAM_Page10*/ + {0x02C00000,SDRAM_DGENERIC}, /*SDRAM_Page11*/ + {0x03000000,SDRAM_DGENERIC}, /*SDRAM_Page12*/ + {0x20000000,SDRAM_EBIU}, /*For Network */ +}; + + + + + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + __asm__ __volatile__ + ("cli r3;" + "P0 = %0;" + "JUMP (P0);" + : + : "r" (L1_ISRAM) + ); + + return 0; +} + +/* These functions are just used to satisfy the linker */ +int cpu_init(void) +{ + return 0; +} + +int cleanup_before_linux(void) +{ + return 0; +} + +void icache_enable(void) +{ + unsigned int *I0,*I1; + int i; + + I0 = (unsigned int *)ICPLB_ADDR0; + I1 = (unsigned int *)ICPLB_DATA0; + + for(i=0;i<16;i++){ + *I0++ = icplb_table[i][0]; + *I1++ = icplb_table[i][1]; + } + cli(); + SSYNC(); + *(unsigned int *)IMEM_CONTROL = IMC | ENICPLB; + SSYNC(); + sti(); +} + +void icache_disable(void) +{ + cli(); + SSYNC(); + *(unsigned int *)IMEM_CONTROL &= ~(IMC | ENICPLB); + SSYNC(); + sti(); +} + +int icache_status(void) +{ + unsigned int value; + value = *(unsigned int *)IMEM_CONTROL; + + if( value & (IMC|ENICPLB) ) + return CACHE_ON; + else + return CACHE_OFF; +} + +void dcache_enable(void) +{ + unsigned int *I0,*I1; + unsigned int temp; + int i; + I0 = (unsigned int *)DCPLB_ADDR0; + I1 = (unsigned int *)DCPLB_DATA0; + + for(i=0;i<16;i++){ + *I0++ = dcplb_table[i][0]; + *I1++ = dcplb_table[i][1]; + } + cli(); + temp = *(unsigned int *)DMEM_CONTROL; + SSYNC(); + *(unsigned int *)DMEM_CONTROL = ACACHE_BCACHE |ENDCPLB |PORT_PREF0|temp; + SSYNC(); + sti(); +} + + +void dcache_disable(void) +{ + cli(); + SSYNC(); + *(unsigned int *)DMEM_CONTROL &= ~(ACACHE_BCACHE |ENDCPLB |PORT_PREF0); + SSYNC(); + sti(); +} + +int dcache_status(void) +{ + unsigned int value; + value = *(unsigned int *)DMEM_CONTROL; + if( value & (ENDCPLB)) + return CACHE_ON; + else + return CACHE_OFF; +} diff --git a/cpu/bf533/cpu.h b/cpu/bf533/cpu.h new file mode 100644 index 0000000000..7ec33878ea --- /dev/null +++ b/cpu/bf533/cpu.h @@ -0,0 +1,65 @@ +/* + * U-boot - cpu.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _CPU_H_ +#define _CPU_H_ + +#include + +#define INTERNAL_IRQS (32) +#define NUM_IRQ_NODES 16 +#define DEF_INTERRUPT_FLAGS 1 +#define MAX_TIM_LOAD 0xFFFFFFFF + +void blackfin_irq_panic(int reason, struct pt_regs * reg); +extern void dump(struct pt_regs * regs); +void display_excp(void); +asmlinkage void evt_nmi(void); +asmlinkage void evt_exception(void); +asmlinkage void trap(void); +asmlinkage void evt_ivhw(void); +asmlinkage void evt_rst(void); +asmlinkage void evt_timer(void); +asmlinkage void evt_evt7(void); +asmlinkage void evt_evt8(void); +asmlinkage void evt_evt9(void); +asmlinkage void evt_evt10(void); +asmlinkage void evt_evt11(void); +asmlinkage void evt_evt12(void); +asmlinkage void evt_evt13(void); +asmlinkage void evt_soft_int1(void); +asmlinkage void evt_system_call(void); +void blackfin_irq_panic(int reason, struct pt_regs * regs); +void blackfin_free_irq(unsigned int irq, void *dev_id); +void call_isr(int irq, struct pt_regs * fp); +void blackfin_do_irq(int vec, struct pt_regs *fp); +void blackfin_init_IRQ(void); +void blackfin_enable_irq(unsigned int irq); +void blackfin_disable_irq(unsigned int irq); +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +int blackfin_request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags,const char *devname,void *dev_id); +void timer_init(void); +#endif diff --git a/cpu/bf533/flush.S b/cpu/bf533/flush.S new file mode 100644 index 0000000000..1f9ec9899e --- /dev/null +++ b/cpu/bf533/flush.S @@ -0,0 +1,402 @@ +/* Copyright (C) 2003 Analog Devices, Inc. All Rights Reserved. + * Copyright (C) 2004 LG SOft India. All Rights Reserved. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. + * + * Blackfin BF533/2.6 support : LG Soft India + */ +#define ASSEMBLY + +#include +#include +#include + +.text + +/* This is an external function being called by the user + * application through __flush_cache_all. Currently this function + * serves the purpose of flushing all the pending writes in + * in the instruction cache. + */ + +ENTRY(flush_instruction_cache) + [--SP] = ( R7:6, P5:4 ); + LINK 12; + SP += -12; + P5.H = (ICPLB_ADDR0 >> 16); + P5.L = (ICPLB_ADDR0 & 0xFFFF); + P4.H = (ICPLB_DATA0 >> 16); + P4.L = (ICPLB_DATA0 & 0xFFFF); + R7 = CPLB_VALID | CPLB_L1_CHBL; + R6 = 16; +inext: R0 = [P5++]; + R1 = [P4++]; + [--SP] = RETS; + CALL icplb_flush; /* R0 = page, R1 = data*/ + RETS = [SP++]; +iskip: R6 += -1; + CC = R6; + IF CC JUMP inext; + SSYNC; + SP += 12; + UNLINK; + ( R7:6, P5:4 ) = [SP++]; + RTS; + +/* This is an internal function to flush all pending + * writes in the cache associated with a particular ICPLB. + * + * R0 - page's start address + * R1 - CPLB's data field. + */ + +.align 2 +ENTRY(icplb_flush) + [--SP] = ( R7:0, P5:0 ); + [--SP] = LC0; + [--SP] = LT0; + [--SP] = LB0; + [--SP] = LC1; + [--SP] = LT1; + [--SP] = LB1; + + /* If it's a 1K or 4K page, then it's quickest to + * just systematically flush all the addresses in + * the page, regardless of whether they're in the + * cache, or dirty. If it's a 1M or 4M page, there + * are too many addresses, and we have to search the + * cache for lines corresponding to the page. + */ + + CC = BITTST(R1, 17); /* 1MB or 4MB */ + IF !CC JUMP iflush_whole_page; + + /* We're only interested in the page's size, so extract + * this from the CPLB (bits 17:16), and scale to give an + * offset into the page_size and page_prefix tables. + */ + + R1 <<= 14; + R1 >>= 30; + R1 <<= 2; + + /* We can also determine the sub-bank used, because this is + * taken from bits 13:12 of the address. + */ + + R3 = ((12<<8)|2); /* Extraction pattern */ + nop; /*Anamoly 05000209*/ + R4 = EXTRACT(R0, R3.L) (Z); /* Extract bits*/ + R3.H = R4.L << 0 ; /* Save in extraction pattern for later deposit.*/ + + + /* So: + * R0 = Page start + * R1 = Page length (actually, offset into size/prefix tables) + * R3 = sub-bank deposit values + * + * The cache has 2 Ways, and 64 sets, so we iterate through + * the sets, accessing the tag for each Way, for our Bank and + * sub-bank, looking for dirty, valid tags that match our + * address prefix. + */ + + P5.L = (ITEST_COMMAND & 0xFFFF); + P5.H = (ITEST_COMMAND >> 16); + P4.L = (ITEST_DATA0 & 0xFFFF); + P4.H = (ITEST_DATA0 >> 16); + + P0.L = page_prefix_table; + P0.H = page_prefix_table; + P1 = R1; + R5 = 0; /* Set counter*/ + P0 = P1 + P0; + R4 = [P0]; /* This is the address prefix*/ + + /* We're reading (bit 1==0) the tag (bit 2==0), and we + * don't care about which double-word, since we're only + * fetching tags, so we only have to set Set, Bank, + * Sub-bank and Way. + */ + + P2 = 4; + LSETUP (ifs1, ife1) LC1 = P2; +ifs1: P0 = 32; /* iterate over all sets*/ + LSETUP (ifs0, ife0) LC0 = P0; +ifs0: R6 = R5 << 5; /* Combine set*/ + R6.H = R3.H << 0 ; /* and sub-bank*/ + [P5] = R6; /* Issue Command*/ + SSYNC; /* CSYNC will not work here :(*/ + R7 = [P4]; /* and read Tag.*/ + CC = BITTST(R7, 0); /* Check if valid*/ + IF !CC JUMP ifskip; /* and skip if not.*/ + + /* Compare against the page address. First, plant bits 13:12 + * into the tag, since those aren't part of the returned data. + */ + + R7 = DEPOSIT(R7, R3); /* set 13:12*/ + R1 = R7 & R4; /* Mask off lower bits*/ + CC = R1 == R0; /* Compare against page start.*/ + IF !CC JUMP ifskip; /* Skip it if it doesn't match.*/ + + /* Tag address matches against page, so this is an entry + * we must flush. + */ + + R7 >>= 10; /* Mask off the non-address bits*/ + R7 <<= 10; + P3 = R7; + IFLUSH [P3]; /* And flush the entry*/ +ifskip: +ife0: R5 += 1; /* Advance to next Set*/ +ife1: NOP; + +ifinished: + SSYNC; /* Ensure the data gets out to mem.*/ + + /*Finished. Restore context.*/ + LB1 = [SP++]; + LT1 = [SP++]; + LC1 = [SP++]; + LB0 = [SP++]; + LT0 = [SP++]; + LC0 = [SP++]; + ( R7:0, P5:0 ) = [SP++]; + RTS; + +iflush_whole_page: + /* It's a 1K or 4K page, so quicker to just flush the + * entire page. + */ + + P1 = 32; /* For 1K pages*/ + P2 = P1 << 2; /* For 4K pages*/ + P0 = R0; /* Start of page*/ + CC = BITTST(R1, 16); /* Whether 1K or 4K*/ + IF CC P1 = P2; + P1 += -1; /* Unroll one iteration*/ + SSYNC; + IFLUSH [P0++]; /* because CSYNC can't end loops.*/ + LSETUP (isall, ieall) LC0 = P1; +isall:IFLUSH [P0++]; +ieall: NOP; + SSYNC; + JUMP ifinished; + +/* This is an external function being called by the user + * application through __flush_cache_all. Currently this function + * serves the purpose of flushing all the pending writes in + * in the data cache. + */ + +ENTRY(flush_data_cache) + [--SP] = ( R7:6, P5:4 ); + LINK 12; + SP += -12; + P5.H = (DCPLB_ADDR0 >> 16); + P5.L = (DCPLB_ADDR0 & 0xFFFF); + P4.H = (DCPLB_DATA0 >> 16); + P4.L = (DCPLB_DATA0 & 0xFFFF); + R7 = CPLB_VALID | CPLB_L1_CHBL | CPLB_DIRTY (Z); + R6 = 16; +next: R0 = [P5++]; + R1 = [P4++]; + CC = BITTST(R1, 14); /* Is it write-through?*/ + IF CC JUMP skip; /* If so, ignore it.*/ + R2 = R1 & R7; /* Is it a dirty, cached page?*/ + CC = R2; + IF !CC JUMP skip; /* If not, ignore it.*/ + [--SP] = RETS; + CALL dcplb_flush; /* R0 = page, R1 = data*/ + RETS = [SP++]; +skip: R6 += -1; + CC = R6; + IF CC JUMP next; + SSYNC; + SP += 12; + UNLINK; + ( R7:6, P5:4 ) = [SP++]; + RTS; + +/* This is an internal function to flush all pending + * writes in the cache associated with a particular DCPLB. + * + * R0 - page's start address + * R1 - CPLB's data field. + */ + +.align 2 +ENTRY(dcplb_flush) + [--SP] = ( R7:0, P5:0 ); + [--SP] = LC0; + [--SP] = LT0; + [--SP] = LB0; + [--SP] = LC1; + [--SP] = LT1; + [--SP] = LB1; + + /* If it's a 1K or 4K page, then it's quickest to + * just systematically flush all the addresses in + * the page, regardless of whether they're in the + * cache, or dirty. If it's a 1M or 4M page, there + * are too many addresses, and we have to search the + * cache for lines corresponding to the page. + */ + + CC = BITTST(R1, 17); /* 1MB or 4MB */ + IF !CC JUMP dflush_whole_page; + + /* We're only interested in the page's size, so extract + * this from the CPLB (bits 17:16), and scale to give an + * offset into the page_size and page_prefix tables. + */ + + R1 <<= 14; + R1 >>= 30; + R1 <<= 2; + + /* The page could be mapped into Bank A or Bank B, depending + * on (a) whether both banks are configured as cache, and + * (b) on whether address bit A[x] is set. x is determined + * by DCBS in DMEM_CONTROL + */ + + R2 = 0; /* Default to Bank A (Bank B would be 1)*/ + + P0.L = (DMEM_CONTROL & 0xFFFF); + P0.H = (DMEM_CONTROL >> 16); + + R3 = [P0]; /* If Bank B is not enabled as cache*/ + CC = BITTST(R3, 2); /* then Bank A is our only option.*/ + IF CC JUMP bank_chosen; + + R4 = 1<<14; /* If DCBS==0, use A[14].*/ + R5 = R4 << 7; /* If DCBS==1, use A[23];*/ + CC = BITTST(R3, 4); + IF CC R4 = R5; /* R4 now has either bit 14 or bit 23 set.*/ + R5 = R0 & R4; /* Use it to test the Page address*/ + CC = R5; /* and if that bit is set, we use Bank B,*/ + R2 = CC; /* else we use Bank A.*/ + R2 <<= 23; /* The Bank selection's at posn 23.*/ + +bank_chosen: + + /* We can also determine the sub-bank used, because this is + * taken from bits 13:12 of the address. + */ + + R3 = ((12<<8)|2); /* Extraction pattern */ + nop; /*Anamoly 05000209*/ + R4 = EXTRACT(R0, R3.L) (Z); /* Extract bits*/ + R3.H = R4.L << 0 ; /* Save in extraction pattern for later deposit.*/ + + /* So: + * R0 = Page start + * R1 = Page length (actually, offset into size/prefix tables) + * R2 = Bank select mask + * R3 = sub-bank deposit values + * + * The cache has 2 Ways, and 64 sets, so we iterate through + * the sets, accessing the tag for each Way, for our Bank and + * sub-bank, looking for dirty, valid tags that match our + * address prefix. + */ + + P5.L = (DTEST_COMMAND & 0xFFFF); + P5.H = (DTEST_COMMAND >> 16); + P4.L = (DTEST_DATA0 & 0xFFFF); + P4.H = (DTEST_DATA0 >> 16); + + P0.L = page_prefix_table; + P0.H = page_prefix_table; + P1 = R1; + R5 = 0; /* Set counter*/ + P0 = P1 + P0; + R4 = [P0]; /* This is the address prefix*/ + + + /* We're reading (bit 1==0) the tag (bit 2==0), and we + * don't care about which double-word, since we're only + * fetching tags, so we only have to set Set, Bank, + * Sub-bank and Way. + */ + + P2 = 2; + LSETUP (fs1, fe1) LC1 = P2; +fs1: P0 = 64; /* iterate over all sets*/ + LSETUP (fs0, fe0) LC0 = P0; +fs0: R6 = R5 << 5; /* Combine set*/ + R6.H = R3.H << 0 ; /* and sub-bank*/ + R6 = R6 | R2; /* and Bank. Leave Way==0 at first.*/ + BITSET(R6,14); + [P5] = R6; /* Issue Command*/ + SSYNC; + R7 = [P4]; /* and read Tag.*/ + CC = BITTST(R7, 0); /* Check if valid*/ + IF !CC JUMP fskip; /* and skip if not.*/ + CC = BITTST(R7, 1); /* Check if dirty*/ + IF !CC JUMP fskip; /* and skip if not.*/ + + /* Compare against the page address. First, plant bits 13:12 + * into the tag, since those aren't part of the returned data. + */ + + R7 = DEPOSIT(R7, R3); /* set 13:12*/ + R1 = R7 & R4; /* Mask off lower bits*/ + CC = R1 == R0; /* Compare against page start.*/ + IF !CC JUMP fskip; /* Skip it if it doesn't match.*/ + + /* Tag address matches against page, so this is an entry + * we must flush. + */ + + R7 >>= 10; /* Mask off the non-address bits*/ + R7 <<= 10; + P3 = R7; + SSYNC; + FLUSHINV [P3]; /* And flush the entry*/ +fskip: +fe0: R5 += 1; /* Advance to next Set*/ +fe1: BITSET(R2, 26); /* Go to next Way.*/ + +dfinished: + SSYNC; /* Ensure the data gets out to mem.*/ + + /*Finished. Restore context.*/ + LB1 = [SP++]; + LT1 = [SP++]; + LC1 = [SP++]; + LB0 = [SP++]; + LT0 = [SP++]; + LC0 = [SP++]; + ( R7:0, P5:0 ) = [SP++]; + RTS; + +dflush_whole_page: + + /* It's a 1K or 4K page, so quicker to just flush the + * entire page. + */ + + P1 = 32; /* For 1K pages*/ + P2 = P1 << 2; /* For 4K pages*/ + P0 = R0; /* Start of page*/ + CC = BITTST(R1, 16); /* Whether 1K or 4K*/ + IF CC P1 = P2; + P1 += -1; /* Unroll one iteration*/ + SSYNC; + FLUSHINV [P0++]; /* because CSYNC can't end loops.*/ + LSETUP (eall, eall) LC0 = P1; +eall: FLUSHINV [P0++]; + SSYNC; + JUMP dfinished; + +.align 4; +page_prefix_table: +.byte4 0xFFFFFC00; /* 1K */ +.byte4 0xFFFFF000; /* 4K */ +.byte4 0xFFF00000; /* 1M */ +.byte4 0xFFC00000; /* 4M */ +.page_prefix_table.end: diff --git a/cpu/bf533/interrupt.S b/cpu/bf533/interrupt.S new file mode 100644 index 0000000000..b4d2579c44 --- /dev/null +++ b/cpu/bf533/interrupt.S @@ -0,0 +1,391 @@ +/* + * U-boot - interrupt.S Processing of interrupts and exception handling + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * This file is based on interrupt.S + * + * Copyright (C) 2003 Metrowerks, Inc. + * Copyright (C) 2002 Arcturus Networks Ltd. Ted Ma + * Copyright (C) 1998 D. Jeff Dionne , + * Kenneth Albanowski , + * The Silver Hammer Group, Ltd. + * + * (c) 1995, Dionne & Associates + * (c) 1995, DKG Display Tech. + * + * This file is also based on exception.asm + * (C) Copyright 2001-2005 - Analog Devices, Inc. All rights reserved. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#define ASSEMBLY + +#include +#include +#include +#include + +.global blackfin_irq_panic; + +.text +.align 2 + +#ifndef CONFIG_KGDB +.global evt_emulation +evt_emulation: + SAVE_CONTEXT + r0 = IRQ_EMU; + r1 = seqstat; + sp += -12; + call blackfin_irq_panic; + sp += 12; + rte; +#endif + +.global evt_nmi +evt_nmi: + SAVE_CONTEXT + r0 = IRQ_NMI; + r1 = RETN; + sp += -12; + call blackfin_irq_panic; + sp += 12; + +_evt_nmi_exit: + rtn; + +.global trap +trap: + [--sp] = r0; + [--sp] = r1; + [--sp] = p0; + [--sp] = p1; + [--sp] = astat; + r0 = seqstat; + R0 <<= 26; + R0 >>= 26; + p0 = r0; + p1.l = EVTABLE; + p1.h = EVTABLE; + p0 = p1 + (p0 << 1); + r1 = W[p0] (Z); + p1 = r1; + jump (pc + p1); + +.global _EVENT1 +_EVENT1: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT2 +_EVENT2: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT3 +_EVENT3: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT4 +_EVENT4: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT5 +_EVENT5: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT6 +_EVENT6: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT7 +_EVENT7: + RAISE 15; + JUMP.S _EXIT; + +.global _EVENT8 +_EVENT8: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT9 +_EVENT9: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT10 +_EVENT10: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT11 +_EVENT11: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT12 +_EVENT12: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT13 +_EVENT13: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT14 +_EVENT14: +/* RAISE 14; */ + CALL _cplb_hdr; + JUMP.S _EXIT; + +.global _EVENT19 +_EVENT19: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT20 +_EVENT20: + RAISE 14; + JUMP.S _EXIT; + +.global _EVENT21 +_EVENT21: + RAISE 14; + JUMP.S _EXIT; + +.global _EXIT +_EXIT: + ASTAT = [sp++]; + p1 = [sp++]; + p0 = [sp++]; + r1 = [sp++]; + r0 = [sp++]; + RTX; + +EVTABLE: + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x0000; + .byte2 0x003E; + .byte2 0x0042; + .byte4 0x0000; + .byte4 0x0000; + .byte4 0x0000; + .byte4 0x0000; + .byte4 0x0000; + .byte4 0x0000; + .byte4 0x0000; + .byte2 0x0000; + .byte2 0x001E; + .byte2 0x0022; + .byte2 0x0032; + .byte2 0x002e; + .byte2 0x0002; + .byte2 0x0036; + .byte2 0x002A; + .byte2 0x001A; + .byte2 0x0016; + .byte2 0x000A; + .byte2 0x000E; + .byte2 0x0012; + .byte2 0x0006; + .byte2 0x0026; + +.global evt_rst +evt_rst: + SAVE_CONTEXT + r0 = IRQ_RST; + r1 = RETN; + sp += -12; + call do_reset; + sp += 12; + +_evt_rst_exit: + rtn; + +irq_panic: + r0 = IRQ_EVX; + r1 = sp; + sp += -12; + call blackfin_irq_panic; + sp += 12; + +.global evt_ivhw +evt_ivhw: + SAVE_CONTEXT + RAISE 14; + +_evt_ivhw_exit: + rti; + +.global evt_timer +evt_timer: + SAVE_CONTEXT + r0 = IRQ_CORETMR; + sp += -12; + /* Polling method used now. */ + /* call timer_int; */ + sp += 12; + RESTORE_CONTEXT + rti; + nop; + +.global evt_evt7 +evt_evt7: + SAVE_CONTEXT + r0 = 7; + sp += -12; + call process_int; + sp += 12; + +evt_evt7_exit: + RESTORE_CONTEXT + rti; + +.global evt_evt8 +evt_evt8: + SAVE_CONTEXT + r0 = 8; + sp += -12; + call process_int; + sp += 12; + +evt_evt8_exit: + RESTORE_CONTEXT + rti; + +.global evt_evt9 +evt_evt9: + SAVE_CONTEXT + r0 = 9; + sp += -12; + call process_int; + sp += 12; + +evt_evt9_exit: + RESTORE_CONTEXT + rti; + +.global evt_evt10 +evt_evt10: + SAVE_CONTEXT + r0 = 10; + sp += -12; + call process_int; + sp += 12; + +evt_evt10_exit: + RESTORE_CONTEXT + rti; + +.global evt_evt11 +evt_evt11: + SAVE_CONTEXT + r0 = 11; + sp += -12; + call process_int; + sp += 12; + +evt_evt11_exit: + RESTORE_CONTEXT + rti; + +.global evt_evt12 +evt_evt12: + SAVE_CONTEXT + r0 = 12; + sp += -12; + call process_int; + sp += 12; +evt_evt12_exit: + RESTORE_CONTEXT + rti; + +.global evt_evt13 +evt_evt13: + SAVE_CONTEXT + r0 = 13; + sp += -12; + call process_int; + sp += 12; + +evt_evt13_exit: + RESTORE_CONTEXT + rti; + +.global evt_system_call +evt_system_call: + [--sp] = r0; + [--SP] = RETI; + r0 = [sp++]; + r0 += 2; + [--sp] = r0; + RETI = [SP++]; + r0 = [SP++]; + SAVE_CONTEXT + sp += -12; + call display_excp; + sp += 12; + RESTORE_CONTEXT + RTI; + +evt_system_call_exit: + rti; + +.global evt_soft_int1 +evt_soft_int1: + [--sp] = r0; + [--SP] = RETI; + r0 = [sp++]; + r0 += 2; + [--sp] = r0; + RETI = [SP++]; + r0 = [SP++]; + SAVE_CONTEXT + sp += -12; + call display_excp; + sp += 12; + RESTORE_CONTEXT + RTI; + +evt_soft_int1_exit: + rti; diff --git a/cpu/bf533/interrupts.c b/cpu/bf533/interrupts.c new file mode 100644 index 0000000000..df1a25ec75 --- /dev/null +++ b/cpu/bf533/interrupts.c @@ -0,0 +1,165 @@ +/* + * U-boot - interrupts.c Interrupt related routines + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on interrupts.c + * Copyright 1996 Roman Zippel + * Copyright 1999 D. Jeff Dionne + * Copyright 2000-2001 Lineo, Inc. D. Jefff Dionne + * Copyright 2002 Arcturus Networks Inc. MaTed + * Copyright 2003 Metrowerks/Motorola + * Copyright 2003 Bas Vermeulen , + * BuyWays B.V. (www.buyways.nl) + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include "cpu.h" + +static ulong timestamp; +static ulong last_time; +static int int_flag; + +int irq_flags; /* needed by asm-blackfin/system.h */ + +/* Functions just to satisfy the linker */ + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On BF533 it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On BF533 it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CFG_HZ; + return tbclk; +} + +void enable_interrupts(void) +{ + restore_flags(int_flag); +} + +int disable_interrupts(void) +{ + save_and_cli(int_flag); + return 1; +} + +int interrupt_init(void) +{ + return (0); +} + +void udelay(unsigned long usec) +{ + unsigned long delay, start, stop; + unsigned long cclk; + cclk = (CONFIG_CCLK_HZ); + + while ( usec > 1 ) { + /* + * how many clock ticks to delay? + * - request(in useconds) * clock_ticks(Hz) / useconds/second + */ + if (usec < 1000) { + delay = (usec * (cclk/244)) >> 12 ; + usec = 0; + } else { + delay = (1000 * (cclk/244)) >> 12 ; + usec -= 1000; + } + + asm volatile (" %0 = CYCLES;": "=g"(start)); + do { + asm volatile (" %0 = CYCLES; ": "=g"(stop)); + } while (stop - start < delay); + } + + return; +} + +void timer_init(void) +{ + *pTCNTL = 0x1; + *pTSCALE = 0x0; + *pTCOUNT = MAX_TIM_LOAD; + *pTPERIOD = MAX_TIM_LOAD; + *pTCNTL = 0x7; + asm("CSYNC;"); + + timestamp = 0; + last_time = 0; +} + +/* Any network command or flash + * command is started get_timer shall + * be called before TCOUNT gets reset, + * to implement the accurate timeouts. + * + * How ever milliconds doesn't return + * the number that has been elapsed from + * the last reset. + * + * As get_timer is used in the u-boot + * only for timeouts this should be + * sufficient + */ +ulong get_timer(ulong base) +{ + ulong milisec; + + /* Number of clocks elapsed */ + ulong clocks = (MAX_TIM_LOAD - (*pTCOUNT)); + + /* Find if the TCOUNT is reset + timestamp gives the number of times + TCOUNT got reset */ + if(clocks < last_time) + timestamp++; + last_time = clocks; + + /* Get the number of milliseconds */ + milisec = clocks/(CONFIG_CCLK_HZ / 1000); + + /* Find the number of millisonds + that got elapsed before this TCOUNT + cycle */ + milisec += timestamp * (MAX_TIM_LOAD/(CONFIG_CCLK_HZ / 1000)); + + return (milisec - base); +} diff --git a/cpu/bf533/ints.c b/cpu/bf533/ints.c new file mode 100644 index 0000000000..859f4b2f09 --- /dev/null +++ b/cpu/bf533/ints.c @@ -0,0 +1,107 @@ +/* + * U-boot - ints.c Interrupt related routines + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on ints.c + * + * Apr18 2003, Changed by HuTao to support interrupt cascading for Blackfin + * drivers + * + * Copyright 1996 Roman Zippel + * Copyright 1999 D. Jeff Dionne + * Copyright 2000-2001 Lineo, Inc. D. Jefff Dionne + * Copyright 2002 Arcturus Networks Inc. MaTed + * Copyright 2003 Metrowerks/Motorola + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cpu.h" + +void blackfin_irq_panic(int reason, struct pt_regs *regs) +{ + printf("\n\nException: IRQ 0x%x entered\n", reason); + printf("code=[0x%x], ", (unsigned int) (regs->seqstat & 0x3f)); + printf("stack frame=0x%x, ", (unsigned int) regs); + printf("bad PC=0x%04x\n", (unsigned int) regs->pc); + dump(regs); + printf("Unhandled IRQ or exceptions!\n"); + printf("Please reset the board \n"); +} + +void blackfin_init_IRQ(void) +{ + *(unsigned volatile long *) (SIC_IMASK) = SIC_UNMASK_ALL; + cli(); +#ifndef CONFIG_KGDB + *(unsigned volatile long *) (EVT_EMULATION_ADDR) = 0x0; +#endif + *(unsigned volatile long *) (EVT_NMI_ADDR) = + (unsigned volatile long) evt_nmi; + *(unsigned volatile long *) (EVT_EXCEPTION_ADDR) = + (unsigned volatile long) trap; + *(unsigned volatile long *) (EVT_HARDWARE_ERROR_ADDR) = + (unsigned volatile long) evt_ivhw; + *(unsigned volatile long *) (EVT_RESET_ADDR) = + (unsigned volatile long) evt_rst; + *(unsigned volatile long *) (EVT_TIMER_ADDR) = + (unsigned volatile long) evt_timer; + *(unsigned volatile long *) (EVT_IVG7_ADDR) = + (unsigned volatile long) evt_evt7; + *(unsigned volatile long *) (EVT_IVG8_ADDR) = + (unsigned volatile long) evt_evt8; + *(unsigned volatile long *) (EVT_IVG9_ADDR) = + (unsigned volatile long) evt_evt9; + *(unsigned volatile long *) (EVT_IVG10_ADDR) = + (unsigned volatile long) evt_evt10; + *(unsigned volatile long *) (EVT_IVG11_ADDR) = + (unsigned volatile long) evt_evt11; + *(unsigned volatile long *) (EVT_IVG12_ADDR) = + (unsigned volatile long) evt_evt12; + *(unsigned volatile long *) (EVT_IVG13_ADDR) = + (unsigned volatile long) evt_evt13; + *(unsigned volatile long *) (EVT_IVG14_ADDR) = + (unsigned volatile long) evt_system_call; + *(unsigned volatile long *) (EVT_IVG15_ADDR) = + (unsigned volatile long) evt_soft_int1; + *(volatile unsigned long *) ILAT = 0; + asm("csync;"); + sti(); + *(volatile unsigned long *) IMASK = 0xffbf; + asm("csync;"); +} + +void display_excp(void) +{ + printf("Exception!\n"); +} diff --git a/cpu/bf533/serial.c b/cpu/bf533/serial.c new file mode 100644 index 0000000000..8f0cd1649d --- /dev/null +++ b/cpu/bf533/serial.c @@ -0,0 +1,194 @@ +/* + * U-boot - serial.c Serial driver for BF533 + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on + * bf533_serial.c: Serial driver for BlackFin BF533 DSP internal UART. + * Copyright (c) 2003 Bas Vermeulen , + * BuyWays B.V. (www.buyways.nl) + * + * Based heavily on blkfinserial.c + * blkfinserial.c: Serial driver for BlackFin DSP internal USRTs. + * Copyright(c) 2003 Metrowerks + * Copyright(c) 2001 Tony Z. Kou + * Copyright(c) 2001-2002 Arcturus Networks Inc. + * + * Based on code from 68328 version serial driver imlpementation which was: + * Copyright (C) 1995 David S. Miller + * Copyright (C) 1998 Kenneth Albanowski + * Copyright (C) 1998, 1999 D. Jeff Dionne + * Copyright (C) 1999 Vladimir Gurevich + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include "bf533_serial.h" + +unsigned long pll_div_fact; + +void calc_baud(void) +{ + unsigned char i; + int temp; + + for(i = 0; i < sizeof(baud_table)/sizeof(int); i++) { + temp = CONFIG_SCLK_HZ/(baud_table[i]*8); + if ( temp && 0x1 == 1 ) { + temp++; + } + temp = temp/2; + hw_baud_table[i].dl_high = (temp >> 8)& 0xFF; + hw_baud_table[i].dl_low = (temp) & 0xFF; + } +} + +void serial_setbrg(void) +{ + int i; + DECLARE_GLOBAL_DATA_PTR; + + calc_baud(); + + for (i = 0; i < sizeof(baud_table) / sizeof(int); i++) { + if (gd->baudrate == baud_table[i]) + break; + } + + /* Enable UART */ + *pUART_GCTL |= UART_GCTL_UCEN; + asm("ssync;"); + + /* Set DLAB in LCR to Access DLL and DLH */ + ACCESS_LATCH; + asm("ssync;"); + + *pUART_DLL = hw_baud_table[i].dl_low; + asm("ssync;"); + *pUART_DLH = hw_baud_table[i].dl_high; + asm("ssync;"); + + /* Clear DLAB in LCR to Access THR RBR IER */ + ACCESS_PORT_IER; + asm("ssync;"); + + /* Enable ERBFI and ELSI interrupts + * to poll SIC_ISR register*/ + *pUART_IER = UART_IER_ELSI | UART_IER_ERBFI | UART_IER_ETBEI; + asm("ssync;"); + + /* Set LCR to Word Lengh 8-bit word select */ + *pUART_LCR = UART_LCR_WLS8; + asm("ssync;"); + + return; +} + +int serial_init(void) +{ + serial_setbrg(); + return (0); +} + +void serial_putc(const char c) +{ + if ((*pUART_LSR) & UART_LSR_TEMT) + { + if (c == '\n') + serial_putc('\r'); + + local_put_char(c); + } + + while (!((*pUART_LSR) & UART_LSR_TEMT)) + SYNC_ALL; + + return; +} + +int serial_tstc(void) +{ + if (*pUART_LSR & UART_LSR_DR) + return 1; + else + return 0; +} + +int serial_getc(void) +{ + unsigned short uart_lsr_val, uart_rbr_val; + unsigned long isr_val; + int ret; + + /* Poll for RX Interrupt */ + while (!((isr_val = *(volatile unsigned long *)SIC_ISR) & IRQ_UART_RX_BIT)); + asm("csync;"); + + uart_lsr_val = *pUART_LSR; /* Clear status bit */ + uart_rbr_val = *pUART_RBR; /* getc() */ + + if (isr_val & IRQ_UART_ERROR_BIT) { + ret = -1; + } + else + { + ret = uart_rbr_val & 0xff; + } + + return ret; +} + +void serial_puts(const char *s) +{ + while (*s) { + serial_putc(*s++); + } +} + +static void local_put_char(char ch) +{ + int flags = 0; + unsigned long isr_val; + + save_and_cli(flags); + + /* Poll for TX Interruput */ + while (!((isr_val = *pSIC_ISR) & IRQ_UART_TX_BIT)); + asm("csync;"); + + *pUART_THR = ch; /* putc() */ + + if (isr_val & IRQ_UART_ERROR_BIT) { + printf("?"); + } + + restore_flags(flags); + + return ; +} diff --git a/cpu/bf533/start.S b/cpu/bf533/start.S new file mode 100644 index 0000000000..7414d8873d --- /dev/null +++ b/cpu/bf533/start.S @@ -0,0 +1,435 @@ +/* + * U-boot - start.S Startup file of u-boot for BF533 + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on head.S + * Copyright (c) 2003 Metrowerks/Motorola + * Copyright (C) 1998 D. Jeff Dionne , + * Kenneth Albanowski , + * The Silver Hammer Group, Ltd. + * (c) 1995, Dionne & Associates + * (c) 1995, DKG Display Tech. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Note: A change in this file subsequently requires a change in + * board/$(board_name)/config.mk for a valid u-boot.bin + */ + +#define ASSEMBLY + +#include +#include +#include +#include + +#if (CONFIG_CCLK_DIV == 1) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV1 +#endif +#if (CONFIG_CCLK_DIV == 2) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV2 +#endif +#if (CONFIG_CCLK_DIV == 4) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV4 +#endif +#if (CONFIG_CCLK_DIV == 8) +#define CONFIG_CCLK_ACT_DIV CCLK_DIV8 +#endif +#ifndef CONFIG_CCLK_ACT_DIV +#define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly +#endif + +.global _stext; +.global __bss_start; +.global start; +.global _start; +.global _rambase; +.global _ramstart; +.global _ramend; +.global _bf533_data_dest; +.global _bf533_data_size; +.global edata; +.global _initialize; +.global _exit; +.global flashdataend; + +.text +_start: +start: +_stext: + + R0 = 0x30; + SYSCFG = R0; + SSYNC; + + /* As per HW reference manual DAG registers, + * DATA and Address resgister shall be zero'd + * in initialization, after a reset state + */ + r1 = 0; /* Data registers zero'd */ + r2 = 0; + r3 = 0; + r4 = 0; + r5 = 0; + r6 = 0; + r7 = 0; + + p0 = 0; /* Address registers zero'd */ + p1 = 0; + p2 = 0; + p3 = 0; + p4 = 0; + p5 = 0; + + i0 = 0; /* DAG Registers zero'd */ + i1 = 0; + i2 = 0; + i3 = 0; + m0 = 0; + m1 = 0; + m3 = 0; + m3 = 0; + l0 = 0; + l1 = 0; + l2 = 0; + l3 = 0; + b0 = 0; + b1 = 0; + b2 = 0; + b3 = 0; + + /* Set loop counters to zero, to make sure that + * hw loops are disabled. + */ + lc0 = 0; + lc1 = 0; + + SSYNC; + + /* Check soft reset status */ + p0.h = SWRST >> 16; + p0.l = SWRST & 0xFFFF; + r0.l = w[p0]; + + cc = bittst(r0, 15); + if !cc jump no_soft_reset; + + /* Clear Soft reset */ + r0 = 0x0000; + w[p0] = r0; + ssync; + +no_soft_reset: + nop; + + /* Clear EVT registers */ + p0.h = (EVT_EMULATION_ADDR >> 16); + p0.l = (EVT_EMULATION_ADDR & 0xFFFF); + p0 += 8; + p1 = 14; + r1 = 0; + LSETUP(4,4) lc0 = p1; + [ p0 ++ ] = r1; + + /* + * Set PLL_CTL + * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors + * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK + * - [7] = output delay (add 200ps of delay to mem signals) + * - [6] = input delay (add 200ps of input delay to mem signals) + * - [5] = PDWN : 1=All Clocks off + * - [3] = STOPCK : 1=Core Clock off + * - [1] = PLL_OFF : 1=Disable Power to PLL + * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL + * all other bits set to zero + */ + + r0 = CONFIG_VCO_MULT; /* Load the VCO multiplier */ + r0 = r0 << 9; /* Shift it over */ + r1 = CONFIG_CLKIN_HALF; /* Do we need to divide CLKIN by 2? */ + r0 = r1 | r0; + r1 = CONFIG_PLL_BYPASS; /* Bypass the PLL? */ + r1 = r1 << 8; /* Shift it over */ + r0 = r1 | r0; /* add them all together */ + + p0.h = (PLL_CTL >> 16); + p0.l = (PLL_CTL & 0xFFFF); /* Load the address */ + cli r2; /* Disable interrupts */ + w[p0] = r0; /* Set the value */ + idle; /* Wait for the PLL to stablize */ + sti r2; /* Enable interrupts */ + ssync; + + /* + * Turn on the CYCLES COUNTER + */ + r2 = SYSCFG; + BITSET (r2,1); + SYSCFG = r2; + + /* Configure SCLK & CCLK Dividers */ + r0 = CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV; + p0.h = (PLL_DIV >> 16); + p0.l = (PLL_DIV & 0xFFFF); + w[p0] = r0; + ssync; + +wait_for_pll_stab: + p0.h = (PLL_STAT >> 16); + p0.l = (PLL_STAT & 0xFFFF); + r0.l = w[p0]; + cc = bittst(r0,5); + if !cc jump wait_for_pll_stab; + + /* Configure SDRAM if SDRAM is already not enabled */ + p0.l = (EBIU_SDSTAT & 0xFFFF); + p0.h = (EBIU_SDSTAT >> 16); + r0.l = w[p0]; + cc = bittst(r0, 3); + if !cc jump skip_sdram_enable; + + /* SDRAM initialization */ + p0.l = (EBIU_SDGCTL & 0xFFFF); + p0.h = (EBIU_SDGCTL >> 16); /* SDRAM Memory Global Control Register */ + r0.h = (mem_SDGCTL >> 16); + r0.l = (mem_SDGCTL & 0xFFFF); + [p0] = r0; + ssync; + + p0.l = (EBIU_SDBCTL & 0xFFFF); + p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */ + r0 = mem_SDBCTL; + w[p0] = r0.l; + ssync; + + p0.l = (EBIU_SDRRC & 0xFFFF); + p0.h = (EBIU_SDRRC >> 16); /* SDRAM Refresh Rate Control Register */ + r0 = mem_SDRRC; + w[p0] = r0.l; + ssync; + +skip_sdram_enable: + nop; + +#ifndef CFG_NO_FLASH + /* relocate into to RAM */ + p1.l = (CFG_FLASH_BASE & 0xffff); + p1.h = (CFG_FLASH_BASE >> 16); + p2.l = (CFG_MONITOR_BASE & 0xffff); + p2.h = (CFG_MONITOR_BASE >> 16); + r0.l = (CFG_MONITOR_LEN & 0xffff); + r0.h = (CFG_MONITOR_LEN >> 16); +loop1: + r1 = [p1]; + [p2] = r1; + p3=0x4; + p1=p1+p3; + p2=p2+p3; + r2=0x4; + r0=r0-r2; + cc=r0==0x0; + if !cc jump loop1; +#endif + /* + * configure STACK + */ + r0.h = (CONFIG_STACKBASE >> 16); + r0.l = (CONFIG_STACKBASE & 0xFFFF); + sp = r0; + fp = sp; + + /* + * This next section keeps the processor in supervisor mode + * during kernel boot. Switches to user mode at end of boot. + * See page 3-9 of Hardware Reference manual for documentation. + */ + + /* To keep ourselves in the supervisor mode */ + p0.l = (EVT_IVG15_ADDR & 0xFFFF); + p0.h = (EVT_IVG15_ADDR >> 16); + + p1.l = _real_start; + p1.h = _real_start; + [p0] = p1; + + p0.l = (IMASK & 0xFFFF); + p0.h = (IMASK >> 16); + r0 = IVG15_POS; + [p0] = r0; + raise 15; + p0.l = WAIT_HERE; + p0.h = WAIT_HERE; + reti = p0; + rti; + +WAIT_HERE: + jump WAIT_HERE; + +.global _real_start; +_real_start: + [ -- sp ] = reti; + +#ifdef CONFIG_EZKIT533 + p0.l = (WDOG_CTL & 0xFFFF); + p0.h = (WDOG_CTL >> 16); + r0 = WATCHDOG_DISABLE(z); + w[p0] = r0; +#endif + + /* Code for initializing Async mem banks */ + p2.h = (EBIU_AMBCTL1 >> 16); + p2.l = (EBIU_AMBCTL1 & 0xFFFF); + r0.h = (AMBCTL1VAL >> 16); + r0.l = (AMBCTL1VAL & 0xFFFF); + [p2] = r0; + ssync; + + p2.h = (EBIU_AMBCTL0 >> 16); + p2.l = (EBIU_AMBCTL0 & 0xFFFF); + r0.h = (AMBCTL0VAL >> 16); + r0.l = (AMBCTL0VAL & 0xFFFF); + [p2] = r0; + ssync; + + p2.h = (EBIU_AMGCTL >> 16); + p2.l = (EBIU_AMGCTL & 0xffff); + r0 = AMGCTLVAL; + w[p2] = r0; + ssync; + + /* DMA reset code to Hi of L1 SRAM */ +copy: + P1.H = hi(SYSMMR_BASE); /* P1 Points to the beginning of SYSTEM MMR Space */ + P1.L = lo(SYSMMR_BASE); + + R0.H = reset_start; /* Source Address (high) */ + R0.L = reset_start; /* Source Address (low) */ + R1.H = reset_end; + R1.L = reset_end; + R2 = R1 - R0; /* Count */ + R1.H = hi(L1_ISRAM); /* Destination Address (high) */ + R1.L = lo(L1_ISRAM); /* Destination Address (low) */ + R3.L = DMAEN; /* Source DMAConfig Value (8-bit words) */ + R4.L = (DI_EN | WNR | DMAEN); /* Destination DMAConfig Value (8-bit words) */ + +DMA: + R6 = 0x1 (Z); + W[P1+OFFSET_(MDMA_S0_X_MODIFY)] = R6; /* Source Modify = 1 */ + W[P1+OFFSET_(MDMA_D0_X_MODIFY)] = R6; /* Destination Modify = 1 */ + + [P1+OFFSET_(MDMA_S0_START_ADDR)] = R0; /* Set Source Base Address */ + W[P1+OFFSET_(MDMA_S0_X_COUNT)] = R2; /* Set Source Count */ + /* Set Source DMAConfig = DMA Enable, + Memory Read, 8-Bit Transfers, 1-D DMA, Flow - Stop */ + W[P1+OFFSET_(MDMA_S0_CONFIG)] = R3; + + [P1+OFFSET_(MDMA_D0_START_ADDR)] = R1; /* Set Destination Base Address */ + W[P1+OFFSET_(MDMA_D0_X_COUNT)] = R2; /* Set Destination Count */ + /* Set Destination DMAConfig = DMA Enable, + Memory Write, 8-Bit Transfers, 1-D DMA, Flow - Stop, IOC */ + W[P1+OFFSET_(MDMA_D0_CONFIG)] = R4; + + IDLE; /* Wait for DMA to Complete */ + + R0 = 0x1; + W[P1+OFFSET_(MDMA_D0_IRQ_STATUS)] = R0; /* Write 1 to clear DMA interrupt */ + + /* DMA reset code to DATA BANK A which uses this port + * to avoid following problem + * " Data from a Data Cache fill can be corrupoted after or during + * instruction DMA if certain core stalls exist" + */ + +copy_as_data: + R0.H = reset_start; /* Source Address (high) */ + R0.L = reset_start; /* Source Address (low) */ + R1.H = reset_end; + R1.L = reset_end; + R2 = R1 - R0; /* Count */ + R1.H = hi(DATA_BANKA_SRAM); /* Destination Address (high) */ + R1.L = lo(DATA_BANKA_SRAM); /* Destination Address (low) */ + R3.L = DMAEN; /* Source DMAConfig Value (8-bit words) */ + R4.L = (DI_EN | WNR | DMAEN); /* Destination DMAConfig Value (8-bit words) */ + +DMA_DATA: + R6 = 0x1 (Z); + W[P1+OFFSET_(MDMA_S0_X_MODIFY)] = R6; /* Source Modify = 1 */ + W[P1+OFFSET_(MDMA_D0_X_MODIFY)] = R6; /* Destination Modify = 1 */ + + [P1+OFFSET_(MDMA_S0_START_ADDR)] = R0; /* Set Source Base Address */ + W[P1+OFFSET_(MDMA_S0_X_COUNT)] = R2; /* Set Source Count */ + /* Set Source DMAConfig = DMA Enable, + Memory Read, 8-Bit Transfers, 1-D DMA, Flow - Stop */ + W[P1+OFFSET_(MDMA_S0_CONFIG)] = R3; + + [P1+OFFSET_(MDMA_D0_START_ADDR)] = R1; /* Set Destination Base Address */ + W[P1+OFFSET_(MDMA_D0_X_COUNT)] = R2; /* Set Destination Count */ + /* Set Destination DMAConfig = DMA Enable, + Memory Write, 8-Bit Transfers, 1-D DMA, Flow - Stop, IOC */ + W[P1+OFFSET_(MDMA_D0_CONFIG)] = R4; + + IDLE; /* Wait for DMA to Complete */ + + R0 = 0x1; + W[P1+OFFSET_(MDMA_D0_IRQ_STATUS)] = R0; /* Write 1 to clear DMA interrupt */ + +copy_end: nop; + + /* Initialize BSS Section with 0 s */ + p1.l = __bss_start; + p1.h = __bss_start; + p2.l = _end; + p2.h = _end; + r1 = p1; + r2 = p2; + r3 = r2 - r1; + r3 = r3 >> 2; + p3 = r3; + lsetup (_clear_bss, _clear_bss_end ) lc1 = p3; + CC = p2<=p1; + if CC jump _clear_bss_skip; + r0 = 0; +_clear_bss: +_clear_bss_end: + [p1++] = r0; +_clear_bss_skip: + + p0.l = _start1; + p0.h = _start1; + jump (p0); + +reset_start: + p0.h = WDOG_CNT >> 16; + p0.l = WDOG_CNT & 0xffff; + r0 = 0x0010; + w[p0] = r0; + p0.h = WDOG_CTL >> 16; + p0.l = WDOG_CTL & 0xffff; + r0 = 0x0000; + w[p0] = r0; +reset_wait: + jump reset_wait; + +reset_end: nop; + +_exit: + jump.s _exit; diff --git a/cpu/bf533/start1.S b/cpu/bf533/start1.S new file mode 100644 index 0000000000..6f48124055 --- /dev/null +++ b/cpu/bf533/start1.S @@ -0,0 +1,38 @@ +/* + * U-boot - start1.S Code running out of RAM after relocation + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#define ASSEMBLY +#include +#include +#include + +.global start1; +.global _start1; + +.text +_start1: +start1: + sp += -12; + call board_init_f; + sp += 12; diff --git a/cpu/bf533/traps.c b/cpu/bf533/traps.c new file mode 100644 index 0000000000..37470d583e --- /dev/null +++ b/cpu/bf533/traps.c @@ -0,0 +1,73 @@ +/* + * U-boot - traps.c Routines related to interrupts and exceptions + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on + * No original Copyright holder listed, + * Probabily original (C) Roman Zippel (assigned DJD, 1999) + * + * Copyright 2003 Metrowerks - for Blackfin + * Copyright 2000-2001 Lineo, Inc. D. Jeff Dionne + * Copyright 1999-2000 D. Jeff Dionne, + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "cpu.h" + +void init_IRQ(void) +{ + blackfin_init_IRQ(); + return; +} + +void process_int(unsigned long vec, struct pt_regs *fp) +{ + return; +} + +void dump(struct pt_regs *fp) +{ + printf("PC: %08lx\n", fp->pc); + printf("SEQSTAT: %08lx SP: %08lx\n", (long) fp->seqstat, + (long) fp); + printf("R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n", + fp->r0, fp->r1, fp->r2, fp->r3); + printf("R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n", + fp->r4, fp->r5, fp->r6, fp->r7); + printf("P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n", + fp->p0, fp->p1, fp->p2, fp->p3); + printf("P4: %08lx P5: %08lx FP: %08lx\n", fp->p4, fp->p5, + fp->fp); + printf("A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", + fp->a0w, fp->a0x, fp->a1w, fp->a1x); + printf("\n"); +} diff --git a/include/asm-blackfin/bitops.h b/include/asm-blackfin/bitops.h new file mode 100644 index 0000000000..65d2c25345 --- /dev/null +++ b/include/asm-blackfin/bitops.h @@ -0,0 +1,380 @@ +/* + * U-boot - bitops.h Routines for bit operations + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_BITOPS_H +#define _BLACKFIN_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + */ + +#include +#include +#include + +#ifdef __KERNEL__ +/* + * Function prototypes to keep gcc -Wall happy + */ + +/* + * The __ functions are not atomic + */ + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +static __inline__ unsigned long ffz(unsigned long word) +{ + unsigned long result = 0; + + while (word & 1) { + result++; + word >>= 1; + } + return result; +} + +static __inline__ void set_bit(int nr, volatile void *addr) +{ + int *a = (int *) addr; + int mask; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + save_and_cli(flags); + *a |= mask; + restore_flags(flags); +} + +static __inline__ void __set_bit(int nr, volatile void *addr) +{ + int *a = (int *) addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + *a |= mask; +} + +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +static __inline__ void clear_bit(int nr, volatile void *addr) +{ + int *a = (int *) addr; + int mask; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + save_and_cli(flags); + *a &= ~mask; + restore_flags(flags); +} + +static __inline__ void change_bit(int nr, volatile void *addr) +{ + int mask, flags; + unsigned long *ADDR = (unsigned long *) addr; + + ADDR += nr >> 5; + mask = 1 << (nr & 31); + save_and_cli(flags); + *ADDR ^= mask; + restore_flags(flags); +} + +static __inline__ void __change_bit(int nr, volatile void *addr) +{ + int mask; + unsigned long *ADDR = (unsigned long *) addr; + + ADDR += nr >> 5; + mask = 1 << (nr & 31); + *ADDR ^= mask; +} + +static __inline__ int test_and_set_bit(int nr, volatile void *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *) addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + save_and_cli(flags); + retval = (mask & *a) != 0; + *a |= mask; + restore_flags(flags); + + return retval; +} + +static __inline__ int __test_and_set_bit(int nr, volatile void *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *) addr; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + retval = (mask & *a) != 0; + *a |= mask; + return retval; +} + +static __inline__ int test_and_clear_bit(int nr, volatile void *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *) addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + save_and_cli(flags); + retval = (mask & *a) != 0; + *a &= ~mask; + restore_flags(flags); + + return retval; +} + +static __inline__ int __test_and_clear_bit(int nr, volatile void *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *) addr; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + retval = (mask & *a) != 0; + *a &= ~mask; + return retval; +} + +static __inline__ int test_and_change_bit(int nr, volatile void *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *) addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + save_and_cli(flags); + retval = (mask & *a) != 0; + *a ^= mask; + restore_flags(flags); + + return retval; +} + +static __inline__ int __test_and_change_bit(int nr, volatile void *addr) +{ + int mask, retval; + volatile unsigned int *a = (volatile unsigned int *) addr; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + retval = (mask & *a) != 0; + *a ^= mask; + return retval; +} + +/* + * This routine doesn't need to be atomic. + */ +static __inline__ int __constant_test_bit(int nr, + const volatile void *addr) +{ + return ((1UL << (nr & 31)) & + (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static __inline__ int __test_bit(int nr, volatile void *addr) +{ + int *a = (int *) addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + return ((mask & *a) != 0); +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + __constant_test_bit((nr),(addr)) : \ + __test_bit((nr),(addr))) + +#define find_first_zero_bit(addr, size) \ + find_next_zero_bit((addr), (size), 0) + +static __inline__ int find_next_zero_bit(void *addr, int size, int offset) +{ + unsigned long *p = ((unsigned long *) addr) + (offset >> 5); + unsigned long result = offset & ~31UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if (offset) { + tmp = *(p++); + tmp |= ~0UL >> (32 - offset); + if (size < 32) + goto found_first; + if (~tmp) + goto found_middle; + size -= 32; + result += 32; + } + while (size & ~31UL) { + if (~(tmp = *(p++))) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = *p; + + found_first: + tmp |= ~0UL >> size; + found_middle: + return result + ffz(tmp); +} + +/* + * ffs: find first bit set. This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ + +#define ffs(x) generic_ffs(x) + +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +static __inline__ int ext2_set_bit(int nr, volatile void *addr) +{ + int mask, retval; + unsigned long flags; + volatile unsigned char *ADDR = (unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + save_and_cli(flags); + retval = (mask & *ADDR) != 0; + *ADDR |= mask; + restore_flags(flags); + return retval; +} + +static __inline__ int ext2_clear_bit(int nr, volatile void *addr) +{ + int mask, retval; + unsigned long flags; + volatile unsigned char *ADDR = (unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + save_and_cli(flags); + retval = (mask & *ADDR) != 0; + *ADDR &= ~mask; + restore_flags(flags); + return retval; +} + +static __inline__ int ext2_test_bit(int nr, const volatile void *addr) +{ + int mask; + const volatile unsigned char *ADDR = (const unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + return ((mask & *ADDR) != 0); +} + +#define ext2_find_first_zero_bit(addr, size) \ + ext2_find_next_zero_bit((addr), (size), 0) + +static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, + unsigned long size, + unsigned long + offset) +{ + unsigned long *p = ((unsigned long *) addr) + (offset >> 5); + unsigned long result = offset & ~31UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if (offset) { + tmp = *(p++); + tmp |= ~0UL >> (32 - offset); + if (size < 32) + goto found_first; + if (~tmp) + goto found_middle; + size -= 32; + result += 32; + } + while (size & ~31UL) { + if (~(tmp = *(p++))) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = *p; + + found_first: + tmp |= ~0UL >> size; + found_middle: + return result + ffz(tmp); +} + +/* Bitmap functions for the minix filesystem. */ +#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr) +#define minix_set_bit(nr,addr) set_bit(nr,addr) +#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr) +#define minix_test_bit(nr,addr) test_bit(nr,addr) +#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) + +#endif + +#endif diff --git a/include/asm-blackfin/blackfin.h b/include/asm-blackfin/blackfin.h new file mode 100644 index 0000000000..fbdbf30fa1 --- /dev/null +++ b/include/asm-blackfin/blackfin.h @@ -0,0 +1,46 @@ +/* + * U-boot - blackfin.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_H_ +#define _BLACKFIN_H_ + +#include +#include + +#ifndef __ASSEMBLY__ +#ifndef ASSEMBLY + +#ifdef SHARED_RESOURCES + #include +#endif +#include + +#endif +#endif + +#include +#include +#include + +#endif diff --git a/include/asm-blackfin/blackfin_defs.h b/include/asm-blackfin/blackfin_defs.h new file mode 100644 index 0000000000..2190215971 --- /dev/null +++ b/include/asm-blackfin/blackfin_defs.h @@ -0,0 +1,83 @@ +/* + * U-boot - blackfin_defs.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __BLACKFIN_DEFS_H__ +#define __BLACKFIN_DEFS_H__ + +#define TS_MAGICKEY 0x5a5a5a5a +#define TASK_STATE 0 +#define TASK_FLAGS 4 +#define TASK_PTRACE 24 +#define TASK_BLOCKED 636 +#define TASK_COUNTER 32 +#define TASK_SIGPENDING 8 +#define TASK_NEEDRESCHED 20 +#define TASK_THREAD 600 +#define TASK_MM 44 +#define TASK_ACTIVE_MM 80 +#define THREAD_KSP 0 +#define THREAD_USP 4 +#define THREAD_SR 8 +#define THREAD_ESP0 12 +#define THREAD_PC 16 +#define PT_ORIG_R0 208 +#define PT_R0 204 +#define PT_R1 200 +#define PT_R2 196 +#define PT_R3 192 +#define PT_R4 188 +#define PT_R5 184 +#define PT_R6 180 +#define PT_R7 176 +#define PT_P0 172 +#define PT_P1 168 +#define PT_P2 164 +#define PT_P3 160 +#define PT_P4 156 +#define PT_P5 152 +#define PT_A0w 72 +#define PT_A1w 64 +#define PT_A0x 76 +#define PT_A1x 68 +#define PT_RETS 28 +#define PT_RESERVED 32 +#define PT_ASTAT 36 +#define PT_SEQSTAT 8 +#define PT_PC 24 +#define PT_IPEND 0 +#define PT_USP 144 +#define PT_FP 148 +#define PT_SYSCFG 4 +#define IRQ_HANDLER 0 +#define IRQ_DEVID 8 +#define IRQ_NEXT 16 +#define STAT_IRQ 5148 +#define SIGSEGV 11 +#define SEGV_MAPERR 196609 +#define SIGTRAP 5 +#define PT_PTRACED 1 +#define PT_TRACESYS 2 +#define PT_DTRACE 4 + +#endif diff --git a/include/asm-blackfin/byteorder.h b/include/asm-blackfin/byteorder.h new file mode 100644 index 0000000000..3b4df4e134 --- /dev/null +++ b/include/asm-blackfin/byteorder.h @@ -0,0 +1,40 @@ +/* + * U-boot - byteorder.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_BYTEORDER_H +#define _BLACKFIN_BYTEORDER_H + +#include + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#include + +#endif diff --git a/include/asm-blackfin/cplb.h b/include/asm-blackfin/cplb.h new file mode 100644 index 0000000000..7715f645de --- /dev/null +++ b/include/asm-blackfin/cplb.h @@ -0,0 +1,48 @@ +/************************************************************************ + * + * cplb.h + * + * (c) Copyright 2002-2003 Analog Devices, Inc. All rights reserved. + * + ************************************************************************/ + +/* Defines necessary for cplb initialisation routines. */ + +#ifndef _CPLB_H +#define _CPLB_H + +#define CPLB_ENABLE_ICACHE_P 0 +#define CPLB_ENABLE_DCACHE_P 1 +#define CPLB_ENABLE_DCACHE2_P 2 +#define CPLB_ENABLE_CPLBS_P 3 /* Deprecated!*/ +#define CPLB_ENABLE_ICPLBS_P 4 +#define CPLB_ENABLE_DCPLBS_P 5 + +#define CPLB_ENABLE_ICACHE (1< + +#ifndef __ARCH_BFINNOMMU_CPLBTAB_H +#define __ARCH_BFINNOMMU_CPLBTAB_H + +/************************************************************************* + * ICPLB TABLE + *************************************************************************/ + +.data + +/* This table is configurable */ + +.align 4; + +/* Data Attibutes*/ + +#define SDRAM_IGENERIC (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID) +#define SDRAM_IKERNEL (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_LOCK) +#define L1_IMEMORY (PAGE_SIZE_1MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_LOCK) +#define SDRAM_INON_CHBL (PAGE_SIZE_4MB | CPLB_USER_RD | CPLB_VALID) + +/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/ + +#define ANOMALY_05000158 0x200 +#ifdef CONFIG_BLKFIN_WB /*Write Back Policy */ + #define SDRAM_DGENERIC (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_DIRTY | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158) + #define SDRAM_DNON_CHBL (PAGE_SIZE_4MB | CPLB_DIRTY | CPLB_SUPV_WR | CPLB_USER_RD | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158) + #define SDRAM_DKERNEL (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_USER_WR | CPLB_DIRTY | CPLB_SUPV_WR | CPLB_VALID | CPLB_LOCK | ANOMALY_05000158) + #define L1_DMEMORY (PAGE_SIZE_4KB | CPLB_L1_CHBL | CPLB_DIRTY | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158) + #define SDRAM_EBIU (PAGE_SIZE_1MB | CPLB_DIRTY | CPLB_USER_RD | CPLB_USER_WR | CPLB_SUPV_WR | CPLB_VALID | ANOMALY_05000158) + +#else /*Write Through*/ + #define SDRAM_DGENERIC (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_SUPV_WR | CPLB_USER_RD | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158) + #define SDRAM_DNON_CHBL (PAGE_SIZE_4MB | CPLB_WT | CPLB_L1_AOW | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158) + #define SDRAM_DKERNEL (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_USER_RD | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_VALID | CPLB_LOCK | ANOMALY_05000158) + #define L1_DMEMORY (PAGE_SIZE_4KB | CPLB_L1_CHBL | CPLB_L1_AOW | CPLB_WT | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158) + #define SDRAM_EBIU (PAGE_SIZE_1MB | CPLB_WT | CPLB_L1_AOW | CPLB_USER_RD | CPLB_USER_WR | CPLB_SUPV_WR | CPLB_VALID | ANOMALY_05000158) +#endif + +.global icplb_table +icplb_table: +.byte4 0xFFA00000; +.byte4 (L1_IMEMORY); +.byte4 0x00000000; +.byte4 (SDRAM_IKERNEL); /*SDRAM_Page1*/ +.byte4 0x00400000; +.byte4 (SDRAM_IKERNEL); /*SDRAM_Page1*/ +.byte4 0x07C00000; +.byte4 (SDRAM_IKERNEL); /*SDRAM_Page14*/ +.byte4 0x00800000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page2*/ +.byte4 0x00C00000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page2*/ +.byte4 0x01000000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page4*/ +.byte4 0x01400000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page5*/ +.byte4 0x01800000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page6*/ +.byte4 0x01C00000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page7*/ +#ifndef CONFIG_EZKIT /*STAMP Memory regions*/ +.byte4 0x02000000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page8*/ +.byte4 0x02400000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page9*/ +.byte4 0x02800000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page10*/ +.byte4 0x02C00000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page11*/ +.byte4 0x03000000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page12*/ +.byte4 0x03400000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page13*/ +#endif +.byte4 0xffffffff; /* end of section - termination*/ + +.align 4; +.global ipdt_table +ipdt_table: +#ifdef CONFIG_CPLB_INFO +.byte4 0x00000000; +.byte4 (SDRAM_IKERNEL); /*SDRAM_Page0*/ +.byte4 0x00400000; +.byte4 (SDRAM_IKERNEL); /*SDRAM_Page1*/ +#endif +.byte4 0x00800000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page2*/ +.byte4 0x00C00000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page3*/ +.byte4 0x01000000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page4*/ +.byte4 0x01400000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page5*/ +.byte4 0x01800000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page6*/ +.byte4 0x01C00000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page7*/ +#ifndef CONFIG_EZKIT /*STAMP Memory regions*/ +.byte4 0x02000000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page8*/ +.byte4 0x02400000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page9*/ +.byte4 0x02800000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page10*/ +.byte4 0x02C00000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page11*/ +.byte4 0x03000000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page12*/ +.byte4 0x03400000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page13*/ +.byte4 0x03800000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page14*/ +.byte4 0x03C00000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page15*/ +#endif +.byte4 0x20200000; +.byte4 (SDRAM_EBIU); /* Async Memory Bank 2 (Secnd)*/ +.byte4 0x20100000; +.byte4 (SDRAM_EBIU); /* Async Memory Bank 1 (Prim B)*/ +.byte4 0x20000000; +.byte4 (SDRAM_EBIU); /* Async Memory Bank 0 (Prim A)*/ +.byte4 0x20300000; /*Fix for Network*/ +.byte4 (SDRAM_EBIU); /*Async Memory bank 3*/ + +#ifdef CONFIG_STAMP +.byte4 0x04000000; +.byte4 (SDRAM_IGENERIC); +.byte4 0x04400000; +.byte4 (SDRAM_IGENERIC); +.byte4 0x04800000; +.byte4 (SDRAM_IGENERIC); +.byte4 0x04C00000; +.byte4 (SDRAM_IGENERIC); +.byte4 0x05000000; +.byte4 (SDRAM_IGENERIC); +.byte4 0x05400000; +.byte4 (SDRAM_IGENERIC); +.byte4 0x05800000; +.byte4 (SDRAM_IGENERIC); +.byte4 0x05C00000; +.byte4 (SDRAM_IGENERIC); +.byte4 0x06000000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page25*/ +.byte4 0x06400000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page26*/ +.byte4 0x06800000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page27*/ +.byte4 0x06C00000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page28*/ +.byte4 0x07000000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page29*/ +.byte4 0x07400000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page30*/ +.byte4 0x07800000; +.byte4 (SDRAM_IGENERIC); /*SDRAM_Page31*/ +#ifdef CONFIG_CPLB_INFO +.byte4 0x07C00000; +.byte4 (SDRAM_IKERNEL); /*SDRAM_Page32*/ +#endif +#endif +.byte4 0xffffffff; /* end of section - termination*/ + +/********************************************************************* + * DCPLB TABLE + ********************************************************************/ + +.global dcplb_table +dcplb_table: +.byte4 0x00000000; +.byte4 (SDRAM_DKERNEL); /*SDRAM_Page1*/ +.byte4 0x00400000; +.byte4 (SDRAM_DKERNEL); /*SDRAM_Page1*/ +.byte4 0x07C00000; +.byte4 (SDRAM_DKERNEL); /*SDRAM_Page15*/ +.byte4 0x00800000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page2*/ +.byte4 0x00C00000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page3*/ +.byte4 0x01000000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page4*/ +.byte4 0x01400000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page5*/ +.byte4 0x01800000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page6*/ +.byte4 0x01C00000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page7*/ +#ifndef CONFIG_EZKIT +.byte4 0x02000000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page8*/ +.byte4 0x02400000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page9*/ +.byte4 0x02800000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page10*/ +.byte4 0x02C00000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page11*/ +.byte4 0x03000000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page12*/ +.byte4 0x03400000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page13*/ +.byte4 0x03800000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page14*/ +#endif +.byte4 0xffffffff; /*end of section - termination*/ + +/********************************************************************** + * PAGE DESCRIPTOR TABLE + * + **********************************************************************/ + +/* Till here we are discussing about the static memory management model. + * However, the operating envoronments commonly define more CPLB + * descriptors to cover the entire addressable memory than will fit into + * the available on-chip 16 CPLB MMRs. When this happens, the below table + * will be used which will hold all the potentially required CPLB descriptors + * + * This is how Page descriptor Table is implemented in uClinux/Blackfin. + */ +.global dpdt_table +dpdt_table: +#ifdef CONFIG_CPLB_INFO +.byte4 0x00000000; +.byte4 (SDRAM_DKERNEL); /*SDRAM_Page0*/ +.byte4 0x00400000; +.byte4 (SDRAM_DKERNEL); /*SDRAM_Page1*/ +#endif +.byte4 0x00800000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page2*/ +.byte4 0x00C00000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page3*/ +.byte4 0x01000000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page4*/ +.byte4 0x01400000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page5*/ +.byte4 0x01800000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page6*/ +.byte4 0x01C00000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page7*/ + +#ifndef CONFIG_EZKIT +.byte4 0x02000000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page8*/ +.byte4 0x02400000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page9*/ +.byte4 0x02800000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page10*/ +.byte4 0x02C00000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page11*/ +.byte4 0x03000000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page12*/ +.byte4 0x03400000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page13*/ +.byte4 0x03800000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page14*/ +.byte4 0x03C00000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page15*/ +#endif +.byte4 0x20200000; +.byte4 (SDRAM_EBIU); /* Async Memory Bank 2 (Secnd)*/ +.byte4 0x20100000; +.byte4 (SDRAM_EBIU); /* Async Memory Bank 1 (Prim B)*/ +.byte4 0x20000000; +.byte4 (SDRAM_EBIU); /* Async Memory Bank 0 (Prim A)*/ +.byte4 0x20300000; /*Fix for Network*/ +.byte4 (SDRAM_EBIU); /*Async Memory bank 3*/ + +#ifdef CONFIG_STAMP +.byte4 0x04000000; +.byte4 (SDRAM_DGENERIC); +.byte4 0x04400000; +.byte4 (SDRAM_DGENERIC); +.byte4 0x04800000; +.byte4 (SDRAM_DGENERIC); +.byte4 0x04C00000; +.byte4 (SDRAM_DGENERIC); +.byte4 0x05000000; +.byte4 (SDRAM_DGENERIC); +.byte4 0x05400000; +.byte4 (SDRAM_DGENERIC); +.byte4 0x05800000; +.byte4 (SDRAM_DGENERIC); +.byte4 0x05C00000; +.byte4 (SDRAM_DGENERIC); +.byte4 0x06000000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page25*/ +.byte4 0x06400000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page26*/ +.byte4 0x06800000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page27*/ +.byte4 0x06C00000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page28*/ +.byte4 0x07000000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page29*/ +.byte4 0x07400000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page30*/ +.byte4 0x07800000; +.byte4 (SDRAM_DGENERIC); /*SDRAM_Page31*/ +#ifdef CONFIG_CPLB_INFO +.byte4 0x07C00000; +.byte4 (SDRAM_DKERNEL); /*SDRAM_Page32*/ +#endif +#endif + +.byte4 0xFF900000; +.byte4 (L1_DMEMORY); +.byte4 0xFF901000; +.byte4 (L1_DMEMORY); +.byte4 0xFF902000; +.byte4 (L1_DMEMORY); +.byte4 0xFF903000; +.byte4 (L1_DMEMORY); +.byte4 0xFF904000; +.byte4 (L1_DMEMORY); +.byte4 0xFF905000; +.byte4 (L1_DMEMORY); +.byte4 0xFF906000; +.byte4 (L1_DMEMORY); +.byte4 0xFF907000; +.byte4 (L1_DMEMORY); +.byte4 0xFF800000; +.byte4 (L1_DMEMORY); +.byte4 0xFF801000; +.byte4 (L1_DMEMORY); +.byte4 0xFF802000; +.byte4 (L1_DMEMORY); +.byte4 0xFF803000; +.byte4 (L1_DMEMORY); + +.byte4 0xffffffff; /*end of section - termination*/ + +#ifdef CONFIG_CPLB_INFO +.global ipdt_swapcount_table; /* swapin count first, then swapout count*/ +ipdt_swapcount_table: +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 10 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 20 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 30 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 40 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 50 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 60 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 70 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 80 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 90 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 100 */ + +.global dpdt_swapcount_table; /* swapin count first, then swapout count*/ +dpdt_swapcount_table: +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 10 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 20 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 30 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 40 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 50 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 60 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 70 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 80 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 80 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 100 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 110 */ +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; +.byte4 0x00000000; /* 120 */ + +#endif + +#endif /*__ARCH_BFINNOMMU_CPLBTAB_H*/ diff --git a/include/asm-blackfin/cpu/bf533_irq.h b/include/asm-blackfin/cpu/bf533_irq.h new file mode 100644 index 0000000000..902308a486 --- /dev/null +++ b/include/asm-blackfin/cpu/bf533_irq.h @@ -0,0 +1,137 @@ +/* + * U-boot bf533_irq.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on + * linux/arch/$(ARCH)/platform/$(PLATFORM)/irq.c + * Changed by HuTao Apr18, 2003 + * + * Copyright was missing when I got the code so took from MIPS arch ...MaTed--- + * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle + * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle + * + * Adapted for BlackFin (ADI) by Ted Ma + * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com) + * Copyright (c) 2002 Lineo, Inc. + * + * Adapted for BlackFin BF533 by Bas Vermeulen + * Copyright (c) 2003 BuyWays B.V. (www.buyways.nl) + + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BF533_IRQ_H_ +#define _BF533_IRQ_H_ + +/* + * Interrupt source definitions + * Event Source Core Event Name Number + * EMU 0 + * Reset RST 1 + * NMI NMI 2 + * Exception EVX 3 + * Reserved -- 4 + * Hardware Error IVHW 5 + * Core Timer IVTMR 6 + * PLL Wakeup Interrupt IVG7 7 + * DMA Error (generic) IVG7 8 + * PPI Error Interrupt IVG7 9 + * SPORT0 Error Interrupt IVG7 10 + * SPORT1 Error Interrupt IVG7 11 + * SPI Error Interrupt IVG7 12 + * UART Error Interrupt IVG7 13 + * RTC Interrupt IVG8 14 + * DMA0 Interrupt (PPI) IVG8 15 + * DMA1 (SPORT0 RX) IVG9 16 + * DMA2 (SPORT0 TX) IVG9 17 + * DMA3 (SPORT1 RX) IVG9 18 + * DMA4 (SPORT1 TX) IVG9 19 + * DMA5 (PPI) IVG10 20 + * DMA6 (UART RX) IVG10 21 + * DMA7 (UART TX) IVG10 22 + * Timer0 IVG11 23 + * Timer1 IVG11 24 + * Timer2 IVG11 25 + * PF Interrupt A IVG12 26 + * PF Interrupt B IVG12 27 + * DMA8/9 Interrupt IVG13 28 + * DMA10/11 Interrupt IVG13 29 + * Watchdog Timer IVG13 30 + * Software Interrupt 1 IVG14 31 + * Software Interrupt 2 -- + * (lowest priority) IVG15 32 + */ + +/* The ABSTRACT IRQ definitions */ + +/* The first seven of the following are fixed, + * the rest you change if you need to + */ + +#define IRQ_EMU 0 /* Emulation */ +#define IRQ_RST 1 /* reset */ +#define IRQ_NMI 2 /* Non Maskable */ +#define IRQ_EVX 3 /* Exception */ +#define IRQ_UNUSED 4 /* - unused interrupt */ +#define IRQ_HWERR 5 /* Hardware Error */ +#define IRQ_CORETMR 6 /* Core timer */ +#define IRQ_PLL_WAKEUP 7 /* PLL Wakeup Interrupt */ +#define IRQ_DMA_ERROR 8 /* DMA Error (general) */ +#define IRQ_PPI_ERROR 9 /* PPI Error Interrupt */ +#define IRQ_SPORT0_ERROR 10 /* SPORT0 Error Interrupt */ +#define IRQ_SPORT1_ERROR 11 /* SPORT1 Error Interrupt */ +#define IRQ_SPI_ERROR 12 /* SPI Error Interrupt */ +#define IRQ_UART_ERROR 13 /* UART Error Interrupt */ +#define IRQ_RTC 14 /* RTC Interrupt */ +#define IRQ_PPI 15 /* DMA0 Interrupt (PPI) */ +#define IRQ_SPORT0 16 /* DMA1 Interrupt (SPORT0 RX) */ +#define IRQ_SPARE1 17 /* DMA2 Interrupt (SPORT0 TX) */ +#define IRQ_SPORT1 18 /* DMA3 Interrupt (SPORT1 RX) */ +#define IRQ_SPARE2 19 /* DMA4 Interrupt (SPORT1 TX) */ +#define IRQ_SPI 20 /* DMA5 Interrupt (SPI) */ +#define IRQ_UART 21 /* DMA6 Interrupt (UART RX) */ +#define IRQ_SPARE3 22 /* DMA7 Interrupt (UART TX) */ +#define IRQ_TMR0 23 /* Timer 0 */ +#define IRQ_TMR1 24 /* Timer 1 */ +#define IRQ_TMR2 25 /* Timer 2 */ +#define IRQ_PROG_INTA 26 /* Programmable Flags A (8) */ +#define IRQ_PROG_INTB 27 /* Programmable Flags B (8) */ +#define IRQ_MEM_DMA0 28 /* DMA8/9 Interrupt (Memory DMA Stream 0) */ +#define IRQ_MEM_DMA1 29 /* DMA10/11 Interrupt (Memory DMA Stream 1) */ +#define IRQ_WATCH 30 /* Watch Dog Timer */ +#define IRQ_SW_INT1 31 /* Software Int 1 */ +#define IRQ_SW_INT2 32 /* Software Int 2 (reserved for SYSCALL) */ + +#define IRQ_UART_RX_BIT 0x4000 +#define IRQ_UART_TX_BIT 0x8000 +#define IRQ_UART_ERROR_BIT 0x40 + +#define IVG7 7 +#define IVG8 8 +#define IVG9 9 +#define IVG10 10 +#define IVG11 11 +#define IVG12 12 +#define IVG13 13 +#define IVG14 14 +#define IVG15 15 +#define SYS_IRQS 33 + +#endif diff --git a/include/asm-blackfin/cpu/bf533_rtc.h b/include/asm-blackfin/cpu/bf533_rtc.h new file mode 100644 index 0000000000..bc09922a5e --- /dev/null +++ b/include/asm-blackfin/cpu/bf533_rtc.h @@ -0,0 +1,46 @@ +/* + * U-boot - bf533_rtc.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BF533_RTC_H_ +#define _BF533_RTC_H_ + +void rtc_init(void); +void wait_for_complete(void); +void rtc_reset(void); + +#define MIN_TO_SECS(_x_) (60 * _x_) +#define HRS_TO_SECS(_x_) (60 * 60 * _x_) +#define DAYS_TO_SECS(_x_) (24 * 60 * 60 * _x_) + +#define NUM_SECS_IN_DAY (24 * 3600) +#define NUM_SECS_IN_HOUR (3600) +#define NUM_SECS_IN_MIN (60) + +/* Shift values for RTC_STAT register */ +#define DAY_BITS_OFF 17 +#define HOUR_BITS_OFF 12 +#define MIN_BITS_OFF 6 +#define SEC_BITS_OFF 0 + +#endif diff --git a/include/asm-blackfin/cpu/bf533_serial.h b/include/asm-blackfin/cpu/bf533_serial.h new file mode 100644 index 0000000000..d5e162a8f9 --- /dev/null +++ b/include/asm-blackfin/cpu/bf533_serial.h @@ -0,0 +1,79 @@ +/* + * U-boot bf533_serial.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#ifndef _BF533_SERIAL_H_ +#define _BF533_SERIAL_H_ + +#define BYTE_REF(addr) (*((volatile char*)addr)) +#define HALFWORD_REF(addr) (*((volatile short*)addr)) +#define WORD_REF(addr) (*((volatile long*)addr)) + +#define UART_THR_LO HALFWORD_REF(UART_THR) +#define UART_RBR_LO HALFWORD_REF(UART_RBR) +#define UART_DLL_LO HALFWORD_REF(UART_DLL) +#define UART_IER_LO HALFWORD_REF(UART_IER) +#define UART_IER_ERBFI 0x01 +#define UART_IER_ETBEI 0x02 +#define UART_IER_ELSI 0x04 +#define UART_IER_EDDSI 0x08 + +#define UART_DLH_LO HALFWORD_REF(UART_DLH) +#define UART_IIR_LO HALFWORD_REF(UART_IIR) +#define UART_IIR_NOINT 0x01 +#define UART_IIR_STATUS 0x06 +#define UART_IIR_LSR 0x06 +#define UART_IIR_RBR 0x04 +#define UART_IIR_THR 0x02 +#define UART_IIR_MSR 0x00 + +#define UART_LCR_LO HALFWORD_REF(UART_LCR) +#define UART_LCR_WLS5 0 +#define UART_LCR_WLS6 0x01 +#define UART_LCR_WLS7 0x02 +#define UART_LCR_WLS8 0x03 +#define UART_LCR_STB 0x04 +#define UART_LCR_PEN 0x08 +#define UART_LCR_EPS 0x10 +#define UART_LCR_SP 0x20 +#define UART_LCR_SB 0x40 +#define UART_LCR_DLAB 0x80 + +#define UART_MCR_LO HALFWORD_REF(UART_MCR) + +#define UART_LSR_LO HALFWORD_REF(UART_LSR) +#define UART_LSR_DR 0x01 +#define UART_LSR_OE 0x02 +#define UART_LSR_PE 0x04 +#define UART_LSR_FE 0x08 +#define UART_LSR_BI 0x10 +#define UART_LSR_THRE 0x20 +#define UART_LSR_TEMT 0x40 + +#define UART_MSR_LO HALFWORD_REF(UART_MSR) +#define UART_SCR_LO HALFWORD_REF(UART_SCR) +#define UART_GCTL_LO HALFWORD_REF(UART_GCTL) +#define UART_GCTL_UCEN 0x01 + +#endif diff --git a/include/asm-blackfin/cpu/cdefBF531.h b/include/asm-blackfin/cpu/cdefBF531.h new file mode 100644 index 0000000000..68d841d185 --- /dev/null +++ b/include/asm-blackfin/cpu/cdefBF531.h @@ -0,0 +1,24 @@ +/* + * cdefBF531.h + * + * This file is subject to the terms and conditions of the GNU Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Non-GPL License also available as part of VisualDSP++ + * + * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html + * + * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved + * + * This file under source code control, please send bugs or changes to: + * dsptools.support@analog.com + * + */ + +#ifndef _CDEFBF531_H +#define _CDEFBF531_H + +#include + +#endif /* _CDEFBF531_H */ diff --git a/include/asm-blackfin/cpu/cdefBF532.h b/include/asm-blackfin/cpu/cdefBF532.h new file mode 100644 index 0000000000..a4d422f765 --- /dev/null +++ b/include/asm-blackfin/cpu/cdefBF532.h @@ -0,0 +1,398 @@ +/* + * cdefBF532.h + * + * This file is subject to the terms and conditions of the GNU Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Non-GPL License also available as part of VisualDSP++ + * + * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html + * + * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved + * + * This file under source code control, please send bugs or changes to: + * dsptools.support@analog.com + * + */ + +#ifndef _CDEF_BF532_H +#define _CDEF_BF532_H + +/* + * #if !defined(__ADSPLPBLACKFIN__) + * #warning cdefBF532.h should only be included for 532 compatible chips. + * #endif + */ + +/* include all Core registers and bit definitions */ +#include + +/* include core specific register pointer definitions */ +#include + +/* Clock and System Control (0xFFC0 0400-0xFFC0 07FF) */ +#define pPLL_CTL ((volatile unsigned short *)PLL_CTL) +#define pPLL_STAT ((volatile unsigned short *)PLL_STAT) +#define pPLL_LOCKCNT ((volatile unsigned short *)PLL_LOCKCNT) +#define pCHIPID ((volatile unsigned long *)CHIPID) +#define pSWRST ((volatile unsigned short *)SWRST) +#define pSYSCR ((volatile unsigned short *)SYSCR) +#define pPLL_DIV ((volatile unsigned short *)PLL_DIV) +#define pVR_CTL ((volatile unsigned short *)VR_CTL) + +/* System Interrupt Controller (0xFFC0 0C00-0xFFC0 0FFF) */ +#define pSIC_IAR0 ((volatile unsigned long *)SIC_IAR0) +#define pSIC_IAR1 ((volatile unsigned long *)SIC_IAR1) +#define pSIC_IAR2 ((volatile unsigned long *)SIC_IAR2) +#define pSIC_IAR3 ((volatile unsigned long *)SIC_IAR3) +#define pSIC_IMASK ((volatile unsigned long *)SIC_IMASK) +#define pSIC_ISR ((volatile unsigned long *)SIC_ISR) +#define pSIC_IWR ((volatile unsigned long *)SIC_IWR) + +/* Watchdog Timer (0xFFC0 1000-0xFFC0 13FF) */ +#define pWDOG_CTL ((volatile unsigned short *)WDOG_CTL) +#define pWDOG_CNT ((volatile unsigned long *)WDOG_CNT) +#define pWDOG_STAT ((volatile unsigned long *)WDOG_STAT) + +/* Real Time Clock (0xFFC0 1400-0xFFC0 17FF) */ +#define pRTC_STAT ((volatile unsigned long *)RTC_STAT) +#define pRTC_ICTL ((volatile unsigned short *)RTC_ICTL) +#define pRTC_ISTAT ((volatile unsigned short *)RTC_ISTAT) +#define pRTC_SWCNT ((volatile unsigned short *)RTC_SWCNT) +#define pRTC_ALARM ((volatile unsigned long *)RTC_ALARM) +#define pRTC_FAST ((volatile unsigned short *)RTC_FAST) +#define pRTC_PREN ((volatile unsigned short *)RTC_PREN) + +/* General Purpose IO (0xFFC0 2400-0xFFC0 27FF) */ +#define pFIO_DIR ((volatile unsigned short *)FIO_DIR) +#define pFIO_FLAG_C ((volatile unsigned short *)FIO_FLAG_C) +#define pFIO_FLAG_S ((volatile unsigned short *)FIO_FLAG_S) +#define pFIO_MASKA_C ((volatile unsigned short *)FIO_MASKA_C) +#define pFIO_MASKA_S ((volatile unsigned short *)FIO_MASKA_S) +#define pFIO_MASKB_C ((volatile unsigned short *)FIO_MASKB_C) +#define pFIO_MASKB_S ((volatile unsigned short *)FIO_MASKB_S) +#define pFIO_POLAR ((volatile unsigned short *)FIO_POLAR) +#define pFIO_EDGE ((volatile unsigned short *)FIO_EDGE) +#define pFIO_BOTH ((volatile unsigned short *)FIO_BOTH) +#define pFIO_INEN ((volatile unsigned short *)FIO_INEN) +#define pFIO_FLAG_D ((volatile unsigned short *)FIO_FLAG_D) +#define pFIO_FLAG_T ((volatile unsigned short *)FIO_FLAG_T) +#define pFIO_MASKA_D ((volatile unsigned short *)FIO_MASKA_D) +#define pFIO_MASKA_T ((volatile unsigned short *)FIO_MASKA_T) +#define pFIO_MASKB_D ((volatile unsigned short *)FIO_MASKB_D) +#define pFIO_MASKB_T ((volatile unsigned short *)FIO_MASKB_T) + +/* DMA Test Registers */ +#define pDMA_CCOMP ((volatile unsigned long *)DMA_CCOMP) +#define pDMA_ACOMP ((volatile unsigned long *)DMA_ACOMP) +#define pDMA_MISR ((volatile unsigned long *)DMA_MISR) +#define pDMA_TCPER ((volatile unsigned short *)DMA_TCPER) +#define pDMA_TCCNT ((volatile unsigned short *)DMA_TCCNT) +#define pDMA_TMODE ((volatile unsigned short *)DMA_TMODE) +#define pDMA_TMCHAN ((volatile unsigned short *)DMA_TMCHAN) +#define pDMA_TMSTAT ((volatile unsigned short *)DMA_TMSTAT) +#define pDMA_TMBD ((volatile unsigned short *)DMA_TMBD) +#define pDMA_TMM0D ((volatile unsigned short *)DMA_TMM0D) +#define pDMA_TMM1D ((volatile unsigned short *)DMA_TMM1D) +#define pDMA_TMMA ((volatile void **)DMA_TMMA) + +/* DMA Controller */ +#define pDMA0_CONFIG ((volatile unsigned short *)DMA0_CONFIG) +#define pDMA0_NEXT_DESC_PTR ((volatile void **)DMA0_NEXT_DESC_PTR) +#define pDMA0_START_ADDR ((volatile void **)DMA0_START_ADDR) +#define pDMA0_X_COUNT ((volatile unsigned short *)DMA0_X_COUNT) +#define pDMA0_Y_COUNT ((volatile unsigned short *)DMA0_Y_COUNT) +#define pDMA0_X_MODIFY ((volatile signed short *)DMA0_X_MODIFY) +#define pDMA0_Y_MODIFY ((volatile signed short *)DMA0_Y_MODIFY) +#define pDMA0_CURR_DESC_PTR ((volatile void **)DMA0_CURR_DESC_PTR) +#define pDMA0_CURR_ADDR ((volatile void **)DMA0_CURR_ADDR) +#define pDMA0_CURR_X_COUNT ((volatile unsigned short *)DMA0_CURR_X_COUNT) +#define pDMA0_CURR_Y_COUNT ((volatile unsigned short *)DMA0_CURR_Y_COUNT) +#define pDMA0_IRQ_STATUS ((volatile unsigned short *)DMA0_IRQ_STATUS) +#define pDMA0_PERIPHERAL_MAP ((volatile unsigned short *)DMA0_PERIPHERAL_MAP) + +#define pDMA1_CONFIG ((volatile unsigned short *)DMA1_CONFIG) +#define pDMA1_NEXT_DESC_PTR ((volatile void **)DMA1_NEXT_DESC_PTR) +#define pDMA1_START_ADDR ((volatile void **)DMA1_START_ADDR) +#define pDMA1_X_COUNT ((volatile unsigned short *)DMA1_X_COUNT) +#define pDMA1_Y_COUNT ((volatile unsigned short *)DMA1_Y_COUNT) +#define pDMA1_X_MODIFY ((volatile signed short *)DMA1_X_MODIFY) +#define pDMA1_Y_MODIFY ((volatile signed short *)DMA1_Y_MODIFY) +#define pDMA1_CURR_DESC_PTR ((volatile void **)DMA1_CURR_DESC_PTR) +#define pDMA1_CURR_ADDR ((volatile void **)DMA1_CURR_ADDR) +#define pDMA1_CURR_X_COUNT ((volatile unsigned short *)DMA1_CURR_X_COUNT) +#define pDMA1_CURR_Y_COUNT ((volatile unsigned short *)DMA1_CURR_Y_COUNT) +#define pDMA1_IRQ_STATUS ((volatile unsigned short *)DMA1_IRQ_STATUS) +#define pDMA1_PERIPHERAL_MAP ((volatile unsigned short *)DMA1_PERIPHERAL_MAP) + +#define pDMA2_CONFIG ((volatile unsigned short *)DMA2_CONFIG) +#define pDMA2_NEXT_DESC_PTR ((volatile void **)DMA2_NEXT_DESC_PTR) +#define pDMA2_START_ADDR ((volatile void **)DMA2_START_ADDR) +#define pDMA2_X_COUNT ((volatile unsigned short *)DMA2_X_COUNT) +#define pDMA2_Y_COUNT ((volatile unsigned short *)DMA2_Y_COUNT) +#define pDMA2_X_MODIFY ((volatile signed short *)DMA2_X_MODIFY) +#define pDMA2_Y_MODIFY ((volatile signed short *)DMA2_Y_MODIFY) +#define pDMA2_CURR_DESC_PTR ((volatile void **)DMA2_CURR_DESC_PTR) +#define pDMA2_CURR_ADDR ((volatile void **)DMA2_CURR_ADDR) +#define pDMA2_CURR_X_COUNT ((volatile unsigned short *)DMA2_CURR_X_COUNT) +#define pDMA2_CURR_Y_COUNT ((volatile unsigned short *)DMA2_CURR_Y_COUNT) +#define pDMA2_IRQ_STATUS ((volatile unsigned short *)DMA2_IRQ_STATUS) +#define pDMA2_PERIPHERAL_MAP ((volatile unsigned short *)DMA2_PERIPHERAL_MAP) + +#define pDMA3_CONFIG ((volatile unsigned short *)DMA3_CONFIG) +#define pDMA3_NEXT_DESC_PTR ((volatile void **)DMA3_NEXT_DESC_PTR) +#define pDMA3_START_ADDR ((volatile void **)DMA3_START_ADDR) +#define pDMA3_X_COUNT ((volatile unsigned short *)DMA3_X_COUNT) +#define pDMA3_Y_COUNT ((volatile unsigned short *)DMA3_Y_COUNT) +#define pDMA3_X_MODIFY ((volatile signed short *)DMA3_X_MODIFY) +#define pDMA3_Y_MODIFY ((volatile signed short *)DMA3_Y_MODIFY) +#define pDMA3_CURR_DESC_PTR ((volatile void **)DMA3_CURR_DESC_PTR) +#define pDMA3_CURR_ADDR ((volatile void **)DMA3_CURR_ADDR) +#define pDMA3_CURR_X_COUNT ((volatile unsigned short *)DMA3_CURR_X_COUNT) +#define pDMA3_CURR_Y_COUNT ((volatile unsigned short *)DMA3_CURR_Y_COUNT) +#define pDMA3_IRQ_STATUS ((volatile unsigned short *)DMA3_IRQ_STATUS) +#define pDMA3_PERIPHERAL_MAP ((volatile unsigned short *)DMA3_PERIPHERAL_MAP) + +#define pDMA4_CONFIG ((volatile unsigned short *)DMA4_CONFIG) +#define pDMA4_NEXT_DESC_PTR ((volatile void **)DMA4_NEXT_DESC_PTR) +#define pDMA4_START_ADDR ((volatile void **)DMA4_START_ADDR) +#define pDMA4_X_COUNT ((volatile unsigned short *)DMA4_X_COUNT) +#define pDMA4_Y_COUNT ((volatile unsigned short *)DMA4_Y_COUNT) +#define pDMA4_X_MODIFY ((volatile signed short *)DMA4_X_MODIFY) +#define pDMA4_Y_MODIFY ((volatile signed short *)DMA4_Y_MODIFY) +#define pDMA4_CURR_DESC_PTR ((volatile void **)DMA4_CURR_DESC_PTR) +#define pDMA4_CURR_ADDR ((volatile void **)DMA4_CURR_ADDR) +#define pDMA4_CURR_X_COUNT ((volatile unsigned short *)DMA4_CURR_X_COUNT) +#define pDMA4_CURR_Y_COUNT ((volatile unsigned short *)DMA4_CURR_Y_COUNT) +#define pDMA4_IRQ_STATUS ((volatile unsigned short *)DMA4_IRQ_STATUS) +#define pDMA4_PERIPHERAL_MAP ((volatile unsigned short *)DMA4_PERIPHERAL_MAP) + +#define pDMA5_CONFIG ((volatile unsigned short *)DMA5_CONFIG) +#define pDMA5_NEXT_DESC_PTR ((volatile void **)DMA5_NEXT_DESC_PTR) +#define pDMA5_START_ADDR ((volatile void **)DMA5_START_ADDR) +#define pDMA5_X_COUNT ((volatile unsigned short *)DMA5_X_COUNT) +#define pDMA5_Y_COUNT ((volatile unsigned short *)DMA5_Y_COUNT) +#define pDMA5_X_MODIFY ((volatile signed short *)DMA5_X_MODIFY) +#define pDMA5_Y_MODIFY ((volatile signed short *)DMA5_Y_MODIFY) +#define pDMA5_CURR_DESC_PTR ((volatile void **)DMA5_CURR_DESC_PTR) +#define pDMA5_CURR_ADDR ((volatile void **)DMA5_CURR_ADDR) +#define pDMA5_CURR_X_COUNT ((volatile unsigned short *)DMA5_CURR_X_COUNT) +#define pDMA5_CURR_Y_COUNT ((volatile unsigned short *)DMA5_CURR_Y_COUNT) +#define pDMA5_IRQ_STATUS ((volatile unsigned short *)DMA5_IRQ_STATUS) +#define pDMA5_PERIPHERAL_MAP ((volatile unsigned short *)DMA5_PERIPHERAL_MAP) + +#define pDMA6_CONFIG ((volatile unsigned short *)DMA6_CONFIG) +#define pDMA6_NEXT_DESC_PTR ((volatile void **)DMA6_NEXT_DESC_PTR) +#define pDMA6_START_ADDR ((volatile void **)DMA6_START_ADDR) +#define pDMA6_X_COUNT ((volatile unsigned short *)DMA6_X_COUNT) +#define pDMA6_Y_COUNT ((volatile unsigned short *)DMA6_Y_COUNT) +#define pDMA6_X_MODIFY ((volatile signed short *)DMA6_X_MODIFY) +#define pDMA6_Y_MODIFY ((volatile signed short *)DMA6_Y_MODIFY) +#define pDMA6_CURR_DESC_PTR ((volatile void **)DMA6_CURR_DESC_PTR) +#define pDMA6_CURR_ADDR ((volatile void **)DMA6_CURR_ADDR) +#define pDMA6_CURR_X_COUNT ((volatile unsigned short *)DMA6_CURR_X_COUNT) +#define pDMA6_CURR_Y_COUNT ((volatile unsigned short *)DMA6_CURR_Y_COUNT) +#define pDMA6_IRQ_STATUS ((volatile unsigned short *)DMA6_IRQ_STATUS) +#define pDMA6_PERIPHERAL_MAP ((volatile unsigned short *)DMA6_PERIPHERAL_MAP) + +#define pDMA7_CONFIG ((volatile unsigned short *)DMA7_CONFIG) +#define pDMA7_NEXT_DESC_PTR ((volatile void **)DMA7_NEXT_DESC_PTR) +#define pDMA7_START_ADDR ((volatile void **)DMA7_START_ADDR) +#define pDMA7_X_COUNT ((volatile unsigned short *)DMA7_X_COUNT) +#define pDMA7_Y_COUNT ((volatile unsigned short *)DMA7_Y_COUNT) +#define pDMA7_X_MODIFY ((volatile signed short *)DMA7_X_MODIFY) +#define pDMA7_Y_MODIFY ((volatile signed short *)DMA7_Y_MODIFY) +#define pDMA7_CURR_DESC_PTR ((volatile void **)DMA7_CURR_DESC_PTR) +#define pDMA7_CURR_ADDR ((volatile void **)DMA7_CURR_ADDR) +#define pDMA7_CURR_X_COUNT ((volatile unsigned short *)DMA7_CURR_X_COUNT) +#define pDMA7_CURR_Y_COUNT ((volatile unsigned short *)DMA7_CURR_Y_COUNT) +#define pDMA7_IRQ_STATUS ((volatile unsigned short *)DMA7_IRQ_STATUS) +#define pDMA7_PERIPHERAL_MAP ((volatile unsigned short *)DMA7_PERIPHERAL_MAP) + +#define pMDMA_D1_CONFIG ((volatile unsigned short *)MDMA_D1_CONFIG) +#define pMDMA_D1_NEXT_DESC_PTR ((volatile void **)MDMA_D1_NEXT_DESC_PTR) +#define pMDMA_D1_START_ADDR ((volatile void **)MDMA_D1_START_ADDR) +#define pMDMA_D1_X_COUNT ((volatile unsigned short *)MDMA_D1_X_COUNT) +#define pMDMA_D1_Y_COUNT ((volatile unsigned short *)MDMA_D1_Y_COUNT) +#define pMDMA_D1_X_MODIFY ((volatile signed short *)MDMA_D1_X_MODIFY) +#define pMDMA_D1_Y_MODIFY ((volatile signed short *)MDMA_D1_Y_MODIFY) +#define pMDMA_D1_CURR_DESC_PTR ((volatile void **)MDMA_D1_CURR_DESC_PTR) +#define pMDMA_D1_CURR_ADDR ((volatile void **)MDMA_D1_CURR_ADDR) +#define pMDMA_D1_CURR_X_COUNT ((volatile unsigned short *)MDMA_D1_CURR_X_COUNT) +#define pMDMA_D1_CURR_Y_COUNT ((volatile unsigned short *)MDMA_D1_CURR_Y_COUNT) +#define pMDMA_D1_IRQ_STATUS ((volatile unsigned short *)MDMA_D1_IRQ_STATUS) +#define pMDMA_D1_PERIPHERAL_MAP ((volatile unsigned short *)MDMA_D1_PERIPHERAL_MAP) + +#define pMDMA_S1_CONFIG ((volatile unsigned short *)MDMA_S1_CONFIG) +#define pMDMA_S1_NEXT_DESC_PTR ((volatile void **)MDMA_S1_NEXT_DESC_PTR) +#define pMDMA_S1_START_ADDR ((volatile void **)MDMA_S1_START_ADDR) +#define pMDMA_S1_X_COUNT ((volatile unsigned short *)MDMA_S1_X_COUNT) +#define pMDMA_S1_Y_COUNT ((volatile unsigned short *)MDMA_S1_Y_COUNT) +#define pMDMA_S1_X_MODIFY ((volatile signed short *)MDMA_S1_X_MODIFY) +#define pMDMA_S1_Y_MODIFY ((volatile signed short *)MDMA_S1_Y_MODIFY) +#define pMDMA_S1_CURR_DESC_PTR ((volatile void **)MDMA_S1_CURR_DESC_PTR) +#define pMDMA_S1_CURR_ADDR ((volatile void **)MDMA_S1_CURR_ADDR) +#define pMDMA_S1_CURR_X_COUNT ((volatile unsigned short *)MDMA_S1_CURR_X_COUNT) +#define pMDMA_S1_CURR_Y_COUNT ((volatile unsigned short *)MDMA_S1_CURR_Y_COUNT) +#define pMDMA_S1_IRQ_STATUS ((volatile unsigned short *)MDMA_S1_IRQ_STATUS) +#define pMDMA_S1_PERIPHERAL_MAP ((volatile unsigned short *)MDMA_S1_PERIPHERAL_MAP) + +#define pMDMA_D0_CONFIG ((volatile unsigned short *)MDMA_D0_CONFIG) +#define pMDMA_D0_NEXT_DESC_PTR ((volatile void **)MDMA_D0_NEXT_DESC_PTR) +#define pMDMA_D0_START_ADDR ((volatile void **)MDMA_D0_START_ADDR) +#define pMDMA_D0_X_COUNT ((volatile unsigned short *)MDMA_D0_X_COUNT) +#define pMDMA_D0_Y_COUNT ((volatile unsigned short *)MDMA_D0_Y_COUNT) +#define pMDMA_D0_X_MODIFY ((volatile signed short *)MDMA_D0_X_MODIFY) +#define pMDMA_D0_Y_MODIFY ((volatile signed short *)MDMA_D0_Y_MODIFY) +#define pMDMA_D0_CURR_DESC_PTR ((volatile void **)MDMA_D0_CURR_DESC_PTR) +#define pMDMA_D0_CURR_ADDR ((volatile void **)MDMA_D0_CURR_ADDR) +#define pMDMA_D0_CURR_X_COUNT ((volatile unsigned short *)MDMA_D0_CURR_X_COUNT) +#define pMDMA_D0_CURR_Y_COUNT ((volatile unsigned short *)MDMA_D0_CURR_Y_COUNT) +#define pMDMA_D0_IRQ_STATUS ((volatile unsigned short *)MDMA_D0_IRQ_STATUS) +#define pMDMA_D0_PERIPHERAL_MAP ((volatile unsigned short *)MDMA_D0_PERIPHERAL_MAP) + +#define pMDMA_S0_CONFIG ((volatile unsigned short *)MDMA_S0_CONFIG) +#define pMDMA_S0_NEXT_DESC_PTR ((volatile void **)MDMA_S0_NEXT_DESC_PTR) +#define pMDMA_S0_START_ADDR ((volatile void **)MDMA_S0_START_ADDR) +#define pMDMA_S0_X_COUNT ((volatile unsigned short *)MDMA_S0_X_COUNT) +#define pMDMA_S0_Y_COUNT ((volatile unsigned short *)MDMA_S0_Y_COUNT) +#define pMDMA_S0_X_MODIFY ((volatile signed short *)MDMA_S0_X_MODIFY) +#define pMDMA_S0_Y_MODIFY ((volatile signed short *)MDMA_S0_Y_MODIFY) +#define pMDMA_S0_CURR_DESC_PTR ((volatile void **)MDMA_S0_CURR_DESC_PTR) +#define pMDMA_S0_CURR_ADDR ((volatile void **)MDMA_S0_CURR_ADDR) +#define pMDMA_S0_CURR_X_COUNT ((volatile unsigned short *)MDMA_S0_CURR_X_COUNT) +#define pMDMA_S0_CURR_Y_COUNT ((volatile unsigned short *)MDMA_S0_CURR_Y_COUNT) +#define pMDMA_S0_IRQ_STATUS ((volatile unsigned short *)MDMA_S0_IRQ_STATUS) +#define pMDMA_S0_PERIPHERAL_MAP ((volatile unsigned short *)MDMA_S0_PERIPHERAL_MAP) + +/* Aysnchronous Memory Controller - External Bus Interface Unit (0xFFC0 3C00-0xFFC0 3FFF) */ +#define pEBIU_AMGCTL ((volatile unsigned short *)EBIU_AMGCTL) +#define pEBIU_AMBCTL0 ((volatile unsigned long *)EBIU_AMBCTL0) +#define pEBIU_AMBCTL1 ((volatile unsigned long *)EBIU_AMBCTL1) + +/* System Bus Interface Unit (0xFFC0 4800-0xFFC0 4FFF) */ +/* #define L1SBAR 0xFFC04840 */ /* L1 SRAM Base Address Register */ +/* #define L1CSR 0xFFC04844 */ /* L1 SRAM Control Initialization Register */ + +/* + * #define pDB_ACOMP ((volatile void **)DB_ACOMP) + * #define pDB_CCOMP ((volatile unsigned long *)DB_CCOMP) + */ + +/* SDRAM Controller External Bus Interface Unit (0xFFC0 4C00-0xFFC0 4FFF) */ +#define pEBIU_SDGCTL ((volatile unsigned long *)EBIU_SDGCTL) +#define pEBIU_SDRRC ((volatile unsigned short *)EBIU_SDRRC) +#define pEBIU_SDSTAT ((volatile unsigned short *)EBIU_SDSTAT) +#define pEBIU_SDBCTL ((volatile unsigned short *)EBIU_SDBCTL) + +/* UART Controller */ +#define pUART_THR ((volatile unsigned short *)UART_THR) +#define pUART_RBR ((volatile unsigned short *)UART_RBR) +#define pUART_DLL ((volatile unsigned short *)UART_DLL) +#define pUART_IER ((volatile unsigned short *)UART_IER) +#define pUART_DLH ((volatile unsigned short *)UART_DLH) +#define pUART_IIR ((volatile unsigned short *)UART_IIR) +#define pUART_LCR ((volatile unsigned short *)UART_LCR) +#define pUART_MCR ((volatile unsigned short *)UART_MCR) +#define pUART_LSR ((volatile unsigned short *)UART_LSR) + +/* + * #define UART_MSR + */ +#define pUART_SCR ((volatile unsigned short *)UART_SCR) +#define pUART_GCTL ((volatile unsigned short *)UART_GCTL) + +/* SPI Controller */ +#define pSPI_CTL ((volatile unsigned short *)SPI_CTL) +#define pSPI_FLG ((volatile unsigned short *)SPI_FLG) +#define pSPI_STAT ((volatile unsigned short *)SPI_STAT) +#define pSPI_TDBR ((volatile unsigned short *)SPI_TDBR) +#define pSPI_RDBR ((volatile unsigned short *)SPI_RDBR) +#define pSPI_BAUD ((volatile unsigned short *)SPI_BAUD) +#define pSPI_SHADOW ((volatile unsigned short *)SPI_SHADOW) + +/* TIMER 0, 1, 2 Registers */ +#define pTIMER0_CONFIG ((volatile unsigned short *)TIMER0_CONFIG) +#define pTIMER0_COUNTER ((volatile unsigned long *)TIMER0_COUNTER) +#define pTIMER0_PERIOD ((volatile unsigned long *)TIMER0_PERIOD) +#define pTIMER0_WIDTH ((volatile unsigned long *)TIMER0_WIDTH) + +#define pTIMER1_CONFIG ((volatile unsigned short *)TIMER1_CONFIG) +#define pTIMER1_COUNTER ((volatile unsigned long *)TIMER1_COUNTER) +#define pTIMER1_PERIOD ((volatile unsigned long *)TIMER1_PERIOD) +#define pTIMER1_WIDTH ((volatile unsigned long *)TIMER1_WIDTH) + +#define pTIMER2_CONFIG ((volatile unsigned short *)TIMER2_CONFIG) +#define pTIMER2_COUNTER ((volatile unsigned long *)TIMER2_COUNTER) +#define pTIMER2_PERIOD ((volatile unsigned long *)TIMER2_PERIOD) +#define pTIMER2_WIDTH ((volatile unsigned long *)TIMER2_WIDTH) + +#define pTIMER_ENABLE ((volatile unsigned short *)TIMER_ENABLE) +#define pTIMER_DISABLE ((volatile unsigned short *)TIMER_DISABLE) +#define pTIMER_STATUS ((volatile unsigned short *)TIMER_STATUS) + +/* SPORT0 Controller */ +#define pSPORT0_TCR1 ((volatile unsigned short *)SPORT0_TCR1) +#define pSPORT0_TCR2 ((volatile unsigned short *)SPORT0_TCR2) +#define pSPORT0_TCLKDIV ((volatile unsigned short *)SPORT0_TCLKDIV) +#define pSPORT0_TFSDIV ((volatile unsigned short *)SPORT0_TFSDIV) +#define pSPORT0_TX ((volatile long *)SPORT0_TX) +#define pSPORT0_RX ((volatile long *)SPORT0_RX) +#define pSPORT0_TX32 ((volatile long *)SPORT0_TX) +#define pSPORT0_RX32 ((volatile long *)SPORT0_RX) +#define pSPORT0_TX16 ((volatile unsigned short *)SPORT0_TX) +#define pSPORT0_RX16 ((volatile unsigned short *)SPORT0_RX) +#define pSPORT0_RCR1 ((volatile unsigned short *)SPORT0_RCR1) +#define pSPORT0_RCR2 ((volatile unsigned short *)SPORT0_RCR2) +#define pSPORT0_RCLKDIV ((volatile unsigned short *)SPORT0_RCLKDIV) +#define pSPORT0_RFSDIV ((volatile unsigned short *)SPORT0_RFSDIV) +#define pSPORT0_STAT ((volatile unsigned short *)SPORT0_STAT) +#define pSPORT0_CHNL ((volatile unsigned short *)SPORT0_CHNL) +#define pSPORT0_MCMC1 ((volatile unsigned short *)SPORT0_MCMC1) +#define pSPORT0_MCMC2 ((volatile unsigned short *)SPORT0_MCMC2) +#define pSPORT0_MTCS0 ((volatile unsigned long *)SPORT0_MTCS0) +#define pSPORT0_MTCS1 ((volatile unsigned long *)SPORT0_MTCS1) +#define pSPORT0_MTCS2 ((volatile unsigned long *)SPORT0_MTCS2) +#define pSPORT0_MTCS3 ((volatile unsigned long *)SPORT0_MTCS3) +#define pSPORT0_MRCS0 ((volatile unsigned long *)SPORT0_MRCS0) +#define pSPORT0_MRCS1 ((volatile unsigned long *)SPORT0_MRCS1) +#define pSPORT0_MRCS2 ((volatile unsigned long *)SPORT0_MRCS2) +#define pSPORT0_MRCS3 ((volatile unsigned long *)SPORT0_MRCS3) + +/* SPORT1 Controller */ +#define pSPORT1_TCR1 ((volatile unsigned short *)SPORT1_TCR1) +#define pSPORT1_TCR2 ((volatile unsigned short *)SPORT1_TCR2) +#define pSPORT1_TCLKDIV ((volatile unsigned short *)SPORT1_TCLKDIV) +#define pSPORT1_TFSDIV ((volatile unsigned short *)SPORT1_TFSDIV) +#define pSPORT1_TX ((volatile long *)SPORT1_TX) +#define pSPORT1_RX ((volatile long *)SPORT1_RX) +#define pSPORT1_TX32 ((volatile long *)SPORT1_TX) +#define pSPORT1_RX32 ((volatile long *)SPORT1_RX) +#define pSPORT1_TX16 ((volatile unsigned short *)SPORT1_TX) +#define pSPORT1_RX16 ((volatile unsigned short *)SPORT1_RX) +#define pSPORT1_RCR1 ((volatile unsigned short *)SPORT1_RCR1) +#define pSPORT1_RCR2 ((volatile unsigned short *)SPORT1_RCR2) +#define pSPORT1_RCLKDIV ((volatile unsigned short *)SPORT1_RCLKDIV) +#define pSPORT1_RFSDIV ((volatile unsigned short *)SPORT1_RFSDIV) +#define pSPORT1_STAT ((volatile unsigned short *)SPORT1_STAT) +#define pSPORT1_CHNL ((volatile unsigned short *)SPORT1_CHNL) +#define pSPORT1_MCMC1 ((volatile unsigned short *)SPORT1_MCMC1) +#define pSPORT1_MCMC2 ((volatile unsigned short *)SPORT1_MCMC2) +#define pSPORT1_MTCS0 ((volatile unsigned long *)SPORT1_MTCS0) +#define pSPORT1_MTCS1 ((volatile unsigned long *)SPORT1_MTCS1) +#define pSPORT1_MTCS2 ((volatile unsigned long *)SPORT1_MTCS2) +#define pSPORT1_MTCS3 ((volatile unsigned long *)SPORT1_MTCS3) +#define pSPORT1_MRCS0 ((volatile unsigned long *)SPORT1_MRCS0) +#define pSPORT1_MRCS1 ((volatile unsigned long *)SPORT1_MRCS1) +#define pSPORT1_MRCS2 ((volatile unsigned long *)SPORT1_MRCS2) +#define pSPORT1_MRCS3 ((volatile unsigned long *)SPORT1_MRCS3) + +/* Parallel Peripheral Interface (PPI) */ +#define pPPI_CONTROL ((volatile unsigned short *)PPI_CONTROL) +#define pPPI_STATUS ((volatile unsigned short *)PPI_STATUS) +#define pPPI_DELAY ((volatile unsigned short *)PPI_DELAY) +#define pPPI_COUNT ((volatile unsigned short *)PPI_COUNT) +#define pPPI_FRAME ((volatile unsigned short *)PPI_FRAME) + +#endif /* _CDEF_BF532_H */ diff --git a/include/asm-blackfin/cpu/cdefBF533.h b/include/asm-blackfin/cpu/cdefBF533.h new file mode 100644 index 0000000000..8c751e6073 --- /dev/null +++ b/include/asm-blackfin/cpu/cdefBF533.h @@ -0,0 +1,24 @@ +/* + * cdefBF533.h + * + * This file is subject to the terms and conditions of the GNU Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Non-GPL License also available as part of VisualDSP++ + * + * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html + * + * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved + * + * This file under source code control, please send bugs or changes to: + * dsptools.support@analog.com + * + */ + +#ifndef _CDEFBF533_H +#define _CDEFBF533_H + +#include + +#endif /* _CDEFBF533_H */ diff --git a/include/asm-blackfin/cpu/cdefBF53x.h b/include/asm-blackfin/cpu/cdefBF53x.h new file mode 100644 index 0000000000..db4eaa9cf2 --- /dev/null +++ b/include/asm-blackfin/cpu/cdefBF53x.h @@ -0,0 +1,32 @@ +/************************************************************************ + * + * cdefBF53x.h + * + * (c) Copyright 2002-2003 Analog Devices, Inc. All rights reserved. + * + ************************************************************************/ + +#ifndef _CDEFBF53x_H +#define _CDEFBF53x_H + +#if defined(__ADSPBF531__) + #include +#elif defined(__ADSPBF532__) + #include +#elif defined(__ADSPBF533__) + #include +#elif defined(__ADSPBF561__) + #include +#elif defined(__ADSPBF535__) + #include +#elif defined(__AD6532__) + #include +#else + #if defined(__ADSPLPBLACKFIN__) + #include + #else + #include + #endif +#endif + +#endif /* _CDEFBF53x_H */ diff --git a/include/asm-blackfin/cpu/cdef_LPBlackfin.h b/include/asm-blackfin/cpu/cdef_LPBlackfin.h new file mode 100644 index 0000000000..e6471cbcb3 --- /dev/null +++ b/include/asm-blackfin/cpu/cdef_LPBlackfin.h @@ -0,0 +1,185 @@ +/* + * cdef_LPBlackfin.h + * + * This file is subject to the terms and conditions of the GNU Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Non-GPL License also available as part of VisualDSP++ + * + * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html + * + * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved + * + * This file under source code control, please send bugs or changes to: + * dsptools.support@analog.com + * + */ + +#ifndef _CDEF_LPBLACKFIN_H +#define _CDEF_LPBLACKFIN_H + +/* + * #if !defined(__ADSPLPBLACKFIN__) + * #warning cdef_LPBlackfin.h should only be included for 532 compatible chips. + * #endif + */ +#include + +/* Cache & SRAM Memory */ +#define pSRAM_BASE_ADDRESS ((volatile void **)SRAM_BASE_ADDRESS) +#define pDMEM_CONTROL ((volatile unsigned long *)DMEM_CONTROL) +#define pDCPLB_STATUS ((volatile unsigned long *)DCPLB_STATUS) +#define pDCPLB_FAULT_ADDR ((volatile void **)DCPLB_FAULT_ADDR) + +/* #define MMR_TIMEOUT 0xFFE00010 */ /* Memory-Mapped Register Timeout Register */ +#define pDCPLB_ADDR0 ((volatile void **)DCPLB_ADDR0) +#define pDCPLB_ADDR1 ((volatile void **)DCPLB_ADDR1) +#define pDCPLB_ADDR2 ((volatile void **)DCPLB_ADDR2) +#define pDCPLB_ADDR3 ((volatile void **)DCPLB_ADDR3) +#define pDCPLB_ADDR4 ((volatile void **)DCPLB_ADDR4) +#define pDCPLB_ADDR5 ((volatile void **)DCPLB_ADDR5) +#define pDCPLB_ADDR6 ((volatile void **)DCPLB_ADDR6) +#define pDCPLB_ADDR7 ((volatile void **)DCPLB_ADDR7) +#define pDCPLB_ADDR8 ((volatile void **)DCPLB_ADDR8) +#define pDCPLB_ADDR9 ((volatile void **)DCPLB_ADDR9) +#define pDCPLB_ADDR10 ((volatile void **)DCPLB_ADDR10) +#define pDCPLB_ADDR11 ((volatile void **)DCPLB_ADDR11) +#define pDCPLB_ADDR12 ((volatile void **)DCPLB_ADDR12) +#define pDCPLB_ADDR13 ((volatile void **)DCPLB_ADDR13) +#define pDCPLB_ADDR14 ((volatile void **)DCPLB_ADDR14) +#define pDCPLB_ADDR15 ((volatile void **)DCPLB_ADDR15) +#define pDCPLB_DATA0 ((volatile unsigned long *)DCPLB_DATA0) +#define pDCPLB_DATA1 ((volatile unsigned long *)DCPLB_DATA1) +#define pDCPLB_DATA2 ((volatile unsigned long *)DCPLB_DATA2) +#define pDCPLB_DATA3 ((volatile unsigned long *)DCPLB_DATA3) +#define pDCPLB_DATA4 ((volatile unsigned long *)DCPLB_DATA4) +#define pDCPLB_DATA5 ((volatile unsigned long *)DCPLB_DATA5) +#define pDCPLB_DATA6 ((volatile unsigned long *)DCPLB_DATA6) +#define pDCPLB_DATA7 ((volatile unsigned long *)DCPLB_DATA7) +#define pDCPLB_DATA8 ((volatile unsigned long *)DCPLB_DATA8) +#define pDCPLB_DATA9 ((volatile unsigned long *)DCPLB_DATA9) +#define pDCPLB_DATA10 ((volatile unsigned long *)DCPLB_DATA10) +#define pDCPLB_DATA11 ((volatile unsigned long *)DCPLB_DATA11) +#define pDCPLB_DATA12 ((volatile unsigned long *)DCPLB_DATA12) +#define pDCPLB_DATA13 ((volatile unsigned long *)DCPLB_DATA13) +#define pDCPLB_DATA14 ((volatile unsigned long *)DCPLB_DATA14) +#define pDCPLB_DATA15 ((volatile unsigned long *)DCPLB_DATA15) +#define pDTEST_COMMAND ((volatile unsigned long *)DTEST_COMMAND) + +/* #define DTEST_INDEX 0xFFE00304 */ /* Data Test Index Register */ +#define pDTEST_DATA0 ((volatile unsigned long *)DTEST_DATA0) +#define pDTEST_DATA1 ((volatile unsigned long *)DTEST_DATA1) + +/* + * # define DTEST_DATA2 0xFFE00408 Data Test Data Register + * #define DTEST_DATA3 0xFFE0040C Data Test Data Register + */ +#define pIMEM_CONTROL ((volatile unsigned long *)IMEM_CONTROL) +#define pICPLB_STATUS ((volatile unsigned long *)ICPLB_STATUS) +#define pICPLB_FAULT_ADDR ((volatile void **)ICPLB_FAULT_ADDR) +#define pICPLB_ADDR0 ((volatile void **)ICPLB_ADDR0) +#define pICPLB_ADDR1 ((volatile void **)ICPLB_ADDR1) +#define pICPLB_ADDR2 ((volatile void **)ICPLB_ADDR2) +#define pICPLB_ADDR3 ((volatile void **)ICPLB_ADDR3) +#define pICPLB_ADDR4 ((volatile void **)ICPLB_ADDR4) +#define pICPLB_ADDR5 ((volatile void **)ICPLB_ADDR5) +#define pICPLB_ADDR6 ((volatile void **)ICPLB_ADDR6) +#define pICPLB_ADDR7 ((volatile void **)ICPLB_ADDR7) +#define pICPLB_ADDR8 ((volatile void **)ICPLB_ADDR8) +#define pICPLB_ADDR9 ((volatile void **)ICPLB_ADDR9) +#define pICPLB_ADDR10 ((volatile void **)ICPLB_ADDR10) +#define pICPLB_ADDR11 ((volatile void **)ICPLB_ADDR11) +#define pICPLB_ADDR12 ((volatile void **)ICPLB_ADDR12) +#define pICPLB_ADDR13 ((volatile void **)ICPLB_ADDR13) +#define pICPLB_ADDR14 ((volatile void **)ICPLB_ADDR14) +#define pICPLB_ADDR15 ((volatile void **)ICPLB_ADDR15) +#define pICPLB_DATA0 ((volatile unsigned long *)ICPLB_DATA0) +#define pICPLB_DATA1 ((volatile unsigned long *)ICPLB_DATA1) +#define pICPLB_DATA2 ((volatile unsigned long *)ICPLB_DATA2) +#define pICPLB_DATA3 ((volatile unsigned long *)ICPLB_DATA3) +#define pICPLB_DATA4 ((volatile unsigned long *)ICPLB_DATA4) +#define pICPLB_DATA5 ((volatile unsigned long *)ICPLB_DATA5) +#define pICPLB_DATA6 ((volatile unsigned long *)ICPLB_DATA6) +#define pICPLB_DATA7 ((volatile unsigned long *)ICPLB_DATA7) +#define pICPLB_DATA8 ((volatile unsigned long *)ICPLB_DATA8) +#define pICPLB_DATA9 ((volatile unsigned long *)ICPLB_DATA9) +#define pICPLB_DATA10 ((volatile unsigned long *)ICPLB_DATA10) +#define pICPLB_DATA11 ((volatile unsigned long *)ICPLB_DATA11) +#define pICPLB_DATA12 ((volatile unsigned long *)ICPLB_DATA12) +#define pICPLB_DATA13 ((volatile unsigned long *)ICPLB_DATA13) +#define pICPLB_DATA14 ((volatile unsigned long *)ICPLB_DATA14) +#define pICPLB_DATA15 ((volatile unsigned long *)ICPLB_DATA15) +#define pITEST_COMMAND ((volatile unsigned long *)ITEST_COMMAND) + +/* #define ITEST_INDEX 0xFFE01304 */ /* Instruction Test Index Register */ +#define pITEST_DATA0 ((volatile unsigned long *)ITEST_DATA0) +#define pITEST_DATA1 ((volatile unsigned long *)ITEST_DATA1) + +/* Event/Interrupt Registers */ +#define pEVT0 ((volatile void **)EVT0) +#define pEVT1 ((volatile void **)EVT1) +#define pEVT2 ((volatile void **)EVT2) +#define pEVT3 ((volatile void **)EVT3) +#define pEVT4 ((volatile void **)EVT4) +#define pEVT5 ((volatile void **)EVT5) +#define pEVT6 ((volatile void **)EVT6) +#define pEVT7 ((volatile void **)EVT7) +#define pEVT8 ((volatile void **)EVT8) +#define pEVT9 ((volatile void **)EVT9) +#define pEVT10 ((volatile void **)EVT10) +#define pEVT11 ((volatile void **)EVT11) +#define pEVT12 ((volatile void **)EVT12) +#define pEVT13 ((volatile void **)EVT13) +#define pEVT14 ((volatile void **)EVT14) +#define pEVT15 ((volatile void **)EVT15) +#define pIMASK ((volatile unsigned long *)IMASK) +#define pIPEND ((volatile unsigned long *)IPEND) +#define pILAT ((volatile unsigned long *)ILAT) + +/* Core Timer Registers */ +#define pTCNTL ((volatile unsigned long *)TCNTL) +#define pTPERIOD ((volatile unsigned long *)TPERIOD) +#define pTSCALE ((volatile unsigned long *)TSCALE) +#define pTCOUNT ((volatile unsigned long *)TCOUNT) + +/* Debug/MP/Emulation Registers */ +#define pDSPID ((volatile unsigned long *)DSPID) +#define pDBGCTL ((volatile unsigned long *)DBGCTL) +#define pDBGSTAT ((volatile unsigned long *)DBGSTAT) +#define pEMUDAT ((volatile unsigned long *)EMUDAT) + +/* Trace Buffer Registers */ +#define pTBUFCTL ((volatile unsigned long *)TBUFCTL) +#define pTBUFSTAT ((volatile unsigned long *)TBUFSTAT) +#define pTBUF ((volatile void **)TBUF) + +/* Watch Point Control Registers */ +#define pWPIACTL ((volatile unsigned long *)WPIACTL) +#define pWPIA0 ((volatile void **)WPIA0) +#define pWPIA1 ((volatile void **)WPIA1) +#define pWPIA2 ((volatile void **)WPIA2) +#define pWPIA3 ((volatile void **)WPIA3) +#define pWPIA4 ((volatile void **)WPIA4) +#define pWPIA5 ((volatile void **)WPIA5) +#define pWPIACNT0 ((volatile unsigned long *)WPIACNT0) +#define pWPIACNT1 ((volatile unsigned long *)WPIACNT1) +#define pWPIACNT2 ((volatile unsigned long *)WPIACNT2) +#define pWPIACNT3 ((volatile unsigned long *)WPIACNT3) +#define pWPIACNT4 ((volatile unsigned long *)WPIACNT4) +#define pWPIACNT5 ((volatile unsigned long *)WPIACNT5) +#define pWPDACTL ((volatile unsigned long *)WPDACTL) +#define pWPDA0 ((volatile void **)WPDA0) +#define pWPDA1 ((volatile void **)WPDA1) +#define pWPDACNT0 ((volatile unsigned long *)WPDACNT0) +#define pWPDACNT1 ((volatile unsigned long *)WPDACNT1) +#define pWPSTAT ((volatile unsigned long *)WPSTAT) + +/* Performance Monitor Registers */ +#define pPFCTL ((volatile unsigned long *)PFCTL) +#define pPFCNTR0 ((volatile unsigned long *)PFCNTR0) +#define pPFCNTR1 ((volatile unsigned long *)PFCNTR1) + +/* #define IPRIO 0xFFE02110 */ /* Core Interrupt Priority Register */ + +#endif /* _CDEF_LPBLACKFIN_H */ diff --git a/include/asm-blackfin/cpu/defBF531.h b/include/asm-blackfin/cpu/defBF531.h new file mode 100644 index 0000000000..6c7cd5a6db --- /dev/null +++ b/include/asm-blackfin/cpu/defBF531.h @@ -0,0 +1,24 @@ +/* + * defBF531.h + * + * This file is subject to the terms and conditions of the GNU Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Non-GPL License also available as part of VisualDSP++ + * + * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html + * + * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved + * + * This file under source code control, please send bugs or changes to: + * dsptools.support@analog.com + * + */ + +#ifndef _DEFBF531_H +#define _DEFBF531_H + +#include + +#endif /* _DEFBF531_H */ diff --git a/include/asm-blackfin/cpu/defBF532.h b/include/asm-blackfin/cpu/defBF532.h new file mode 100644 index 0000000000..c30d5cd7bc --- /dev/null +++ b/include/asm-blackfin/cpu/defBF532.h @@ -0,0 +1,1159 @@ +/* + * defBF532.h + * + * This file is subject to the terms and conditions of the GNU Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Non-GPL License also available as part of VisualDSP++ + * + * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html + * + * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved + * + * This file under source code control, please send bugs or changes to: + * dsptools.support@analog.com + * + */ + +/* SYSTEM & MM REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF532 */ + +#ifndef _DEF_BF532_H +#define _DEF_BF532_H + +/* + * #if !defined(__ADSPLPBLACKFIN__) + * #warning defBF532.h should only be included for 532 compatible chips + * #endif + */ + +/* include all Core registers and bit definitions */ +#include + +/* Helper macros + * usage: + * P0.H = HI(UART_THR); + * P0.L = LO(UART_THR); + */ + +#define LO(con32) ((con32) & 0xFFFF) +#define lo(con32) ((con32) & 0xFFFF) +#define HI(con32) (((con32) >> 16) & 0xFFFF) +#define hi(con32) (((con32) >> 16) & 0xFFFF) + +/* + * System MMR Register Map + */ + +/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */ +#define PLL_CTL 0xFFC00000 /* PLL Control register (16-bit) */ +#define PLL_DIV 0xFFC00004 /* PLL Divide Register (16-bit) */ +#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register (16-bit) */ +#define PLL_STAT 0xFFC0000C /* PLL Status register (16-bit) */ +#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count register (16-bit) */ +#define CHIPID 0xFFC00014 /* Chip ID register (32-bit) */ +#define SWRST 0xFFC00100 /* Software Reset Register (16-bit) */ +#define SYSCR 0xFFC00104 /* System Configuration register */ + +/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */ +#define SIC_RVECT 0xFFC00108 /* Interrupt Reset Vector Address Register */ +#define SIC_IMASK 0xFFC0010C /* Interrupt Mask Register */ +#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */ +#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */ +#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */ +#define SIC_ISR 0xFFC00120 /* Interrupt Status Register */ +#define SIC_IWR 0xFFC00124 /* Interrupt Wakeup Register */ + +/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */ +#define WDOG_CTL 0xFFC00200 /* Watchdog Control Register */ +#define WDOG_CNT 0xFFC00204 /* Watchdog Count Register */ +#define WDOG_STAT 0xFFC00208 /* Watchdog Status Register */ + +/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */ +#define RTC_STAT 0xFFC00300 /* RTC Status Register */ +#define RTC_ICTL 0xFFC00304 /* RTC Interrupt Control Register */ +#define RTC_ISTAT 0xFFC00308 /* RTC Interrupt Status Register */ +#define RTC_SWCNT 0xFFC0030C /* RTC Stopwatch Count Register */ +#define RTC_ALARM 0xFFC00310 /* RTC Alarm Time Register */ +#define RTC_FAST 0xFFC00314 /* RTC Prescaler Enable Register */ +#define RTC_PREN 0xFFC00314 /* RTC Prescaler Enable Register (alternate macro) */ + +/* UART Controller (0xFFC00400 - 0xFFC004FF) */ +#define UART_THR 0xFFC00400 /* Transmit Holding register */ +#define UART_RBR 0xFFC00400 /* Receive Buffer register */ +#define UART_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */ +#define UART_IER 0xFFC00404 /* Interrupt Enable Register */ +#define UART_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */ +#define UART_IIR 0xFFC00408 /* Interrupt Identification Register */ +#define UART_LCR 0xFFC0040C /* Line Control Register */ +#define UART_MCR 0xFFC00410 /* Modem Control Register */ +#define UART_LSR 0xFFC00414 /* Line Status Register */ +/* #define UART_MSR 0xFFC00418 */ /* Modem Status Register (UNUSED in ADSP-BF532) */ +#define UART_SCR 0xFFC0041C /* SCR Scratch Register */ +#define UART_GCTL 0xFFC00424 /* Global Control Register */ + +/* SPI Controller (0xFFC00500 - 0xFFC005FF) */ +#define SPI_CTL 0xFFC00500 /* SPI Control Register */ +#define SPI_FLG 0xFFC00504 /* SPI Flag register */ +#define SPI_STAT 0xFFC00508 /* SPI Status register */ +#define SPI_TDBR 0xFFC0050C /* SPI Transmit Data Buffer Register */ +#define SPI_RDBR 0xFFC00510 /* SPI Receive Data Buffer Register */ +#define SPI_BAUD 0xFFC00514 /* SPI Baud rate Register */ +#define SPI_SHADOW 0xFFC00518 /* SPI_RDBR Shadow Register */ + +/* TIMER 0, 1, 2 Registers (0xFFC00600 - 0xFFC006FF) */ +#define TIMER0_CONFIG 0xFFC00600 /* Timer 0 Configuration Register */ +#define TIMER0_COUNTER 0xFFC00604 /* Timer 0 Counter Register */ +#define TIMER0_PERIOD 0xFFC00608 /* Timer 0 Period Register */ +#define TIMER0_WIDTH 0xFFC0060C /* Timer 0 Width Register */ + +#define TIMER1_CONFIG 0xFFC00610 /* Timer 1 Configuration Register */ +#define TIMER1_COUNTER 0xFFC00614 /* Timer 1 Counter Register */ +#define TIMER1_PERIOD 0xFFC00618 /* Timer 1 Period Register */ +#define TIMER1_WIDTH 0xFFC0061C /* Timer 1 Width Register */ + +#define TIMER2_CONFIG 0xFFC00620 /* Timer 2 Configuration Register */ +#define TIMER2_COUNTER 0xFFC00624 /* Timer 2 Counter Register */ +#define TIMER2_PERIOD 0xFFC00628 /* Timer 2 Period Register */ +#define TIMER2_WIDTH 0xFFC0062C /* Timer 2 Width Register */ + +#define TIMER_ENABLE 0xFFC00640 /* Timer Enable Register */ +#define TIMER_DISABLE 0xFFC00644 /* Timer Disable Register */ +#define TIMER_STATUS 0xFFC00648 /* Timer Status Register */ + +/* General Purpose IO (0xFFC00700 - 0xFFC007FF) */ +#define FIO_FLAG_D 0xFFC00700 /* Flag Mask to directly specify state of pins */ +#define FIO_FLAG_C 0xFFC00704 /* Peripheral Interrupt Flag Register (clear) */ +#define FIO_FLAG_S 0xFFC00708 /* Peripheral Interrupt Flag Register (set) */ +#define FIO_FLAG_T 0xFFC0070C /* Flag Mask to directly toggle state of pins */ +#define FIO_MASKA_D 0xFFC00710 /* Flag Mask Interrupt A Register (set directly) */ +#define FIO_MASKA_C 0xFFC00714 /* Flag Mask Interrupt A Register (clear) */ +#define FIO_MASKA_S 0xFFC00718 /* Flag Mask Interrupt A Register (set) */ +#define FIO_MASKA_T 0xFFC0071C /* Flag Mask Interrupt A Register (toggle) */ +#define FIO_MASKB_D 0xFFC00720 /* Flag Mask Interrupt B Register (set directly) */ +#define FIO_MASKB_C 0xFFC00724 /* Flag Mask Interrupt B Register (clear) */ +#define FIO_MASKB_S 0xFFC00728 /* Flag Mask Interrupt B Register (set) */ +#define FIO_MASKB_T 0xFFC0072C /* Flag Mask Interrupt B Register (toggle) */ +#define FIO_DIR 0xFFC00730 /* Peripheral Flag Direction Register */ +#define FIO_POLAR 0xFFC00734 /* Flag Source Polarity Register */ +#define FIO_EDGE 0xFFC00738 /* Flag Source Sensitivity Register */ +#define FIO_BOTH 0xFFC0073C /* Flag Set on BOTH Edges Register */ +#define FIO_INEN 0xFFC00740 /* Flag Input Enable Register */ + +/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */ +#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */ +#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */ +#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */ +#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */ +#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */ +#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */ +#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */ +#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */ +#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */ +#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */ +#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */ +#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */ +#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */ +#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */ +#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */ +#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */ +#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */ +#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */ +#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */ +#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */ +#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */ +#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */ + +/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */ +#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */ +#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */ +#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */ +#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */ +#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */ +#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */ +#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */ +#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */ +#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */ +#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */ +#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */ +#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */ +#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */ +#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */ +#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */ +#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */ +#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */ +#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */ +#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */ +#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */ +#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */ +#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */ + +/* Asynchronous Memory Controller - External Bus Interface Unit */ +#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */ +#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */ +#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */ + +/* SDRAM Controller External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */ +#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */ +#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */ +#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */ +#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */ + +/* DMA Test Registers */ +#define DMA_CCOMP 0xFFC00B04 /* DMA Cycle Count Register */ +#define DMA_ACOMP 0xFFC00B00 /* Debug Compare Address Register */ +#define DMA_MISR 0xFFC00B08 /* MISR Register */ +#define DMA_TCPER 0xFFC00B0C /* Traffic Control Periods Register */ +#define DMA_TCCNT 0xFFC00B10 /* Traffic Control Current Counts Register */ +#define DMA_TMODE 0xFFC00B14 /* DMA Test Modes Register */ +#define DMA_TMCHAN 0xFFC00B18 /* DMA Testmode Selected Channel Register */ +#define DMA_TMSTAT 0xFFC00B1C /* DMA Testmode Channel Status Register */ +#define DMA_TMBD 0xFFC00B20 /* DMA Testmode DAB Bus Data Register */ +#define DMA_TMM0D 0xFFC00B24 /* DMA Testmode Mem0 Data Register */ +#define DMA_TMM1D 0xFFC00B28 /* DMA Testmode Mem1 Data Register */ +#define DMA_TMMA 0xFFC00B2C /* DMA Testmode Memory Address Register */ + +/* DMA Controller (0xFFC00C00 - 0xFFC00FFF) */ +#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */ +#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */ +#define DMA0_START_ADDR 0xFFC00C04 /* DMA Channel 0 Start Address Register */ +#define DMA0_X_COUNT 0xFFC00C10 /* DMA Channel 0 X Count Register */ +#define DMA0_Y_COUNT 0xFFC00C18 /* DMA Channel 0 Y Count Register */ +#define DMA0_X_MODIFY 0xFFC00C14 /* DMA Channel 0 X Modify Register */ +#define DMA0_Y_MODIFY 0xFFC00C1C /* DMA Channel 0 Y Modify Register */ +#define DMA0_CURR_DESC_PTR 0xFFC00C20 /* DMA Channel 0 Current Descriptor Pointer Register */ +#define DMA0_CURR_ADDR 0xFFC00C24 /* DMA Channel 0 Current Address Register */ +#define DMA0_CURR_X_COUNT 0xFFC00C30 /* DMA Channel 0 Current X Count Register */ +#define DMA0_CURR_Y_COUNT 0xFFC00C38 /* DMA Channel 0 Current Y Count Register */ +#define DMA0_IRQ_STATUS 0xFFC00C28 /* DMA Channel 0 Interrupt/Status Register */ +#define DMA0_PERIPHERAL_MAP 0xFFC00C2C /* DMA Channel 0 Peripheral Map Register */ + +#define DMA1_CONFIG 0xFFC00C48 /* DMA Channel 1 Configuration Register */ +#define DMA1_NEXT_DESC_PTR 0xFFC00C40 /* DMA Channel 1 Next Descriptor Pointer Register */ +#define DMA1_START_ADDR 0xFFC00C44 /* DMA Channel 1 Start Address Register */ +#define DMA1_X_COUNT 0xFFC00C50 /* DMA Channel 1 X Count Register */ +#define DMA1_Y_COUNT 0xFFC00C58 /* DMA Channel 1 Y Count Register */ +#define DMA1_X_MODIFY 0xFFC00C54 /* DMA Channel 1 X Modify Register */ +#define DMA1_Y_MODIFY 0xFFC00C5C /* DMA Channel 1 Y Modify Register */ +#define DMA1_CURR_DESC_PTR 0xFFC00C60 /* DMA Channel 1 Current Descriptor Pointer Register */ +#define DMA1_CURR_ADDR 0xFFC00C64 /* DMA Channel 1 Current Address Register */ +#define DMA1_CURR_X_COUNT 0xFFC00C70 /* DMA Channel 1 Current X Count Register */ +#define DMA1_CURR_Y_COUNT 0xFFC00C78 /* DMA Channel 1 Current Y Count Register */ +#define DMA1_IRQ_STATUS 0xFFC00C68 /* DMA Channel 1 Interrupt/Status Register */ +#define DMA1_PERIPHERAL_MAP 0xFFC00C6C /* DMA Channel 1 Peripheral Map Register */ + +#define DMA2_CONFIG 0xFFC00C88 /* DMA Channel 2 Configuration Register */ +#define DMA2_NEXT_DESC_PTR 0xFFC00C80 /* DMA Channel 2 Next Descriptor Pointer Register */ +#define DMA2_START_ADDR 0xFFC00C84 /* DMA Channel 2 Start Address Register */ +#define DMA2_X_COUNT 0xFFC00C90 /* DMA Channel 2 X Count Register */ +#define DMA2_Y_COUNT 0xFFC00C98 /* DMA Channel 2 Y Count Register */ +#define DMA2_X_MODIFY 0xFFC00C94 /* DMA Channel 2 X Modify Register */ +#define DMA2_Y_MODIFY 0xFFC00C9C /* DMA Channel 2 Y Modify Register */ +#define DMA2_CURR_DESC_PTR 0xFFC00CA0 /* DMA Channel 2 Current Descriptor Pointer Register */ +#define DMA2_CURR_ADDR 0xFFC00CA4 /* DMA Channel 2 Current Address Register */ +#define DMA2_CURR_X_COUNT 0xFFC00CB0 /* DMA Channel 2 Current X Count Register */ +#define DMA2_CURR_Y_COUNT 0xFFC00CB8 /* DMA Channel 2 Current Y Count Register */ +#define DMA2_IRQ_STATUS 0xFFC00CA8 /* DMA Channel 2 Interrupt/Status Register */ +#define DMA2_PERIPHERAL_MAP 0xFFC00CAC /* DMA Channel 2 Peripheral Map Register */ + +#define DMA3_CONFIG 0xFFC00CC8 /* DMA Channel 3 Configuration Register */ +#define DMA3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA Channel 3 Next Descriptor Pointer Register */ +#define DMA3_START_ADDR 0xFFC00CC4 /* DMA Channel 3 Start Address Register */ +#define DMA3_X_COUNT 0xFFC00CD0 /* DMA Channel 3 X Count Register */ +#define DMA3_Y_COUNT 0xFFC00CD8 /* DMA Channel 3 Y Count Register */ +#define DMA3_X_MODIFY 0xFFC00CD4 /* DMA Channel 3 X Modify Register */ +#define DMA3_Y_MODIFY 0xFFC00CDC /* DMA Channel 3 Y Modify Register */ +#define DMA3_CURR_DESC_PTR 0xFFC00CE0 /* DMA Channel 3 Current Descriptor Pointer Register */ +#define DMA3_CURR_ADDR 0xFFC00CE4 /* DMA Channel 3 Current Address Register */ +#define DMA3_CURR_X_COUNT 0xFFC00CF0 /* DMA Channel 3 Current X Count Register */ +#define DMA3_CURR_Y_COUNT 0xFFC00CF8 /* DMA Channel 3 Current Y Count Register */ +#define DMA3_IRQ_STATUS 0xFFC00CE8 /* DMA Channel 3 Interrupt/Status Register */ +#define DMA3_PERIPHERAL_MAP 0xFFC00CEC /* DMA Channel 3 Peripheral Map Register */ + +#define DMA4_CONFIG 0xFFC00D08 /* DMA Channel 4 Configuration Register */ +#define DMA4_NEXT_DESC_PTR 0xFFC00D00 /* DMA Channel 4 Next Descriptor Pointer Register */ +#define DMA4_START_ADDR 0xFFC00D04 /* DMA Channel 4 Start Address Register */ +#define DMA4_X_COUNT 0xFFC00D10 /* DMA Channel 4 X Count Register */ +#define DMA4_Y_COUNT 0xFFC00D18 /* DMA Channel 4 Y Count Register */ +#define DMA4_X_MODIFY 0xFFC00D14 /* DMA Channel 4 X Modify Register */ +#define DMA4_Y_MODIFY 0xFFC00D1C /* DMA Channel 4 Y Modify Register */ +#define DMA4_CURR_DESC_PTR 0xFFC00D20 /* DMA Channel 4 Current Descriptor Pointer Register */ +#define DMA4_CURR_ADDR 0xFFC00D24 /* DMA Channel 4 Current Address Register */ +#define DMA4_CURR_X_COUNT 0xFFC00D30 /* DMA Channel 4 Current X Count Register */ +#define DMA4_CURR_Y_COUNT 0xFFC00D38 /* DMA Channel 4 Current Y Count Register */ +#define DMA4_IRQ_STATUS 0xFFC00D28 /* DMA Channel 4 Interrupt/Status Register */ +#define DMA4_PERIPHERAL_MAP 0xFFC00D2C /* DMA Channel 4 Peripheral Map Register */ + +#define DMA5_CONFIG 0xFFC00D48 /* DMA Channel 5 Configuration Register */ +#define DMA5_NEXT_DESC_PTR 0xFFC00D40 /* DMA Channel 5 Next Descriptor Pointer Register */ +#define DMA5_START_ADDR 0xFFC00D44 /* DMA Channel 5 Start Address Register */ +#define DMA5_X_COUNT 0xFFC00D50 /* DMA Channel 5 X Count Register */ +#define DMA5_Y_COUNT 0xFFC00D58 /* DMA Channel 5 Y Count Register */ +#define DMA5_X_MODIFY 0xFFC00D54 /* DMA Channel 5 X Modify Register */ +#define DMA5_Y_MODIFY 0xFFC00D5C /* DMA Channel 5 Y Modify Register */ +#define DMA5_CURR_DESC_PTR 0xFFC00D60 /* DMA Channel 5 Current Descriptor Pointer Register */ +#define DMA5_CURR_ADDR 0xFFC00D64 /* DMA Channel 5 Current Address Register */ +#define DMA5_CURR_X_COUNT 0xFFC00D70 /* DMA Channel 5 Current X Count Register */ +#define DMA5_CURR_Y_COUNT 0xFFC00D78 /* DMA Channel 5 Current Y Count Register */ +#define DMA5_IRQ_STATUS 0xFFC00D68 /* DMA Channel 5 Interrupt/Status Register */ +#define DMA5_PERIPHERAL_MAP 0xFFC00D6C /* DMA Channel 5 Peripheral Map Register */ + +#define DMA6_CONFIG 0xFFC00D88 /* DMA Channel 6 Configuration Register */ +#define DMA6_NEXT_DESC_PTR 0xFFC00D80 /* DMA Channel 6 Next Descriptor Pointer Register */ +#define DMA6_START_ADDR 0xFFC00D84 /* DMA Channel 6 Start Address Register */ +#define DMA6_X_COUNT 0xFFC00D90 /* DMA Channel 6 X Count Register */ +#define DMA6_Y_COUNT 0xFFC00D98 /* DMA Channel 6 Y Count Register */ +#define DMA6_X_MODIFY 0xFFC00D94 /* DMA Channel 6 X Modify Register */ +#define DMA6_Y_MODIFY 0xFFC00D9C /* DMA Channel 6 Y Modify Register */ +#define DMA6_CURR_DESC_PTR 0xFFC00DA0 /* DMA Channel 6 Current Descriptor Pointer Register */ +#define DMA6_CURR_ADDR 0xFFC00DA4 /* DMA Channel 6 Current Address Register */ +#define DMA6_CURR_X_COUNT 0xFFC00DB0 /* DMA Channel 6 Current X Count Register */ +#define DMA6_CURR_Y_COUNT 0xFFC00DB8 /* DMA Channel 6 Current Y Count Register */ +#define DMA6_IRQ_STATUS 0xFFC00DA8 /* DMA Channel 6 Interrupt/Status Register */ +#define DMA6_PERIPHERAL_MAP 0xFFC00DAC /* DMA Channel 6 Peripheral Map Register */ + +#define DMA7_CONFIG 0xFFC00DC8 /* DMA Channel 7 Configuration Register */ +#define DMA7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA Channel 7 Next Descriptor Pointer Register */ +#define DMA7_START_ADDR 0xFFC00DC4 /* DMA Channel 7 Start Address Register */ +#define DMA7_X_COUNT 0xFFC00DD0 /* DMA Channel 7 X Count Register */ +#define DMA7_Y_COUNT 0xFFC00DD8 /* DMA Channel 7 Y Count Register */ +#define DMA7_X_MODIFY 0xFFC00DD4 /* DMA Channel 7 X Modify Register */ +#define DMA7_Y_MODIFY 0xFFC00DDC /* DMA Channel 7 Y Modify Register */ +#define DMA7_CURR_DESC_PTR 0xFFC00DE0 /* DMA Channel 7 Current Descriptor Pointer Register */ +#define DMA7_CURR_ADDR 0xFFC00DE4 /* DMA Channel 7 Current Address Register */ +#define DMA7_CURR_X_COUNT 0xFFC00DF0 /* DMA Channel 7 Current X Count Register */ +#define DMA7_CURR_Y_COUNT 0xFFC00DF8 /* DMA Channel 7 Current Y Count Register */ +#define DMA7_IRQ_STATUS 0xFFC00DE8 /* DMA Channel 7 Interrupt/Status Register */ +#define DMA7_PERIPHERAL_MAP 0xFFC00DEC /* DMA Channel 7 Peripheral Map Register */ + +#define MDMA_D1_CONFIG 0xFFC00E88 /* MemDMA Stream 1 Destination Configuration Register */ +#define MDMA_D1_NEXT_DESC_PTR 0xFFC00E80 /* MemDMA Stream 1 Destination Next Descriptor Pointer Register */ +#define MDMA_D1_START_ADDR 0xFFC00E84 /* MemDMA Stream 1 Destination Start Address Register */ +#define MDMA_D1_X_COUNT 0xFFC00E90 /* MemDMA Stream 1 Destination X Count Register */ +#define MDMA_D1_Y_COUNT 0xFFC00E98 /* MemDMA Stream 1 Destination Y Count Register */ +#define MDMA_D1_X_MODIFY 0xFFC00E94 /* MemDMA Stream 1 Destination X Modify Register */ +#define MDMA_D1_Y_MODIFY 0xFFC00E9C /* MemDMA Stream 1 Destination Y Modify Register */ +#define MDMA_D1_CURR_DESC_PTR 0xFFC00EA0 /* MemDMA Stream 1 Destination Current Descriptor Pointer Register */ +#define MDMA_D1_CURR_ADDR 0xFFC00EA4 /* MemDMA Stream 1 Destination Current Address Register */ +#define MDMA_D1_CURR_X_COUNT 0xFFC00EB0 /* MemDMA Stream 1 Destination Current X Count Register */ +#define MDMA_D1_CURR_Y_COUNT 0xFFC00EB8 /* MemDMA Stream 1 Destination Current Y Count Register */ +#define MDMA_D1_IRQ_STATUS 0xFFC00EA8 /* MemDMA Stream 1 Destination Interrupt/Status Register */ +#define MDMA_D1_PERIPHERAL_MAP 0xFFC00EAC /* MemDMA Stream 1 Destination Peripheral Map Register */ + +#define MDMA_S1_CONFIG 0xFFC00EC8 /* MemDMA Stream 1 Source Configuration Register */ +#define MDMA_S1_NEXT_DESC_PTR 0xFFC00EC0 /* MemDMA Stream 1 Source Next Descriptor Pointer Register */ +#define MDMA_S1_START_ADDR 0xFFC00EC4 /* MemDMA Stream 1 Source Start Address Register */ +#define MDMA_S1_X_COUNT 0xFFC00ED0 /* MemDMA Stream 1 Source X Count Register */ +#define MDMA_S1_Y_COUNT 0xFFC00ED8 /* MemDMA Stream 1 Source Y Count Register */ +#define MDMA_S1_X_MODIFY 0xFFC00ED4 /* MemDMA Stream 1 Source X Modify Register */ +#define MDMA_S1_Y_MODIFY 0xFFC00EDC /* MemDMA Stream 1 Source Y Modify Register */ +#define MDMA_S1_CURR_DESC_PTR 0xFFC00EE0 /* MemDMA Stream 1 Source Current Descriptor Pointer Register */ +#define MDMA_S1_CURR_ADDR 0xFFC00EE4 /* MemDMA Stream 1 Source Current Address Register */ +#define MDMA_S1_CURR_X_COUNT 0xFFC00EF0 /* MemDMA Stream 1 Source Current X Count Register */ +#define MDMA_S1_CURR_Y_COUNT 0xFFC00EF8 /* MemDMA Stream 1 Source Current Y Count Register */ +#define MDMA_S1_IRQ_STATUS 0xFFC00EE8 /* MemDMA Stream 1 Source Interrupt/Status Register */ +#define MDMA_S1_PERIPHERAL_MAP 0xFFC00EEC /* MemDMA Stream 1 Source Peripheral Map Register */ + +#define MDMA_D0_CONFIG 0xFFC00E08 /* MemDMA Stream 0 Destination Configuration Register */ +#define MDMA_D0_NEXT_DESC_PTR 0xFFC00E00 /* MemDMA Stream 0 Destination Next Descriptor Pointer Register */ +#define MDMA_D0_START_ADDR 0xFFC00E04 /* MemDMA Stream 0 Destination Start Address Register */ +#define MDMA_D0_X_COUNT 0xFFC00E10 /* MemDMA Stream 0 Destination X Count Register */ +#define MDMA_D0_Y_COUNT 0xFFC00E18 /* MemDMA Stream 0 Destination Y Count Register */ +#define MDMA_D0_X_MODIFY 0xFFC00E14 /* MemDMA Stream 0 Destination X Modify Register */ +#define MDMA_D0_Y_MODIFY 0xFFC00E1C /* MemDMA Stream 0 Destination Y Modify Register */ +#define MDMA_D0_CURR_DESC_PTR 0xFFC00E20 /* MemDMA Stream 0 Destination Current Descriptor Pointer Register */ +#define MDMA_D0_CURR_ADDR 0xFFC00E24 /* MemDMA Stream 0 Destination Current Address Register */ +#define MDMA_D0_CURR_X_COUNT 0xFFC00E30 /* MemDMA Stream 0 Destination Current X Count Register */ +#define MDMA_D0_CURR_Y_COUNT 0xFFC00E38 /* MemDMA Stream 0 Destination Current Y Count Register */ +#define MDMA_D0_IRQ_STATUS 0xFFC00E28 /* MemDMA Stream 0 Destination Interrupt/Status Register */ +#define MDMA_D0_PERIPHERAL_MAP 0xFFC00E2C /* MemDMA Stream 0 Destination Peripheral Map Register */ + +#define MDMA_S0_CONFIG 0xFFC00E48 /* MemDMA Stream 0 Source Configuration Register */ +#define MDMA_S0_NEXT_DESC_PTR 0xFFC00E40 /* MemDMA Stream 0 Source Next Descriptor Pointer Register */ +#define MDMA_S0_START_ADDR 0xFFC00E44 /* MemDMA Stream 0 Source Start Address Register */ +#define MDMA_S0_X_COUNT 0xFFC00E50 /* MemDMA Stream 0 Source X Count Register */ +#define MDMA_S0_Y_COUNT 0xFFC00E58 /* MemDMA Stream 0 Source Y Count Register */ +#define MDMA_S0_X_MODIFY 0xFFC00E54 /* MemDMA Stream 0 Source X Modify Register */ +#define MDMA_S0_Y_MODIFY 0xFFC00E5C /* MemDMA Stream 0 Source Y Modify Register */ +#define MDMA_S0_CURR_DESC_PTR 0xFFC00E60 /* MemDMA Stream 0 Source Current Descriptor Pointer Register */ +#define MDMA_S0_CURR_ADDR 0xFFC00E64 /* MemDMA Stream 0 Source Current Address Register */ +#define MDMA_S0_CURR_X_COUNT 0xFFC00E70 /* MemDMA Stream 0 Source Current X Count Register */ +#define MDMA_S0_CURR_Y_COUNT 0xFFC00E78 /* MemDMA Stream 0 Source Current Y Count Register */ +#define MDMA_S0_IRQ_STATUS 0xFFC00E68 /* MemDMA Stream 0 Source Interrupt/Status Register */ +#define MDMA_S0_PERIPHERAL_MAP 0xFFC00E6C /* MemDMA Stream 0 Source Peripheral Map Register */ + +/* Parallel Peripheral Interface (PPI) (0xFFC01000 - 0xFFC010FF) */ +#define PPI_CONTROL 0xFFC01000 /* PPI Control Register */ +#define PPI_STATUS 0xFFC01004 /* PPI Status Register */ +#define PPI_COUNT 0xFFC01008 /* PPI Transfer Count Register */ +#define PPI_DELAY 0xFFC0100C /* PPI Delay Count Register */ +#define PPI_FRAME 0xFFC01010 /* PPI Frame Length Register */ + +/* + * System MMR Register Bits + */ +/* + * PLL AND RESET MASKS + */ + +/* PLL_CTL Masks */ +#define PLL_CLKIN 0x00000000 /* Pass CLKIN to PLL */ +#define PLL_CLKIN_DIV2 0x00000001 /* Pass CLKIN/2 to PLL */ +#define PLL_OFF 0x00000002 /* Shut off PLL clocks */ +#define STOPCK_OFF 0x00000008 /* Core clock off */ +#define PDWN 0x00000020 /* Put the PLL in a Deep Sleep state */ +#define BYPASS 0x00000100 /* Bypass the PLL */ + +/* PLL_DIV Masks */ +#define SCLK_DIV(x) (x) /* SCLK = VCO / x */ + +#define CCLK_DIV1 0x00000000 /* CCLK = VCO / 1 */ +#define CCLK_DIV2 0x00000010 /* CCLK = VCO / 2 */ +#define CCLK_DIV4 0x00000020 /* CCLK = VCO / 4 */ +#define CCLK_DIV8 0x00000030 /* CCLK = VCO / 8 */ + +/* SWRST Mask */ +#define SYSTEM_RESET 0x00000007 /* Initiates a system software reset */ + +/* + * SYSTEM INTERRUPT CONTROLLER MASKS + */ + +/* SIC_IAR0 Masks */ +#define P0_IVG(x) ((x)-7) /* Peripheral #0 assigned IVG #x */ +#define P1_IVG(x) ((x)-7) << 0x4 /* Peripheral #1 assigned IVG #x */ +#define P2_IVG(x) ((x)-7) << 0x8 /* Peripheral #2 assigned IVG #x */ +#define P3_IVG(x) ((x)-7) << 0xC /* Peripheral #3 assigned IVG #x */ +#define P4_IVG(x) ((x)-7) << 0x10 /* Peripheral #4 assigned IVG #x */ +#define P5_IVG(x) ((x)-7) << 0x14 /* Peripheral #5 assigned IVG #x */ +#define P6_IVG(x) ((x)-7) << 0x18 /* Peripheral #6 assigned IVG #x */ +#define P7_IVG(x) ((x)-7) << 0x1C /* Peripheral #7 assigned IVG #x */ + +/* SIC_IAR1 Masks */ +#define P8_IVG(x) ((x)-7) /* Peripheral #8 assigned IVG #x */ +#define P9_IVG(x) ((x)-7) << 0x4 /* Peripheral #9 assigned IVG #x */ +#define P10_IVG(x) ((x)-7) << 0x8 /* Peripheral #10 assigned IVG #x */ +#define P11_IVG(x) ((x)-7) << 0xC /* Peripheral #11 assigned IVG #x */ +#define P12_IVG(x) ((x)-7) << 0x10 /* Peripheral #12 assigned IVG #x */ +#define P13_IVG(x) ((x)-7) << 0x14 /* Peripheral #13 assigned IVG #x */ +#define P14_IVG(x) ((x)-7) << 0x18 /* Peripheral #14 assigned IVG #x */ +#define P15_IVG(x) ((x)-7) << 0x1C /* Peripheral #15 assigned IVG #x */ + +/* SIC_IAR2 Masks */ +#define P16_IVG(x) ((x)-7) /* Peripheral #16 assigned IVG #x */ +#define P17_IVG(x) ((x)-7) << 0x4 /* Peripheral #17 assigned IVG #x */ +#define P18_IVG(x) ((x)-7) << 0x8 /* Peripheral #18 assigned IVG #x */ +#define P19_IVG(x) ((x)-7) << 0xC /* Peripheral #19 assigned IVG #x */ +#define P20_IVG(x) ((x)-7) << 0x10 /* Peripheral #20 assigned IVG #x */ +#define P21_IVG(x) ((x)-7) << 0x14 /* Peripheral #21 assigned IVG #x */ +#define P22_IVG(x) ((x)-7) << 0x18 /* Peripheral #22 assigned IVG #x */ +#define P23_IVG(x) ((x)-7) << 0x1C /* Peripheral #23 assigned IVG #x */ + +/* SIC_IMASK Masks */ +#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */ +#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */ +#define SIC_MASK(x) (1 << (x)) /* Mask Peripheral #x interrupt */ +#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << (x))) /* Unmask Peripheral #x interrupt */ + +/* SIC_IWR Masks */ +#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */ +#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */ +#define IWR_ENABLE(x) (1 << (x)) /* Wakeup Enable Peripheral #x */ +#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << (x))) /* Wakeup Disable Peripheral #x */ + +/* + * WATCHDOG TIMER MASKS + */ +/* Watchdog Timer WDOG_CTL Register */ +#define ICTL(x) ((x<<1) & 0x0006) +#define ENABLE_RESET 0x00000000 /* Set Watchdog Timer to generate reset */ +#define ENABLE_NMI 0x00000002 /* Set Watchdog Timer to generate non-maskable interrupt */ +#define ENABLE_GPI 0x00000004 /* Set Watchdog Timer to generate general-purpose interrupt */ +#define DISABLE_EVT 0x00000006 /* Disable Watchdog Timer interrupts */ + +#define TMR_EN 0x0000 +#define TMR_DIS 0x0AD0 +#define TRO 0x8000 + +#define ICTL_P0 0x01 +#define ICTL_P1 0x02 +#define TRO_P 0x0F + +/* RTC_STAT and RTC_ALARM register */ +#define RTSEC 0x0000003F /* Real-Time Clock Seconds */ +#define RTMIN 0x00000FC0 /* Real-Time Clock Minutes */ +#define RTHR 0x0001F000 /* Real-Time Clock Hours */ +#define RTDAY 0xFFFE0000 /* Real-Time Clock Days */ + +/* RTC_ICTL register */ +#define SWIE 0x0001 /* Stopwatch Interrupt Enable */ +#define AIE 0x0002 /* Alarm Interrupt Enable */ +#define SIE 0x0004 /* Seconds (1 Hz) Interrupt Enable */ +#define MIE 0x0008 /* Minutes Interrupt Enable */ +#define HIE 0x0010 /* Hours Interrupt Enable */ +#define DIE 0x0020 /* 24 Hours (Days) Interrupt Enable */ +#define DAIE 0x0040 /* Day Alarm (Day, Hour, Minute, Second) Interrupt Enable */ +#define WCIE 0x8000 /* Write Complete Interrupt Enable */ + +/* RTC_ISTAT register */ +#define SWEF 0x0001 /* Stopwatch Event Flag */ +#define AEF 0x0002 /* Alarm Event Flag */ +#define SEF 0x0004 /* Seconds (1 Hz) Event Flag */ +#define MEF 0x0008 /* Minutes Event Flag */ +#define HEF 0x0010 /* Hours Event Flag */ +#define DEF 0x0020 /* 24 Hours (Days) Event Flag */ +#define DAEF 0x0040 /* Day Alarm (Day, Hour, Minute, Second) Event Flag */ +#define WPS 0x4000 /* Write Pending Status (RO) */ +#define WCOM 0x8000 /* Write Complete */ + +/* RTC_FAST Mask (RTC_PREN Mask) */ +#define ENABLE_PRESCALE 0x00000001 /* Enable prescaler so RTC runs at 1 Hz */ +#define PREN 0x00000001 /* ** Must be set after power-up for proper operation of RTC */ + +/* + * UART CONTROLLER MASKS + */ + +/* UART_LCR Register */ +#define DLAB 0x80 +#define SB 0x40 +#define STP 0x20 +#define EPS 0x10 +#define PEN 0x08 +#define STB 0x04 +#define WLS(x) ((x-5) & 0x03) + +#define DLAB_P 0x07 +#define SB_P 0x06 +#define STP_P 0x05 +#define EPS_P 0x04 +#define PEN_P 0x03 +#define STB_P 0x02 +#define WLS_P1 0x01 +#define WLS_P0 0x00 + +/* UART_MCR Register */ +#define LOOP_ENA 0x10 +#define LOOP_ENA_P 0x04 + +/* UART_LSR Register */ +#define TEMT 0x40 +#define THRE 0x20 +#define BI 0x10 +#define FE 0x08 +#define PE 0x04 +#define OE 0x02 +#define DR 0x01 + +#define TEMP_P 0x06 +#define THRE_P 0x05 +#define BI_P 0x04 +#define FE_P 0x03 +#define PE_P 0x02 +#define OE_P 0x01 +#define DR_P 0x00 + +/* UART_IER Register */ +#define ELSI 0x04 +#define ETBEI 0x02 +#define ERBFI 0x01 + +#define ELSI_P 0x02 +#define ETBEI_P 0x01 +#define ERBFI_P 0x00 + +/* UART_IIR Register */ +#define STATUS(x) ((x << 1) & 0x06) +#define NINT 0x01 +#define STATUS_P1 0x02 +#define STATUS_P0 0x01 +#define NINT_P 0x00 + +/* UART_GCTL Register */ +#define FFE 0x20 +#define FPE 0x10 +#define RPOLC 0x08 +#define TPOLC 0x04 +#define IREN 0x02 +#define UCEN 0x01 + +#define FFE_P 0x05 +#define FPE_P 0x04 +#define RPOLC_P 0x03 +#define TPOLC_P 0x02 +#define IREN_P 0x01 +#define UCEN_P 0x00 + +/* + * SERIAL PORT MASKS + */ +/* SPORTx_TCR1 Masks */ +#define TSPEN 0x0001 /* TX enable */ +#define ITCLK 0x0002 /* Internal TX Clock Select */ +#define TDTYPE 0x000C /* TX Data Formatting Select */ +#define TLSBIT 0x0010 /* TX Bit Order */ +#define ITFS 0x0200 /* Internal TX Frame Sync Select */ +#define TFSR 0x0400 /* TX Frame Sync Required Select */ +#define DITFS 0x0800 /* Data Independent TX Frame Sync Select */ +#define LTFS 0x1000 /* Low TX Frame Sync Select */ +#define LATFS 0x2000 /* Late TX Frame Sync Select */ +#define TCKFE 0x4000 /* TX Clock Falling Edge Select */ + +/* SPORTx_TCR2 Masks */ +#define SLEN 0x001F /*TX Word Length */ +#define TXSE 0x0100 /*TX Secondary Enable */ +#define TSFSE 0x0200 /*TX Stereo Frame Sync Enable */ +#define TRFST 0x0400 /*TX Right-First Data Order */ + +/* SPORTx_RCR1 Masks */ +#define RSPEN 0x0001 /* RX enable */ +#define IRCLK 0x0002 /* Internal RX Clock Select */ +#define RDTYPE 0x000C /* RX Data Formatting Select */ +#define RULAW 0x0008 /* u-Law enable */ +#define RALAW 0x000C /* A-Law enable */ +#define RLSBIT 0x0010 /* RX Bit Order */ +#define IRFS 0x0200 /* Internal RX Frame Sync Select */ +#define RFSR 0x0400 /* RX Frame Sync Required Select */ +#define LRFS 0x1000 /* Low RX Frame Sync Select */ +#define LARFS 0x2000 /* Late RX Frame Sync Select */ +#define RCKFE 0x4000 /* RX Clock Falling Edge Select */ + +/* SPORTx_RCR2 Masks */ +#define SLEN 0x001F /* RX Word Length */ +#define RXSE 0x0100 /* RX Secondary Enable */ +#define RSFSE 0x0200 /* RX Stereo Frame Sync Enable */ +#define RRFST 0x0400 /* Right-First Data Order */ + +/* SPORTx_STAT Masks */ +#define RXNE 0x0001 /* RX FIFO Not Empty Status */ +#define RUVF 0x0002 /* RX Underflow Status */ +#define ROVF 0x0004 /* RX Overflow Status */ +#define TXF 0x0008 /* TX FIFO Full Status */ +#define TUVF 0x0010 /* TX Underflow Status */ +#define TOVF 0x0020 /* TX Overflow Status */ +#define TXHRE 0x0040 /* TX Hold Register Empty */ + +/* SPORTx_MCMC1 Masks */ +#define WSIZE 0x0000F000 /* Multichannel Window Size Field */ +#define WOFF 0x000003FF /* /Multichannel Window Offset Field */ + +/* SPORTx_MCMC2 Masks */ +#define MCCRM 0x00000003 /* Multichannel Clock Recovery Mode */ +#define MCDTXPE 0x00000004 /* Multichannel DMA Transmit Packing */ +#define MCDRXPE 0x00000008 /* Multichannel DMA Receive Packing */ +#define MCMEN 0x00000010 /* Multichannel Frame Mode Enable */ +#define FSDR 0x00000080 /* Multichannel Frame Sync to Data Relationship */ +#define MFD 0x0000F000 /* Multichannel Frame Delay */ + +/* + * PARALLEL PERIPHERAL INTERFACE (PPI) MASKS + */ + +/* PPI_CONTROL Masks */ +#define PORT_EN 0x00000001 /* PPI Port Enable */ +#define PORT_DIR 0x00000002 /* PPI Port Direction */ +#define XFR_TYPE 0x0000000C /* PPI Transfer Type */ +#define PORT_CFG 0x00000030 /* PPI Port Configuration */ +#define FLD_SEL 0x00000040 /* PPI Active Field Select */ +#define PACK_EN 0x00000080 /* PPI Packing Mode */ +#define DMA32 0x00000100 /* PPI 32-bit DMA Enable */ +#define SKIP_EN 0x00000200 /* PPI Skip Element Enable */ +#define SKIP_EO 0x00000400 /* PPI Skip Even/Odd Elements */ +#define DLENGTH 0x00003800 /* PPI Data Length */ +#define DLEN_8 0x0 /* PPI Data Length mask for DLEN=8 */ +#define DLEN(x) (((x-9) & 0x07) << 11) /* PPI Data Length (only works for x=10-->x=16) */ +#define POL 0x0000C000 /* PPI Signal Polarities */ + +/* PPI_STATUS Masks */ +#define FLD 0x00000400 /* Field Indicator */ +#define FT_ERR 0x00000800 /* Frame Track Error */ +#define OVR 0x00001000 /* FIFO Overflow Error */ +#define UNDR 0x00002000 /* FIFO Underrun Error */ +#define ERR_DET 0x00004000 /* Error Detected Indicator */ +#define ERR_NCOR 0x00008000 /* Error Not Corrected Indicator */ + +/* + * DMA CONTROLLER MASKS + */ + +/* DMAx_CONFIG, MDMA_yy_CONFIG Masks */ +#define DMAEN 0x00000001 /* Channel Enable */ +#define WNR 0x00000002 /* Channel Direction (W/R*) */ +#define WDSIZE_8 0x00000000 /* Word Size 8 bits */ +#define WDSIZE_16 0x00000004 /* Word Size 16 bits */ +#define WDSIZE_32 0x00000008 /* Word Size 32 bits */ +#define DMA2D 0x00000010 /* 2D/1D* Mode */ +#define RESTART 0x00000020 /* Restart */ +#define DI_SEL 0x00000040 /* Data Interrupt Select */ +#define DI_EN 0x00000080 /* Data Interrupt Enable */ +#define NDSIZE 0x00000900 /* Next Descriptor Size */ +#define FLOW 0x00007000 /* Flow Control */ + +#define DMAEN_P 0 /* Channel Enable */ +#define WNR_P 1 /* Channel Direction (W/R*) */ +#define DMA2D_P 4 /* 2D/1D* Mode */ +#define RESTART_P 5 /* Restart */ +#define DI_SEL_P 6 /* Data Interrupt Select */ +#define DI_EN_P 7 /* Data Interrupt Enable */ + +/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */ +#define DMA_DONE 0x00000001 /* DMA Done Indicator */ +#define DMA_ERR 0x00000002 /* DMA Error Indicator */ +#define DFETCH 0x00000004 /* Descriptor Fetch Indicator */ +#define DMA_RUN 0x00000008 /* DMA Running Indicator */ + +#define DMA_DONE_P 0 /* DMA Done Indicator */ +#define DMA_ERR_P 1 /* DMA Error Indicator */ +#define DFETCH_P 2 /* Descriptor Fetch Indicator */ +#define DMA_RUN_P 3 /* DMA Running Indicator */ + +/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */ +#define CTYPE 0x00000040 /* DMA Channel Type Indicator */ +#define CTYPE_P 6 /* DMA Channel Type Indicator BIT POSITION */ +#define PCAP8 0x00000080 /* DMA 8-bit Operation Indicator */ +#define PCAP16 0x00000100 /* DMA 16-bit Operation Indicator */ +#define PCAP32 0x00000200 /* DMA 32-bit Operation Indicator */ +#define PCAPWR 0x00000400 /* DMA Write Operation Indicator */ +#define PCAPRD 0x00000800 /* DMA Read Operation Indicator */ +#define PMAP 0x00007000 /* DMA Peripheral Map Field */ + +/* + * GENERAL PURPOSE TIMER MASKS + */ + +/* PWM Timer bit definitions */ + +/* TIMER_ENABLE Register */ +#define TIMEN0 0x0001 +#define TIMEN1 0x0002 +#define TIMEN2 0x0004 + +#define TIMEN0_P 0x00 +#define TIMEN1_P 0x01 +#define TIMEN2_P 0x02 + +/* TIMER_DISABLE Register */ +#define TIMDIS0 0x0001 +#define TIMDIS1 0x0002 +#define TIMDIS2 0x0004 + +#define TIMDIS0_P 0x00 +#define TIMDIS1_P 0x01 +#define TIMDIS2_P 0x02 + +/* TIMER_STATUS Register */ +#define TIMIL0 0x0001 +#define TIMIL1 0x0002 +#define TIMIL2 0x0004 +#define TOVL_ERR0 0x0010 +#define TOVL_ERR1 0x0020 +#define TOVL_ERR2 0x0040 +#define TRUN0 0x1000 +#define TRUN1 0x2000 +#define TRUN2 0x4000 + +#define TIMIL0_P 0x00 +#define TIMIL1_P 0x01 +#define TIMIL2_P 0x02 +#define TOVL_ERR0_P 0x04 +#define TOVL_ERR1_P 0x05 +#define TOVL_ERR2_P 0x06 +#define TRUN0_P 0x0C +#define TRUN1_P 0x0D +#define TRUN2_P 0x0E + +/* TIMERx_CONFIG Registers */ +#define PWM_OUT 0x0001 +#define WDTH_CAP 0x0002 +#define EXT_CLK 0x0003 +#define PULSE_HI 0x0004 +#define PERIOD_CNT 0x0008 +#define IRQ_ENA 0x0010 +#define TIN_SEL 0x0020 +#define OUT_DIS 0x0040 +#define CLK_SEL 0x0080 +#define TOGGLE_HI 0x0100 +#define EMU_RUN 0x0200 +#define ERR_TYP(x) ((x & 0x03) << 14) + +#define TMODE_P0 0x00 +#define TMODE_P1 0x01 +#define PULSE_HI_P 0x02 +#define PERIOD_CNT_P 0x03 +#define IRQ_ENA_P 0x04 +#define TIN_SEL_P 0x05 +#define OUT_DIS_P 0x06 +#define CLK_SEL_P 0x07 +#define TOGGLE_HI_P 0x08 +#define EMU_RUN_P 0x09 +#define ERR_TYP_P0 0x0E +#define ERR_TYP_P1 0x0F + +/* + * PROGRAMMABLE FLAG MASKS + */ + +/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */ +#define PF0 0x0001 +#define PF1 0x0002 +#define PF2 0x0004 +#define PF3 0x0008 +#define PF4 0x0010 +#define PF5 0x0020 +#define PF6 0x0040 +#define PF7 0x0080 +#define PF8 0x0100 +#define PF9 0x0200 +#define PF10 0x0400 +#define PF11 0x0800 +#define PF12 0x1000 +#define PF13 0x2000 +#define PF14 0x4000 +#define PF15 0x8000 + +/* General Purpose IO (0xFFC00700 - 0xFFC007FF) BIT POSITIONS */ +#define PF0_P 0 +#define PF1_P 1 +#define PF2_P 2 +#define PF3_P 3 +#define PF4_P 4 +#define PF5_P 5 +#define PF6_P 6 +#define PF7_P 7 +#define PF8_P 8 +#define PF9_P 9 +#define PF10_P 10 +#define PF11_P 11 +#define PF12_P 12 +#define PF13_P 13 +#define PF14_P 14 +#define PF15_P 15 + +/* + * SERIAL PERIPHERAL INTERFACE (SPI) MASKS + */ + +/* SPI_CTL Masks */ +#define TIMOD 0x00000003 /* Transfer initiation mode and interrupt generation */ +#define SZ 0x00000004 /* Send Zero (=0) or last (=1) word when TDBR empty. */ +#define GM 0x00000008 /* When RDBR full, get more (=1) data or discard (=0) incoming Data */ +#define PSSE 0x00000010 /* Enable (=1) Slave-Select input for Master. */ +#define EMISO 0x00000020 /* Enable (=1) MISO pin as an output. */ +#define SIZE 0x00000100 /* Word length (0 => 8 bits, 1 => 16 bits) */ +#define LSBF 0x00000200 /* Data format (0 => MSB sent/received first 1 => LSB sent/received first) */ +#define CPHA 0x00000400 /* Clock phase (0 => SPICLK starts toggling in middle of xfer, 1 => SPICLK toggles at the beginning of xfer. */ +#define CPOL 0x00000800 /* Clock polarity (0 => active-high, 1 => active-low) */ +#define MSTR 0x00001000 /* Configures SPI as master (=1) or slave (=0) */ +#define WOM 0x00002000 /* Open drain (=1) data output enable (for MOSI and MISO) */ +#define SPE 0x00004000 /* SPI module enable (=1), disable (=0) */ + +/* SPI_FLG Masks */ +#define FLS1 0x00000002 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLS2 0x00000004 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLS3 0x00000008 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLS4 0x00000010 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLS5 0x00000020 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLS6 0x00000040 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLS7 0x00000080 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */ +#define FLG1 0x00000200 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLG2 0x00000400 /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLG3 0x00000800 /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLG4 0x00001000 /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLG5 0x00002000 /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLG6 0x00004000 /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLG7 0x00008000 /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */ + +/* SPI_FLG Bit Positions */ +#define FLS1_P 0x00000001 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLS2_P 0x00000002 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLS3_P 0x00000003 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLS4_P 0x00000004 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLS5_P 0x00000005 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLS6_P 0x00000006 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLS7_P 0x00000007 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */ +#define FLG1_P 0x00000009 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */ +#define FLG2_P 0x0000000A /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */ +#define FLG3_P 0x0000000B /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */ +#define FLG4_P 0x0000000C /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */ +#define FLG5_P 0x0000000D /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */ +#define FLG6_P 0x0000000E /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */ +#define FLG7_P 0x0000000F /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */ + +/* SPI_STAT Masks */ +#define SPIF 0x00000001 /* Set (=1) when SPI single-word transfer complete */ +#define MODF 0x00000002 /* Set(=1)in a master device when some other device tries to become master */ +#define TXE 0x00000004 /* Set (=1) when transmission occurs with no new data in SPI_TDBR */ +#define TXS 0x00000008 /* SPI_TDBR Data Buffer Status (0=Empty, 1=Full) */ +#define RBSY 0x00000010 /* Set (=1) when data is received with RDBR full */ +#define RXS 0x00000020 /* SPI_RDBR Data Buffer Status (0=Empty, 1=Full) */ +#define TXCOL 0x00000040 /* When set (=1), corrupt data may have been transmitted */ + +/* + * ASYNCHRONOUS MEMORY CONTROLLER MASKS + */ + +/* AMGCTL Masks */ +#define AMCKEN 0x00000001 /* Enable CLKOUT */ +#define AMBEN_B0 0x00000002 /* Enable Asynchronous Memory Bank 0 only */ +#define AMBEN_B0_B1 0x00000004 /* Enable Asynchronous Memory Banks 0 & 1 only */ +#define AMBEN_B0_B1_B2 0x00000006 /* Enable Asynchronous Memory Banks 0, 1, and 2 */ +#define AMBEN_ALL 0x00000008 /* Enable Asynchronous Memory Banks (all) 0, 1, 2, and 3 */ + +/* AMGCTL Bit Positions */ +#define AMCKEN_P 0x00000000 /* Enable CLKOUT */ +#define AMBEN_P0 0x00000001 /* Asynchronous Memory Enable, 000 - banks 0-3 disabled, 001 - Bank 0 enabled */ +#define AMBEN_P1 0x00000002 /* Asynchronous Memory Enable, 010 - banks 0&1 enabled, 011 - banks 0-3 enabled */ +#define AMBEN_P2 0x00000003 /* Asynchronous Memory Enable, 1xx - All banks (bank 0, 1, 2, and 3) enabled */ + +/* AMBCTL0 Masks */ +#define B0RDYEN 0x00000001 /* Bank 0 RDY Enable, 0=disable, 1=enable */ +#define B0RDYPOL 0x00000002 /* Bank 0 RDY Active high, 0=active low, 1=active high */ +#define B0TT_1 0x00000004 /* Bank 0 Transition Time from Read to Write = 1 cycle */ +#define B0TT_2 0x00000008 /* Bank 0 Transition Time from Read to Write = 2 cycles */ +#define B0TT_3 0x0000000C /* Bank 0 Transition Time from Read to Write = 3 cycles */ +#define B0TT_4 0x00000000 /* Bank 0 Transition Time from Read to Write = 4 cycles */ +#define B0ST_1 0x00000010 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=1 cycle */ +#define B0ST_2 0x00000020 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=2 cycles */ +#define B0ST_3 0x00000030 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=3 cycles */ +#define B0ST_4 0x00000000 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=4 cycles */ +#define B0HT_1 0x00000040 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 1 cycle */ +#define B0HT_2 0x00000080 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 2 cycles */ +#define B0HT_3 0x000000C0 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 3 cycles */ +#define B0HT_0 0x00000000 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 0 cycles */ +#define B0RAT_1 0x00000100 /* Bank 0 Read Access Time = 1 cycle */ +#define B0RAT_2 0x00000200 /* Bank 0 Read Access Time = 2 cycles */ +#define B0RAT_3 0x00000300 /* Bank 0 Read Access Time = 3 cycles */ +#define B0RAT_4 0x00000400 /* Bank 0 Read Access Time = 4 cycles */ +#define B0RAT_5 0x00000500 /* Bank 0 Read Access Time = 5 cycles */ +#define B0RAT_6 0x00000600 /* Bank 0 Read Access Time = 6 cycles */ +#define B0RAT_7 0x00000700 /* Bank 0 Read Access Time = 7 cycles */ +#define B0RAT_8 0x00000800 /* Bank 0 Read Access Time = 8 cycles */ +#define B0RAT_9 0x00000900 /* Bank 0 Read Access Time = 9 cycles */ +#define B0RAT_10 0x00000A00 /* Bank 0 Read Access Time = 10 cycles */ +#define B0RAT_11 0x00000B00 /* Bank 0 Read Access Time = 11 cycles */ +#define B0RAT_12 0x00000C00 /* Bank 0 Read Access Time = 12 cycles */ +#define B0RAT_13 0x00000D00 /* Bank 0 Read Access Time = 13 cycles */ +#define B0RAT_14 0x00000E00 /* Bank 0 Read Access Time = 14 cycles */ +#define B0RAT_15 0x00000F00 /* Bank 0 Read Access Time = 15 cycles */ +#define B0WAT_1 0x00001000 /* Bank 0 Write Access Time = 1 cycle */ +#define B0WAT_2 0x00002000 /* Bank 0 Write Access Time = 2 cycles */ +#define B0WAT_3 0x00003000 /* Bank 0 Write Access Time = 3 cycles */ +#define B0WAT_4 0x00004000 /* Bank 0 Write Access Time = 4 cycles */ +#define B0WAT_5 0x00005000 /* Bank 0 Write Access Time = 5 cycles */ +#define B0WAT_6 0x00006000 /* Bank 0 Write Access Time = 6 cycles */ +#define B0WAT_7 0x00007000 /* Bank 0 Write Access Time = 7 cycles */ +#define B0WAT_8 0x00008000 /* Bank 0 Write Access Time = 8 cycles */ +#define B0WAT_9 0x00009000 /* Bank 0 Write Access Time = 9 cycles */ +#define B0WAT_10 0x0000A000 /* Bank 0 Write Access Time = 10 cycles */ +#define B0WAT_11 0x0000B000 /* Bank 0 Write Access Time = 11 cycles */ +#define B0WAT_12 0x0000C000 /* Bank 0 Write Access Time = 12 cycles */ +#define B0WAT_13 0x0000D000 /* Bank 0 Write Access Time = 13 cycles */ +#define B0WAT_14 0x0000E000 /* Bank 0 Write Access Time = 14 cycles */ +#define B0WAT_15 0x0000F000 /* Bank 0 Write Access Time = 15 cycles */ +#define B1RDYEN 0x00010000 /* Bank 1 RDY enable, 0=disable, 1=enable */ +#define B1RDYPOL 0x00020000 /* Bank 1 RDY Active high, 0=active low, 1=active high */ +#define B1TT_1 0x00040000 /* Bank 1 Transition Time from Read to Write = 1 cycle */ +#define B1TT_2 0x00080000 /* Bank 1 Transition Time from Read to Write = 2 cycles */ +#define B1TT_3 0x000C0000 /* Bank 1 Transition Time from Read to Write = 3 cycles */ +#define B1TT_4 0x00000000 /* Bank 1 Transition Time from Read to Write = 4 cycles */ +#define B1ST_1 0x00100000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */ +#define B1ST_2 0x00200000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */ +#define B1ST_3 0x00300000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */ +#define B1ST_4 0x00000000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */ +#define B1HT_1 0x00400000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */ +#define B1HT_2 0x00800000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */ +#define B1HT_3 0x00C00000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */ +#define B1HT_0 0x00000000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */ +#define B1RAT_1 0x01000000 /* Bank 1 Read Access Time = 1 cycle */ +#define B1RAT_2 0x02000000 /* Bank 1 Read Access Time = 2 cycles */ +#define B1RAT_3 0x03000000 /* Bank 1 Read Access Time = 3 cycles */ +#define B1RAT_4 0x04000000 /* Bank 1 Read Access Time = 4 cycles */ +#define B1RAT_5 0x05000000 /* Bank 1 Read Access Time = 5 cycles */ +#define B1RAT_6 0x06000000 /* Bank 1 Read Access Time = 6 cycles */ +#define B1RAT_7 0x07000000 /* Bank 1 Read Access Time = 7 cycles */ +#define B1RAT_8 0x08000000 /* Bank 1 Read Access Time = 8 cycles */ +#define B1RAT_9 0x09000000 /* Bank 1 Read Access Time = 9 cycles */ +#define B1RAT_10 0x0A000000 /* Bank 1 Read Access Time = 10 cycles */ +#define B1RAT_11 0x0B000000 /* Bank 1 Read Access Time = 11 cycles */ +#define B1RAT_12 0x0C000000 /* Bank 1 Read Access Time = 12 cycles */ +#define B1RAT_13 0x0D000000 /* Bank 1 Read Access Time = 13 cycles */ +#define B1RAT_14 0x0E000000 /* Bank 1 Read Access Time = 14 cycles */ +#define B1RAT_15 0x0F000000 /* Bank 1 Read Access Time = 15 cycles */ +#define B1WAT_1 0x10000000 /* Bank 1 Write Access Time = 1 cycle */ +#define B1WAT_2 0x20000000 /* Bank 1 Write Access Time = 2 cycles */ +#define B1WAT_3 0x30000000 /* Bank 1 Write Access Time = 3 cycles */ +#define B1WAT_4 0x40000000 /* Bank 1 Write Access Time = 4 cycles */ +#define B1WAT_5 0x50000000 /* Bank 1 Write Access Time = 5 cycles */ +#define B1WAT_6 0x60000000 /* Bank 1 Write Access Time = 6 cycles */ +#define B1WAT_7 0x70000000 /* Bank 1 Write Access Time = 7 cycles */ +#define B1WAT_8 0x80000000 /* Bank 1 Write Access Time = 8 cycles */ +#define B1WAT_9 0x90000000 /* Bank 1 Write Access Time = 9 cycles */ +#define B1WAT_10 0xA0000000 /* Bank 1 Write Access Time = 10 cycles */ +#define B1WAT_11 0xB0000000 /* Bank 1 Write Access Time = 11 cycles */ +#define B1WAT_12 0xC0000000 /* Bank 1 Write Access Time = 12 cycles */ +#define B1WAT_13 0xD0000000 /* Bank 1 Write Access Time = 13 cycles */ +#define B1WAT_14 0xE0000000 /* Bank 1 Write Access Time = 14 cycles */ +#define B1WAT_15 0xF0000000 /* Bank 1 Write Access Time = 15 cycles */ + +/* AMBCTL1 Masks */ +#define B2RDYEN 0x00000001 /* Bank 2 RDY Enable, 0=disable, 1=enable */ +#define B2RDYPOL 0x00000002 /* Bank 2 RDY Active high, 0=active low, 1=active high */ +#define B2TT_1 0x00000004 /* Bank 2 Transition Time from Read to Write = 1 cycle */ +#define B2TT_2 0x00000008 /* Bank 2 Transition Time from Read to Write = 2 cycles */ +#define B2TT_3 0x0000000C /* Bank 2 Transition Time from Read to Write = 3 cycles */ +#define B2TT_4 0x00000000 /* Bank 2 Transition Time from Read to Write = 4 cycles */ +#define B2ST_1 0x00000010 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */ +#define B2ST_2 0x00000020 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */ +#define B2ST_3 0x00000030 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */ +#define B2ST_4 0x00000000 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */ +#define B2HT_1 0x00000040 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */ +#define B2HT_2 0x00000080 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */ +#define B2HT_3 0x000000C0 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */ +#define B2HT_0 0x00000000 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */ +#define B2RAT_1 0x00000100 /* Bank 2 Read Access Time = 1 cycle */ +#define B2RAT_2 0x00000200 /* Bank 2 Read Access Time = 2 cycles */ +#define B2RAT_3 0x00000300 /* Bank 2 Read Access Time = 3 cycles */ +#define B2RAT_4 0x00000400 /* Bank 2 Read Access Time = 4 cycles */ +#define B2RAT_5 0x00000500 /* Bank 2 Read Access Time = 5 cycles */ +#define B2RAT_6 0x00000600 /* Bank 2 Read Access Time = 6 cycles */ +#define B2RAT_7 0x00000700 /* Bank 2 Read Access Time = 7 cycles */ +#define B2RAT_8 0x00000800 /* Bank 2 Read Access Time = 8 cycles */ +#define B2RAT_9 0x00000900 /* Bank 2 Read Access Time = 9 cycles */ +#define B2RAT_10 0x00000A00 /* Bank 2 Read Access Time = 10 cycles */ +#define B2RAT_11 0x00000B00 /* Bank 2 Read Access Time = 11 cycles */ +#define B2RAT_12 0x00000C00 /* Bank 2 Read Access Time = 12 cycles */ +#define B2RAT_13 0x00000D00 /* Bank 2 Read Access Time = 13 cycles */ +#define B2RAT_14 0x00000E00 /* Bank 2 Read Access Time = 14 cycles */ +#define B2RAT_15 0x00000F00 /* Bank 2 Read Access Time = 15 cycles */ +#define B2WAT_1 0x00001000 /* Bank 2 Write Access Time = 1 cycle */ +#define B2WAT_2 0x00002000 /* Bank 2 Write Access Time = 2 cycles */ +#define B2WAT_3 0x00003000 /* Bank 2 Write Access Time = 3 cycles */ +#define B2WAT_4 0x00004000 /* Bank 2 Write Access Time = 4 cycles */ +#define B2WAT_5 0x00005000 /* Bank 2 Write Access Time = 5 cycles */ +#define B2WAT_6 0x00006000 /* Bank 2 Write Access Time = 6 cycles */ +#define B2WAT_7 0x00007000 /* Bank 2 Write Access Time = 7 cycles */ +#define B2WAT_8 0x00008000 /* Bank 2 Write Access Time = 8 cycles */ +#define B2WAT_9 0x00009000 /* Bank 2 Write Access Time = 9 cycles */ +#define B2WAT_10 0x0000A000 /* Bank 2 Write Access Time = 10 cycles */ +#define B2WAT_11 0x0000B000 /* Bank 2 Write Access Time = 11 cycles */ +#define B2WAT_12 0x0000C000 /* Bank 2 Write Access Time = 12 cycles */ +#define B2WAT_13 0x0000D000 /* Bank 2 Write Access Time = 13 cycles */ +#define B2WAT_14 0x0000E000 /* Bank 2 Write Access Time = 14 cycles */ +#define B2WAT_15 0x0000F000 /* Bank 2 Write Access Time = 15 cycles */ +#define B3RDYEN 0x00010000 /* Bank 3 RDY enable, 0=disable, 1=enable */ +#define B3RDYPOL 0x00020000 /* Bank 3 RDY Active high, 0=active low, 1=active high */ +#define B3TT_1 0x00040000 /* Bank 3 Transition Time from Read to Write = 1 cycle */ +#define B3TT_2 0x00080000 /* Bank 3 Transition Time from Read to Write = 2 cycles */ +#define B3TT_3 0x000C0000 /* Bank 3 Transition Time from Read to Write = 3 cycles */ +#define B3TT_4 0x00000000 /* Bank 3 Transition Time from Read to Write = 4 cycles */ +#define B3ST_1 0x00100000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */ +#define B3ST_2 0x00200000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */ +#define B3ST_3 0x00300000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */ +#define B3ST_4 0x00000000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */ +#define B3HT_1 0x00400000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */ +#define B3HT_2 0x00800000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */ +#define B3HT_3 0x00C00000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */ +#define B3HT_0 0x00000000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */ +#define B3RAT_1 0x01000000 /* Bank 3 Read Access Time = 1 cycle */ +#define B3RAT_2 0x02000000 /* Bank 3 Read Access Time = 2 cycles */ +#define B3RAT_3 0x03000000 /* Bank 3 Read Access Time = 3 cycles */ +#define B3RAT_4 0x04000000 /* Bank 3 Read Access Time = 4 cycles */ +#define B3RAT_5 0x05000000 /* Bank 3 Read Access Time = 5 cycles */ +#define B3RAT_6 0x06000000 /* Bank 3 Read Access Time = 6 cycles */ +#define B3RAT_7 0x07000000 /* Bank 3 Read Access Time = 7 cycles */ +#define B3RAT_8 0x08000000 /* Bank 3 Read Access Time = 8 cycles */ +#define B3RAT_9 0x09000000 /* Bank 3 Read Access Time = 9 cycles */ +#define B3RAT_10 0x0A000000 /* Bank 3 Read Access Time = 10 cycles */ +#define B3RAT_11 0x0B000000 /* Bank 3 Read Access Time = 11 cycles */ +#define B3RAT_12 0x0C000000 /* Bank 3 Read Access Time = 12 cycles */ +#define B3RAT_13 0x0D000000 /* Bank 3 Read Access Time = 13 cycles */ +#define B3RAT_14 0x0E000000 /* Bank 3 Read Access Time = 14 cycles */ +#define B3RAT_15 0x0F000000 /* Bank 3 Read Access Time = 15 cycles */ +#define B3WAT_1 0x10000000 /* Bank 3 Write Access Time = 1 cycle */ +#define B3WAT_2 0x20000000 /* Bank 3 Write Access Time = 2 cycles */ +#define B3WAT_3 0x30000000 /* Bank 3 Write Access Time = 3 cycles */ +#define B3WAT_4 0x40000000 /* Bank 3 Write Access Time = 4 cycles */ +#define B3WAT_5 0x50000000 /* Bank 3 Write Access Time = 5 cycles */ +#define B3WAT_6 0x60000000 /* Bank 3 Write Access Time = 6 cycles */ +#define B3WAT_7 0x70000000 /* Bank 3 Write Access Time = 7 cycles */ +#define B3WAT_8 0x80000000 /* Bank 3 Write Access Time = 8 cycles */ +#define B3WAT_9 0x90000000 /* Bank 3 Write Access Time = 9 cycles */ +#define B3WAT_10 0xA0000000 /* Bank 3 Write Access Time = 10 cycles */ +#define B3WAT_11 0xB0000000 /* Bank 3 Write Access Time = 11 cycles */ +#define B3WAT_12 0xC0000000 /* Bank 3 Write Access Time = 12 cycles */ +#define B3WAT_13 0xD0000000 /* Bank 3 Write Access Time = 13 cycles */ +#define B3WAT_14 0xE0000000 /* Bank 3 Write Access Time = 14 cycles */ +#define B3WAT_15 0xF0000000 /* Bank 3 Write Access Time = 15 cycles */ + +/* + * SDRAM CONTROLLER MASKS + */ + +/* SDGCTL Masks */ +#define SCTLE 0x00000001 /* Enable SCLK[0], /SRAS, /SCAS, /SWE, SDQM[3:0] */ +#define CL_2 0x00000008 /* SDRAM CAS latency = 2 cycles */ +#define CL_3 0x0000000C /* SDRAM CAS latency = 3 cycles */ +#define PFE 0x00000010 /* Enable SDRAM prefetch */ +#define PFP 0x00000020 /* Prefetch has priority over AMC requests */ +#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */ +#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */ +#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */ +#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */ +#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */ +#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */ +#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */ +#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */ +#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */ +#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */ +#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */ +#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */ +#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */ +#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */ +#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */ +#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */ +#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */ +#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */ +#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */ +#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */ +#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */ +#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */ +#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */ +#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */ +#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */ +#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */ +#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */ +#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */ +#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */ +#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */ +#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */ +#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */ +#define PUPSD 0x00200000 /* Power-up start delay */ +#define PSM 0x00400000 /* SDRAM power-up sequence = Precharge, mode register set, 8 CBR refresh cycles */ +#define PSS 0x00800000 /* enable SDRAM power-up sequence on next SDRAM access */ +#define SRFS 0x01000000 /* Start SDRAM self-refresh mode */ +#define EBUFE 0x02000000 /* Enable external buffering timing */ +#define FBBRW 0x04000000 /* Fast back-to-back read write enable */ +#define EMREN 0x10000000 /* Extended mode register enable */ +#define TCSR 0x20000000 /* Temp compensated self refresh value 85 deg C */ +#define CDDBG 0x40000000 /* Tristate SDRAM controls during bus grant */ + +/* EBIU_SDBCTL Masks */ +#define EBE 0x00000001 /* Enable SDRAM external bank */ +#define EBSZ_16 0x00000000 /* SDRAM external bank size = 16MB */ +#define EBSZ_32 0x00000002 /* SDRAM external bank size = 32MB */ +#define EBSZ_64 0x00000004 /* SDRAM external bank size = 64MB */ +#define EBSZ_128 0x00000006 /* SDRAM external bank size = 128MB */ +#define EBCAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */ +#define EBCAW_9 0x00000010 /* SDRAM external bank column address width = 9 bits */ +#define EBCAW_10 0x00000020 /* SDRAM external bank column address width = 9 bits */ +#define EBCAW_11 0x00000030 /* SDRAM external bank column address width = 9 bits */ + +/* EBIU_SDSTAT Masks */ +#define SDCI 0x00000001 /* SDRAM controller is idle */ +#define SDSRA 0x00000002 /* SDRAM SDRAM self refresh is active */ +#define SDPUA 0x00000004 /* SDRAM power up active */ +#define SDRS 0x00000008 /* SDRAM is in reset state */ +#define SDEASE 0x00000010 /* SDRAM EAB sticky error status - W1C */ +#define BGSTAT 0x00000020 /* Bus granted */ + +#endif /* _DEF_BF532_H */ diff --git a/include/asm-blackfin/cpu/defBF533.h b/include/asm-blackfin/cpu/defBF533.h new file mode 100644 index 0000000000..90e50afa7f --- /dev/null +++ b/include/asm-blackfin/cpu/defBF533.h @@ -0,0 +1,24 @@ +/* + * defBF533.h + * + * This file is subject to the terms and conditions of the GNU Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Non-GPL License also available as part of VisualDSP++ + * + * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html + * + * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved + * + * This file under source code control, please send bugs or changes to: + * dsptools.support@analog.com + * + */ + +#ifndef _DEFBF533_H +#define _DEFBF533_H + +#include + +#endif /* _DEFBF533_H */ diff --git a/include/asm-blackfin/cpu/defBF533_extn.h b/include/asm-blackfin/cpu/defBF533_extn.h new file mode 100644 index 0000000000..a9a1c7ccbd --- /dev/null +++ b/include/asm-blackfin/cpu/defBF533_extn.h @@ -0,0 +1,76 @@ +/* + * defBF533_extn.h + * + * This file is subject to the terms and conditions of the GNU Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Non-GPL License also available as part of VisualDSP++ + * + * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html + * + * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved + * + * This file under source code control, please send bugs or changes to: + * dsptools.support@analog.com + * + */ + +#ifndef _DEF_BF533_EXTN_H +#define _DEF_BF533_EXTN_H + +#define OFFSET_( x ) ((x) & 0x0000FFFF) /* define macro for offset */ +/* Delay inserted for PLL transition */ +#define DELAY 0x1000 + +#define L1_ISRAM 0xFFA00000 +#define L1_ISRAM_END 0xFFA10000 +#define DATA_BANKA_SRAM 0xFF800000 +#define DATA_BANKA_SRAM_END 0xFF808000 +#define DATA_BANKB_SRAM 0xFF900000 +#define DATA_BANKB_SRAM_END 0xFF908000 +#define SYSMMR_BASE 0xFFC00000 +#define WDSIZE16 0x00000004 + +/* Event Vector Table Address */ +#define EVT_EMULATION_ADDR 0xffe02000 +#define EVT_RESET_ADDR 0xffe02004 +#define EVT_NMI_ADDR 0xffe02008 +#define EVT_EXCEPTION_ADDR 0xffe0200c +#define EVT_GLOBAL_INT_ENB_ADDR 0xffe02010 +#define EVT_HARDWARE_ERROR_ADDR 0xffe02014 +#define EVT_TIMER_ADDR 0xffe02018 +#define EVT_IVG7_ADDR 0xffe0201c +#define EVT_IVG8_ADDR 0xffe02020 +#define EVT_IVG9_ADDR 0xffe02024 +#define EVT_IVG10_ADDR 0xffe02028 +#define EVT_IVG11_ADDR 0xffe0202c +#define EVT_IVG12_ADDR 0xffe02030 +#define EVT_IVG13_ADDR 0xffe02034 +#define EVT_IVG14_ADDR 0xffe02038 +#define EVT_IVG15_ADDR 0xffe0203c +#define EVT_OVERRIDE_ADDR 0xffe02100 + +/* IMASK Bit values */ +#define IVG15_POS 0x00008000 +#define IVG14_POS 0x00004000 +#define IVG13_POS 0x00002000 +#define IVG12_POS 0x00001000 +#define IVG11_POS 0x00000800 +#define IVG10_POS 0x00000400 +#define IVG9_POS 0x00000200 +#define IVG8_POS 0x00000100 +#define IVG7_POS 0x00000080 +#define IVGTMR_POS 0x00000040 +#define IVGHW_POS 0x00000020 + +#define WDOG_TMR_DISABLE (0xAD << 4) +#define ICTL_RST 0x00000000 +#define ICTL_NMI 0x00000002 +#define ICTL_GP 0x00000004 +#define ICTL_DISABLE 0x00000003 + +/* Watch Dog timer values setup */ +#define WATCHDOG_DISABLE WDOG_TMR_DISABLE | ICTL_DISABLE + +#endif /* _DEF_BF533_EXTN_H */ diff --git a/include/asm-blackfin/cpu/def_LPBlackfin.h b/include/asm-blackfin/cpu/def_LPBlackfin.h new file mode 100644 index 0000000000..11a6504391 --- /dev/null +++ b/include/asm-blackfin/cpu/def_LPBlackfin.h @@ -0,0 +1,445 @@ +/* + * def_LPBlackfin.h + * + * This file is subject to the terms and conditions of the GNU Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Non-GPL License also available as part of VisualDSP++ + * + * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html + * + * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved + * + * This file under source code control, please send bugs or changes to: + * dsptools.support@analog.com + * + */ + +/* LP Blackfin CORE REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF532 */ + +#ifndef _DEF_LPBLACKFIN_H +#define _DEF_LPBLACKFIN_H + +/* + * #if !defined(__ADSPLPBLACKFIN__) + * #warning def_LPBlackfin.h should only be included for 532 compatible chips. + * #endif + */ + +#define MK_BMSK_( x ) (1<31 */ +#define TEST_WAY0 0x00000000 /* Access Way0 */ +#define TEST_WAY1 0x04000000 /* Access Way1 */ + +/* ** ITEST_COMMAND only */ +#define TEST_WAY2 0x08000000 /* Access Way2 */ +#define TEST_WAY3 0x0C000000 /* Access Way3 */ + +/* ** DTEST_COMMAND only */ +#define TEST_BNKSELA 0x00000000 /* Access SuperBank A */ +#define TEST_BNKSELB 0x00800000 /* Access SuperBank B */ + +#endif /* _DEF_LPBLACKFIN_H */ diff --git a/include/asm-blackfin/current.h b/include/asm-blackfin/current.h new file mode 100644 index 0000000000..108c2792a0 --- /dev/null +++ b/include/asm-blackfin/current.h @@ -0,0 +1,40 @@ +/* + * U-boot - current.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_CURRENT_H +#define _BLACKFIN_CURRENT_H +/* + * current.h + * (C) Copyright 2000, Lineo, David McCullough + * + * rather than dedicate a register (as the m68k source does), we + * just keep a global, we should probably just change it all to be + * current and lose _current_task. + */ + +extern struct task_struct *_current_task; +#define get_current() _current_task +#define current _current_task + +#endif diff --git a/include/asm-blackfin/delay.h b/include/asm-blackfin/delay.h new file mode 100644 index 0000000000..dbb73887ef --- /dev/null +++ b/include/asm-blackfin/delay.h @@ -0,0 +1,55 @@ +/* + * U-boot - delay.h Routines for introducing delays + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_DELAY_H +#define _BLACKFIN_DELAY_H + +/* + * Changes made by akbar.hussain@Lineo.com, for BLACKFIN + * Copyright (C) 1994 Hamish Macdonald + * + * Delay routines, using a pre-computed "loops_per_second" value. + */ + +extern __inline__ void __delay(unsigned long loops) +{ + __asm__ __volatile__("1:\t%0 += -1;\n\t" + "cc = %0 == 0;\n\t" + "if ! cc jump 1b;\n":"=d"(loops) + :"0"(loops)); +} + +/* + * Use only for very small delays ( < 1 msec). Should probably use a + * lookup table, really, as the multiplications take much too long with + * short delays. This is a "reasonable" implementation, though (and the + * first constant multiplications gets optimized away if the delay is + * a constant) + */ +extern __inline__ void udelay(unsigned long usecs) +{ + __delay(usecs); +} + +#endif diff --git a/include/asm-blackfin/entry.h b/include/asm-blackfin/entry.h new file mode 100644 index 0000000000..607a5b8e98 --- /dev/null +++ b/include/asm-blackfin/entry.h @@ -0,0 +1,385 @@ +/* + * U-boot - entry.h Routines for context saving and restoring + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __BLACKFIN_ENTRY_H +#define __BLACKFIN_ENTRY_H + +#include +#include +#include + +/* + * Stack layout in 'ret_from_exception': + * + */ + +/* + * Register %p2 is now set to the current task throughout + * the whole kernel. + */ + +#ifdef __ASSEMBLY__ + +#define LFLUSH_I_AND_D 0x00000808 +#define LSIGTRAP 5 + +/* process bits for task_struct.flags */ +#define PF_TRACESYS_OFF 3 +#define PF_TRACESYS_BIT 5 +#define PF_PTRACED_OFF 3 +#define PF_PTRACED_BIT 4 +#define PF_DTRACE_OFF 1 +#define PF_DTRACE_BIT 5 + +#define NEW_PT_REGS + +#if defined(NEW_PT_REGS) + +#define SAVE_ALL_INT save_context_no_interrupts +#define SAVE_ALL_SYS save_context_no_interrupts +#define SAVE_CONTEXT save_context_with_interrupts + +#define RESTORE_ALL restore_context_no_interrupts +#define RESTORE_ALL_SYS restore_context_no_interrupts +#define RESTORE_CONTEXT restore_context_with_interrupts + +#else + +#define SAVE_ALL_INT save_all_int +#define SAVE_ALL_SYS save_all_sys +#define SAVE_CONTEXT save_context +#define RESTORE_ALL restore_context +#define RESTORE_CONTEXT restore_context + +#endif + +/* + * Code to save processor context. + * We even save the register which are preserved by a function call + * - r4, r5, r6, r7, p3, p4, p5 + */ +.macro save_context_with_interrupts + [--sp] = R0; + [--sp] = ( R7:0, P5:0 ); + [--sp] = fp; + [--sp] = usp; + + [--sp] = i0; + [--sp] = i1; + [--sp] = i2; + [--sp] = i3; + + [--sp] = m0; + [--sp] = m1; + [--sp] = m2; + [--sp] = m3; + + [--sp] = l0; + [--sp] = l1; + [--sp] = l2; + [--sp] = l3; + + [--sp] = b0; + [--sp] = b1; + [--sp] = b2; + [--sp] = b3; + [--sp] = a0.x; + [--sp] = a0.w; + [--sp] = a1.x; + [--sp] = a1.w; + + [--sp] = LC0; + [--sp] = LC1; + [--sp] = LT0; + [--sp] = LT1; + [--sp] = LB0; + [--sp] = LB1; + + [--sp] = ASTAT; + + [--sp] = r0; /* Skip reserved */ + [--sp] = RETS; + [--sp] = RETI; + [--sp] = RETX; + [--sp] = RETN; + [--sp] = RETE; + [--sp] = SEQSTAT; + [--sp] = SYSCFG; + [--sp] = r0; /* Skip IPEND as well. */ +.endm + +.macro save_context_no_interrupts + [--sp] = R0; + [--sp] = ( R7:0, P5:0 ); + [--sp] = fp; + [--sp] = usp; + + [--sp] = i0; + [--sp] = i1; + [--sp] = i2; + [--sp] = i3; + + [--sp] = m0; + [--sp] = m1; + [--sp] = m2; + [--sp] = m3; + + [--sp] = l0; + [--sp] = l1; + [--sp] = l2; + [--sp] = l3; + + [--sp] = b0; + [--sp] = b1; + [--sp] = b2; + [--sp] = b3; + [--sp] = a0.x; + [--sp] = a0.w; + [--sp] = a1.x; + [--sp] = a1.w; + + [--sp] = LC0; + [--sp] = LC1; + [--sp] = LT0; + [--sp] = LT1; + [--sp] = LB0; + [--sp] = LB1; + + [--sp] = ASTAT; + + [--sp] = r0; /* Skip reserved */ + [--sp] = RETS; + r0 = RETI; + [--sp] = r0; + [--sp] = RETX; + [--sp] = RETN; + [--sp] = RETE; + [--sp] = SEQSTAT; + [--sp] = SYSCFG; + [--sp] = r0; /* Skip IPEND as well. */ +.endm + +.macro restore_context_no_interrupts + sp += 4; + SYSCFG = [sp++]; + SEQSTAT = [sp++]; + RETE = [sp++]; + RETN = [sp++]; + RETX = [sp++]; + r0 = [sp++]; + RETI = r0; + RETS = [sp++]; + + sp += 4; + + ASTAT = [sp++]; + + LB1 = [sp++]; + LB0 = [sp++]; + LT1 = [sp++]; + LT0 = [sp++]; + LC1 = [sp++]; + LC0 = [sp++]; + + a1.w = [sp++]; + a1.x = [sp++]; + a0.w = [sp++]; + a0.x = [sp++]; + b3 = [sp++]; + b2 = [sp++]; + b1 = [sp++]; + b0 = [sp++]; + + l3 = [sp++]; + l2 = [sp++]; + l1 = [sp++]; + l0 = [sp++]; + + m3 = [sp++]; + m2 = [sp++]; + m1 = [sp++]; + m0 = [sp++]; + + i3 = [sp++]; + i2 = [sp++]; + i1 = [sp++]; + i0 = [sp++]; + + sp += 4; + fp = [sp++]; + + ( R7 : 0, P5 : 0) = [ SP ++ ]; + sp += 4; +.endm + +.macro restore_context_with_interrupts + sp += 4; + SYSCFG = [sp++]; + SEQSTAT = [sp++]; + RETE = [sp++]; + RETN = [sp++]; + RETX = [sp++]; + RETI = [sp++]; + RETS = [sp++]; + + sp += 4; + + ASTAT = [sp++]; + + LB1 = [sp++]; + LB0 = [sp++]; + LT1 = [sp++]; + LT0 = [sp++]; + LC1 = [sp++]; + LC0 = [sp++]; + + a1.w = [sp++]; + a1.x = [sp++]; + a0.w = [sp++]; + a0.x = [sp++]; + b3 = [sp++]; + b2 = [sp++]; + b1 = [sp++]; + b0 = [sp++]; + + l3 = [sp++]; + l2 = [sp++]; + l1 = [sp++]; + l0 = [sp++]; + + m3 = [sp++]; + m2 = [sp++]; + m1 = [sp++]; + m0 = [sp++]; + + i3 = [sp++]; + i2 = [sp++]; + i1 = [sp++]; + i0 = [sp++]; + + sp += 4; + fp = [sp++]; + + ( R7 : 0, P5 : 0) = [ SP ++ ]; + sp += 4; +.endm + +#if !defined(NEW_PT_REGS) +/* + * a -1 in the orig_r0 field signifies + * that the stack frame is NOT for syscall + */ +.macro save_all_int +/* reserved and disable the single step of SYSCFG, by Steven Chen 03/07/10 */ + [--sp] = r0; + r0.l = 0x30; /* Errata for BF533 */ + r0.h = 0x0; + syscfg = r0; /* disable single step flag in SYSCFG */ + r0 = [sp++]; + [--sp] = syscfg; /* store SYSCFG */ + + [--sp] = r0; /* Reserved for IPEND */ + [--sp] = fp; + [--sp] = usp; + [--sp] = r0; + + [--sp] = r0; + r0 = [sp + 8]; + [--sp] = a0.x; + [--sp] = a1.x; + [--sp] = a0.w; + [--sp] = a1.w; + [--sp] = rets; + [--sp] = astat; + [--sp] = seqstat; + [--sp] = retx; /* current pc when exception happens */ + [--sp] = ( r7:5, p5:0 ); + [--sp] = r1; + [--sp] = r2; + [--sp] = r4; + [--sp] = r3; +.endm + +.macro save_all_sys + [--sp] = r0; + [--sp] = r0; + [--sp] = a0.x; + [--sp] = a1.x; + [--sp] = a0.w; + [--sp] = a1.w; + [--sp] = rets; + [--sp] = astat; + [--sp] = seqstat; + [--sp] = retx; /* current pc when exception happens */ + [--sp] = ( r7:5, p5:0 ); + [--sp] = r1; + [--sp] = r2; + [--sp] = r4; + [--sp] = r3; +.endm + +.macro restore_all + r3 = [sp++]; + r4 = [sp++]; + r2 = [sp++]; + r1 = [sp++]; + ( r7:5, p5:0 ) = [sp++]; + retx = [sp++]; + seqstat = [sp++]; + astat = [sp++]; + rets = [sp++]; + a1.w = [sp++]; + a0.w = [sp++]; + a1.x = [sp++]; + a0.x = [sp++]; + sp += 4; /* orig r0 */ + r0 = [sp++]; + + sp += 4; + fp = [sp++]; + sp +=4; /* Skip the IPEND */ + + syscfg = [sp++]; + +.endm + +#endif + +#define STR(X) STR1(X) +#define STR1(X) #X + +#if defined(NEW_PT_REGS) + +#define PT_OFF_ORIG_R0 208 +#define PT_OFF_SR 8 + +#else + +#define PT_OFF_ORIG_R0 0x54 +#define PT_OFF_SR 0x38 /* seqstat in pt_regs */ + +#endif +#endif + +#endif diff --git a/include/asm-blackfin/errno.h b/include/asm-blackfin/errno.h new file mode 100644 index 0000000000..713bba0b22 --- /dev/null +++ b/include/asm-blackfin/errno.h @@ -0,0 +1,156 @@ +/* + * U-boot - errno.h Error number defines + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_ERRNO_H +#define _BLACKFIN_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +#endif diff --git a/include/asm-blackfin/global_data.h b/include/asm-blackfin/global_data.h new file mode 100644 index 0000000000..56a12f07b3 --- /dev/null +++ b/include/asm-blackfin/global_data.h @@ -0,0 +1,64 @@ +/* + * U-boot - global_data.h Declarations for global data of u-boot + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_GBL_DATA_H +#define __ASM_GBL_DATA_H + +#include + +/* + * The following data structure is placed in some memory wich is + * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or + * some locked parts of the data cache) to allow for a minimum set of + * global variables during system initialization (until we have set + * up the memory controller so that we can use RAM). + * + * Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t) + */ +typedef struct global_data { + bd_t *bd; + unsigned long flags; + unsigned long board_type; + unsigned long baudrate; + unsigned long have_console; /* serial_init() was called */ + unsigned long ram_size; /* RAM size */ + unsigned long reloc_off; /* Relocation Offset */ + unsigned long env_addr; /* Address of Environment struct */ + unsigned long env_valid; /* Checksum of Environment valid? */ + void **jt; /* jump table */ +} gd_t; + +/* + * Global Data Flags + */ +#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */ +#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */ +#define GD_FLG_SILENT 0x00004 /* Silent mode */ + +#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("P5") + +#endif diff --git a/include/asm-blackfin/hw_irq.h b/include/asm-blackfin/hw_irq.h new file mode 100644 index 0000000000..1ee050ec14 --- /dev/null +++ b/include/asm-blackfin/hw_irq.h @@ -0,0 +1,37 @@ +/* + * U-boot - hw_irq.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on + * linux/arch/$(ARCH)/platform/$(PLATFORM)/hw_irq.h + * BlackFin (ADI) assembler restricted values by Ted Ma + * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com) + * Copyright (c) 2002 Lineo, Inc + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#ifdef CONFIG_EZKIT533 +#include +#endif +#ifdef CONFIG_STAMP +#include +#endif diff --git a/include/asm-blackfin/io-kernel.h b/include/asm-blackfin/io-kernel.h new file mode 100644 index 0000000000..0b0572ffa4 --- /dev/null +++ b/include/asm-blackfin/io-kernel.h @@ -0,0 +1,135 @@ +/* + * U-boot - io-kernel.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_IO_H +#define _BLACKFIN_IO_H + +#ifdef __KERNEL__ + +#include + +/* + * These are for ISA/PCI shared memory _only_ and should never be used + * on any other type of memory, including Zorro memory. They are meant to + * access the bus in the bus byte order which is little-endian!. + * + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the m68k architecture, we just read/write the + * memory location directly. + */ +/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates + * two accesses to memory, which may be undesireable for some devices. + */ +#define readb(addr) ({ unsigned char __v = (*(volatile unsigned char *) (addr));asm("ssync;"); __v; }) +#define readw(addr) ({ unsigned short __v = (*(volatile unsigned short *) (addr)); asm("ssync;");__v; }) +#define readl(addr) ({ unsigned int __v = (*(volatile unsigned int *) (addr));asm("ssync;"); __v; }) +#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b)) +#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b)) +#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel +#define memset_io(a,b,c) memset((void *)(a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) +#define inb(addr) cf_inb((volatile unsigned char*)(addr)) +#define inw(addr) readw(addr) +#define inl(addr) readl(addr) +#define outb(x,addr) cf_outb((unsigned char)(x), (volatile unsigned char*)(addr)) +#define outw(x,addr) ((void) writew(x,addr)) +#define outl(x,addr) ((void) writel(x,addr)) +#define inb_p(addr) inb(addr) +#define inw_p(addr) inw(addr) +#define inl_p(addr) inl(addr) +#define outb_p(x,addr) outb(x,addr) +#define outw_p(x,addr) outw(x,addr) +#define outl_p(x,addr) outl(x,addr) +#define insb(port, addr, count) memcpy((void*)addr, (void*)port, count) +#define insw(port, addr, count) cf_insw((unsigned short*)addr, (unsigned short*)(port), (count)) +#define insl(port, addr, count) memcpy((void*)addr, (void*)port, (4*count)) +#define outsb(port, addr, count) memcpy((void*)port, (void*)addr, count) +#define outsw(port,addr,count) cf_outsw((unsigned short*)(port), (unsigned short*)addr, (count)) +#define outsl(port, addr, count) memcpy((void*)port, (void*)addr, (4*count)) +#define IO_SPACE_LIMIT 0xffff + +/* Values for nocacheflag and cmode */ +#define IOMAP_FULL_CACHING 0 +#define IOMAP_NOCACHE_SER 1 +#define IOMAP_NOCACHE_NONSER 2 +#define IOMAP_WRITETHROUGH 3 + +#ifndef __ASSEMBLY__ +extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag); +extern void __iounmap(void *addr, unsigned long size); +extern inline void *ioremap(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} +extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + +extern void iounmap(void *addr); + +/* Nothing to do */ + +extern void blkfin_inv_cache_all(void); + +#endif + +#define dma_cache_inv(_start,_size) do { blkfin_inv_cache_all();} while (0) +#define dma_cache_wback(_start,_size) do { } while (0) +#define dma_cache_wback_inv(_start,_size) do { blkfin_inv_cache_all();} while (0) + +/* Pages to physical address... */ +#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) +#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT) + +#define mm_ptov(vaddr) ((void *) (vaddr)) +#define mm_vtop(vaddr) ((unsigned long) (vaddr)) +#define phys_to_virt(vaddr) ((void *) (vaddr)) +#define virt_to_phys(vaddr) ((unsigned long) (vaddr)) + +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +#endif + +#endif diff --git a/include/asm-blackfin/io.h b/include/asm-blackfin/io.h new file mode 100644 index 0000000000..e5b388e262 --- /dev/null +++ b/include/asm-blackfin/io.h @@ -0,0 +1,122 @@ +/* + * U-boot - io.h IO routines + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_IO_H +#define _BLACKFIN_IO_H + +#ifdef __KERNEL__ + +#include + +/* function prototypes for CF support */ +extern void cf_outsw(unsigned short *addr, unsigned short *sect_buf, int words); +extern void cf_insw(unsigned short *sect_buf, unsigned short *addr, int words); +extern unsigned char cf_inb(volatile unsigned char *addr); +extern void cf_outb(unsigned char val, volatile unsigned char* addr); + +/* + * These are for ISA/PCI shared memory _only_ and should never be used + * on any other type of memory, including Zorro memory. They are meant to + * access the bus in the bus byte order which is little-endian!. + * + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the m68k architecture, we just read/write the + * memory location directly. + */ + + +#define readb(addr) ({ unsigned char __v = (*(volatile unsigned char *) (addr));asm("ssync;"); __v; }) +#define readw(addr) ({ unsigned short __v = (*(volatile unsigned short *) (addr)); asm("ssync;");__v; }) +#define readl(addr) ({ unsigned int __v = (*(volatile unsigned int *) (addr));asm("ssync;"); __v; }) + +#define writeb(b,addr) {((*(volatile unsigned char *) (addr)) = (b)); asm("ssync;");} +#define writew(b,addr) {((*(volatile unsigned short *) (addr)) = (b)); asm("ssync;");} +#define writel(b,addr) {((*(volatile unsigned int *) (addr)) = (b)); asm("ssync;");} + +#define memset_io(a,b,c) memset((void *)(a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) + +#define inb_p(addr) readb((addr) + BF533_PCIIO_BASE) +#define inb(addr) cf_inb((volatile unsigned char*)(addr)) + +#define outb(x,addr) cf_outb((unsigned char)(x), (volatile unsigned char*)(addr)) +#define outb_p(x,addr) outb(x, (addr) + BF533_PCIIO_BASE) + +#define inw(addr) readw((addr) + BF533_PCIIO_BASE) +#define inl(addr) readl((addr) + BF533_PCIIO_BASE) + +#define outw(x,addr) writew(x, (addr) + BF533_PCIIO_BASE) +#define outl(x,addr) writel(x, (addr) + BF533_PCIIO_BASE) + +#define insb(port, addr, count) memcpy((void*)addr, (void*)(BF533_PCIIO_BASE + port), count) +#define insw(port, addr, count) cf_insw((unsigned short*)addr, (unsigned short*)(port), (count)) +#define insl(port, addr, count) memcpy((void*)addr, (void*)(BF533_PCIIO_BASE + port), (4*count)) + +#define outsb(port,addr,count) memcpy((void*)(BF533_PCIIO_BASE + port), (void*)addr, count) +#define outsw(port,addr,count) cf_outsw((unsigned short*)(port), (unsigned short*)addr, (count)) +#define outsl(port,addr,count) memcpy((void*)(BF533_PCIIO_BASE + port), (void*)addr, (4*count)) + +#define IO_SPACE_LIMIT 0xffff + +/* Values for nocacheflag and cmode */ +#define IOMAP_FULL_CACHING 0 +#define IOMAP_NOCACHE_SER 1 +#define IOMAP_NOCACHE_NONSER 2 +#define IOMAP_WRITETHROUGH 3 + +extern void *__ioremap(unsigned long physaddr, unsigned long size, + int cacheflag); +extern void __iounmap(void *addr, unsigned long size); + +extern inline void *ioremap(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +extern inline void *ioremap_nocache(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +extern inline void *ioremap_writethrough(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} +extern inline void *ioremap_fullcache(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + +extern void iounmap(void *addr); + +extern void blkfin_inv_cache_all(void); +#define dma_cache_inv(_start,_size) do { blkfin_inv_cache_all();} while (0) +#define dma_cache_wback(_start,_size) do { } while (0) +#define dma_cache_wback_inv(_start,_size) do { blkfin_inv_cache_all();} while (0) + +#endif +#endif diff --git a/include/asm-blackfin/irq.h b/include/asm-blackfin/irq.h new file mode 100644 index 0000000000..5fbc5a363b --- /dev/null +++ b/include/asm-blackfin/irq.h @@ -0,0 +1,142 @@ +/* + * U-boot - irq.h Interrupt related header file + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file was based on + * linux/arch/$(ARCH)/platform/$(PLATFORM)/irq.c + * + * Changed by HuTao Apr18, 2003 + * + * Copyright was missing when I got the code so took from MIPS arch ...MaTed--- + * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle + * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle + * + * Adapted for BlackFin (ADI) by Ted Ma + * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com) + * Copyright (c) 2002 Lineo, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_IRQ_H_ +#define _BLACKFIN_IRQ_H_ + +#include +#include + +/* + * On the Blackfin, the interrupt structure allows remmapping of the hardware + * levels. + * - I'm going to assume that the H/W level is going to stay at the default + * settings. If someone wants to go through and abstart this out, feel free + * to mod the interrupt numbering scheme. + * - I'm abstracting the interrupts so that uClinux does not know anything + * about the H/W levels. If you want to change the H/W AND keep the abstracted + * levels that uClinux sees, you should be able to do most of it here. + * - I've left the "abstract" numbering sparce in case someone wants to pull the + * interrupts apart (just the TX/RX for the various devices) + */ + +#define NR_IRQS SYS_IRQS +/* + * "Generic" interrupt sources + */ +#define IRQ_SCHED_TIMER (8) /* interrupt source for scheduling timer */ + +static __inline__ int irq_cannonicalize(int irq) +{ + return irq; +} + +/* + * Machine specific interrupt sources. + * + * Adding an interrupt service routine for a source with this bit + * set indicates a special machine specific interrupt source. + * The machine specific files define these sources. + * + * The IRQ_MACHSPEC bit is now gone - the only thing it did was to + * introduce unnecessary overhead. + * + * All interrupt handling is actually machine specific so it is better + * to use function pointers, as used by the Sparc port, and select the + * interrupt handling functions when initializing the kernel. This way + * we save some unnecessary overhead at run-time. + * 01/11/97 - Jes + */ + +extern void (*mach_enable_irq) (unsigned int); +extern void (*mach_disable_irq) (unsigned int); +extern int sys_request_irq(unsigned int, + void (*)(int, void *, struct pt_regs *), + unsigned long, const char *, void *); +extern void sys_free_irq(unsigned int, void *); + +/* + * various flags for request_irq() - the Amiga now uses the standard + * mechanism like all other architectures - SA_INTERRUPT and SA_SHIRQ + * are your friends. + */ +#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */ +#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */ +#define IRQ_FLG_FAST (0x0004) +#define IRQ_FLG_SLOW (0x0008) +#define IRQ_FLG_STD (0x8000) /* internally used */ + +/* + * This structure is used to chain together the ISRs for a particular + * interrupt source (if it supports chaining). + */ +typedef struct irq_node { + void (*handler) (int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; + struct irq_node *next; +} irq_node_t; + +/* + * This structure has only 4 elements for speed reasons + */ +typedef struct irq_handler { + void (*handler) (int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; +} irq_handler_t; + +/* count of spurious interrupts */ +extern volatile unsigned int num_spurious; + +/* + * This function returns a new irq_node_t + */ +extern irq_node_t *new_irq_node(void); + +/* + * Some drivers want these entry points + */ +#define enable_irq(x) (mach_enable_irq ? (*mach_enable_irq)(x) : 0) +#define disable_irq(x) (mach_disable_irq ? (*mach_disable_irq)(x) : 0) + +#define enable_irq_nosync(x) enable_irq(x) +#define disable_irq_nosync(x) disable_irq(x) + +#endif diff --git a/include/asm-blackfin/linkage.h b/include/asm-blackfin/linkage.h new file mode 100644 index 0000000000..18f0c36d24 --- /dev/null +++ b/include/asm-blackfin/linkage.h @@ -0,0 +1,60 @@ +/* + * U-boot - linkage.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _LINUX_LINKAGE_H +#define _LINUX_LINKAGE_H + +#include + +#ifdef __cplusplus +#define CPP_ASMLINKAGE extern "C" +#else +#define CPP_ASMLINKAGE +#endif + +#define asmlinkage CPP_ASMLINKAGE + +#define SYMBOL_NAME_STR(X) #X +#define SYMBOL_NAME(X) X +#ifdef __STDC__ +#define SYMBOL_NAME_LABEL(X) X##: +#else +#define SYMBOL_NAME_LABEL(X) X: +#endif + +#define __ALIGN .align 4 +#define __ALIGN_STR ".align 4" + +#ifdef __ASSEMBLY__ + +#define ALIGN __ALIGN +#define ALIGN_STR __ALIGN_STR + +#define ENTRY(name) \ + .globl SYMBOL_NAME(name); \ + ALIGN; \ + SYMBOL_NAME_LABEL(name) +#endif + +#endif diff --git a/include/asm-blackfin/machdep.h b/include/asm-blackfin/machdep.h new file mode 100644 index 0000000000..0a43ba1c5a --- /dev/null +++ b/include/asm-blackfin/machdep.h @@ -0,0 +1,89 @@ +/* + * U-boot - machdep.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_MACHDEP_H +#define _BLACKFIN_MACHDEP_H + +/* Machine dependent initial routines: + * + * Based on include/asm-m68knommu/machdep.h + * For blackfin, just now we only have bfin, so they'd point to the default bfin + * + */ + +struct pt_regs; +struct kbd_repeat; +struct mktime; +struct hwclk_time; +struct gendisk; +struct buffer_head; + +extern void (*mach_sched_init) (void (*handler) (int, void *, struct pt_regs *)); + +/* machine dependent keyboard functions */ +extern int (*mach_keyb_init) (void); +extern int (*mach_kbdrate) (struct kbd_repeat *); +extern void (*mach_kbd_leds) (unsigned int); + +/* machine dependent irq functions */ +extern void (*mach_init_IRQ) (void); +extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); +extern int (*mach_request_irq) (unsigned int irq, + void (*handler) (int, void *, + struct pt_regs *), + unsigned long flags, const char *devname, + void *dev_id); +extern void (*mach_free_irq) (unsigned int irq, void *dev_id); +extern void (*mach_get_model) (char *model); +extern int (*mach_get_hardware_list) (char *buffer); +extern int (*mach_get_irq_list) (char *buf); +extern void (*mach_process_int) (int irq, struct pt_regs * fp); + +/* machine dependent timer functions */ +extern unsigned long (*mach_gettimeoffset) (void); +extern void (*mach_gettod) (int *year, int *mon, int *day, int *hour, + int *min, int *sec); +extern int (*mach_hwclk) (int, struct hwclk_time *); +extern int (*mach_set_clock_mmss) (unsigned long); +extern void (*mach_reset) (void); +extern void (*mach_halt) (void); +extern void (*mach_power_off) (void); +extern unsigned long (*mach_hd_init) (unsigned long, unsigned long); +extern void (*mach_hd_setup) (char *, int *); +extern long mach_max_dma_address; +extern void (*mach_floppy_setup) (char *, int *); +extern void (*mach_floppy_eject) (void); +extern void (*mach_heartbeat) (int); +extern void (*mach_l2_flush) (int); +extern int mach_sysrq_key; +extern int mach_sysrq_shift_state; +extern int mach_sysrq_shift_mask; +extern char *mach_sysrq_xlate; + +#ifdef CONFIG_UCLINUX +extern void config_BSP(char *command, int len); +extern void (*mach_tick) (void); +#endif + +#endif diff --git a/include/asm-blackfin/mem_init.h b/include/asm-blackfin/mem_init.h new file mode 100644 index 0000000000..1a13d908e0 --- /dev/null +++ b/include/asm-blackfin/mem_init.h @@ -0,0 +1,287 @@ +/* + * U-boot - mem_init.h Header file for memory initialization + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#if ( CONFIG_MEM_MT48LC16M16A2TG_75 || CONFIG_MEM_MT48LC64M4A2FB_7E ) + #if ( CONFIG_SCLK_HZ > 119402985 ) + #define SDRAM_tRP TRP_2 + #define SDRAM_tRP_num 2 + #define SDRAM_tRAS TRAS_7 + #define SDRAM_tRAS_num 7 + #define SDRAM_tRCD TRCD_2 + #define SDRAM_tWR TWR_2 + #endif + #if ( CONFIG_SCLK_HZ > 104477612 ) && ( CONFIG_SCLK_HZ <= 119402985 ) + #define SDRAM_tRP TRP_2 + #define SDRAM_tRP_num 2 + #define SDRAM_tRAS TRAS_6 + #define SDRAM_tRAS_num 6 + #define SDRAM_tRCD TRCD_2 + #define SDRAM_tWR TWR_2 + #endif + #if ( CONFIG_SCLK_HZ > 89552239 ) && ( CONFIG_SCLK_HZ <= 104477612 ) + #define SDRAM_tRP TRP_2 + #define SDRAM_tRP_num 2 + #define SDRAM_tRAS TRAS_5 + #define SDRAM_tRAS_num 5 + #define SDRAM_tRCD TRCD_2 + #define SDRAM_tWR TWR_2 + #endif + #if ( CONFIG_SCLK_HZ > 74626866 ) && ( CONFIG_SCLK_HZ <= 89552239 ) + #define SDRAM_tRP TRP_2 + #define SDRAM_tRP_num 2 + #define SDRAM_tRAS TRAS_4 + #define SDRAM_tRAS_num 4 + #define SDRAM_tRCD TRCD_2 + #define SDRAM_tWR TWR_2 + #endif + #if ( CONFIG_SCLK_HZ > 66666667 ) && ( CONFIG_SCLK_HZ <= 74626866 ) + #define SDRAM_tRP TRP_2 + #define SDRAM_tRP_num 2 + #define SDRAM_tRAS TRAS_3 + #define SDRAM_tRAS_num 3 + #define SDRAM_tRCD TRCD_2 + #define SDRAM_tWR TWR_2 + #endif + #if ( CONFIG_SCLK_HZ > 59701493 ) && ( CONFIG_SCLK_HZ <= 66666667 ) + #define SDRAM_tRP TRP_1 + #define SDRAM_tRP_num 1 + #define SDRAM_tRAS TRAS_4 + #define SDRAM_tRAS_num 3 + #define SDRAM_tRCD TRCD_1 + #define SDRAM_tWR TWR_2 + #endif + #if ( CONFIG_SCLK_HZ > 44776119 ) && ( CONFIG_SCLK_HZ <= 59701493 ) + #define SDRAM_tRP TRP_1 + #define SDRAM_tRP_num 1 + #define SDRAM_tRAS TRAS_3 + #define SDRAM_tRAS_num 3 + #define SDRAM_tRCD TRCD_1 + #define SDRAM_tWR TWR_2 + #endif + #if ( CONFIG_SCLK_HZ > 29850746 ) && ( CONFIG_SCLK_HZ <= 44776119 ) + #define SDRAM_tRP TRP_1 + #define SDRAM_tRP_num 1 + #define SDRAM_tRAS TRAS_2 + #define SDRAM_tRAS_num 2 + #define SDRAM_tRCD TRCD_1 + #define SDRAM_tWR TWR_2 + #endif + #if ( CONFIG_SCLK_HZ <= 29850746 ) + #define SDRAM_tRP TRP_1 + #define SDRAM_tRP_num 1 + #define SDRAM_tRAS TRAS_1 + #define SDRAM_tRAS_num 1 + #define SDRAM_tRCD TRCD_1 + #define SDRAM_tWR TWR_2 + #endif +#endif + +#if (CONFIG_MEM_MT48LC16M16A2TG_75) + /*SDRAM INFORMATION: */ + #define SDRAM_Tref 64 /* Refresh period in milliseconds */ + #define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ + #define SDRAM_CL CL_3 +#endif + +#if (CONFIG_MEM_MT48LC64M4A2FB_7E) + /*SDRAM INFORMATION: */ + #define SDRAM_Tref 64 /* Refresh period in milliseconds */ + #define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */ + #define SDRAM_CL CL_2 +#endif + +#if ( CONFIG_MEM_SIZE == 128 ) + #define SDRAM_SIZE EBSZ_128 +#endif +#if ( CONFIG_MEM_SIZE == 64 ) + #define SDRAM_SIZE EBSZ_64 +#endif +#if ( CONFIG_MEM_SIZE == 32 ) + #define SDRAM_SIZE EBSZ_32 +#endif +#if ( CONFIG_MEM_SIZE == 16 ) + #define SDRAM_SIZE EBSZ_16 +#endif +#if ( CONFIG_MEM_ADD_WDTH == 11 ) + #define SDRAM_WIDTH EBCAW_11 +#endif +#if ( CONFIG_MEM_ADD_WDTH == 10 ) + #define SDRAM_WIDTH EBCAW_10 +#endif +#if ( CONFIG_MEM_ADD_WDTH == 9 ) + #define SDRAM_WIDTH EBCAW_9 +#endif +#if ( CONFIG_MEM_ADD_WDTH == 8 ) + #define SDRAM_WIDTH EBCAW_8 +#endif + +#define mem_SDBCTL SDRAM_WIDTH | SDRAM_SIZE | EBE + +/* Equation from section 17 (p17-46) of BF533 HRM */ +#define mem_SDRRC ((( CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) + +/* Enable SCLK Out */ +#define mem_SDGCTL ( SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS ) + +#define flash_EBIU_AMBCTL_WAT ( ( CONFIG_FLASH_SPEED_BWAT * 4 ) / ( 4000000000 / CONFIG_SCLK_HZ ) ) + 1 +#define flash_EBIU_AMBCTL_RAT ( ( CONFIG_FLASH_SPEED_BRAT * 4 ) / ( 4000000000 / CONFIG_SCLK_HZ ) ) + 1 +#define flash_EBIU_AMBCTL_HT ( ( CONFIG_FLASH_SPEED_BHT * 4 ) / ( 4000000000 / CONFIG_SCLK_HZ ) ) +#define flash_EBIU_AMBCTL_ST ( ( CONFIG_FLASH_SPEED_BST * 4 ) / ( 4000000000 / CONFIG_SCLK_HZ ) ) + 1 +#define flash_EBIU_AMBCTL_TT ( ( CONFIG_FLASH_SPEED_BTT * 4 ) / ( 4000000000 / CONFIG_SCLK_HZ ) ) + 1 + +#if (flash_EBIU_AMBCTL_TT > 3 ) + #define flash_EBIU_AMBCTL0_TT B0TT_4 +#endif +#if (flash_EBIU_AMBCTL_TT == 3 ) + #define flash_EBIU_AMBCTL0_TT B0TT_3 +#endif +#if (flash_EBIU_AMBCTL_TT == 2 ) + #define flash_EBIU_AMBCTL0_TT B0TT_2 +#endif +#if (flash_EBIU_AMBCTL_TT < 2 ) + #define flash_EBIU_AMBCTL0_TT B0TT_1 +#endif + +#if (flash_EBIU_AMBCTL_ST > 3 ) + #define flash_EBIU_AMBCTL0_ST B0ST_4 +#endif +#if (flash_EBIU_AMBCTL_ST == 3 ) + #define flash_EBIU_AMBCTL0_ST B0ST_3 +#endif +#if (flash_EBIU_AMBCTL_ST == 2 ) + #define flash_EBIU_AMBCTL0_ST B0ST_2 +#endif +#if (flash_EBIU_AMBCTL_ST < 2 ) + #define flash_EBIU_AMBCTL0_ST B0ST_1 +#endif + +#if (flash_EBIU_AMBCTL_HT > 2 ) + #define flash_EBIU_AMBCTL0_HT B0HT_3 +#endif +#if (flash_EBIU_AMBCTL_HT == 2 ) + #define flash_EBIU_AMBCTL0_HT B0HT_2 +#endif +#if (flash_EBIU_AMBCTL_HT == 1 ) + #define flash_EBIU_AMBCTL0_HT B0HT_1 +#endif +#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0) + #define flash_EBIU_AMBCTL0_HT B0HT_0 +#endif +#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0) + #define flash_EBIU_AMBCTL0_HT B0HT_1 +#endif + +#if (flash_EBIU_AMBCTL_WAT > 14) + #define flash_EBIU_AMBCTL0_WAT B0WAT_15 +#endif +#if (flash_EBIU_AMBCTL_WAT == 14) + #define flash_EBIU_AMBCTL0_WAT B0WAT_14 +#endif +#if (flash_EBIU_AMBCTL_WAT == 13) + #define flash_EBIU_AMBCTL0_WAT B0WAT_13 +#endif +#if (flash_EBIU_AMBCTL_WAT == 12) + #define flash_EBIU_AMBCTL0_WAT B0WAT_12 +#endif +#if (flash_EBIU_AMBCTL_WAT == 11) + #define flash_EBIU_AMBCTL0_WAT B0WAT_11 +#endif +#if (flash_EBIU_AMBCTL_WAT == 10) + #define flash_EBIU_AMBCTL0_WAT B0WAT_10 +#endif +#if (flash_EBIU_AMBCTL_WAT == 9) + #define flash_EBIU_AMBCTL0_WAT B0WAT_9 +#endif +#if (flash_EBIU_AMBCTL_WAT == 8) + #define flash_EBIU_AMBCTL0_WAT B0WAT_8 +#endif +#if (flash_EBIU_AMBCTL_WAT == 7) + #define flash_EBIU_AMBCTL0_WAT B0WAT_7 +#endif +#if (flash_EBIU_AMBCTL_WAT == 6) + #define flash_EBIU_AMBCTL0_WAT B0WAT_6 +#endif +#if (flash_EBIU_AMBCTL_WAT == 5) + #define flash_EBIU_AMBCTL0_WAT B0WAT_5 +#endif +#if (flash_EBIU_AMBCTL_WAT == 4) + #define flash_EBIU_AMBCTL0_WAT B0WAT_4 +#endif +#if (flash_EBIU_AMBCTL_WAT == 3) + #define flash_EBIU_AMBCTL0_WAT B0WAT_3 +#endif +#if (flash_EBIU_AMBCTL_WAT == 2) + #define flash_EBIU_AMBCTL0_WAT B0WAT_2 +#endif +#if (flash_EBIU_AMBCTL_WAT == 1) + #define flash_EBIU_AMBCTL0_WAT B0WAT_1 +#endif + +#if (flash_EBIU_AMBCTL_RAT > 14) + #define flash_EBIU_AMBCTL0_RAT B0RAT_15 +#endif +#if (flash_EBIU_AMBCTL_RAT == 14) + #define flash_EBIU_AMBCTL0_RAT B0RAT_14 +#endif +#if (flash_EBIU_AMBCTL_RAT == 13) + #define flash_EBIU_AMBCTL0_RAT B0RAT_13 +#endif +#if (flash_EBIU_AMBCTL_RAT == 12) + #define flash_EBIU_AMBCTL0_RAT B0RAT_12 +#endif +#if (flash_EBIU_AMBCTL_RAT == 11) + #define flash_EBIU_AMBCTL0_RAT B0RAT_11 +#endif +#if (flash_EBIU_AMBCTL_RAT == 10) + #define flash_EBIU_AMBCTL0_RAT B0RAT_10 +#endif +#if (flash_EBIU_AMBCTL_RAT == 9) + #define flash_EBIU_AMBCTL0_RAT B0RAT_9 +#endif +#if (flash_EBIU_AMBCTL_RAT == 8) + #define flash_EBIU_AMBCTL0_RAT B0RAT_8 +#endif +#if (flash_EBIU_AMBCTL_RAT == 7) + #define flash_EBIU_AMBCTL0_RAT B0RAT_7 +#endif +#if (flash_EBIU_AMBCTL_RAT == 6) + #define flash_EBIU_AMBCTL0_RAT B0RAT_6 +#endif +#if (flash_EBIU_AMBCTL_RAT == 5) + #define flash_EBIU_AMBCTL0_RAT B0RAT_5 +#endif +#if (flash_EBIU_AMBCTL_RAT == 4) + #define flash_EBIU_AMBCTL0_RAT B0RAT_4 +#endif +#if (flash_EBIU_AMBCTL_RAT == 3) + #define flash_EBIU_AMBCTL0_RAT B0RAT_3 +#endif +#if (flash_EBIU_AMBCTL_RAT == 2) + #define flash_EBIU_AMBCTL0_RAT B0RAT_2 +#endif +#if (flash_EBIU_AMBCTL_RAT == 1) + #define flash_EBIU_AMBCTL0_RAT B0RAT_1 +#endif + +#define flash_EBIU_AMBCTL0 flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN diff --git a/include/asm-blackfin/page.h b/include/asm-blackfin/page.h new file mode 100644 index 0000000000..406ece5377 --- /dev/null +++ b/include/asm-blackfin/page.h @@ -0,0 +1,128 @@ +/* + * U-boot - page.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_PAGE_H +#define _BLACKFIN_PAGE_H + +#include + +/* PAGE_SHIFT determines the page size */ + +#define PAGE_SHIFT (12) +#define PAGE_SIZE (4096) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +#include + +#if PAGE_SHIFT < 13 +#define KTHREAD_SIZE (8192) +#else +#define KTHREAD_SIZE PAGE_SIZE +#endif + +#ifndef __ASSEMBLY__ + +#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) +#define free_user_page(page, addr) free_page(addr) + +#define clear_page(page) memset((page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) + +#define clear_user_page(page, vaddr) clear_page(page) +#define copy_user_page(to, from, vaddr) copy_page(to, from) + +/* + * These are used to make use of C type-checking.. + */ +typedef struct { + unsigned long pte; +} pte_t; +typedef struct { + unsigned long pmd[16]; +} pmd_t; +typedef struct { + unsigned long pgd; +} pgd_t; +typedef struct { + unsigned long pgprot; +} pgprot_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((&x)->pmd[0]) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +/* Pure 2^n version of get_order */ +extern __inline__ int get_order(unsigned long size) +{ + int order; + + size = (size - 1) >> (PAGE_SHIFT - 1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +#endif /* !__ASSEMBLY__ */ + +#include + +#define PAGE_OFFSET (PAGE_OFFSET_RAW) + +#ifndef __ASSEMBLY__ + +#define __pa(vaddr) virt_to_phys((void *)vaddr) +#define __va(paddr) phys_to_virt((unsigned long)paddr) + +#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) +#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)) +#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) + +#define BUG() do { \ + \ + while (1); /* dead-loop */ \ +} while (0) + +#define PAGE_BUG(page) do { \ + BUG(); \ +} while (0) + +#endif + +#endif + +#endif diff --git a/include/asm-blackfin/page_offset.h b/include/asm-blackfin/page_offset.h new file mode 100644 index 0000000000..45e34b5178 --- /dev/null +++ b/include/asm-blackfin/page_offset.h @@ -0,0 +1,35 @@ +/* + * U-boot - page_offset.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Changes made by Akbar Hussain April 10, 2001 + */ + +#include + +/* This handles the memory map.. */ + +#ifdef CONFIG_BLACKFIN +#define PAGE_OFFSET_RAW 0x00000000 +#endif diff --git a/include/asm-blackfin/posix_types.h b/include/asm-blackfin/posix_types.h new file mode 100644 index 0000000000..f1f2b5ffc2 --- /dev/null +++ b/include/asm-blackfin/posix_types.h @@ -0,0 +1,90 @@ +/* + * U-boot - posix_types.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ARCH_BLACKFIN_POSIX_TYPES_H +#define __ARCH_BLACKFIN_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char *__kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) + +#undef __FD_CLR +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) + +#undef __FD_ISSET +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif diff --git a/include/asm-blackfin/processor.h b/include/asm-blackfin/processor.h new file mode 100644 index 0000000000..19bd720106 --- /dev/null +++ b/include/asm-blackfin/processor.h @@ -0,0 +1,174 @@ +/* + * U-boot - processor.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on + * include/asm-m68k/processor.h + * Changes made by Akbar Hussain Lineo, Inc, May 2001 for BLACKFIN + * Copyright (C) 1995 Hamish Macdonald + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_BLACKFIN_PROCESSOR_H +#define __ASM_BLACKFIN_PROCESSOR_H + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) + +#include +#include +#include +#include + +extern inline unsigned long rdusp(void) +{ + unsigned long usp; + + __asm__ __volatile__("%0 = usp;\n\t":"=da"(usp)); + return usp; +} + +extern inline void wrusp(unsigned long usp) +{ + __asm__ __volatile__("usp = %0;\n\t"::"da"(usp)); +} + +/* + * User space process size: 3.75GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ +#define TASK_SIZE (0xF0000000UL) + +/* + * Bus types + */ +#define EISA_bus 0 +#define MCA_bus 0 + +/* There is no pc register avaliable for BLACKFIN, so we are going to get + * it indirectly + */ + +#if 0 +inline unsigned long obtain_pc_indirectly(void) +{ + unsigned long pc; + __asm__ __volatile__("%0 = rets;\n":"=d"(pc)); + return (pc - 4); /* call pcrel24 is 4 bytes long */ +} +#endif + +/* + * if you change this structure, you must change the code and offsets + * in m68k/machasm.S + */ + +struct thread_struct { + unsigned long ksp; /* kernel stack pointer */ + unsigned long usp; /* user stack pointer */ + unsigned short seqstat; /* saved status register */ + unsigned long esp0; /* points to SR of stack frame pt_regs */ + unsigned long pc; /* instruction pointer */ +}; + +#define INIT_MMAP { &init_mm, 0, 0x40000000, NULL, __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED), VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL } + +#define INIT_THREAD { \ + sizeof(init_stack) + (unsigned long) init_stack, 0, \ + PS_S, 0\ +} + +/* + * Do necessary setup to start up a newly executed thread. + * + * pass the data segment into user programs if it exists, + * it can't hurt anything as far as I can tell + */ +#define start_thread(_regs, _pc, _usp) \ +do { \ + set_fs(USER_DS); /* reads from user space */ \ + (_regs)->pc = (_pc); \ + if (current->mm) \ + (_regs)->r5 = current->mm->start_data; \ + (_regs)->seqstat &= ~0x0c00; \ + wrusp(_usp); \ + /* Adde by HuTao, May 26, 2003 3:39PM */\ + if ((_regs)->ipend & 0x8000) /* check whether system in supper mode - StChen */\ + (_regs)->ipend = 0x0;\ +} while(0) + +/* Forward declaration, a strange C thing */ +struct task_struct; + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +extern int kernel_thread(int (*fn) (void *), void *arg, + unsigned long flags); + +#define copy_segments(tsk, mm) do { } while (0) +#define release_segments(mm) do { } while (0) +#define forget_segments() do { } while (0) + +/* + * Free current thread data structures etc.. + */ +static inline void exit_thread(void) +{ +} + +/* + * Return saved PC of a blocked thread. + */ +extern inline unsigned long thread_saved_pc(struct thread_struct *t) +{ + extern void scheduling_functions_start_here(void); + extern void scheduling_functions_end_here(void); + return 0; +} + +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) \ + ({ \ + unsigned long eip = 0; \ + if ((tsk)->thread.esp0 > PAGE_SIZE && \ + MAP_NR((tsk)->thread.esp0) < max_mapnr) \ + eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ + eip; }) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) +#define THREAD_SIZE (2*PAGE_SIZE) + +/* Allocation and freeing of basic task resources. */ +#define alloc_task_struct() \ + ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) +#define free_task_struct(p) free_pages((unsigned long)(p),1) +#define get_task_struct(tsk) atomic_inc(&mem_map[MAP_NR(tsk)].count) + +#define init_task (init_task_union.task) +#define init_stack (init_task_union.stack) + +#endif diff --git a/include/asm-blackfin/ptrace.h b/include/asm-blackfin/ptrace.h new file mode 100644 index 0000000000..afd57773ac --- /dev/null +++ b/include/asm-blackfin/ptrace.h @@ -0,0 +1,269 @@ +/* + * U-boot - ptrace.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_PTRACE_H +#define _BLACKFIN_PTRACE_H + +#define NEW_PT_REGS + +/* + * GCC defines register number like this: + * ----------------------------- + * 0 - 7 are data registers R0-R7 + * 8 - 15 are address registers P0-P7 + * 16 - 31 dsp registers I/B/L0 -- I/B/L3 & M0--M3 + * 32 - 33 A registers A0 & A1 + * 34 - status register + * + * We follows above, except: + * 32-33 --- Low 32-bit of A0&1 + * 34-35 --- High 8-bit of A0&1 + */ + +#if defined(NEW_PT_REGS) + +#define PT_IPEND 0 +#define PT_SYSCFG (PT_IPEND+4) +#define PT_SEQSTAT (PT_SYSCFG+4) +#define PT_RETE (PT_SEQSTAT+4) +#define PT_RETN (PT_RETE+4) +#define PT_RETX (PT_RETN+4) +#define PT_RETI (PT_RETX+4) +#define PT_PC PT_RETI +#define PT_RETS (PT_RETI+4) +#define PT_RESERVED (PT_RETS+4) +#define PT_ASTAT (PT_RESERVED+4) +#define PT_LB1 (PT_ASTAT+4) +#define PT_LB0 (PT_LB1+4) +#define PT_LT1 (PT_LB0+4) +#define PT_LT0 (PT_LT1+4) +#define PT_LC1 (PT_LT0+4) +#define PT_LC0 (PT_LC1+4) +#define PT_A1W (PT_LC0+4) +#define PT_A1X (PT_A1W+4) +#define PT_A0W (PT_A1X+4) +#define PT_A0X (PT_A0W+4) +#define PT_B3 (PT_A0X+4) +#define PT_B2 (PT_B3+4) +#define PT_B1 (PT_B2+4) +#define PT_B0 (PT_B1+4) +#define PT_L3 (PT_B0+4) +#define PT_L2 (PT_L3+4) +#define PT_L1 (PT_L2+4) +#define PT_L0 (PT_L1+4) +#define PT_M3 (PT_L0+4) +#define PT_M2 (PT_M3+4) +#define PT_M1 (PT_M2+4) +#define PT_M0 (PT_M1+4) +#define PT_I3 (PT_M0+4) +#define PT_I2 (PT_I3+4) +#define PT_I1 (PT_I2+4) +#define PT_I0 (PT_I1+4) +#define PT_USP (PT_I0+4) +#define PT_FP (PT_USP+4) +#define PT_P5 (PT_FP+4) +#define PT_P4 (PT_P5+4) +#define PT_P3 (PT_P4+4) +#define PT_P2 (PT_P3+4) +#define PT_P1 (PT_P2+4) +#define PT_P0 (PT_P1+4) +#define PT_R7 (PT_P0+4) +#define PT_R6 (PT_R7+4) +#define PT_R5 (PT_R6+4) +#define PT_R4 (PT_R5+4) +#define PT_R3 (PT_R4+4) +#define PT_R2 (PT_R3+4) +#define PT_R1 (PT_R2+4) +#define PT_R0 (PT_R1+4) +#define PT_ORIG_R0 (PT_R0+4) +#define PT_SR PT_SEQSTAT + +#else +/* + * Here utilize blackfin : dpregs = [pregs + imm16s4] + * [pregs + imm16s4] = dpregs + * to access defferent saved reg in stack + */ +#define PT_R3 0 +#define PT_R4 4 +#define PT_R2 8 +#define PT_R1 12 +#define PT_P5 16 +#define PT_P4 20 +#define PT_P3 24 +#define PT_P2 28 +#define PT_P1 32 +#define PT_P0 36 +#define PT_R7 40 +#define PT_R6 44 +#define PT_R5 48 +#define PT_PC 52 +#define PT_SEQSTAT 56 /* so-called SR reg */ +#define PT_SR PT_SEQSTAT +#define PT_ASTAT 60 +#define PT_RETS 64 +#define PT_A1w 68 +#define PT_A0w 72 +#define PT_A1x 76 +#define PT_A0x 80 +#define PT_ORIG_R0 84 +#define PT_R0 88 +#define PT_USP 92 +#define PT_FP 96 +#define PT_SP 100 + +/* Added by HuTao, May26 2003 3:18PM */ +#define PT_IPEND 100 + +/* Add SYSCFG register for single stepping support */ +#define PT_SYSCFG 104 + +#endif + +#ifndef __ASSEMBLY__ + +#if defined(NEW_PT_REGS) +/* this struct defines the way the registers are stored on the + * stack during a system call. + */ +struct pt_regs { + long ipend; + long syscfg; + long seqstat; + long rete; + long retn; + long retx; + long pc; + long rets; + long reserved; + long astat; + long lb1; + long lb0; + long lt1; + long lt0; + long lc1; + long lc0; + long a1w; + long a1x; + long a0w; + long a0x; + long b3; + long b2; + long b1; + long b0; + long l3; + long l2; + long l1; + long l0; + long m3; + long m2; + long m1; + long m0; + long i3; + long i2; + long i1; + long i0; + long usp; + long fp; + long p5; + long p4; + long p3; + long p2; + long p1; + long p0; + long r7; + long r6; + long r5; + long r4; + long r3; + long r2; + long r1; + long r0; + long orig_r0; +}; + +#else +/* now we don't know what regs the system call will use */ +struct pt_regs { + long r3; + long r4; + long r2; + long r1; + long p5; + long p4; + long p3; + long p2; + long p1; + long p0; + long r7; + long r6; + long r5; + unsigned long pc; + unsigned long seqstat; + unsigned long astat; + unsigned long rets; + long a1w; + long a0w; + long a1x; + long a0x; + long orig_r0; + long r0; + long usp; + long fp; +/* + * Added for supervisor/user mode switch. + * + * HuTao May26 03 3:23PM + */ + long ipend; + long syscfg; +}; + +#endif + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 /* ptrace signal */ + +#ifdef __KERNEL__ + +#ifndef PS_S +#define PS_S (0x0c00) + +/* Bit 11:10 of SEQSTAT defines user/supervisor/debug mode + * 00: user + * 01: supervisor + * 1x: debug + */ + +#define PS_M (0x1000) /* I am not sure why this is required here Akbar */ +#endif + +#define user_mode(regs) (!((regs)->seqstat & PS_S)) +#define instruction_pointer(regs) ((regs)->pc) +extern void show_regs(struct pt_regs *); + +#endif +#endif +#endif diff --git a/include/asm-blackfin/segment.h b/include/asm-blackfin/segment.h new file mode 100644 index 0000000000..9e6d817fc7 --- /dev/null +++ b/include/asm-blackfin/segment.h @@ -0,0 +1,46 @@ +/* + * U-boot - segment.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_SEGMENT_H +#define _BLACKFIN_SEGMENT_H + +/* define constants */ +typedef unsigned long mm_segment_t; /* domain register */ + +#define KERNEL_CS 0x0 +#define KERNEL_DS 0x0 +#define __KERNEL_CS 0x0 +#define __KERNEL_DS 0x0 + +#define USER_CS 0x1 +#define USER_DS 0x1 +#define __USER_CS 0x1 +#define __USER_DS 0x1 + +#define get_ds() (KERNEL_DS) +#define get_fs() (__USER_DS) +#define segment_eq(a,b) ((a) == (b)) +#define set_fs(val) + +#endif diff --git a/include/asm-blackfin/setup.h b/include/asm-blackfin/setup.h new file mode 100644 index 0000000000..6ce96880ac --- /dev/null +++ b/include/asm-blackfin/setup.h @@ -0,0 +1,86 @@ +/* + * U-boot - setup.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on + * asm/setup.h -- Definition of the Linux/Blackfin setup information + * Copyright Lineo, Inc 2001 Tony Kou + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_SETUP_H +#define _BLACKFIN_SETUP_H + +#include + +/* + * Linux/Blackfin Architectures + */ + +#define MACH_BFIN 1 + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ +extern unsigned long blackfin_machtype; +#endif + +#if defined(CONFIG_BFIN) +#define MACH_IS_BFIN (blackfin_machtype == MACH_BFIN) +#endif + +#ifndef MACH_TYPE +#define MACH_TYPE (blackfin_machtype) +#endif + +#endif + +/* + * CPU, FPU and MMU types + * + * Note: we don't need now: + * + */ + +#ifndef __ASSEMBLY__ +extern unsigned long blackfin_cputype; +#ifdef CONFIG_VME +extern unsigned long vme_brdtype; +#endif + +/* + * Miscellaneous + */ + +#define NUM_MEMINFO 4 +#define CL_SIZE 256 + +extern int blackfin_num_memory; /* # of memory blocks found (and used) */ +extern int blackfin_realnum_memory; /* real # of memory blocks found */ +extern struct mem_info blackfin_memory[NUM_MEMINFO]; /* memory description */ + +struct mem_info { + unsigned long addr; /* physical address of memory chunk */ + unsigned long size; /* length of memory chunk (in bytes) */ +}; +#endif + +#endif diff --git a/include/asm-blackfin/shared_resources.h b/include/asm-blackfin/shared_resources.h new file mode 100644 index 0000000000..fbef18618c --- /dev/null +++ b/include/asm-blackfin/shared_resources.h @@ -0,0 +1,33 @@ +/* + * U-boot - setup.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _SHARED_RESOURCES_H_ +#define _SHARED_RESOURCES_H_ + +void swap_to(int device_id); + +#define FLASH 0 +#define ETHERNET 1 + +#endif /* _SHARED_RESOURCES_H_ */ diff --git a/include/asm-blackfin/string.h b/include/asm-blackfin/string.h new file mode 100644 index 0000000000..ffd81d61a8 --- /dev/null +++ b/include/asm-blackfin/string.h @@ -0,0 +1,79 @@ +/* + * U-boot - string.h String functions + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* Changed by Lineo Inc. May 2001 */ + +#ifndef _BLACKFINNOMMU_STRING_H_ +#define _BLACKFINNOMMU_STRING_H_ + +#ifdef __KERNEL__ /* only set these up for kernel code */ + +#include +#include +#include + +#define __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRNCPY +#define __HAVE_ARCH_STRCMP +#define __HAVE_ARCH_STRNCMP +#define __HAVE_ARCH_MEMCPY + +extern char *strcpy(char *dest, const char *src); +extern char *strncpy(char *dest, const char *src, size_t n); +extern int strcmp(const char *cs, const char *ct); +extern int strncmp(const char *cs, const char *ct, size_t count); +extern void * memcpy(void * dest,const void *src,size_t count); +extern void *memset(void *s, int c, size_t count); +extern int memcmp(const void *, const void *, __kernel_size_t); + +#else /* KERNEL */ + +/* + * let user libraries deal with these, + * IMHO the kernel has no place defining these functions for user apps + */ + +#define __HAVE_ARCH_STRCPY 1 +#define __HAVE_ARCH_STRNCPY 1 +#define __HAVE_ARCH_STRCAT 1 +#define __HAVE_ARCH_STRNCAT 1 +#define __HAVE_ARCH_STRCMP 1 +#define __HAVE_ARCH_STRNCMP 1 +#define __HAVE_ARCH_STRNICMP 1 +#define __HAVE_ARCH_STRCHR 1 +#define __HAVE_ARCH_STRRCHR 1 +#define __HAVE_ARCH_STRSTR 1 +#define __HAVE_ARCH_STRLEN 1 +#define __HAVE_ARCH_STRNLEN 1 +#define __HAVE_ARCH_MEMSET 1 +#define __HAVE_ARCH_MEMCPY 1 +#define __HAVE_ARCH_MEMMOVE 1 +#define __HAVE_ARCH_MEMSCAN 1 +#define __HAVE_ARCH_MEMCMP 1 +#define __HAVE_ARCH_MEMCHR 1 +#define __HAVE_ARCH_STRTOK 1 + +#endif /* KERNEL */ + +#endif /* _BLACKFIN_STRING_H_ */ diff --git a/include/asm-blackfin/system.h b/include/asm-blackfin/system.h new file mode 100644 index 0000000000..0e53adfe0f --- /dev/null +++ b/include/asm-blackfin/system.h @@ -0,0 +1,182 @@ +/* + * U-boot - system.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_SYSTEM_H +#define _BLACKFIN_SYSTEM_H + +#include /* get configuration macros */ +#include +#include +#include +#include + +#define prepare_to_switch() do { } while(0) + +/* + * switch_to(n) should switch tasks to task ptr, first checking that + * ptr isn't the current task, in which case it does nothing. This + * also clears the TS-flag if the task we switched to has used the + * math co-processor latest. + * + * 05/25/01 - Tony Kou (tonyko@lineo.ca) + * + * Adapted for BlackFin (ADI) by Ted Ma, Metrowerks, and Motorola GSG + * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com) + * Copyright (c) 2003 Metrowerks (www.metrowerks.com) + */ + +asmlinkage void resume(void); + +#define switch_to(prev,next,last) { \ + void *_last; \ + __asm__ __volatile__( \ + "r0 = %1;\n\t" \ + "r1 = %2;\n\t" \ + "call resume;\n\t" \ + "%0 = r0;\n\t" \ + : "=d" (_last) \ + : "d" (prev), \ + "d" (next) \ + : "CC", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1");\ + (last) = _last; \ +} + +/* Force kerenl switch to user mode -- Steven Chen */ +#define switch_to_user_mode() { \ + __asm__ __volatile__( \ + "call kernel_to_user_mode;\n\t" \ + :: \ + : "CC", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1");\ +} + +/* + * Interrupt configuring macros. + */ + +extern int irq_flags; + +#define __sti() { \ + __asm__ __volatile__ ( \ + "r3 = %0;" \ + "sti r3;" \ + ::"m"(irq_flags):"R3"); \ +} + +#define __cli() { \ + __asm__ __volatile__ ( \ + "cli r3;" \ + :::"R3"); \ +} + +#define __save_flags(x) { \ + __asm__ __volatile__ ( \ + "cli r3;" \ + "%0 = r3;" \ + "sti r3;" \ + ::"m"(x):"R3"); \ +} + +#define __save_and_cli(x) { \ + __asm__ __volatile__ ( \ + "cli r3;" \ + "%0 = r3;" \ + ::"m"(x):"R3"); \ +} + +#define __restore_flags(x) { \ + __asm__ __volatile__ ( \ + "r3 = %0;" \ + "sti r3;" \ + ::"m"(x):"R3"); \ +} + +/* For spinlocks etc */ +#define local_irq_save(x) __save_and_cli(x) +#define local_irq_restore(x) __restore_flags(x) +#define local_irq_disable() __cli() +#define local_irq_enable() __sti() + +#define cli() __cli() +#define sti() __sti() +#define save_flags(x) __save_flags(x) +#define restore_flags(x) __restore_flags(x) +#define save_and_cli(x) __save_and_cli(x) + +/* + * Force strict CPU ordering. + */ +#define nop() asm volatile ("nop;\n\t"::) +#define mb() asm volatile ("" : : :"memory") +#define rmb() asm volatile ("" : : :"memory") +#define wmb() asm volatile ("" : : :"memory") +#define set_rmb(var, value) do { xchg(&var, value); } while (0) +#define set_mb(var, value) set_rmb(var, value) +#define set_wmb(var, value) do { var = value; wmb(); } while (0) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#endif + +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) + +struct __xchg_dummy { + unsigned long a[100]; +}; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) + +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, + int size) +{ + unsigned long tmp; + unsigned long flags = 0; + + save_and_cli(flags); + + switch (size) { + case 1: + __asm__ __volatile__("%0 = %2;\n\t" "%2 = %1;\n\t": "=&d"(tmp): "d"(x), "m"(*__xg(ptr)):"memory"); + break; + case 2: + __asm__ __volatile__("%0 = %2;\n\t" "%2 = %1;\n\t": "=&d"(tmp): "d"(x), "m"(*__xg(ptr)):"memory"); + break; + case 4: + __asm__ __volatile__("%0 = %2;\n\t" "%2 = %1;\n\t": "=&d"(tmp): "d"(x), "m"(*__xg(ptr)):"memory"); + break; + } + restore_flags(flags); + return tmp; +} + +/* Depend on whether Blackfin has hard reset function */ +/* YES it does, but it is tricky to implement - FIXME later ...MaTed--- */ +#define HARD_RESET_NOW() ({}) + +#endif /* _BLACKFIN_SYSTEM_H */ diff --git a/include/asm-blackfin/traps.h b/include/asm-blackfin/traps.h new file mode 100644 index 0000000000..29e6eba6fa --- /dev/null +++ b/include/asm-blackfin/traps.h @@ -0,0 +1,86 @@ +/* + * U-boot - traps.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on + * linux/include/asm/traps.h + * Copyright (C) 1993 Hamish Macdonald + * Lineo, Inc Jul 2001 Tony Kou + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + */ + +#ifndef _BLACKFIN_TRAPS_H +#define _BLACKFIN_TRAPS_H + +#ifndef __ASSEMBLY__ +typedef void (*e_vector) (void); +extern e_vector vectors[]; +#endif + +#define VEC_SYS (0) +#define VEC_EXCPT01 (1) +#define VEC_EXCPT02 (2) +#define VEC_EXCPT03 (3) +#define VEC_EXCPT04 (4) +#define VEC_EXCPT05 (5) +#define VEC_EXCPT06 (6) +#define VEC_EXCPT07 (7) +#define VEC_EXCPT08 (8) +#define VEC_EXCPT09 (9) +#define VEC_EXCPT10 (10) +#define VEC_EXCPT11 (11) +#define VEC_EXCPT12 (12) +#define VEC_EXCPT13 (13) +#define VEC_EXCPT14 (14) +#define VEC_EXCPT15 (15) +#define VEC_STEP (16) +#define VEC_OVFLOW (17) +#define VEC_UNDEF_I (33) +#define VEC_ILGAL_I (34) +#define VEC_CPLB_VL (35) +#define VEC_MISALI_D (36) +#define VEC_UNCOV (37) +#define VEC_CPLB_M (38) +#define VEC_CPLB_MHIT (39) +#define VEC_WATCH (40) +#define VEC_ISTRU_VL (41) +#define VEC_MISALI_I (42) +#define VEC_CPLB_I_VL (43) +#define VEC_CPLB_I_M (44) +#define VEC_CPLB_I_MHIT (45) +#define VEC_ILL_RES (46) /* including unvalid supervisor mode insn */ + +#define VECOFF(vec) ((vec)<<2) + +#ifndef __ASSEMBLY__ + +/* Status register bits */ +#define PS_T (0x8000) +#define PS_S (0x0c00) /* Supervisor mode = 0b01 */ +#define PS_D (0x0c00) /* Debug mode = 0b1x */ +#define PS_M (0x1000) +#define PS_C (0x0001) + +#endif +#endif diff --git a/include/asm-blackfin/types.h b/include/asm-blackfin/types.h new file mode 100644 index 0000000000..942ed275af --- /dev/null +++ b/include/asm-blackfin/types.h @@ -0,0 +1,83 @@ +/* + * U-boot - types.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _BLACKFIN_TYPES_H +#define _BLACKFIN_TYPES_H + +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +/* HK0617 -- Changes to unsigned long temporarily */ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG 32 + +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; + +#endif + +#endif diff --git a/include/asm-blackfin/u-boot.h b/include/asm-blackfin/u-boot.h new file mode 100644 index 0000000000..ec39338039 --- /dev/null +++ b/include/asm-blackfin/u-boot.h @@ -0,0 +1,47 @@ +/* + * U-boot - u-boot.h Structure declarations for board specific data + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _U_BOOT_H_ +#define _U_BOOT_H_ 1 + +typedef struct bd_info { + int bi_baudrate; /* serial console baudrate */ + unsigned long bi_ip_addr; /* IP Address */ + unsigned char bi_enetaddr[6]; /* Ethernet adress */ + unsigned long bi_arch_number; /* unique id for this board */ + unsigned long bi_boot_params; /* where this board expects params */ + unsigned long bi_memstart; /* start of DRAM memory */ + unsigned long bi_memsize; /* size of DRAM memory in bytes */ + unsigned long bi_flashstart; /* start of FLASH memory */ + unsigned long bi_flashsize; /* size of FLASH memory */ + unsigned long bi_flashoffset; /* reserved area for startup monitor */ +} bd_t; + +#define bi_env_data bi_env->data +#define bi_env_crc bi_env->crc + +#endif /* _U_BOOT_H_ */ diff --git a/include/asm-blackfin/uaccess.h b/include/asm-blackfin/uaccess.h new file mode 100644 index 0000000000..84b4b4ead7 --- /dev/null +++ b/include/asm-blackfin/uaccess.h @@ -0,0 +1,207 @@ +/* + * U-boot - uaccess.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * This file is based on + * Based on: include/asm-m68knommu/uaccess.h + * Changes made by Lineo Inc. May 2001 + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __BLACKFIN_UACCESS_H +#define __BLACKFIN_UACCESS_H + +/* + * User space memory access functions + */ +#include +#include + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* We let the MMU do all checking */ +static inline int access_ok(int type, const void *addr, unsigned long size) +{ + return ((unsigned long) addr < 0x10f00000); /* need final decision - Tony */ +} + +static inline int verify_area(int type, const void *addr, + unsigned long size) +{ + return access_ok(type, addr, size) ? 0 : -EFAULT; +} + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry { + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + */ + +#define put_user(x, ptr) \ +({ \ + int __pu_err = 0; \ + typeof(*(ptr)) __pu_val = (x); \ + switch (sizeof (*(ptr))) { \ + case 1: \ + __put_user_asm(__pu_err, __pu_val, ptr, B); \ + break; \ + case 2: \ + __put_user_asm(__pu_err, __pu_val, ptr, W); \ + break; \ + case 4: \ + __put_user_asm(__pu_err, __pu_val, ptr, ); \ + break; \ + default: \ + __pu_err = __put_user_bad(); \ + break; \ + } \ + __pu_err; \ +}) +/* + * [pregs] = dregs ==> 32bits + * H[pregs] = dregs ==> 16bits + * B[pregs] = dregs ==> 8 bits + */ + +#define __put_user(x, ptr) put_user(x, ptr) + +static inline int bad_user_access_length(void) +{ + panic("bad_user_access_length"); + return -1; +} + +#define __put_user_bad() (bad_user_access_length(), (-EFAULT)) + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ + +#define __ptr(x) ((unsigned long *)(x)) + +#define __put_user_asm(err,x,ptr,bhw) \ + __asm__ (#bhw"[%1] = %0;\n\t" \ + : /* no outputs */ \ + :"d" (x),"a" (__ptr(ptr)) : "memory") + +#define get_user(x, ptr) \ +({ \ + int __gu_err = 0; \ + typeof(*(ptr)) __gu_val = 0; \ + switch (sizeof(*(ptr))) { \ + case 1: \ + __get_user_asm(__gu_err, __gu_val, ptr, B, "=d",(Z)); \ + break; \ + case 2: \ + __get_user_asm(__gu_err, __gu_val, ptr, W, "=r",(Z)); \ + break; \ + case 4: \ + __get_user_asm(__gu_err, __gu_val, ptr, , "=r",); \ + break; \ + default: \ + __gu_val = 0; \ + __gu_err = __get_user_bad(); \ + break; \ + } \ + (x) = __gu_val; \ + __gu_err; \ +}) + +/* dregs = [pregs] ==> 32bits + * H[pregs] ==> 16bits + * B[pregs] ==> 8 bits + */ + +#define __get_user(x, ptr) get_user(x, ptr) +#define __get_user_bad() (bad_user_access_length(), (-EFAULT)) + +#define __get_user_asm(err,x,ptr,bhw,reg,option) \ + __asm__ ("%0 =" #bhw "[%1]"#option";\n\t" \ + : "=d" (x) \ + : "a" (__ptr(ptr))) + +#define copy_from_user(to, from, n) (memcpy(to, from, n), 0) +#define copy_to_user(to, from, n) (memcpy(to, from, n), 0) + +#define __copy_from_user(to, from, n) copy_from_user(to, from, n) +#define __copy_to_user(to, from, n) copy_to_user(to, from, n) + +#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; }) +#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; }) + +/* + * Copy a null terminated string from userspace. + */ + +static inline long strncpy_from_user(char *dst, const char *src, + long count) +{ + char *tmp; + strncpy(dst, src, count); + for (tmp = dst; *tmp && count > 0; tmp++, count--); + return (tmp - dst); /* DAVIDM should we count a NUL ? check getname */ +} + +/* + * Return the size of a string (including the ending 0) + * + * Return 0 on exception, a value greater than N if too long + */ +static inline long strnlen_user(const char *src, long n) +{ + return (strlen(src) + 1); /* DAVIDM make safer */ +} + +#define strlen_user(str) strnlen_user(str, 32767) + +/* + * Zero Userspace + */ + +static inline unsigned long clear_user(void *to, unsigned long n) +{ + memset(to, 0, n); + return (0); +} + +#endif diff --git a/include/asm-blackfin/virtconvert.h b/include/asm-blackfin/virtconvert.h new file mode 100644 index 0000000000..769f5a089c --- /dev/null +++ b/include/asm-blackfin/virtconvert.h @@ -0,0 +1,47 @@ +/* + * U-boot - virtconvert.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __BLACKFIN_VIRT_CONVERT__ +#define __BLACKFIN_VIRT_CONVERT__ + +/* + * Macros used for converting between virtual and physical mappings. + */ + +#ifdef __KERNEL__ + +#include +#include +#include + +#define mm_vtop(vaddr) ((unsigned long) vaddr) +#define mm_ptov(vaddr) ((unsigned long) vaddr) +#define phys_to_virt(vaddr) ((unsigned long) vaddr) +#define virt_to_phys(vaddr) ((unsigned long) vaddr) + +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +#endif +#endif diff --git a/include/configs/ezkit533.h b/include/configs/ezkit533.h new file mode 100644 index 0000000000..a52af4eebe --- /dev/null +++ b/include/configs/ezkit533.h @@ -0,0 +1,188 @@ +#ifndef __CONFIG_EZKIT533_H__ +#define __CONFIG_EZKIT533_H__ + +#define CFG_LONGHELP 1 +#define CONFIG_BAUDRATE 57600 +#define CONFIG_STAMP 1 +#define CONFIG_BOOTDELAY 5 + +#define CONFIG_DRIVER_SMC91111 1 +#define CONFIG_SMC91111_BASE 0x20310300 +#if 0 +#define CONFIG_MII +#define CFG_DISCOVER_PHY +#endif + +#define CONFIG_RTC_BF533 1 +#define CONFIG_BOOT_RETRY_TIME -1 /* Enable this if bootretry required, currently its disabled */ + +/* CONFIG_CLKIN_HZ is any value in Hz */ +#define CONFIG_CLKIN_HZ 27000000 +/* CONFIG_CLKIN_HALF controls what is passed to PLL 0=CLKIN */ +/* 1=CLKIN/2 */ +#define CONFIG_CLKIN_HALF 0 +/* CONFIG_PLL_BYPASS controls if the PLL is used 0=don't bypass */ +/* 1=bypass PLL */ +#define CONFIG_PLL_BYPASS 0 +/* CONFIG_VCO_MULT controls what the multiplier of the PLL is. */ +/* Values can range from 1-64 */ +#define CONFIG_VCO_MULT 22 +/* CONFIG_CCLK_DIV controls what the core clock divider is */ +/* Values can be 1, 2, 4, or 8 ONLY */ +#define CONFIG_CCLK_DIV 1 +/* CONFIG_SCLK_DIV controls what the peripheral clock divider is */ +/* Values can range from 1-15 */ +#define CONFIG_SCLK_DIV 5 + +#if ( CONFIG_CLKIN_HALF == 0 ) +#define CONFIG_VCO_HZ ( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT ) +#else +#define CONFIG_VCO_HZ (( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT ) / 2 ) +#endif + +#if (CONFIG_PLL_BYPASS == 0) +#define CONFIG_CCLK_HZ ( CONFIG_VCO_HZ / CONFIG_CCLK_DIV ) +#define CONFIG_SCLK_HZ ( CONFIG_VCO_HZ / CONFIG_SCLK_DIV ) +#else +#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ +#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ +#endif + +#define CONFIG_MEM_SIZE 32 /* 128, 64, 32, 16 */ +#define CONFIG_MEM_ADD_WDTH 9 /* 8, 9, 10, 11 */ +#define CONFIG_MEM_MT48LC16M16A2TG_75 1 + +#define CONFIG_LOADS_ECHO 1 + + +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ + CFG_CMD_PING | \ + CFG_CMD_ELF | \ + CFG_CMD_I2C | \ + CFG_CMD_JFFS2 | \ + CFG_CMD_DATE) +#define CONFIG_BOOTARGS "root=/dev/mtdblock0 ip=192.168.0.15:192.168.0.2:192.168.0.1:255.255.255.0:ezkit:eth0:off" + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +#define CFG_PROMPT "ezkit> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_MEMTEST_START 0x00100000 /* memtest works on */ +#define CFG_MEMTEST_END 0x01F00000 /* 1 ... 31 MB in DRAM */ +#define CFG_LOAD_ADDR 0x01000000 /* default load address */ +#define CFG_HZ 1000 /* decrementer freq: 10 ms ticks */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } +#define CFG_SDRAM_BASE 0x00000000 +#define CFG_MAX_RAM_SIZE 0x02000000 +#define CFG_FLASH_BASE 0x20000000 + +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#define CFG_MONITOR_BASE (CFG_MAX_RAM_SIZE - CFG_MONITOR_LEN) +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ +#define CFG_MALLOC_BASE (CFG_MONITOR_BASE - CFG_MALLOC_LEN) +#define CFG_GBL_DATA_SIZE 0x4000 +#define CFG_GBL_DATA_ADDR (CFG_MALLOC_BASE - CFG_GBL_DATA_SIZE) +#define CONFIG_STACKBASE (CFG_GBL_DATA_ADDR - 4) + +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ +#define CFG_FLASH0_BASE 0x20000000 +#define CFG_FLASH1_BASE 0x20200000 +#define CFG_FLASH2_BASE 0x20280000 +#define CFG_MAX_FLASH_BANKS 3 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 40 /* max number of sectors on one chip */ + +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_ENV_ADDR 0x20020000 +#define CFG_ENV_SECT_SIZE 0x10000 /* Total Size of Environment Sector */ + +/* JFFS Partition offset set */ +#define CFG_JFFS2_FIRST_BANK 0 +#define CFG_JFFS2_NUM_BANKS 1 +/* 512k reserved for u-boot */ +#define CFG_JFFS2_FIRST_SECTOR 11 + + +/* + * Stack sizes + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ + +#define POLL_MODE 1 +#define FLASH_TOT_SECT 40 +#define FLASH_SIZE 0x220000 +#define CFG_FLASH_SIZE 0x220000 + +/* + * Initialize PSD4256 registers for using I2C + */ +#define CONFIG_MISC_INIT_R + +/* + * I2C settings + * By default PF1 is used as SDA and PF0 as SCL on the Stamp board + */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +/* + * Software (bit-bang) I2C driver configuration + */ +#define PF_SCL PF0 +#define PF_SDA PF1 + +#define I2C_INIT (*pFIO_DIR |= PF_SCL); asm("ssync;") +#define I2C_ACTIVE (*pFIO_DIR |= PF_SDA); *pFIO_INEN &= ~PF_SDA; asm("ssync;") +#define I2C_TRISTATE (*pFIO_DIR &= ~PF_SDA); *pFIO_INEN |= PF_SDA; asm("ssync;") +#define I2C_READ ((volatile)(*pFIO_FLAG_D & PF_SDA) != 0); asm("ssync;") +#define I2C_SDA(bit) if(bit) { \ + *pFIO_FLAG_S = PF_SDA; \ + asm("ssync;"); \ + } \ + else { \ + *pFIO_FLAG_C = PF_SDA; \ + asm("ssync;"); \ + } +#define I2C_SCL(bit) if(bit) { \ + *pFIO_FLAG_S = PF_SCL; \ + asm("ssync;"); \ + } \ + else { \ + *pFIO_FLAG_C = PF_SCL; \ + asm("ssync;"); \ + } +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ + +#define CFG_I2C_SPEED 50000 +#define CFG_I2C_SLAVE 0xFE + + +#define __ADSPLPBLACKFIN__ 1 +#define __ADSPBF533__ 1 + +/* 0xFF, 0x7BB07BB0, 0x22547BB0 */ +/* #define AMGCTLVAL (AMBEN_P0 | AMBEN_P1 | AMBEN_P2 | AMCKEN) +#define AMBCTL0VAL (B1WAT_7 | B1RAT_11 | B1HT_2 | B1ST_3 | B1TT_4 | ~B1RDYPOL | \ + ~B1RDYEN | B0WAT_7 | B0RAT_11 | B0HT_2 | B0ST_3 | B0TT_4 | ~B0RDYPOL | ~B0RDYEN) +#define AMBCTL1VAL (B3WAT_2 | B3RAT_2 | B3HT_1 | B3ST_1 | B3TT_4 | B3RDYPOL | ~B3RDYEN | \ + B2WAT_7 | B2RAT_11 | B2HT_2 | B2ST_3 | B2TT_4 | ~B2RDYPOL | ~B2RDYEN) +*/ +#define AMGCTLVAL 0xFF +#define AMBCTL0VAL 0x7BB07BB0 +#define AMBCTL1VAL 0xFFC27BB0 + +#define CONFIG_VDSP 1 + +#ifdef CONFIG_VDSP +#define ET_EXEC_VDSP 0x8 +#define SHT_STRTAB_VDSP 0x1 +#define ELFSHDRSIZE_VDSP 0x2C +#define VDSP_ENTRY_ADDR 0xFFA00000 +#endif + +#endif diff --git a/include/configs/stamp.h b/include/configs/stamp.h new file mode 100644 index 0000000000..1402a4131a --- /dev/null +++ b/include/configs/stamp.h @@ -0,0 +1,340 @@ +/* + * U-boot - stamp.h Configuration file for STAMP board + * having BF533 processor + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_STAMP_H__ +#define __CONFIG_STAMP_H__ + +/* + * Board settings + * + */ + +#define __ADSPLPBLACKFIN__ 1 +#define __ADSPBF533__ 1 +#define CONFIG_STAMP 1 +#define CONFIG_RTC_BF533 1 + +/* FLASH/ETHERNET uses the same address range */ +#define SHARED_RESOURCES 1 + +#define CONFIG_VDSP 1 + +/* + * Clock settings + * + */ + +/* CONFIG_CLKIN_HZ is any value in Hz */ +#define CONFIG_CLKIN_HZ 11059200 +/* CONFIG_CLKIN_HALF controls what is passed to PLL 0=CLKIN */ +/* 1=CLKIN/2 */ +#define CONFIG_CLKIN_HALF 0 +/* CONFIG_PLL_BYPASS controls if the PLL is used 0=don't bypass */ +/* 1=bypass PLL */ +#define CONFIG_PLL_BYPASS 0 +/* CONFIG_VCO_MULT controls what the multiplier of the PLL is. */ +/* Values can range from 1-64 */ +#define CONFIG_VCO_MULT 45 +/* CONFIG_CCLK_DIV controls what the core clock divider is */ +/* Values can be 1, 2, 4, or 8 ONLY */ +#define CONFIG_CCLK_DIV 1 +/* CONFIG_SCLK_DIV controls what the peripheral clock divider is */ +/* Values can range from 1-15 */ +#define CONFIG_SCLK_DIV 6 + +/* + * Network Settings + */ +/* network support */ +#define CONFIG_IPADDR 192.168.0.15 +#define CONFIG_NETMASK 255.255.255.0 +#define CONFIG_GATEWAYIP 192.168.0.1 +#define CONFIG_SERVERIP 192.168.0.2 +#define CONFIG_HOSTNAME STAMP +#define CONFIG_ROOTPATH /checkout/uClinux-dist/romfs + +/* To remove hardcoding and enable MAC storage in EEPROM */ +/* #define CONFIG_ETHADDR 02:80:ad:20:31:b8 */ + +/* + * Command settings + * + */ + +#define CFG_LONGHELP 1 + +#define CONFIG_BOOTDELAY 5 +#define CONFIG_BOOT_RETRY_TIME -1 /* Enable this if bootretry required, currently its disabled */ +#define CONFIG_BOOTCOMMAND "run ramboot" +#define CONFIG_AUTOBOOT_PROMPT "autoboot in %d seconds\n" + +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ + CFG_CMD_PING | \ + CFG_CMD_ELF | \ + CFG_CMD_I2C | \ + CFG_CMD_CACHE | \ + CFG_CMD_JFFS2 | \ + CFG_CMD_DATE) +#define CONFIG_BOOTARGS "root=/dev/mtdblock0 rw" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "ramargs=setenv bootargs root=/dev/mtdblock0 rw\0" \ + "nfsargs=setenv bootargs root=/dev/nfs rw " \ + "nfsroot=$(serverip):$(rootpath)\0" \ + "addip=setenv bootargs $(bootargs) " \ + "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask)" \ + ":$(hostname):eth0:off\0" \ + "ramboot=tftpboot 0x1000000 linux;" \ + "run ramargs;run addip;bootelf\0" \ + "nfsboot=tftpboot 0x1000000 linux;" \ + "run nfsargs;run addip;bootelf\0" \ + "flashboot=bootm 0x20100000\0" \ + "" + +/* This must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +/* + * Console settings + * + */ + +#define CONFIG_BAUDRATE 57600 +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +#define CFG_PROMPT "stamp>" /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CONFIG_LOADS_ECHO 1 + +/* + * Network settings + * + */ + +#define CONFIG_DRIVER_SMC91111 1 +#define CONFIG_SMC91111_BASE 0x20300300 +/* To remove hardcoding and enable MAC storage in EEPROM */ +/* #define HARDCODE_MAC 1 */ + +/* + * Flash settings + * + */ + +#define CFG_FLASH_CFI /* The flash is CFI compatible */ +#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CFG_FLASH_CFI_AMD_RESET + +#define CFG_ENV_IS_IN_FLASH 1 + +#define CFG_FLASH_BASE 0x20000000 +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 67 /* max number of sectors on one chip */ + +#define CFG_ENV_ADDR 0x20020000 +#define CFG_ENV_SIZE 0x10000 +#define CFG_ENV_SECT_SIZE 0x10000 /* Total Size of Environment Sector */ + +#define CFG_FLASH_ERASE_TOUT 30000 /* Timeout for Chip Erase (in ms) */ +#define CFG_FLASH_ERASEBLOCK_TOUT 5000 /* Timeout for Block Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 1 /* Timeout for Flash Write (in ms) */ + +/* JFFS Partition offset set */ +#define CFG_JFFS2_FIRST_BANK 0 +#define CFG_JFFS2_NUM_BANKS 1 +/* 512k reserved for u-boot */ +#define CFG_JFFS2_FIRST_SECTOR 11 + +/* + * following timeouts shall be used once the + * Flash real protection is enabled + */ +#define CFG_FLASH_LOCK_TOUT 5 /* Timeout for Flash Set Lock Bit (in ms) */ +#define CFG_FLASH_UNLOCK_TOUT 10000 /* Timeout for Flash Clear Lock Bits (in ms) */ + +/* + * I2C settings + * By default PF2 is used as SDA and PF3 as SCL on the Stamp board + */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +/* + * Software (bit-bang) I2C driver configuration + */ +#define PF_SCL PF3 +#define PF_SDA PF2 + +#define I2C_INIT (*pFIO_DIR |= PF_SCL); asm("ssync;") +#define I2C_ACTIVE (*pFIO_DIR |= PF_SDA); *pFIO_INEN &= ~PF_SDA; asm("ssync;") +#define I2C_TRISTATE (*pFIO_DIR &= ~PF_SDA); *pFIO_INEN |= PF_SDA; asm("ssync;") +#define I2C_READ ((volatile)(*pFIO_FLAG_D & PF_SDA) != 0); asm("ssync;") +#define I2C_SDA(bit) if(bit) { \ + *pFIO_FLAG_S = PF_SDA; \ + asm("ssync;"); \ + } \ + else { \ + *pFIO_FLAG_C = PF_SDA; \ + asm("ssync;"); \ + } +#define I2C_SCL(bit) if(bit) { \ + *pFIO_FLAG_S = PF_SCL; \ + asm("ssync;"); \ + } \ + else { \ + *pFIO_FLAG_C = PF_SCL; \ + asm("ssync;"); \ + } +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ + +#define CFG_I2C_SPEED 50000 +#define CFG_I2C_SLAVE 0xFE + +/* + * Compact Flash settings + */ + +/* Enabled below option for CF support */ +/* #define CONFIG_STAMP_CF 1 */ + +#if defined(CONFIG_STAMP_CF) && (CONFIG_COMMANDS & CFG_CMD_IDE) + +#define CONFIG_MISC_INIT_R 1 +#define CONFIG_DOS_PARTITION 1 + +/* + * IDE/ATA stuff + */ +#undef CONFIG_IDE_8xx_DIRECT /* no pcmcia interface required */ +#undef CONFIG_IDE_LED /* no led for ide supported */ +#undef CONFIG_IDE_RESET /* no reset for ide supported */ + +#define CFG_IDE_MAXBUS 1 /* max. 1 IDE busses */ +#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*1) /* max. 1 drives per IDE bus */ + +#define CFG_ATA_BASE_ADDR 0x20200000 +#define CFG_ATA_IDE0_OFFSET 0x0000 + +#define CFG_ATA_DATA_OFFSET 0x0020 /* Offset for data I/O */ +#define CFG_ATA_REG_OFFSET 0x0020 /* Offset for normal register accesses */ +#define CFG_ATA_ALT_OFFSET 0x0007 /* Offset for alternate registers */ + +#define CFG_ATA_STRIDE 2 +#endif + +/* + * SDRAM settings + * + */ + +#define CONFIG_MEM_SIZE 128 /* 128, 64, 32, 16 */ +#define CONFIG_MEM_ADD_WDTH 11 /* 8, 9, 10, 11 */ +#define CONFIG_MEM_MT48LC64M4A2FB_7E 1 + +#define CFG_MEMTEST_START 0x00100000 /* memtest works on */ +#define CFG_MEMTEST_END 0x07EFFFFF /* 1 ... 127 MB in DRAM */ +#define CFG_LOAD_ADDR 0x01000000 /* default load address */ + +#define CFG_SDRAM_BASE 0x00000000 +#define CFG_MAX_RAM_SIZE 0x08000000 + +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#define CFG_MONITOR_BASE (CFG_MAX_RAM_SIZE - CFG_MONITOR_LEN) + + + + +#if ( CONFIG_CLKIN_HALF == 0 ) +#define CONFIG_VCO_HZ ( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT ) +#else +#define CONFIG_VCO_HZ (( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT ) / 2 ) +#endif + +#if (CONFIG_PLL_BYPASS == 0) +#define CONFIG_CCLK_HZ ( CONFIG_VCO_HZ / CONFIG_CCLK_DIV ) +#define CONFIG_SCLK_HZ ( CONFIG_VCO_HZ / CONFIG_SCLK_DIV ) +#else +#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ +#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ +#endif + + + +/* + * Miscellaneous configurable options + */ +#define CFG_HZ 1000 /* 1ms time tick */ + +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ +#define CFG_MALLOC_BASE (CFG_MONITOR_BASE - CFG_MALLOC_LEN) +#define CFG_GBL_DATA_SIZE 0x4000 +#define CFG_GBL_DATA_ADDR (CFG_MALLOC_BASE - CFG_GBL_DATA_SIZE) +#define CONFIG_STACKBASE (CFG_GBL_DATA_ADDR - 4) + +#define CFG_LARGE_IMAGE_LEN 0x4000000 /* Large Image Length, set to 64 Meg */ + +#define CONFIG_SHOW_BOOT_PROGRESS 1 /* Show boot progress on LEDs */ + +/* + * Stack sizes + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ + + +/* + * FLASH organization and environment definitions + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ + +/* 0xFF, 0xBBC3BBc3, 0x99B39983 */ +/*#define AMGCTLVAL (AMBEN_P0 | AMBEN_P1 | AMBEN_P2 | AMCKEN) +#define AMBCTL0VAL (B1WAT_11 | B1RAT_11 | B1HT_3 | B1ST_4 | B1TT_4 | B1RDYPOL | \ + B1RDYEN | B0WAT_11 | B0RAT_11 | B0HT_3 | B0ST_4 | B0TT_4 | B0RDYPOL | B0RDYEN) +#define AMBCTL1VAL (B3WAT_9 | B3RAT_9 | B3HT_2 | B3ST_3 | B3TT_4 | B3RDYPOL | \ + B3RDYEN | B2WAT_9 | B2RAT_9 | B2HT_2 | B2ST_4 | B2TT_4 | B2RDYPOL | B2RDYEN) +*/ +#define AMGCTLVAL 0xFF +#define AMBCTL0VAL 0xBBC3BBC3 +#define AMBCTL1VAL 0x99B39983 +#define CF_AMBCTL1VAL 0x99B3ffc2 + +#ifdef CONFIG_VDSP +#define ET_EXEC_VDSP 0x8 +#define SHT_STRTAB_VDSP 0x1 +#define ELFSHDRSIZE_VDSP 0x2C +#define VDSP_ENTRY_ADDR 0xFFA00000 +#endif + + +#endif diff --git a/lib_blackfin/Makefile b/lib_blackfin/Makefile new file mode 100644 index 0000000000..bc280d01f8 --- /dev/null +++ b/lib_blackfin/Makefile @@ -0,0 +1,47 @@ +# +# U-boot Makefile +# +# Copyright (c) 2005 blackfin.uclinux.org +# +# (C) Copyright 2000-2004 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(ARCH).a + +AOBJS = + +COBJS = board.o bf533_linux.o bf533_string.o cache.o muldi3.o +OBJS = $(AOBJS) $(COBJS) + +$(LIB): .depend $(OBJS) + $(AR) crv $@ $(OBJS) + +######################################################################### + +.depend: Makefile $(AOBJS:.o=.S) $(COBJS:.o=.c) + $(CC) -M $(CFLAGS) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/lib_blackfin/bf533_linux.c b/lib_blackfin/bf533_linux.c new file mode 100644 index 0000000000..6f29795f9d --- /dev/null +++ b/lib_blackfin/bf533_linux.c @@ -0,0 +1,91 @@ +/* + * U-boot - bf533_linux.c + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* Dummy functions, currently not in Use */ + +#include +#include +#include +#include +#include + +#define LINUX_MAX_ENVS 256 +#define LINUX_MAX_ARGS 256 + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +#include +#define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) +#else +#define SHOW_BOOT_PROGRESS(arg) +#endif + +#define CMD_LINE_ADDR 0xFF900000 /* L1 scratchpad */ + +#ifdef SHARED_RESOURCES + extern void swap_to(int device_id); +#endif + +static char *make_command_line(void); + +extern image_header_t header; +extern int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], + ulong addr, ulong * len_ptr, int verify) +{ + int (*appl)(char *cmdline); + char *cmdline; + +#ifdef SHARED_RESOURCES + swap_to(FLASH); +#endif + + appl = (int (*)(char *))ntohl(header.ih_ep); + printf("Starting Kernel at = %x\n", appl); + cmdline = make_command_line(); + if(icache_status()){ + flush_instruction_cache(); + icache_disable(); + } + if(dcache_status()){ + flush_data_cache(); + dcache_disable(); + } + (*appl)(cmdline); +} + +char *make_command_line(void) +{ + char *dest = (char *) CMD_LINE_ADDR; + char *bootargs; + + if ( (bootargs = getenv("bootargs")) == NULL ) + return NULL; + + strncpy(dest, bootargs, 0x1000); + dest[0xfff] = 0; + return dest; +} diff --git a/lib_blackfin/bf533_string.c b/lib_blackfin/bf533_string.c new file mode 100644 index 0000000000..cfa515a848 --- /dev/null +++ b/lib_blackfin/bf533_string.c @@ -0,0 +1,185 @@ +/* + * U-boot - bf533_string.c Contains library routines. + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +void *dma_memcpy(void *,const void *,size_t); + +char *strcpy(char *dest, const char *src) +{ + char *xdest = dest; + char temp = 0; + + __asm__ __volatile__ + ("1:\t%2 = B [%1++] (Z);\n\t" + "B [%0++] = %2;\n\t" + "CC = %2;\n\t" + "if cc jump 1b (bp);\n":"=a"(dest), "=a"(src), "=d"(temp) + :"0"(dest), "1"(src), "2"(temp):"memory"); + + return xdest; +} + +char *strncpy(char *dest, const char *src, size_t n) +{ + char *xdest = dest; + char temp = 0; + + if (n == 0) + return xdest; + + __asm__ __volatile__ + ("1:\t%3 = B [%1++] (Z);\n\t" + "B [%0++] = %3;\n\t" + "CC = %3;\n\t" + "if ! cc jump 2f;\n\t" + "%2 += -1;\n\t" + "CC = %2 == 0;\n\t" + "if ! cc jump 1b (bp);\n" + "2:\n":"=a"(dest), "=a"(src), "=da"(n), "=d"(temp) + :"0"(dest), "1"(src), "2"(n), "3"(temp) + :"memory"); + + return xdest; +} + +int strcmp(const char *cs, const char *ct) +{ + char __res1, __res2; + + __asm__ + ("1:\t%2 = B[%0++] (Z);\n\t" /* get *cs */ + "%3 = B[%1++] (Z);\n\t" /* get *ct */ + "CC = %2 == %3;\n\t" /* compare a byte */ + "if ! cc jump 2f;\n\t" /* not equal, break out */ + "CC = %2;\n\t" /* at end of cs? */ + "if cc jump 1b (bp);\n\t" /* no, keep going */ + "jump.s 3f;\n" /* strings are equal */ + "2:\t%2 = %2 - %3;\n" /* *cs - *ct */ + "3:\n": "=a"(cs), "=a"(ct), "=d"(__res1), + "=d"(__res2) + : "0"(cs), "1"(ct)); + + return __res1; +} + +int strncmp(const char *cs, const char *ct, size_t count) +{ + char __res1, __res2; + + if (!count) + return 0; + + __asm__ + ("1:\t%3 = B[%0++] (Z);\n\t" /* get *cs */ + "%4 = B[%1++] (Z);\n\t" /* get *ct */ + "CC = %3 == %4;\n\t" /* compare a byte */ + "if ! cc jump 3f;\n\t" /* not equal, break out */ + "CC = %3;\n\t" /* at end of cs? */ + "if ! cc jump 4f;\n\t" /* yes, all done */ + "%2 += -1;\n\t" /* no, adjust count */ + "CC = %2 == 0;\n\t" "if ! cc jump 1b;\n" /* more to do, keep going */ + "2:\t%3 = 0;\n\t" /* strings are equal */ + "jump.s 4f;\n" "3:\t%3 = %3 - %4;\n" /* *cs - *ct */ + "4:": "=a"(cs), "=a"(ct), "=da"(count), "=d"(__res1), + "=d"(__res2) + : "0"(cs), "1"(ct), "2"(count)); + + return __res1; +} + +/* + * memcpy - Copy one area of memory to another + * @dest: Where to copy to + * @src: Where to copy from + * @count: The size of the area. + * + * You should not use this function to access IO space, use memcpy_toio() + * or memcpy_fromio() instead. + */ +void * memcpy(void * dest,const void *src,size_t count) +{ + char *tmp = (char *) dest, *s = (char *) src; + +/* Turn off the cache, if destination in the L1 memory */ + if ( (tmp >= (char *)L1_ISRAM) && (tmp < (char *)L1_ISRAM_END) + || (tmp >= (char *)DATA_BANKA_SRAM) && (tmp < DATA_BANKA_SRAM_END) + || (tmp >= (char *)DATA_BANKB_SRAM) && (tmp < DATA_BANKB_SRAM_END) ){ + if(icache_status()){ + blackfin_icache_flush_range(src, src+count); + icache_disable(); + } + if(dcache_status()){ + blackfin_dcache_flush_range(src, src+count); + dcache_disable(); + } + dma_memcpy(dest,src,count); + }else{ + while(count--) + *tmp++ = *s++; + } + return dest; +} + +void *dma_memcpy(void * dest,const void *src,size_t count) +{ + + *pMDMA_D0_IRQ_STATUS = DMA_DONE | DMA_ERR; + + /* Copy sram functions from sdram to sram */ + /* Setup destination start address */ + *pMDMA_D0_START_ADDR = (volatile void **)dest; + /* Setup destination xcount */ + *pMDMA_D0_X_COUNT = count ; + /* Setup destination xmodify */ + *pMDMA_D0_X_MODIFY = 1; + + /* Setup Source start address */ + *pMDMA_S0_START_ADDR = (volatile void **)src; + /* Setup Source xcount */ + *pMDMA_S0_X_COUNT = count; + /* Setup Source xmodify */ + *pMDMA_S0_X_MODIFY = 1; + + /* Enable source DMA */ + *pMDMA_S0_CONFIG = (DMAEN); + asm("ssync;"); + + *pMDMA_D0_CONFIG = ( WNR | DMAEN); + + while(*pMDMA_D0_IRQ_STATUS & DMA_RUN){ + *pMDMA_D0_IRQ_STATUS |= (DMA_DONE | DMA_ERR); + } + *pMDMA_D0_IRQ_STATUS |= (DMA_DONE | DMA_ERR); + + dest += count; + src += count; + return dest; +} diff --git a/lib_blackfin/blackfin_board.h b/lib_blackfin/blackfin_board.h new file mode 100644 index 0000000000..35a513fbac --- /dev/null +++ b/lib_blackfin/blackfin_board.h @@ -0,0 +1,62 @@ +/* + * U-boot - blackfin_board.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __BLACKFIN_BOARD_H__ +#define __BLACKFIN_BOARD_H__ + +extern void timer_init(void); +extern void init_IRQ(void); +extern void rtc_init(void); + +extern ulong uboot_end_data; +extern ulong uboot_end; + +ulong monitor_flash_len; + + +#define VERSION_STRING_SIZE 150 /* including 40 bytes buffer to change any string */ +#define VERSION_STRING_FORMAT "%s (%s - %s)\n" +#define VERSION_STRING U_BOOT_VERSION, __DATE__, __TIME__ + +char version_string[VERSION_STRING_SIZE]; + +int *g_addr; +static ulong mem_malloc_start; +static ulong mem_malloc_end; +static ulong mem_malloc_brk; +extern char _sram_in_sdram_start[]; +extern char _sram_inst_size[]; +#ifdef DEBUG +static void display_global_data(void); +#endif + +/* definitions used to check the SMC card availability */ +#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE +#define UPPER_BYTE_MASK 0xFF00 +#define SMC_IDENT 0x3300 + +#endif diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c new file mode 100644 index 0000000000..7bf63eb0af --- /dev/null +++ b/lib_blackfin/board.c @@ -0,0 +1,282 @@ +/* + * U-boot - board.c First C file to be called contains init routines + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include "blackfin_board.h" +#include "../drivers/smc91111.h" + +extern flash_info_t flash_info[]; + + +static void mem_malloc_init(void) +{ + mem_malloc_start = CFG_MALLOC_BASE; + mem_malloc_end = (CFG_MALLOC_BASE + CFG_MALLOC_LEN); + mem_malloc_brk = mem_malloc_start; + memset((void *) mem_malloc_start, 0, + mem_malloc_end - mem_malloc_start); +} + +void *sbrk(ptrdiff_t increment) +{ + ulong old = mem_malloc_brk; + ulong new = old + increment; + + if ((new < mem_malloc_start) || (new > mem_malloc_end)) { + return (NULL); + } + mem_malloc_brk = new; + + return ((void *) old); +} + +static int display_banner(void) +{ + sprintf(version_string, VERSION_STRING_FORMAT, VERSION_STRING); + printf("%s\n", version_string); + return (0); +} + +static void display_flash_config(ulong size) +{ + puts("FLASH: "); + print_size(size, "\n"); + return; +} + +static int init_baudrate(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + uchar tmp[64]; + int i = getenv_r("baudrate", tmp, sizeof(tmp)); + gd->bd->bi_baudrate = gd->baudrate = (i > 0) + ? (int) simple_strtoul(tmp, NULL, 10) + : CONFIG_BAUDRATE; + return (0); +} + +#ifdef DEBUG +static void display_global_data(void) +{ + DECLARE_GLOBAL_DATA_PTR; + bd_t *bd; + bd = gd->bd; + printf("--flags:%x\n", gd->flags); + printf("--board_type:%x\n", gd->board_type); + printf("--baudrate:%x\n", gd->baudrate); + printf("--have_console:%x\n", gd->have_console); + printf("--ram_size:%x\n", gd->ram_size); + printf("--reloc_off:%x\n", gd->reloc_off); + printf("--env_addr:%x\n", gd->env_addr); + printf("--env_valid:%x\n", gd->env_valid); + printf("--bd:%x %x\n", gd->bd, bd); + printf("---bi_baudrate:%x\n", bd->bi_baudrate); + printf("---bi_ip_addr:%x\n", bd->bi_ip_addr); + printf("---bi_enetaddr:%x %x %x %x %x %x\n", + bd->bi_enetaddr[0], + bd->bi_enetaddr[1], + bd->bi_enetaddr[2], + bd->bi_enetaddr[3], + bd->bi_enetaddr[4], + bd->bi_enetaddr[5]); + printf("---bi_arch_number:%x\n", bd->bi_arch_number); + printf("---bi_boot_params:%x\n", bd->bi_boot_params); + printf("---bi_memstart:%x\n", bd->bi_memstart); + printf("---bi_memsize:%x\n", bd->bi_memsize); + printf("---bi_flashstart:%x\n", bd->bi_flashstart); + printf("---bi_flashsize:%x\n", bd->bi_flashsize); + printf("---bi_flashoffset:%x\n", bd->bi_flashoffset); + printf("--jt:%x *:%x\n", gd->jt, *(gd->jt)); +} +#endif + +/* + * All attempts to come up with a "common" initialization sequence + * that works for all boards and architectures failed: some of the + * requirements are just _too_ different. To get rid of the resulting + * mess of board dependend #ifdef'ed code we now make the whole + * initialization sequence configurable to the user. + * + * The requirements for any new initalization function is simple: it + * receives a pointer to the "global data" structure as it's only + * argument, and returns an integer return code, where 0 means + * "continue" and != 0 means "fatal error, hang the system". + */ + +void board_init_f(ulong bootflag) +{ + DECLARE_GLOBAL_DATA_PTR; + ulong addr; + bd_t *bd; + + gd = (gd_t *) (CFG_GBL_DATA_ADDR); + memset((void *) gd, 0, sizeof(gd_t)); + + /* Board data initialization */ + addr = (CFG_GBL_DATA_ADDR + sizeof(gd_t)); + + /* Align to 4 byte boundary */ + addr &= ~(4 - 1); + bd = (bd_t*)addr; + gd->bd = bd; + memset((void *) bd, 0, sizeof(bd_t)); + + /* Initialize */ + init_IRQ(); + env_init(); /* initialize environment */ + init_baudrate(); /* initialze baudrate settings */ + serial_init(); /* serial communications setup */ + console_init_f(); + display_banner(); /* say that we are here */ + checkboard(); +#if defined(CONFIG_RTC_BF533) && (CONFIG_COMMANDS & CFG_CMD_DATE) + rtc_init(); +#endif + timer_init(); + printf("Clock: VCO: %lu MHz, Core: %lu MHz, System: %lu MHz\n", \ + CONFIG_VCO_HZ/1000000, CONFIG_CCLK_HZ/1000000, CONFIG_SCLK_HZ/1000000); + printf("SDRAM: "); + print_size(initdram(0), "\n"); + board_init_r((gd_t *) gd, 0x20000010); +} + +void board_init_r(gd_t * id, ulong dest_addr) +{ + DECLARE_GLOBAL_DATA_PTR; + ulong size; + extern void malloc_bin_reloc(void); + char *s, *e; + bd_t *bd; + int i; + gd = id; + gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ + bd = gd->bd; + +#if CONFIG_STAMP + /* There are some other pointer constants we must deal with */ + /* configure available FLASH banks */ + size = flash_init(); + display_flash_config(size); + flash_protect(FLAG_PROTECT_SET, CFG_FLASH_BASE, CFG_FLASH_BASE + 0x1ffff, &flash_info[0]); + bd->bi_flashstart = CFG_FLASH_BASE; + bd->bi_flashsize = size; + bd->bi_flashoffset = 0; +#else + bd->bi_flashstart = 0; + bd->bi_flashsize = 0; + bd->bi_flashoffset = 0; +#endif + /* initialize malloc() area */ + mem_malloc_init(); + malloc_bin_reloc(); + + /* relocate environment function pointers etc. */ + env_relocate(); + + /* board MAC address */ + s = getenv("ethaddr"); + for (i = 0; i < 6; ++i) { + bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0; + if (s) + s = (*e) ? e + 1 : e; + } + + /* IP Address */ + bd->bi_ip_addr = getenv_IPaddr("ipaddr"); + + /* Initialize devices */ + devices_init(); + jumptable_init(); + + /* Initialize the console (after the relocation and devices init) */ + console_init_r(); + + /* Initialize from environment */ + if ((s = getenv("loadaddr")) != NULL) { + load_addr = simple_strtoul(s, NULL, 16); + } +#if (CONFIG_COMMANDS & CFG_CMD_NET) + if ((s = getenv("bootfile")) != NULL) { + copy_filename(BootFile, s, sizeof(BootFile)); + } +#endif +#if defined(CONFIG_MISC_INIT_R) + /* miscellaneous platform dependent initialisations */ + misc_init_r(); +#endif + +#ifdef CONFIG_DRIVER_SMC91111 +#ifdef SHARED_RESOURCES + /* Switch to Ethernet */ + swap_to(ETHERNET); +#endif + if ( (SMC_inw(BANK_SELECT) & UPPER_BYTE_MASK) != SMC_IDENT ) { + printf("ERROR: Can't find SMC91111 at address %x\n", SMC_BASE_ADDRESS); + } else { + printf("Net: SMC91111 at 0x%08X\n", SMC_BASE_ADDRESS); + } + +#ifdef SHARED_RESOURCES + swap_to(FLASH); +#endif +#endif +#ifdef CONFIG_SOFT_I2C + init_func_i2c(); +#endif + +#ifdef DEBUG + display_global_data(void); +#endif + + /* main_loop() can return to retry autoboot, if so just run it again. */ + for (;;) { + main_loop(); + } +} + +#ifdef CONFIG_SOFT_I2C +static int init_func_i2c (void) +{ + puts ("I2C: "); + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); + puts ("ready\n"); + return (0); +} +#endif + +void hang(void) +{ + puts("### ERROR ### Please RESET the board ###\n"); + for (;;); +} diff --git a/lib_blackfin/cache.c b/lib_blackfin/cache.c new file mode 100644 index 0000000000..4213b861e4 --- /dev/null +++ b/lib_blackfin/cache.c @@ -0,0 +1,41 @@ +/* + * U-boot - cache.c + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* for now: just dummy functions to satisfy the linker */ +extern void blackfin_icache_range(unsigned long *,unsigned long *); +extern void blackfin_dcache_range(unsigned long *,unsigned long *); +void flush_cache(unsigned long dummy1, unsigned long dummy2) +{ + if(icache_status()){ + blackfin_icache_flush_range(dummy1,dummy1+dummy2); + } + if(dcache_status()){ + blackfin_dcache_flush_range(dummy1,dummy1+dummy2); + } + return; +} + diff --git a/lib_blackfin/muldi3.c b/lib_blackfin/muldi3.c new file mode 100644 index 0000000000..a5622424fd --- /dev/null +++ b/lib_blackfin/muldi3.c @@ -0,0 +1,92 @@ +/* + * U-boot - muldi3.c contains routines for mult and div + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* Generic function got from GNU gcc package, libgcc2.c */ +#ifndef SI_TYPE_SIZE +#define SI_TYPE_SIZE 32 +#endif +#define __ll_B (1L << (SI_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((USItype) (t) % __ll_B) +#define __ll_highpart(t) ((USItype) (t) / __ll_B) +#define BITS_PER_UNIT 8 + +#if !defined (umul_ppmm) +#define umul_ppmm(w1, w0, u, v) \ +do { \ + USItype __x0, __x1, __x2, __x3; \ + USItype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (USItype) __ul * __vl; \ + __x1 = (USItype) __ul * __vh; \ + __x2 = (USItype) __uh * __vl; \ + __x3 = (USItype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ +} while (0) +#endif + +#if !defined (__umulsidi3) +#define __umulsidi3(u, v) \ + ({DIunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) +#endif + +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); + +struct DIstruct {SItype low, high;}; +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + +DItype __muldi3 (DItype u, DItype v) +{ + DIunion w; + DIunion uu, vv; + + uu.ll = u, + vv.ll = v; + /* panic("kernel panic for __muldi3"); */ + w.ll = __umulsidi3 (uu.s.low, vv.s.low); + w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high + + (USItype) uu.s.high * (USItype) vv.s.low); + + return w.ll; +} diff --git a/rtc/bf533_rtc.c b/rtc/bf533_rtc.c new file mode 100644 index 0000000000..09b8f2157d --- /dev/null +++ b/rtc/bf533_rtc.c @@ -0,0 +1,143 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * Real Time Clock interface of ADI21535 (Blackfin) for uCLinux + * + * Copyright (C) 2003 Motorola Corporation. All rights reserved. + * Richard Xiao (A2590C@email.mot.com) + * + * Copyright (C) 1996 Paul Gortmaker + * + * + * Based on other minimal char device drivers, like Alan's + * watchdog, Ted's random, etc. etc. + * + * 1.07 Paul Gortmaker. + * 1.08 Miquel van Smoorenburg: disallow certain things on the + * DEC Alpha as the CMOS clock is also used for other things. + * 1.09 Nikita Schmidt: epoch support and some Alpha cleanup. + * 1.09a Pete Zaitcev: Sun SPARC + * 1.09b Jeff Garzik: Modularize, init cleanup + * 1.09c Jeff Garzik: SMP cleanup + * 1.10 Paul Barton-Davis: add support for async I/O + * 1.10a Andrea Arcangeli: Alpha updates + * 1.10b Andrew Morton: SMP lock fix + * 1.10c Cesar Barros: SMP locking fixes and cleanup + * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit + * 1.10e LG Soft India: Register access is different in BF533. + */ + +#include +#include +#include + +#if defined(CONFIG_RTC_BF533) && (CONFIG_COMMANDS & CFG_CMD_DATE) + +#include +#include + +void rtc_reset(void) +{ + return; /* nothing to do */ +} + +/* Wait for pending writes to complete */ +void wait_for_complete(void) +{ + while (!(*(volatile unsigned short *) RTC_ISTAT & 0x8000)) { + printf(""); + } + *(volatile unsigned short *) RTC_ISTAT = 0x8000; +} + +/* Enable the RTC prescaler enable register */ +void rtc_init() +{ + *(volatile unsigned short *) RTC_PREN = 0x1; + wait_for_complete(); +} + +/* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers + * based on this value. + */ +void rtc_set (struct rtc_time *tmp) +{ + unsigned long n_days_1970 = 0; + unsigned long n_secs_rem = 0; + unsigned long n_hrs = 0; + unsigned long n_mins = 0; + unsigned long n_secs = 0; + unsigned long time_in_secs; + + if(tmp == NULL) { + printf("Error setting the date/time \n"); + return; + } + + time_in_secs = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday,tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + /* Compute no. of days since 1970 */ + n_days_1970 = (unsigned long) (time_in_secs / (NUM_SECS_IN_DAY)); + + /* From the remining secs, compute the hrs(0-23), mins(0-59) and secs(0-59) */ + n_secs_rem = (unsigned long)(time_in_secs % (NUM_SECS_IN_DAY)); + n_hrs = n_secs_rem / (NUM_SECS_IN_HOUR); + n_secs_rem = n_secs_rem % (NUM_SECS_IN_HOUR); + n_mins = n_secs_rem / (NUM_SECS_IN_MIN); + n_secs = n_secs_rem % (NUM_SECS_IN_MIN); + + /* Store the new time in the RTC_STAT register */ + *(volatile unsigned long *) RTC_STAT = + ((n_days_1970 << DAY_BITS_OFF) | (n_hrs << HOUR_BITS_OFF) | + (n_mins << MIN_BITS_OFF) | (n_secs << SEC_BITS_OFF)); + + wait_for_complete(); +} + +/* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */ +void rtc_get (struct rtc_time *tmp) +{ + unsigned long cur_rtc_stat = 0; + unsigned long time_in_sec; + unsigned long tm_sec = 0, tm_min = 0, tm_hour = 0, tm_day = 0; + + if(tmp == NULL) { + printf("Error getting the date/time \n"); + return; + } + + /* Read the RTC_STAT register */ + cur_rtc_stat = *(volatile unsigned long *) RTC_STAT; + + /* Get the secs (0-59), mins (0-59), hrs (0-23) and the days since Jan 1970 */ + tm_sec = (cur_rtc_stat >> SEC_BITS_OFF) & 0x3f; + tm_min = (cur_rtc_stat >> MIN_BITS_OFF) & 0x3f; + tm_hour = (cur_rtc_stat >> HOUR_BITS_OFF) & 0x1f; + tm_day = (cur_rtc_stat >> DAY_BITS_OFF) & 0x7fff; + + /* Calculate the total number of seconds since Jan 1970 */ + time_in_sec = (tm_sec) + + MIN_TO_SECS(tm_min) + + HRS_TO_SECS(tm_hour) + + DAYS_TO_SECS(tm_day); + to_tm(time_in_sec,tmp); +} +#endif /* CONFIG_RTC_BF533 && CFG_CMD_DATE */ From 1264b4050c6f635cc237b5821f924817457ce50c Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 02:20:55 +0100 Subject: [PATCH 065/102] Avoid dereferencing NULL in find_cmd() if no valid commands were found Patch by Andrew Dyer, 13 Jun 2005 --- CHANGELOG | 3 +++ common/main.c | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 20e875aabf..2348df63c0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Avoid dereferencing NULL in find_cmd() if no valid commands were found + Patch by Andrew Dyer, 13 Jun 2005 + * Add ADI Blackfin support - add support for Analog Devices Blackfin BF533 CPU - add support for the ADI BF533 Stamp uClinux board diff --git a/common/main.c b/common/main.c index f042f3a636..445cb18491 100644 --- a/common/main.c +++ b/common/main.c @@ -919,7 +919,10 @@ int run_command (const char *cmd, int flag) process_macros (token, finaltoken); /* Extract arguments */ - argc = parse_line (finaltoken, argv); + if ((argc = parse_line (finaltoken, argv)) == 0) { + rc = -1; /* no command at all */ + continue; + } /* Look up command in command table */ if ((cmdtp = find_cmd(argv[0])) == NULL) { @@ -945,9 +948,9 @@ int run_command (const char *cmd, int flag) puts ("'bootd' recursion detected\n"); rc = -1; continue; - } - else + } else { flag |= CMD_FLAG_BOOTD; + } } #endif /* CFG_CMD_BOOTD */ From 8e7b703a62783f0e88d3a7e4b1dd1c033bc95ec8 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 02:55:22 +0100 Subject: [PATCH 066/102] Coding Style cleanup --- CHANGELOG | 4 +- Makefile | 2 +- board/ezkit533/config.mk | 1 - board/ezkit533/flash.c | 14 +- board/ezkit533/psd4256.h | 1 - board/ezkit533/u-boot.lds | 1 - board/stamp/config.mk | 1 - board/stamp/stamp.c | 233 +++++++++++----------- board/stamp/u-boot.lds | 1 - common/soft_i2c.c | 2 +- cpu/bf533/bf533_serial.h | 2 +- cpu/bf533/cache.S | 144 ++++++------- cpu/bf533/cplbhdlr.S | 33 ++- cpu/bf533/cplbmgr.S | 88 ++++---- cpu/bf533/cpu.c | 15 +- cpu/bf533/flush.S | 30 +-- cpu/bf533/interrupt.S | 4 +- cpu/bf533/serial.c | 10 +- cpu/bf533/start.S | 10 +- examples/stubs.c | 2 +- include/asm-blackfin/cplbtab.h | 38 ++-- include/asm-blackfin/cpu/bf533_irq.h | 2 +- include/asm-blackfin/cpu/defBF532.h | 4 +- include/asm-blackfin/cpu/def_LPBlackfin.h | 6 +- include/asm-blackfin/page_offset.h | 2 +- include/asm-blackfin/uaccess.h | 2 +- include/configs/ezkit533.h | 102 +++++----- include/configs/stamp.h | 131 ++++++------ lib_blackfin/bf533_linux.c | 2 +- lib_blackfin/bf533_string.c | 6 +- lib_blackfin/blackfin_board.h | 2 +- lib_blackfin/board.c | 2 +- lib_blackfin/cache.c | 19 +- lib_blackfin/muldi3.c | 4 +- rtc/bf533_rtc.c | 62 +++--- 35 files changed, 482 insertions(+), 500 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 2348df63c0..57b4e78659 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Coding Style cleanup + * Avoid dereferencing NULL in find_cmd() if no valid commands were found Patch by Andrew Dyer, 13 Jun 2005 @@ -34,7 +36,7 @@ Changes since U-Boot 1.1.4: * Add support for Adder boards with 16MB SDRAM; add support for second FEC on Adder87x board. Patch by Yuli Barcohen, 05 Jun 2005 - + * Fix conditional for including ks8695eth driver Patch by Greg Ungerer, 04 Jun 2005 diff --git a/Makefile b/Makefile index 0c8137f0eb..65c457e00e 100644 --- a/Makefile +++ b/Makefile @@ -1899,7 +1899,7 @@ clean: rm -f tools/env/fw_printenv tools/env/fw_setenv rm -f board/cray/L1/bootscript.c board/cray/L1/bootscript.image rm -f board/netstar/eeprom board/netstar/crcek - rm -f board/netstar/*.srec board/netstar/*.bin + rm -f board/netstar/*.srec board/netstar/*.bin rm -f board/trab/trab_fkt board/voiceblue/eeprom rm -f board/integratorap/u-boot.lds board/integratorcp/u-boot.lds diff --git a/board/ezkit533/config.mk b/board/ezkit533/config.mk index e4c089d23e..36c9f997dd 100644 --- a/board/ezkit533/config.mk +++ b/board/ezkit533/config.mk @@ -23,4 +23,3 @@ TEXT_BASE = 0x01FC0000 PLATFORM_CPPFLAGS += -I$(TOPDIR) - diff --git a/board/ezkit533/flash.c b/board/ezkit533/flash.c index 0b59232644..b0a0796b86 100644 --- a/board/ezkit533/flash.c +++ b/board/ezkit533/flash.c @@ -142,15 +142,15 @@ int flash_erase(flash_info_t * info, int s_first, int s_last) int prot,sect; prot = 0; - for (sect = s_first; sect <= s_last; ++sect) { - if (info->protect[sect]) - prot++; - } + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) + prot++; + } if (prot) - printf ("- Warning: %d protected sectors will not be erased!\n", prot); - else - printf ("\n"); + printf ("- Warning: %d protected sectors will not be erased!\n", prot); + else + printf ("\n"); cnt = s_last - s_first + 1; diff --git a/board/ezkit533/psd4256.h b/board/ezkit533/psd4256.h index 9ae678babb..01f656601b 100644 --- a/board/ezkit533/psd4256.h +++ b/board/ezkit533/psd4256.h @@ -65,4 +65,3 @@ #define PSDA_LED6 0x04 /* LED 6, 1 = LED ON */ #define PSDA_LED5 0x02 /* LED 5, 1 = LED ON */ #define PSDA_LED4 0x01 /* LED 4, 1 = LED ON */ - diff --git a/board/ezkit533/u-boot.lds b/board/ezkit533/u-boot.lds index f58b489d80..10203ff89b 100644 --- a/board/ezkit533/u-boot.lds +++ b/board/ezkit533/u-boot.lds @@ -146,4 +146,3 @@ SECTIONS _end = . ; PROVIDE (end = .); } - diff --git a/board/stamp/config.mk b/board/stamp/config.mk index 4ec82cb776..0d0073032d 100644 --- a/board/stamp/config.mk +++ b/board/stamp/config.mk @@ -23,4 +23,3 @@ TEXT_BASE = 0x07FC0000 PLATFORM_CPPFLAGS += -I$(TOPDIR) - diff --git a/board/stamp/stamp.c b/board/stamp/stamp.c index 8485f58c5c..3fe0134d68 100644 --- a/board/stamp/stamp.c +++ b/board/stamp/stamp.c @@ -30,71 +30,71 @@ #include "stamp.h" #define STATUS_LED_OFF 0 -#define STATUS_LED_ON 1 +#define STATUS_LED_ON 1 #ifdef CONFIG_SHOW_BOOT_PROGRESS # define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) #else -# define SHOW_BOOT_PROGRESS(arg) +# define SHOW_BOOT_PROGRESS(arg) #endif -int checkboard(void) +int checkboard (void) { - printf("CPU: ADSP BF533 Rev.: 0.%d\n", *pCHIPID >> 28); - printf("Board: ADI BF533 Stamp board\n"); - printf(" Support: http://blackfin.uclinux.org/\n"); - printf(" Richard Klingler \n"); + printf ("CPU: ADSP BF533 Rev.: 0.%d\n", *pCHIPID >> 28); + printf ("Board: ADI BF533 Stamp board\n"); + printf (" Support: http://blackfin.uclinux.org/\n"); + printf (" Richard Klingler \n"); return 0; } -long int initdram(int board_type) +long int initdram (int board_type) { DECLARE_GLOBAL_DATA_PTR; #ifdef DEBUG - printf("SDRAM attributes:\n"); - printf(" tRCD:%d Cycles; tRP:%d Cycles; tRAS:%d Cycles; tWR:%d Cycles; " - "CAS Latency:%d cycles\n", (SDRAM_tRCD >> 15), (SDRAM_tRP >> 11), - (SDRAM_tRAS >> 6), ( SDRAM_tWR >> 19), (SDRAM_CL >> 2 )); - printf("SDRAM Begin: 0x%x\n", CFG_SDRAM_BASE); - printf("Bank size = %d MB\n", 128); + printf ("SDRAM attributes:\n"); + printf (" tRCD:%d Cycles; tRP:%d Cycles; tRAS:%d Cycles; tWR:%d Cycles; " + "CAS Latency:%d cycles\n", + (SDRAM_tRCD >> 15), + (SDRAM_tRP >> 11), + (SDRAM_tRAS >> 6), + (SDRAM_tWR >> 19), + (SDRAM_CL >> 2)); + printf ("SDRAM Begin: 0x%x\n", CFG_SDRAM_BASE); + printf ("Bank size = %d MB\n", 128); #endif gd->bd->bi_memstart = CFG_SDRAM_BASE; gd->bd->bi_memsize = CFG_MAX_RAM_SIZE; return (gd->bd->bi_memsize); } -void swap_to(int device_id) +void swap_to (int device_id) { - if (device_id == ETHERNET) - { + if (device_id == ETHERNET) { *pFIO_DIR = PF0; - asm("ssync;"); + asm ("ssync;"); *pFIO_FLAG_S = PF0; - asm("ssync;"); - } - else if (device_id == FLASH) - { + asm ("ssync;"); + } else if (device_id == FLASH) { *pFIO_DIR = (PF4 | PF3 | PF2 | PF1 | PF0); - *pFIO_FLAG_S = (PF4 | PF3 | PF2 ); + *pFIO_FLAG_S = (PF4 | PF3 | PF2); *pFIO_MASKA_D = (PF8 | PF6 | PF5); *pFIO_MASKB_D = (PF7); - *pFIO_POLAR = (PF8 | PF6 | PF5 ); + *pFIO_POLAR = (PF8 | PF6 | PF5); *pFIO_EDGE = (PF8 | PF7 | PF6 | PF5); *pFIO_INEN = (PF8 | PF7 | PF6 | PF5); - *pFIO_FLAG_D = (PF4 | PF3 | PF2 ); - asm("ssync;"); + *pFIO_FLAG_D = (PF4 | PF3 | PF2); + asm ("ssync;"); + } else { + printf ("Unknown bank to switch\n"); } - else { - printf("Unknown bank to switch\n"); - } - + return; } #if defined(CONFIG_MISC_INIT_R) /* miscellaneous platform dependent initialisations */ -int misc_init_r(void) +int misc_init_r (void) { int i; int cf_stat = 0; @@ -102,40 +102,39 @@ int misc_init_r(void) /* Check whether CF card is inserted */ *pFIO_EDGE = FIO_EDGE_CF_BITS; *pFIO_POLAR = FIO_POLAR_CF_BITS; - for (i=0; i < 0x300 ; i++) asm("nop;"); - - if ( (*pFIO_FLAG_S) & CF_STAT_BITS) - { + for (i = 0; i < 0x300; i++) + asm ("nop;"); + + if ((*pFIO_FLAG_S) & CF_STAT_BITS) { cf_stat = 0; - } - else - { + } else { cf_stat = 1; } - *pFIO_EDGE = FIO_EDGE_BITS; + *pFIO_EDGE = FIO_EDGE_BITS; *pFIO_POLAR = FIO_POLAR_BITS; - - if (cf_stat) - { - printf ("Booting from COMPACT flash\n"); + + if (cf_stat) { + printf ("Booting from COMPACT flash\n"); /* Set cycle time for CF */ *(volatile unsigned long *) ambctl1 = CF_AMBCTL1VAL; - for (i=0; i < 0x1000 ; i++) asm("nop;"); - for (i=0; i < 0x1000 ; i++) asm("nop;"); - for (i=0; i < 0x1000 ; i++) asm("nop;"); + for (i = 0; i < 0x1000; i++) + asm ("nop;"); + for (i = 0; i < 0x1000; i++) + asm ("nop;"); + for (i = 0; i < 0x1000; i++) + asm ("nop;"); - serial_setbrg(); - ide_init(); + serial_setbrg (); + ide_init (); setenv ("bootargs", ""); - setenv ("bootcmd", "fatload ide 0:1 0x1000000 uImage-stamp;bootm 0x1000000;bootm 0x20100000" ); - } - else - { + setenv ("bootcmd", + "fatload ide 0:1 0x1000000 uImage-stamp;bootm 0x1000000;bootm 0x20100000"); + } else { printf ("Booting from FLASH\n"); } @@ -145,134 +144,132 @@ int misc_init_r(void) #ifdef CONFIG_STAMP_CF -void cf_outb(unsigned char val, volatile unsigned char* addr) +void cf_outb (unsigned char val, volatile unsigned char *addr) { - /* + /* * Set PF1 PF0 respectively to 0 1 to divert address - * to the expansion memory banks + * to the expansion memory banks */ *pFIO_FLAG_S = CF_PF0; *pFIO_FLAG_C = CF_PF1; - asm("ssync;"); + asm ("ssync;"); *(addr) = val; - asm("ssync;"); + asm ("ssync;"); - /* Setback PF1 PF0 to 0 0 to address external + /* Setback PF1 PF0 to 0 0 to address external * memory banks */ *(volatile unsigned short *) pFIO_FLAG_C = CF_PF1_PF0; - asm("ssync;"); + asm ("ssync;"); } -unsigned char cf_inb(volatile unsigned char *addr) +unsigned char cf_inb (volatile unsigned char *addr) { volatile unsigned char c; *pFIO_FLAG_S = CF_PF0; *pFIO_FLAG_C = CF_PF1; - asm("ssync;"); + asm ("ssync;"); c = *(addr); - asm("ssync;"); + asm ("ssync;"); *pFIO_FLAG_C = CF_PF1_PF0; - asm("ssync;"); + asm ("ssync;"); return c; } -void cf_insw(unsigned short *sect_buf, unsigned short *addr, int words) +void cf_insw (unsigned short *sect_buf, unsigned short *addr, int words) { int i; *pFIO_FLAG_S = CF_PF0; *pFIO_FLAG_C = CF_PF1; - asm("ssync;"); + asm ("ssync;"); - for (i = 0;i < words; i++) - { + for (i = 0; i < words; i++) { *(sect_buf + i) = *(addr); - asm("ssync;"); + asm ("ssync;"); } *pFIO_FLAG_C = CF_PF1_PF0; - asm("ssync;"); + asm ("ssync;"); } -void cf_outsw(unsigned short *addr, unsigned short *sect_buf, int words) +void cf_outsw (unsigned short *addr, unsigned short *sect_buf, int words) { int i; *pFIO_FLAG_S = CF_PF0; *pFIO_FLAG_C = CF_PF1; - asm("ssync;"); + asm ("ssync;"); - for (i = 0;i < words; i++) - { + for (i = 0; i < words; i++) { *(addr) = *(sect_buf + i); - asm("ssync;"); + asm ("ssync;"); } *pFIO_FLAG_C = CF_PF1_PF0; - asm("ssync;"); + asm ("ssync;"); } #endif -void stamp_led_set(int LED1, int LED2, int LED3) +void stamp_led_set (int LED1, int LED2, int LED3) { - *pFIO_INEN &= ~( PF2 | PF3 | PF4); - *pFIO_DIR |= ( PF2 | PF3 | PF4); - - if(LED1 == STATUS_LED_OFF) + *pFIO_INEN &= ~(PF2 | PF3 | PF4); + *pFIO_DIR |= (PF2 | PF3 | PF4); + + if (LED1 == STATUS_LED_OFF) *pFIO_FLAG_S = PF2; else *pFIO_FLAG_C = PF2; - if(LED2 == STATUS_LED_OFF) + if (LED2 == STATUS_LED_OFF) *pFIO_FLAG_S = PF3; else *pFIO_FLAG_C = PF3; - if(LED3 == STATUS_LED_OFF) + if (LED3 == STATUS_LED_OFF) *pFIO_FLAG_S = PF4; else *pFIO_FLAG_C = PF4; - asm("ssync;"); + asm ("ssync;"); } -void show_boot_progress(int status) +void show_boot_progress (int status) { - switch(status){ - case 1: - stamp_led_set(STATUS_LED_OFF,STATUS_LED_OFF,STATUS_LED_ON); - break; - case 2: - stamp_led_set(STATUS_LED_OFF,STATUS_LED_ON,STATUS_LED_OFF); - break; - case 3: - stamp_led_set(STATUS_LED_OFF,STATUS_LED_ON,STATUS_LED_ON); - break; - case 4: - stamp_led_set(STATUS_LED_ON,STATUS_LED_OFF,STATUS_LED_OFF); - break; - case 5: - case 6: - stamp_led_set(STATUS_LED_ON,STATUS_LED_OFF,STATUS_LED_ON); - break; - case 7: - case 8: - stamp_led_set(STATUS_LED_ON,STATUS_LED_ON,STATUS_LED_OFF); - break; - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - stamp_led_set(STATUS_LED_OFF,STATUS_LED_OFF,STATUS_LED_OFF); - break; - default: - stamp_led_set(STATUS_LED_ON,STATUS_LED_ON,STATUS_LED_ON); - break; + switch (status) { + case 1: + stamp_led_set (STATUS_LED_OFF, STATUS_LED_OFF, STATUS_LED_ON); + break; + case 2: + stamp_led_set (STATUS_LED_OFF, STATUS_LED_ON, STATUS_LED_OFF); + break; + case 3: + stamp_led_set (STATUS_LED_OFF, STATUS_LED_ON, STATUS_LED_ON); + break; + case 4: + stamp_led_set (STATUS_LED_ON, STATUS_LED_OFF, STATUS_LED_OFF); + break; + case 5: + case 6: + stamp_led_set (STATUS_LED_ON, STATUS_LED_OFF, STATUS_LED_ON); + break; + case 7: + case 8: + stamp_led_set (STATUS_LED_ON, STATUS_LED_ON, STATUS_LED_OFF); + break; + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + stamp_led_set (STATUS_LED_OFF, STATUS_LED_OFF, + STATUS_LED_OFF); + break; + default: + stamp_led_set (STATUS_LED_ON, STATUS_LED_ON, STATUS_LED_ON); + break; } } - diff --git a/board/stamp/u-boot.lds b/board/stamp/u-boot.lds index ad6886f8e1..9a22e50781 100644 --- a/board/stamp/u-boot.lds +++ b/board/stamp/u-boot.lds @@ -145,4 +145,3 @@ SECTIONS _end = . ; PROVIDE (end = .); } - diff --git a/common/soft_i2c.c b/common/soft_i2c.c index 268da2cdc4..48e3d3e1c2 100644 --- a/common/soft_i2c.c +++ b/common/soft_i2c.c @@ -289,7 +289,7 @@ int i2c_probe(uchar addr) int rc; /* - * perform 1 byte write transaction with just address byte + * perform 1 byte write transaction with just address byte * (fake write) */ send_start(); diff --git a/cpu/bf533/bf533_serial.h b/cpu/bf533/bf533_serial.h index ec63a5e00a..d430e6cabd 100644 --- a/cpu/bf533/bf533_serial.h +++ b/cpu/bf533/bf533_serial.h @@ -3,7 +3,7 @@ * * Copyright (c) 2005 blackfin.uclinux.org * - * This file is based on + * This file is based on * bf533_serial.h: Definitions for the BlackFin BF533 DSP serial driver. * Copyright (C) 2003 Bas Vermeulen * BuyWays B.V. (www.buyways.nl) diff --git a/cpu/bf533/cache.S b/cpu/bf533/cache.S index 1822d1f329..8fac402740 100644 --- a/cpu/bf533/cache.S +++ b/cpu/bf533/cache.S @@ -22,88 +22,88 @@ ENTRY(blackfin_icache_flush_range) ENTRY(blackfin_dcache_flush_range) R2 = -32; - R2 = R0 & R2; - P0 = R2; - P1 = R1; - CSYNC; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC; 1: - FLUSH[P0++]; - CC = P0 < P1(iu); - IF CC JUMP 1b(bp); - FLUSH[P0]; - SSYNC; - RTS; + FLUSH[P0++]; + CC = P0 < P1(iu); + IF CC JUMP 1b(bp); + FLUSH[P0]; + SSYNC; + RTS; ENTRY(_icache_invalidate) ENTRY(invalidate_entire_icache) - [--SP] = ( R7:5); - - P0.L = (IMEM_CONTROL & 0xFFFF); - P0.H = (IMEM_CONTROL >> 16); - R7 = [P0]; - - /* Clear the IMC bit , All valid bits in the instruction - * cache are set to the invalid state - */ - BITCLR(R7,IMC_P); - CLI R6; - SSYNC; /* SSYNC required before invalidating cache. */ - .align 8; - [P0] = R7; - SSYNC; - STI R6; - - /* Configures the instruction cache agian */ - R6 = (IMC | ENICPLB); - R7 = R7 | R6; - - CLI R6; - SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ - .align 8; - [P0] = R7; - SSYNC; - STI R6; - - ( R7:5) = [SP++]; - RTS; + [--SP] = ( R7:5); + + P0.L = (IMEM_CONTROL & 0xFFFF); + P0.H = (IMEM_CONTROL >> 16); + R7 = [P0]; + + /* Clear the IMC bit , All valid bits in the instruction + * cache are set to the invalid state + */ + BITCLR(R7,IMC_P); + CLI R6; + SSYNC; /* SSYNC required before invalidating cache. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + /* Configures the instruction cache agian */ + R6 = (IMC | ENICPLB); + R7 = R7 | R6; + + CLI R6; + SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + ( R7:5) = [SP++]; + RTS; /* Invalidate the Entire Data cache by * clearing DMC[1:0] bits */ ENTRY(invalidate_entire_dcache) ENTRY(_dcache_invalidate) - [--SP] = ( R7:6); - - P0.L = (DMEM_CONTROL & 0xFFFF); - P0.H = (DMEM_CONTROL >> 16); - R7 = [P0]; - - /* Clear the DMC[1:0] bits, All valid bits in the data - * cache are set to the invalid state - */ - BITCLR(R7,DMC0_P); - BITCLR(R7,DMC1_P); - CLI R6; - SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ - .align 8; - [P0] = R7; - SSYNC; - STI R6; - - /* Configures the data cache again */ - - R6 = (ACACHE_BCACHE | ENDCPLB | PORT_PREF0); - R7 = R7 | R6; - - CLI R6; - SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ - .align 8; - [P0] = R7; - SSYNC; - STI R6; - - ( R7:6) = [SP++]; - RTS; + [--SP] = ( R7:6); + + P0.L = (DMEM_CONTROL & 0xFFFF); + P0.H = (DMEM_CONTROL >> 16); + R7 = [P0]; + + /* Clear the DMC[1:0] bits, All valid bits in the data + * cache are set to the invalid state + */ + BITCLR(R7,DMC0_P); + BITCLR(R7,DMC1_P); + CLI R6; + SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + /* Configures the data cache again */ + + R6 = (ACACHE_BCACHE | ENDCPLB | PORT_PREF0); + R7 = R7 | R6; + + CLI R6; + SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ + .align 8; + [P0] = R7; + SSYNC; + STI R6; + + ( R7:6) = [SP++]; + RTS; ENTRY(blackfin_dcache_invalidate_range) R2 = -32; diff --git a/cpu/bf533/cplbhdlr.S b/cpu/bf533/cplbhdlr.S index b5abbbcbb6..61be5bb90c 100644 --- a/cpu/bf533/cplbhdlr.S +++ b/cpu/bf533/cplbhdlr.S @@ -1,9 +1,9 @@ -/* Copyright (C) 2003 Analog Devices, Inc. All Rights Reserved. +/* Copyright (C) 2003 Analog Devices, Inc. All Rights Reserved. * * This file is subject to the terms and conditions of the GNU General Public - * License. + * License. * - * Blackfin BF533/2.6 support : LG Soft India + * Blackfin BF533/2.6 support : LG Soft India */ @@ -16,7 +16,7 @@ .text - + .globl _cplb_hdr; .type _cplb_hdr, STT_FUNC; .extern _cplb_mgr; @@ -76,19 +76,19 @@ is_icplb_miss: #if ( defined (CONFIG_BLKFIN_CACHE) || defined (CONFIG_BLKFIN_DCACHE)) #if ( defined (CONFIG_BLKFIN_CACHE) && !defined (CONFIG_BLKFIN_DCACHE)) - R1 = CPLB_ENABLE_ICACHE; + R1 = CPLB_ENABLE_ICACHE; #endif #if ( !defined (CONFIG_BLKFIN_CACHE) && defined (CONFIG_BLKFIN_DCACHE)) - R1 = CPLB_ENABLE_DCACHE; + R1 = CPLB_ENABLE_DCACHE; #endif #if ( defined (CONFIG_BLKFIN_CACHE) && defined (CONFIG_BLKFIN_DCACHE)) - R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE; + R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE; #endif #else R1 = 0; #endif - [--SP] = RETS; + [--SP] = RETS; CALL _cplb_mgr; RETS = [SP++]; CC = R0 == 0; @@ -109,27 +109,27 @@ is_icplb_miss: RTS; unknown: - [--SP] = RETS; + [--SP] = RETS; CALL __unknown_exception_occurred; RETS = [SP++]; JUMP unknown; not_replaced: CC = R0 == CPLB_NO_UNLOCKED; IF !CC JUMP next_check; - [--SP] = RETS; + [--SP] = RETS; CALL __cplb_miss_all_locked; RETS = [SP++]; next_check: CC = R0 == CPLB_NO_ADDR_MATCH; IF !CC JUMP next_check2; - [--SP] = RETS; + [--SP] = RETS; CALL __cplb_miss_without_replacement; RETS = [SP++]; JUMP not_replaced; next_check2: CC = R0 == CPLB_PROT_VIOL; IF !CC JUMP strange_return_from_cplb_mgr; - [--SP] = RETS; + [--SP] = RETS; CALL __cplb_protection_violation; RETS = [SP++]; JUMP not_replaced; @@ -139,8 +139,8 @@ strange_return_from_cplb_mgr: JUMP strange_return_from_cplb_mgr; /************************************ - * Diagnostic exception handlers - */ + * Diagnostic exception handlers + */ __cplb_miss_all_locked: sp += -12; @@ -174,11 +174,11 @@ __unknown_exception_occurred: * other kinds of exceptions, you must replace the * default handler with your own, that handles all the * exceptions you will use. - * + * * Since there's nothing we can do, we just loop here * at what we hope is a suitably informative label. */ - + IDLE; do_not_know_what_to_do: CSYNC; @@ -191,4 +191,3 @@ do_not_know_what_to_do: panic_bfin: RTS; - diff --git a/cpu/bf533/cplbmgr.S b/cpu/bf533/cplbmgr.S index fc3e3a8832..7a0b048629 100644 --- a/cpu/bf533/cplbmgr.S +++ b/cpu/bf533/cplbmgr.S @@ -3,7 +3,7 @@ * * Blackfin BF533/2.6 support : LG Soft India * Modification: Dec 07 2004 - * 1. Correction in icheck_lock. Valid lock entries were + * 1. Correction in icheck_lock. Valid lock entries were * geting victimized, for instruction cplb replacement. * 2. Setup loop's are modified as now toolchain support's P Indexed * addressing @@ -18,15 +18,15 @@ * * Returns: * CPLB_RELOADED => Successfully updated CPLB table. - * CPLB_NO_UNLOCKED => All CPLBs are locked, so cannot be evicted.This indicates - * that the CPLBs in the configuration tablei are badly + * CPLB_NO_UNLOCKED => All CPLBs are locked, so cannot be evicted.This indicates + * that the CPLBs in the configuration tablei are badly * configured, as this should never occur. - * CPLB_NO_ADDR_MATCH => The address being accessed, that triggered the exception, - * is not covered by any of the CPLBs in the configuration + * CPLB_NO_ADDR_MATCH => The address being accessed, that triggered the exception, + * is not covered by any of the CPLBs in the configuration * table. The application isi presumably misbehaving. - * CPLB_PROT_VIOL => The address being accessed, that triggered thei exception, - * was not a first-write to a clean Write Back Data page, - * and so presumably is a genuine violation of the page's + * CPLB_PROT_VIOL => The address being accessed, that triggered thei exception, + * was not a first-write to a clean Write Back Data page, + * and so presumably is a genuine violation of the page's * protection attributes. The application is misbehaving. */ #define ASSEMBLY @@ -35,9 +35,9 @@ #include #include #include - + .text - + .align 2; ENTRY(_cplb_mgr) @@ -51,8 +51,8 @@ ENTRY(_cplb_mgr) /* ICPLB Miss Exception. We need to choose one of the * currently-installed CPLBs, and replace it with one - * from the configuration table. - */ + * from the configuration table. + */ P4.L = (ICPLB_FAULT_ADDR & 0xFFFF); P4.H = (ICPLB_FAULT_ADDR >> 16); @@ -72,7 +72,7 @@ ENTRY(_cplb_mgr) isearch: R1 = [P0-0x100]; /* Address for this CPLB */ - + R0 = [P0++]; /* Info for this CPLB*/ CC = BITTST(R0,0); /* Is the CPLB valid?*/ IF !CC JUMP nomatch; /* Skip it, if not.*/ @@ -94,7 +94,7 @@ nomatch: isearch_done: I0 = R4; /* Fault address we'll search for*/ - + /* set up pointers */ P0.L = (ICPLB_DATA0 & 0xFFFF); P0.H = (ICPLB_DATA0 >> 16); @@ -138,7 +138,7 @@ ifound_victim: P3.H = ipdt_swapcount_table; P3 += -4; icount: - R2 = [P2]; /* address from config table */ + R2 = [P2]; /* address from config table */ P2 += 8; P3 += 8; CC = R2==-1; @@ -153,13 +153,13 @@ icount_done: #endif LC0=R3; LSETUP(is_move,ie_move) LC0; -is_move: +is_move: R0 = [P0]; [P0 - 4] = R0; R0 = [P0 - 0x100]; - [P0-0x104] = R0; + [P0-0x104] = R0; ie_move:P0+=4; - + /* We've made space in the ICPLB table, so that ICPLB15 * is now free to be overwritten. Next, we have to determine * which CPLB we need to install, from the configuration @@ -167,8 +167,8 @@ ie_move:P0+=4; * addresses and page-lengths from the config table, and * determining whether the fault address falls within that * range. - */ - + */ + P2.L = ipdt_table; P2.H = ipdt_table; #ifdef CONFIG_CPLB_INFO @@ -190,7 +190,7 @@ ie_move:P0+=4; */ R1 = ((16<<8)|2); -inext: R4 = [P2++]; /* address from config table */ +inext: R4 = [P2++]; /* address from config table */ R2 = [P2++]; /* data from config table */ #ifdef CONFIG_CPLB_INFO P3 += 8; @@ -201,7 +201,7 @@ inext: R4 = [P2++]; /* address from config table */ /* See if failed address > start address */ CC = R4 <= R0(IU); - IF !CC JUMP inext; + IF !CC JUMP inext; /* extract page size (17:16)*/ R3 = EXTRACT(R2, R1.L) (Z); @@ -250,17 +250,17 @@ inext: R4 = [P2++]; /* address from config table */ /* FAILED CASES*/ no_page_in_table: - ( R7:0,P5:0 ) = [SP++]; - R0 = CPLB_NO_ADDR_MATCH; - RTS; + ( R7:0,P5:0 ) = [SP++]; + R0 = CPLB_NO_ADDR_MATCH; + RTS; all_locked: - ( R7:0,P5:0 ) = [SP++]; - R0 = CPLB_NO_UNLOCKED; - RTS; + ( R7:0,P5:0 ) = [SP++]; + R0 = CPLB_NO_UNLOCKED; + RTS; prot_violation: - ( R7:0,P5:0 ) = [SP++]; - R0 = CPLB_PROT_VIOL; - RTS; + ( R7:0,P5:0 ) = [SP++]; + R0 = CPLB_PROT_VIOL; + RTS; dcplb_write: @@ -275,7 +275,7 @@ dcplb_write: P4.H = (DCPLB_STATUS >> 16); P3.L = (DCPLB_DATA0 & 0xFFFF); P3.H = (DCPLB_DATA0 >> 16); - R5 = [P4]; + R5 = [P4]; /* A protection violation can be caused by more than just writes * to a clean WB page, so we have to ensure that: @@ -315,7 +315,7 @@ dcplb_write: R2 <<= R5; /* if was super, check write in super mode*/ R2 = R3 & R2; CC = R2 == 0; - IF CC JUMP prot_violation; + IF CC JUMP prot_violation; /* It's a genuine write-to-clean-page.*/ @@ -333,7 +333,7 @@ dcplb_miss_compare: * config table, that covers the faulting address. */ - P1.L = (DCPLB_DATA15 & 0xFFFF); + P1.L = (DCPLB_DATA15 & 0xFFFF); P1.H = (DCPLB_DATA15 >> 16); P4.L = (DCPLB_FAULT_ADDR & 0xFFFF); @@ -379,7 +379,7 @@ sdsearch2: CC = R2 == 0; /* If none are set, it'll do.*/ IF !CC JUMP skip_stack_check; - R2 = [P0 - 0x104]; /* R2 - PageStart */ + R2 = [P0 - 0x104]; /* R2 - PageStart */ P3.L = page_size_table; /* retrive end address */ P3.H = page_size_table; /* retrive end address */ R3 = 0x2; /* 0th - position, 2 bits -length */ @@ -392,13 +392,13 @@ sdsearch2: R7 = R7 << 0xA; /* in bytes * 1024*/ R7 = R2 + R7; /* R7 - PageEnd */ - R4 = SP; /* Test SP is in range */ + R4 = SP; /* Test SP is in range */ CC = R7 < R4; /* if PageEnd < SP */ IF CC JUMP dfound_victim; R3 = 0x284; /* stack length from start of trap till the point */ /* 20 stack locations for future modifications */ - R4 = R4 + R3; + R4 = R4 + R3; CC = R4 < R2; /* if SP + stacklen < PageStart */ IF CC JUMP dfound_victim; skip_stack_check: @@ -409,7 +409,7 @@ edsearch1: NOP; /* If we got here, we didn't find a DCPLB we considered * replacable, which means all of them were locked. */ - + JUMP all_locked; dfound_victim: @@ -450,14 +450,14 @@ dicount_done: CC = BITTST(R1, 7); /* Is it dirty?*/ IF !CC JUMP Ddoverwrite (BP); /* Nope.*/ CC = BITTST(R1, 14); /* Is it Write-Through?*/ - IF CC JUMP Ddoverwrite; /* Yep*/ + IF CC JUMP Ddoverwrite; /* Yep*/ /* This is a dirty page, so we need to flush all writes * that are pending on the page. */ /* Retrieve the page start address*/ - R0 = [P0 - 0x104]; + R0 = [P0 - 0x104]; [--sp] = rets; CALL dcplb_flush; /* R0==CPLB addr, R1==CPLB data*/ rets = [sp++]; @@ -467,7 +467,7 @@ Ddoverwrite: * overwrite it by moving all the following CPLBs * one space closer to the start. */ - + R1.L = ((DCPLB_DATA15+4) & 0xFFFF); /*DCPLB_DATA15+4*/ R1.H = ((DCPLB_DATA15+4) >> 16); R0 = P0; @@ -485,7 +485,7 @@ Ddoverwrite: ds_move: R0 = [P0++]; /* move data */ [P0 - 8] = R0; - R0 = [P0-0x104] /* move address */ + R0 = [P0-0x104] /* move address */ de_move: [P0-0x108] = R0; /* We've now made space in DCPLB15 for the new CPLB to be @@ -510,7 +510,7 @@ de_moved:NOP; /* An extraction pattern, to retrieve bits 17:16.*/ R1 = (16<<8)|2; -dnext: R4 = [P2++]; /* address */ +dnext: R4 = [P2++]; /* address */ R2 = [P2++]; /* data */ #ifdef CONFIG_CPLB_INFO P3 += 8; @@ -521,7 +521,7 @@ dnext: R4 = [P2++]; /* address */ /* See if failed address > start address */ CC = R4 <= R0(IU); - IF !CC JUMP dnext; + IF !CC JUMP dnext; /* extract page size (17:16)*/ R3 = EXTRACT(R2, R1.L) (Z); diff --git a/cpu/bf533/cpu.c b/cpu/bf533/cpu.c index 2c139f547d..78e2b966bb 100644 --- a/cpu/bf533/cpu.c +++ b/cpu/bf533/cpu.c @@ -41,7 +41,7 @@ #define L1_IMEMORY (PAGE_SIZE_1MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_LOCK) #define SDRAM_INON_CHBL (PAGE_SIZE_4MB | CPLB_USER_RD | CPLB_VALID) -#define ANOMALY_05000158 0x200 +#define ANOMALY_05000158 0x200 #define SDRAM_DGENERIC (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_SUPV_WR | CPLB_USER_RD | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158) #define SDRAM_DNON_CHBL (PAGE_SIZE_4MB | CPLB_WT | CPLB_L1_AOW | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158) #define SDRAM_DKERNEL (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_USER_RD | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_VALID | CPLB_LOCK | ANOMALY_05000158) @@ -68,7 +68,7 @@ static unsigned int icplb_table[16][2]={ }; static unsigned int dcplb_table[16][2]={ - {0xFFA00000,L1_DMEMORY}, + {0xFFA00000,L1_DMEMORY}, {0x00000000,SDRAM_DKERNEL}, /*SDRAM_Page1*/ {0x00400000,SDRAM_DKERNEL}, /*SDRAM_Page1*/ {0x07C00000,SDRAM_DKERNEL}, /*SDRAM_Page15*/ @@ -83,13 +83,9 @@ static unsigned int dcplb_table[16][2]={ {0x02800000,SDRAM_DGENERIC}, /*SDRAM_Page10*/ {0x02C00000,SDRAM_DGENERIC}, /*SDRAM_Page11*/ {0x03000000,SDRAM_DGENERIC}, /*SDRAM_Page12*/ - {0x20000000,SDRAM_EBIU}, /*For Network */ + {0x20000000,SDRAM_EBIU}, /*For Network */ }; - - - - int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { __asm__ __volatile__ @@ -121,7 +117,7 @@ void icache_enable(void) I0 = (unsigned int *)ICPLB_ADDR0; I1 = (unsigned int *)ICPLB_DATA0; - + for(i=0;i<16;i++){ *I0++ = icplb_table[i][0]; *I1++ = icplb_table[i][1]; @@ -166,13 +162,12 @@ void dcache_enable(void) *I1++ = dcplb_table[i][1]; } cli(); - temp = *(unsigned int *)DMEM_CONTROL; + temp = *(unsigned int *)DMEM_CONTROL; SSYNC(); *(unsigned int *)DMEM_CONTROL = ACACHE_BCACHE |ENDCPLB |PORT_PREF0|temp; SSYNC(); sti(); } - void dcache_disable(void) { diff --git a/cpu/bf533/flush.S b/cpu/bf533/flush.S index 1f9ec9899e..9fbdefc9db 100644 --- a/cpu/bf533/flush.S +++ b/cpu/bf533/flush.S @@ -60,7 +60,7 @@ ENTRY(icplb_flush) [--SP] = LC1; [--SP] = LT1; [--SP] = LB1; - + /* If it's a 1K or 4K page, then it's quickest to * just systematically flush all the addresses in * the page, regardless of whether they're in the @@ -90,7 +90,7 @@ ENTRY(icplb_flush) R4 = EXTRACT(R0, R3.L) (Z); /* Extract bits*/ R3.H = R4.L << 0 ; /* Save in extraction pattern for later deposit.*/ - + /* So: * R0 = Page start * R1 = Page length (actually, offset into size/prefix tables) @@ -101,7 +101,7 @@ ENTRY(icplb_flush) * sub-bank, looking for dirty, valid tags that match our * address prefix. */ - + P5.L = (ITEST_COMMAND & 0xFFFF); P5.H = (ITEST_COMMAND >> 16); P4.L = (ITEST_DATA0 & 0xFFFF); @@ -119,7 +119,7 @@ ENTRY(icplb_flush) * fetching tags, so we only have to set Set, Bank, * Sub-bank and Way. */ - + P2 = 4; LSETUP (ifs1, ife1) LC1 = P2; ifs1: P0 = 32; /* iterate over all sets*/ @@ -142,7 +142,7 @@ ifs0: R6 = R5 << 5; /* Combine set*/ IF !CC JUMP ifskip; /* Skip it if it doesn't match.*/ /* Tag address matches against page, so this is an entry - * we must flush. + * we must flush. */ R7 >>= 10; /* Mask off the non-address bits*/ @@ -181,11 +181,11 @@ iflush_whole_page: IFLUSH [P0++]; /* because CSYNC can't end loops.*/ LSETUP (isall, ieall) LC0 = P1; isall:IFLUSH [P0++]; -ieall: NOP; +ieall: NOP; SSYNC; JUMP ifinished; -/* This is an external function being called by the user +/* This is an external function being called by the user * application through __flush_cache_all. Currently this function * serves the purpose of flushing all the pending writes in * in the data cache. @@ -222,7 +222,7 @@ skip: R6 += -1; /* This is an internal function to flush all pending * writes in the cache associated with a particular DCPLB. - * + * * R0 - page's start address * R1 - CPLB's data field. */ @@ -236,7 +236,7 @@ ENTRY(dcplb_flush) [--SP] = LC1; [--SP] = LT1; [--SP] = LB1; - + /* If it's a 1K or 4K page, then it's quickest to * just systematically flush all the addresses in * the page, regardless of whether they're in the @@ -250,9 +250,9 @@ ENTRY(dcplb_flush) /* We're only interested in the page's size, so extract * this from the CPLB (bits 17:16), and scale to give an - * offset into the page_size and page_prefix tables. + * offset into the page_size and page_prefix tables. */ - + R1 <<= 14; R1 >>= 30; R1 <<= 2; @@ -260,9 +260,9 @@ ENTRY(dcplb_flush) /* The page could be mapped into Bank A or Bank B, depending * on (a) whether both banks are configured as cache, and * (b) on whether address bit A[x] is set. x is determined - * by DCBS in DMEM_CONTROL + * by DCBS in DMEM_CONTROL */ - + R2 = 0; /* Default to Bank A (Bank B would be 1)*/ P0.L = (DMEM_CONTROL & 0xFFFF); @@ -303,7 +303,7 @@ bank_chosen: * sub-bank, looking for dirty, valid tags that match our * address prefix. */ - + P5.L = (DTEST_COMMAND & 0xFFFF); P5.H = (DTEST_COMMAND >> 16); P4.L = (DTEST_DATA0 & 0xFFFF); @@ -322,7 +322,7 @@ bank_chosen: * fetching tags, so we only have to set Set, Bank, * Sub-bank and Way. */ - + P2 = 2; LSETUP (fs1, fe1) LC1 = P2; fs1: P0 = 64; /* iterate over all sets*/ diff --git a/cpu/bf533/interrupt.S b/cpu/bf533/interrupt.S index b4d2579c44..e780dc6d6b 100644 --- a/cpu/bf533/interrupt.S +++ b/cpu/bf533/interrupt.S @@ -240,7 +240,7 @@ evt_rst: sp += 12; _evt_rst_exit: - rtn; + rtn; irq_panic: r0 = IRQ_EVX; @@ -279,7 +279,7 @@ evt_evt7: evt_evt7_exit: RESTORE_CONTEXT - rti; + rti; .global evt_evt8 evt_evt8: diff --git a/cpu/bf533/serial.c b/cpu/bf533/serial.c index 8f0cd1649d..84ae9d9cde 100644 --- a/cpu/bf533/serial.c +++ b/cpu/bf533/serial.c @@ -13,12 +13,12 @@ * Copyright(c) 2003 Metrowerks * Copyright(c) 2001 Tony Z. Kou * Copyright(c) 2001-2002 Arcturus Networks Inc. - * + * * Based on code from 68328 version serial driver imlpementation which was: * Copyright (C) 1995 David S. Miller * Copyright (C) 1998 Kenneth Albanowski * Copyright (C) 1998, 1999 D. Jeff Dionne - * Copyright (C) 1999 Vladimir Gurevich + * Copyright (C) 1999 Vladimir Gurevich * * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -178,9 +178,9 @@ static void local_put_char(char ch) save_and_cli(flags); - /* Poll for TX Interruput */ - while (!((isr_val = *pSIC_ISR) & IRQ_UART_TX_BIT)); - asm("csync;"); + /* Poll for TX Interruput */ + while (!((isr_val = *pSIC_ISR) & IRQ_UART_TX_BIT)); + asm("csync;"); *pUART_THR = ch; /* putc() */ diff --git a/cpu/bf533/start.S b/cpu/bf533/start.S index 7414d8873d..6d585751ab 100644 --- a/cpu/bf533/start.S +++ b/cpu/bf533/start.S @@ -32,7 +32,7 @@ /* * Note: A change in this file subsequently requires a change in - * board/$(board_name)/config.mk for a valid u-boot.bin + * board/$(board_name)/config.mk for a valid u-boot.bin */ #define ASSEMBLY @@ -82,7 +82,7 @@ _stext: SSYNC; /* As per HW reference manual DAG registers, - * DATA and Address resgister shall be zero'd + * DATA and Address resgister shall be zero'd * in initialization, after a reset state */ r1 = 0; /* Data registers zero'd */ @@ -99,7 +99,7 @@ _stext: p3 = 0; p4 = 0; p5 = 0; - + i0 = 0; /* DAG Registers zero'd */ i1 = 0; i2 = 0; @@ -242,9 +242,9 @@ loop1: r1 = [p1]; [p2] = r1; p3=0x4; - p1=p1+p3; + p1=p1+p3; p2=p2+p3; - r2=0x4; + r2=0x4; r0=r0-r2; cc=r0==0x0; if !cc jump loop1; diff --git a/examples/stubs.c b/examples/stubs.c index 1797274eb4..250a9af6e5 100644 --- a/examples/stubs.c +++ b/examples/stubs.c @@ -131,7 +131,7 @@ gd_t *global_data; * register */ #define EXPORT_FUNC(x) \ - asm volatile ( \ + asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ " P0 = [P5 + %0]\n" \ diff --git a/include/asm-blackfin/cplbtab.h b/include/asm-blackfin/cplbtab.h index dc6aee2b94..ab7d989b1a 100644 --- a/include/asm-blackfin/cplbtab.h +++ b/include/asm-blackfin/cplbtab.h @@ -3,9 +3,9 @@ * * Blackfin BF533/2.6 support : LG Soft India * Updated : Ashutosh Singh / Jahid Khan : Rrap Software Pvt Ltd - * Updated : 1. SDRAM_KERNEL, SDRAM_DKENEL are added as initial cplb's + * Updated : 1. SDRAM_KERNEL, SDRAM_DKENEL are added as initial cplb's * shouldn't be victimized. cplbmgr.S search logic is corrected - * to findout the appropriate victim. + * to findout the appropriate victim. * 2. SDRAM_IGENERIC in dpdt_table is replaced with SDRAM_DGENERIC * : LG Soft India */ @@ -15,12 +15,12 @@ #define __ARCH_BFINNOMMU_CPLBTAB_H /************************************************************************* - * ICPLB TABLE + * ICPLB TABLE *************************************************************************/ .data -/* This table is configurable */ +/* This table is configurable */ .align 4; @@ -33,7 +33,7 @@ /*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/ -#define ANOMALY_05000158 0x200 +#define ANOMALY_05000158 0x200 #ifdef CONFIG_BLKFIN_WB /*Write Back Policy */ #define SDRAM_DGENERIC (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_DIRTY | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158) #define SDRAM_DNON_CHBL (PAGE_SIZE_4MB | CPLB_DIRTY | CPLB_SUPV_WR | CPLB_USER_RD | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158) @@ -45,14 +45,14 @@ #define SDRAM_DGENERIC (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_SUPV_WR | CPLB_USER_RD | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158) #define SDRAM_DNON_CHBL (PAGE_SIZE_4MB | CPLB_WT | CPLB_L1_AOW | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158) #define SDRAM_DKERNEL (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_USER_RD | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_VALID | CPLB_LOCK | ANOMALY_05000158) - #define L1_DMEMORY (PAGE_SIZE_4KB | CPLB_L1_CHBL | CPLB_L1_AOW | CPLB_WT | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158) + #define L1_DMEMORY (PAGE_SIZE_4KB | CPLB_L1_CHBL | CPLB_L1_AOW | CPLB_WT | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158) #define SDRAM_EBIU (PAGE_SIZE_1MB | CPLB_WT | CPLB_L1_AOW | CPLB_USER_RD | CPLB_USER_WR | CPLB_SUPV_WR | CPLB_VALID | ANOMALY_05000158) -#endif +#endif .global icplb_table icplb_table: .byte4 0xFFA00000; -.byte4 (L1_IMEMORY); +.byte4 (L1_IMEMORY); .byte4 0x00000000; .byte4 (SDRAM_IKERNEL); /*SDRAM_Page1*/ .byte4 0x00400000; @@ -174,20 +174,20 @@ ipdt_table: .byte4 0xffffffff; /* end of section - termination*/ /********************************************************************* - * DCPLB TABLE + * DCPLB TABLE ********************************************************************/ .global dcplb_table dcplb_table: .byte4 0x00000000; .byte4 (SDRAM_DKERNEL); /*SDRAM_Page1*/ -.byte4 0x00400000; +.byte4 0x00400000; .byte4 (SDRAM_DKERNEL); /*SDRAM_Page1*/ .byte4 0x07C00000; .byte4 (SDRAM_DKERNEL); /*SDRAM_Page15*/ -.byte4 0x00800000; +.byte4 0x00800000; .byte4 (SDRAM_DGENERIC); /*SDRAM_Page2*/ -.byte4 0x00C00000; +.byte4 0x00C00000; .byte4 (SDRAM_DGENERIC); /*SDRAM_Page3*/ .byte4 0x01000000; .byte4 (SDRAM_DGENERIC); /*SDRAM_Page4*/ @@ -197,7 +197,7 @@ dcplb_table: .byte4 (SDRAM_DGENERIC); /*SDRAM_Page6*/ .byte4 0x01C00000; .byte4 (SDRAM_DGENERIC); /*SDRAM_Page7*/ -#ifndef CONFIG_EZKIT +#ifndef CONFIG_EZKIT .byte4 0x02000000; .byte4 (SDRAM_DGENERIC); /*SDRAM_Page8*/ .byte4 0x02400000; @@ -217,7 +217,7 @@ dcplb_table: /********************************************************************** * PAGE DESCRIPTOR TABLE - * + * **********************************************************************/ /* Till here we are discussing about the static memory management model. @@ -225,15 +225,15 @@ dcplb_table: * descriptors to cover the entire addressable memory than will fit into * the available on-chip 16 CPLB MMRs. When this happens, the below table * will be used which will hold all the potentially required CPLB descriptors - * + * * This is how Page descriptor Table is implemented in uClinux/Blackfin. - */ + */ .global dpdt_table dpdt_table: #ifdef CONFIG_CPLB_INFO .byte4 0x00000000; .byte4 (SDRAM_DKERNEL); /*SDRAM_Page0*/ -.byte4 0x00400000; +.byte4 0x00400000; .byte4 (SDRAM_DKERNEL); /*SDRAM_Page1*/ #endif .byte4 0x00800000; @@ -271,12 +271,12 @@ dpdt_table: .byte4 (SDRAM_EBIU); /* Async Memory Bank 2 (Secnd)*/ .byte4 0x20100000; .byte4 (SDRAM_EBIU); /* Async Memory Bank 1 (Prim B)*/ -.byte4 0x20000000; +.byte4 0x20000000; .byte4 (SDRAM_EBIU); /* Async Memory Bank 0 (Prim A)*/ .byte4 0x20300000; /*Fix for Network*/ .byte4 (SDRAM_EBIU); /*Async Memory bank 3*/ -#ifdef CONFIG_STAMP +#ifdef CONFIG_STAMP .byte4 0x04000000; .byte4 (SDRAM_DGENERIC); .byte4 0x04400000; diff --git a/include/asm-blackfin/cpu/bf533_irq.h b/include/asm-blackfin/cpu/bf533_irq.h index 902308a486..9c5230db41 100644 --- a/include/asm-blackfin/cpu/bf533_irq.h +++ b/include/asm-blackfin/cpu/bf533_irq.h @@ -81,7 +81,7 @@ /* The ABSTRACT IRQ definitions */ -/* The first seven of the following are fixed, +/* The first seven of the following are fixed, * the rest you change if you need to */ diff --git a/include/asm-blackfin/cpu/defBF532.h b/include/asm-blackfin/cpu/defBF532.h index c30d5cd7bc..26a5fe6442 100644 --- a/include/asm-blackfin/cpu/defBF532.h +++ b/include/asm-blackfin/cpu/defBF532.h @@ -30,7 +30,7 @@ /* include all Core registers and bit definitions */ #include -/* Helper macros +/* Helper macros * usage: * P0.H = HI(UART_THR); * P0.L = LO(UART_THR); @@ -789,7 +789,7 @@ #define ERR_TYP_P0 0x0E #define ERR_TYP_P1 0x0F -/* +/* * PROGRAMMABLE FLAG MASKS */ diff --git a/include/asm-blackfin/cpu/def_LPBlackfin.h b/include/asm-blackfin/cpu/def_LPBlackfin.h index 11a6504391..9ac78c836a 100644 --- a/include/asm-blackfin/cpu/def_LPBlackfin.h +++ b/include/asm-blackfin/cpu/def_LPBlackfin.h @@ -21,7 +21,7 @@ #ifndef _DEF_LPBLACKFIN_H #define _DEF_LPBLACKFIN_H -/* +/* * #if !defined(__ADSPLPBLACKFIN__) * #warning def_LPBlackfin.h should only be included for 532 compatible chips. * #endif @@ -344,9 +344,9 @@ /* ** Masks */ #define ENDM 0x00000001 /* (doesn't really exist) Enable Data Memory L1 */ #define ENDCPLB 0x00000002 /* Enable DCPLB */ -#define ASRAM_BSRAM 0x00000000 +#define ASRAM_BSRAM 0x00000000 #define ACACHE_BSRAM 0x00000008 -#define ACACHE_BCACHE 0x0000000C +#define ACACHE_BCACHE 0x0000000C #define DCBS 0x00000010 /* L1 Data Cache Bank Select */ #define PORT_PREF0 0x00001000 /* DAG0 Port Preference */ #define PORT_PREF1 0x00002000 /* DAG1 Port Preference */ diff --git a/include/asm-blackfin/page_offset.h b/include/asm-blackfin/page_offset.h index 45e34b5178..262473fc3d 100644 --- a/include/asm-blackfin/page_offset.h +++ b/include/asm-blackfin/page_offset.h @@ -22,7 +22,7 @@ * MA 02111-1307 USA */ -/* +/* * Changes made by Akbar Hussain April 10, 2001 */ diff --git a/include/asm-blackfin/uaccess.h b/include/asm-blackfin/uaccess.h index 84b4b4ead7..8578166a37 100644 --- a/include/asm-blackfin/uaccess.h +++ b/include/asm-blackfin/uaccess.h @@ -3,7 +3,7 @@ * * Copyright (c) 2005 blackfin.uclinux.org * - * This file is based on + * This file is based on * Based on: include/asm-m68knommu/uaccess.h * Changes made by Lineo Inc. May 2001 * diff --git a/include/configs/ezkit533.h b/include/configs/ezkit533.h index a52af4eebe..5eda6732ca 100644 --- a/include/configs/ezkit533.h +++ b/include/configs/ezkit533.h @@ -9,111 +9,111 @@ #define CONFIG_DRIVER_SMC91111 1 #define CONFIG_SMC91111_BASE 0x20310300 #if 0 -#define CONFIG_MII +#define CONFIG_MII #define CFG_DISCOVER_PHY #endif #define CONFIG_RTC_BF533 1 #define CONFIG_BOOT_RETRY_TIME -1 /* Enable this if bootretry required, currently its disabled */ -/* CONFIG_CLKIN_HZ is any value in Hz */ -#define CONFIG_CLKIN_HZ 27000000 -/* CONFIG_CLKIN_HALF controls what is passed to PLL 0=CLKIN */ -/* 1=CLKIN/2 */ -#define CONFIG_CLKIN_HALF 0 -/* CONFIG_PLL_BYPASS controls if the PLL is used 0=don't bypass */ -/* 1=bypass PLL */ -#define CONFIG_PLL_BYPASS 0 -/* CONFIG_VCO_MULT controls what the multiplier of the PLL is. */ -/* Values can range from 1-64 */ +/* CONFIG_CLKIN_HZ is any value in Hz */ +#define CONFIG_CLKIN_HZ 27000000 +/* CONFIG_CLKIN_HALF controls what is passed to PLL 0=CLKIN */ +/* 1=CLKIN/2 */ +#define CONFIG_CLKIN_HALF 0 +/* CONFIG_PLL_BYPASS controls if the PLL is used 0=don't bypass */ +/* 1=bypass PLL */ +#define CONFIG_PLL_BYPASS 0 +/* CONFIG_VCO_MULT controls what the multiplier of the PLL is. */ +/* Values can range from 1-64 */ #define CONFIG_VCO_MULT 22 -/* CONFIG_CCLK_DIV controls what the core clock divider is */ -/* Values can be 1, 2, 4, or 8 ONLY */ +/* CONFIG_CCLK_DIV controls what the core clock divider is */ +/* Values can be 1, 2, 4, or 8 ONLY */ #define CONFIG_CCLK_DIV 1 /* CONFIG_SCLK_DIV controls what the peripheral clock divider is */ -/* Values can range from 1-15 */ +/* Values can range from 1-15 */ #define CONFIG_SCLK_DIV 5 #if ( CONFIG_CLKIN_HALF == 0 ) -#define CONFIG_VCO_HZ ( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT ) +#define CONFIG_VCO_HZ ( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT ) #else -#define CONFIG_VCO_HZ (( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT ) / 2 ) +#define CONFIG_VCO_HZ (( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT ) / 2 ) #endif #if (CONFIG_PLL_BYPASS == 0) -#define CONFIG_CCLK_HZ ( CONFIG_VCO_HZ / CONFIG_CCLK_DIV ) -#define CONFIG_SCLK_HZ ( CONFIG_VCO_HZ / CONFIG_SCLK_DIV ) +#define CONFIG_CCLK_HZ ( CONFIG_VCO_HZ / CONFIG_CCLK_DIV ) +#define CONFIG_SCLK_HZ ( CONFIG_VCO_HZ / CONFIG_SCLK_DIV ) #else -#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ -#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ +#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ +#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ #endif -#define CONFIG_MEM_SIZE 32 /* 128, 64, 32, 16 */ -#define CONFIG_MEM_ADD_WDTH 9 /* 8, 9, 10, 11 */ -#define CONFIG_MEM_MT48LC16M16A2TG_75 1 +#define CONFIG_MEM_SIZE 32 /* 128, 64, 32, 16 */ +#define CONFIG_MEM_ADD_WDTH 9 /* 8, 9, 10, 11 */ +#define CONFIG_MEM_MT48LC16M16A2TG_75 1 #define CONFIG_LOADS_ECHO 1 -#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ CFG_CMD_PING | \ CFG_CMD_ELF | \ CFG_CMD_I2C | \ CFG_CMD_JFFS2 | \ CFG_CMD_DATE) -#define CONFIG_BOOTARGS "root=/dev/mtdblock0 ip=192.168.0.15:192.168.0.2:192.168.0.1:255.255.255.0:ezkit:eth0:off" +#define CONFIG_BOOTARGS "root=/dev/mtdblock0 ip=192.168.0.15:192.168.0.2:192.168.0.1:255.255.255.0:ezkit:eth0:off" /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include -#define CFG_PROMPT "ezkit> " /* Monitor Command Prompt */ +#define CFG_PROMPT "ezkit> " /* Monitor Command Prompt */ #if (CONFIG_COMMANDS & CFG_CMD_KGDB) -#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ #else -#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ #endif -#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ -#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CFG_MEMTEST_START 0x00100000 /* memtest works on */ #define CFG_MEMTEST_END 0x01F00000 /* 1 ... 31 MB in DRAM */ -#define CFG_LOAD_ADDR 0x01000000 /* default load address */ -#define CFG_HZ 1000 /* decrementer freq: 10 ms ticks */ +#define CFG_LOAD_ADDR 0x01000000 /* default load address */ +#define CFG_HZ 1000 /* decrementer freq: 10 ms ticks */ #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } -#define CFG_SDRAM_BASE 0x00000000 +#define CFG_SDRAM_BASE 0x00000000 #define CFG_MAX_RAM_SIZE 0x02000000 #define CFG_FLASH_BASE 0x20000000 -#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ #define CFG_MONITOR_BASE (CFG_MAX_RAM_SIZE - CFG_MONITOR_LEN) -#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ #define CFG_MALLOC_BASE (CFG_MONITOR_BASE - CFG_MALLOC_LEN) #define CFG_GBL_DATA_SIZE 0x4000 #define CFG_GBL_DATA_ADDR (CFG_MALLOC_BASE - CFG_GBL_DATA_SIZE) #define CONFIG_STACKBASE (CFG_GBL_DATA_ADDR - 4) -#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ #define CFG_FLASH0_BASE 0x20000000 #define CFG_FLASH1_BASE 0x20200000 #define CFG_FLASH2_BASE 0x20280000 #define CFG_MAX_FLASH_BANKS 3 /* max number of memory banks */ #define CFG_MAX_FLASH_SECT 40 /* max number of sectors on one chip */ -#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_ADDR 0x20020000 -#define CFG_ENV_SECT_SIZE 0x10000 /* Total Size of Environment Sector */ +#define CFG_ENV_SECT_SIZE 0x10000 /* Total Size of Environment Sector */ /* JFFS Partition offset set */ #define CFG_JFFS2_FIRST_BANK 0 #define CFG_JFFS2_NUM_BANKS 1 /* 512k reserved for u-boot */ -#define CFG_JFFS2_FIRST_SECTOR 11 +#define CFG_JFFS2_FIRST_SECTOR 11 /* * Stack sizes */ -#define CONFIG_STACKSIZE (128*1024) /* regular stack */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ #define POLL_MODE 1 #define FLASH_TOT_SECT 40 @@ -123,7 +123,7 @@ /* * Initialize PSD4256 registers for using I2C */ -#define CONFIG_MISC_INIT_R +#define CONFIG_MISC_INIT_R /* * I2C settings @@ -144,7 +144,7 @@ *pFIO_FLAG_S = PF_SDA; \ asm("ssync;"); \ } \ - else { \ + else { \ *pFIO_FLAG_C = PF_SDA; \ asm("ssync;"); \ } @@ -152,7 +152,7 @@ *pFIO_FLAG_S = PF_SCL; \ asm("ssync;"); \ } \ - else { \ + else { \ *pFIO_FLAG_C = PF_SCL; \ asm("ssync;"); \ } @@ -166,15 +166,15 @@ #define __ADSPBF533__ 1 /* 0xFF, 0x7BB07BB0, 0x22547BB0 */ -/* #define AMGCTLVAL (AMBEN_P0 | AMBEN_P1 | AMBEN_P2 | AMCKEN) -#define AMBCTL0VAL (B1WAT_7 | B1RAT_11 | B1HT_2 | B1ST_3 | B1TT_4 | ~B1RDYPOL | \ - ~B1RDYEN | B0WAT_7 | B0RAT_11 | B0HT_2 | B0ST_3 | B0TT_4 | ~B0RDYPOL | ~B0RDYEN) -#define AMBCTL1VAL (B3WAT_2 | B3RAT_2 | B3HT_1 | B3ST_1 | B3TT_4 | B3RDYPOL | ~B3RDYEN | \ - B2WAT_7 | B2RAT_11 | B2HT_2 | B2ST_3 | B2TT_4 | ~B2RDYPOL | ~B2RDYEN) +/* #define AMGCTLVAL (AMBEN_P0 | AMBEN_P1 | AMBEN_P2 | AMCKEN) +#define AMBCTL0VAL (B1WAT_7 | B1RAT_11 | B1HT_2 | B1ST_3 | B1TT_4 | ~B1RDYPOL | \ + ~B1RDYEN | B0WAT_7 | B0RAT_11 | B0HT_2 | B0ST_3 | B0TT_4 | ~B0RDYPOL | ~B0RDYEN) +#define AMBCTL1VAL (B3WAT_2 | B3RAT_2 | B3HT_1 | B3ST_1 | B3TT_4 | B3RDYPOL | ~B3RDYEN | \ + B2WAT_7 | B2RAT_11 | B2HT_2 | B2ST_3 | B2TT_4 | ~B2RDYPOL | ~B2RDYEN) */ -#define AMGCTLVAL 0xFF -#define AMBCTL0VAL 0x7BB07BB0 -#define AMBCTL1VAL 0xFFC27BB0 +#define AMGCTLVAL 0xFF +#define AMBCTL0VAL 0x7BB07BB0 +#define AMBCTL1VAL 0xFFC27BB0 #define CONFIG_VDSP 1 diff --git a/include/configs/stamp.h b/include/configs/stamp.h index 1402a4131a..248ca70de0 100644 --- a/include/configs/stamp.h +++ b/include/configs/stamp.h @@ -17,7 +17,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -40,7 +40,7 @@ #define CONFIG_RTC_BF533 1 /* FLASH/ETHERNET uses the same address range */ -#define SHARED_RESOURCES 1 +#define SHARED_RESOURCES 1 #define CONFIG_VDSP 1 @@ -49,37 +49,37 @@ * */ -/* CONFIG_CLKIN_HZ is any value in Hz */ +/* CONFIG_CLKIN_HZ is any value in Hz */ #define CONFIG_CLKIN_HZ 11059200 -/* CONFIG_CLKIN_HALF controls what is passed to PLL 0=CLKIN */ -/* 1=CLKIN/2 */ +/* CONFIG_CLKIN_HALF controls what is passed to PLL 0=CLKIN */ +/* 1=CLKIN/2 */ #define CONFIG_CLKIN_HALF 0 -/* CONFIG_PLL_BYPASS controls if the PLL is used 0=don't bypass */ -/* 1=bypass PLL */ -#define CONFIG_PLL_BYPASS 0 -/* CONFIG_VCO_MULT controls what the multiplier of the PLL is. */ -/* Values can range from 1-64 */ +/* CONFIG_PLL_BYPASS controls if the PLL is used 0=don't bypass */ +/* 1=bypass PLL */ +#define CONFIG_PLL_BYPASS 0 +/* CONFIG_VCO_MULT controls what the multiplier of the PLL is. */ +/* Values can range from 1-64 */ #define CONFIG_VCO_MULT 45 -/* CONFIG_CCLK_DIV controls what the core clock divider is */ -/* Values can be 1, 2, 4, or 8 ONLY */ +/* CONFIG_CCLK_DIV controls what the core clock divider is */ +/* Values can be 1, 2, 4, or 8 ONLY */ #define CONFIG_CCLK_DIV 1 /* CONFIG_SCLK_DIV controls what the peripheral clock divider is */ -/* Values can range from 1-15 */ +/* Values can range from 1-15 */ #define CONFIG_SCLK_DIV 6 /* * Network Settings */ /* network support */ -#define CONFIG_IPADDR 192.168.0.15 -#define CONFIG_NETMASK 255.255.255.0 -#define CONFIG_GATEWAYIP 192.168.0.1 -#define CONFIG_SERVERIP 192.168.0.2 -#define CONFIG_HOSTNAME STAMP +#define CONFIG_IPADDR 192.168.0.15 +#define CONFIG_NETMASK 255.255.255.0 +#define CONFIG_GATEWAYIP 192.168.0.1 +#define CONFIG_SERVERIP 192.168.0.2 +#define CONFIG_HOSTNAME STAMP #define CONFIG_ROOTPATH /checkout/uClinux-dist/romfs /* To remove hardcoding and enable MAC storage in EEPROM */ -/* #define CONFIG_ETHADDR 02:80:ad:20:31:b8 */ +/* #define CONFIG_ETHADDR 02:80:ad:20:31:b8 */ /* * Command settings @@ -90,17 +90,17 @@ #define CONFIG_BOOTDELAY 5 #define CONFIG_BOOT_RETRY_TIME -1 /* Enable this if bootretry required, currently its disabled */ -#define CONFIG_BOOTCOMMAND "run ramboot" +#define CONFIG_BOOTCOMMAND "run ramboot" #define CONFIG_AUTOBOOT_PROMPT "autoboot in %d seconds\n" -#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ CFG_CMD_PING | \ CFG_CMD_ELF | \ CFG_CMD_I2C | \ CFG_CMD_CACHE | \ - CFG_CMD_JFFS2 | \ + CFG_CMD_JFFS2 | \ CFG_CMD_DATE) -#define CONFIG_BOOTARGS "root=/dev/mtdblock0 rw" +#define CONFIG_BOOTARGS "root=/dev/mtdblock0 rw" #define CONFIG_EXTRA_ENV_SETTINGS \ "ramargs=setenv bootargs root=/dev/mtdblock0 rw\0" \ @@ -127,14 +127,14 @@ #define CONFIG_BAUDRATE 57600 #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } -#define CFG_PROMPT "stamp>" /* Monitor Command Prompt */ +#define CFG_PROMPT "stamp>" /* Monitor Command Prompt */ #if (CONFIG_COMMANDS & CFG_CMD_KGDB) -#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ #else -#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ #endif -#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ -#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CONFIG_LOADS_ECHO 1 @@ -154,9 +154,9 @@ * */ -#define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ -#define CFG_FLASH_CFI_AMD_RESET +#define CFG_FLASH_CFI /* The flash is CFI compatible */ +#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CFG_FLASH_CFI_AMD_RESET #define CFG_ENV_IS_IN_FLASH 1 @@ -165,8 +165,8 @@ #define CFG_MAX_FLASH_SECT 67 /* max number of sectors on one chip */ #define CFG_ENV_ADDR 0x20020000 -#define CFG_ENV_SIZE 0x10000 -#define CFG_ENV_SECT_SIZE 0x10000 /* Total Size of Environment Sector */ +#define CFG_ENV_SIZE 0x10000 +#define CFG_ENV_SECT_SIZE 0x10000 /* Total Size of Environment Sector */ #define CFG_FLASH_ERASE_TOUT 30000 /* Timeout for Chip Erase (in ms) */ #define CFG_FLASH_ERASEBLOCK_TOUT 5000 /* Timeout for Block Erase (in ms) */ @@ -176,10 +176,10 @@ #define CFG_JFFS2_FIRST_BANK 0 #define CFG_JFFS2_NUM_BANKS 1 /* 512k reserved for u-boot */ -#define CFG_JFFS2_FIRST_SECTOR 11 +#define CFG_JFFS2_FIRST_SECTOR 11 -/* - * following timeouts shall be used once the +/* + * following timeouts shall be used once the * Flash real protection is enabled */ #define CFG_FLASH_LOCK_TOUT 5 /* Timeout for Flash Set Lock Bit (in ms) */ @@ -204,7 +204,7 @@ *pFIO_FLAG_S = PF_SDA; \ asm("ssync;"); \ } \ - else { \ + else { \ *pFIO_FLAG_C = PF_SDA; \ asm("ssync;"); \ } @@ -212,7 +212,7 @@ *pFIO_FLAG_S = PF_SCL; \ asm("ssync;"); \ } \ - else { \ + else { \ *pFIO_FLAG_C = PF_SCL; \ asm("ssync;"); \ } @@ -236,9 +236,9 @@ /* * IDE/ATA stuff */ -#undef CONFIG_IDE_8xx_DIRECT /* no pcmcia interface required */ -#undef CONFIG_IDE_LED /* no led for ide supported */ -#undef CONFIG_IDE_RESET /* no reset for ide supported */ +#undef CONFIG_IDE_8xx_DIRECT /* no pcmcia interface required */ +#undef CONFIG_IDE_LED /* no led for ide supported */ +#undef CONFIG_IDE_RESET /* no reset for ide supported */ #define CFG_IDE_MAXBUS 1 /* max. 1 IDE busses */ #define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*1) /* max. 1 drives per IDE bus */ @@ -246,9 +246,9 @@ #define CFG_ATA_BASE_ADDR 0x20200000 #define CFG_ATA_IDE0_OFFSET 0x0000 -#define CFG_ATA_DATA_OFFSET 0x0020 /* Offset for data I/O */ -#define CFG_ATA_REG_OFFSET 0x0020 /* Offset for normal register accesses */ -#define CFG_ATA_ALT_OFFSET 0x0007 /* Offset for alternate registers */ +#define CFG_ATA_DATA_OFFSET 0x0020 /* Offset for data I/O */ +#define CFG_ATA_REG_OFFSET 0x0020 /* Offset for normal register accesses */ +#define CFG_ATA_ALT_OFFSET 0x0007 /* Offset for alternate registers */ #define CFG_ATA_STRIDE 2 #endif @@ -258,23 +258,20 @@ * */ -#define CONFIG_MEM_SIZE 128 /* 128, 64, 32, 16 */ -#define CONFIG_MEM_ADD_WDTH 11 /* 8, 9, 10, 11 */ +#define CONFIG_MEM_SIZE 128 /* 128, 64, 32, 16 */ +#define CONFIG_MEM_ADD_WDTH 11 /* 8, 9, 10, 11 */ #define CONFIG_MEM_MT48LC64M4A2FB_7E 1 #define CFG_MEMTEST_START 0x00100000 /* memtest works on */ #define CFG_MEMTEST_END 0x07EFFFFF /* 1 ... 127 MB in DRAM */ -#define CFG_LOAD_ADDR 0x01000000 /* default load address */ +#define CFG_LOAD_ADDR 0x01000000 /* default load address */ -#define CFG_SDRAM_BASE 0x00000000 +#define CFG_SDRAM_BASE 0x00000000 #define CFG_MAX_RAM_SIZE 0x08000000 -#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ #define CFG_MONITOR_BASE (CFG_MAX_RAM_SIZE - CFG_MONITOR_LEN) - - - #if ( CONFIG_CLKIN_HALF == 0 ) #define CONFIG_VCO_HZ ( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT ) #else @@ -289,14 +286,12 @@ #define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ #endif - - /* * Miscellaneous configurable options */ -#define CFG_HZ 1000 /* 1ms time tick */ +#define CFG_HZ 1000 /* 1ms time tick */ -#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ #define CFG_MALLOC_BASE (CFG_MONITOR_BASE - CFG_MALLOC_LEN) #define CFG_GBL_DATA_SIZE 0x4000 #define CFG_GBL_DATA_ADDR (CFG_MALLOC_BASE - CFG_GBL_DATA_SIZE) @@ -309,25 +304,24 @@ /* * Stack sizes */ -#define CONFIG_STACKSIZE (128*1024) /* regular stack */ - +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ /* * FLASH organization and environment definitions */ -#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ /* 0xFF, 0xBBC3BBc3, 0x99B39983 */ -/*#define AMGCTLVAL (AMBEN_P0 | AMBEN_P1 | AMBEN_P2 | AMCKEN) -#define AMBCTL0VAL (B1WAT_11 | B1RAT_11 | B1HT_3 | B1ST_4 | B1TT_4 | B1RDYPOL | \ - B1RDYEN | B0WAT_11 | B0RAT_11 | B0HT_3 | B0ST_4 | B0TT_4 | B0RDYPOL | B0RDYEN) -#define AMBCTL1VAL (B3WAT_9 | B3RAT_9 | B3HT_2 | B3ST_3 | B3TT_4 | B3RDYPOL | \ - B3RDYEN | B2WAT_9 | B2RAT_9 | B2HT_2 | B2ST_4 | B2TT_4 | B2RDYPOL | B2RDYEN) +/*#define AMGCTLVAL (AMBEN_P0 | AMBEN_P1 | AMBEN_P2 | AMCKEN) +#define AMBCTL0VAL (B1WAT_11 | B1RAT_11 | B1HT_3 | B1ST_4 | B1TT_4 | B1RDYPOL | \ + B1RDYEN | B0WAT_11 | B0RAT_11 | B0HT_3 | B0ST_4 | B0TT_4 | B0RDYPOL | B0RDYEN) +#define AMBCTL1VAL (B3WAT_9 | B3RAT_9 | B3HT_2 | B3ST_3 | B3TT_4 | B3RDYPOL | \ + B3RDYEN | B2WAT_9 | B2RAT_9 | B2HT_2 | B2ST_4 | B2TT_4 | B2RDYPOL | B2RDYEN) */ -#define AMGCTLVAL 0xFF -#define AMBCTL0VAL 0xBBC3BBC3 -#define AMBCTL1VAL 0x99B39983 -#define CF_AMBCTL1VAL 0x99B3ffc2 +#define AMGCTLVAL 0xFF +#define AMBCTL0VAL 0xBBC3BBC3 +#define AMBCTL1VAL 0x99B39983 +#define CF_AMBCTL1VAL 0x99B3ffc2 #ifdef CONFIG_VDSP #define ET_EXEC_VDSP 0x8 @@ -336,5 +330,4 @@ #define VDSP_ENTRY_ADDR 0xFFA00000 #endif - #endif diff --git a/lib_blackfin/bf533_linux.c b/lib_blackfin/bf533_linux.c index 6f29795f9d..88b4da29df 100644 --- a/lib_blackfin/bf533_linux.c +++ b/lib_blackfin/bf533_linux.c @@ -46,7 +46,7 @@ #define CMD_LINE_ADDR 0xFF900000 /* L1 scratchpad */ #ifdef SHARED_RESOURCES - extern void swap_to(int device_id); + extern void swap_to(int device_id); #endif static char *make_command_line(void); diff --git a/lib_blackfin/bf533_string.c b/lib_blackfin/bf533_string.c index cfa515a848..c8b1a3a983 100644 --- a/lib_blackfin/bf533_string.c +++ b/lib_blackfin/bf533_string.c @@ -127,7 +127,7 @@ int strncmp(const char *cs, const char *ct, size_t count) void * memcpy(void * dest,const void *src,size_t count) { char *tmp = (char *) dest, *s = (char *) src; - + /* Turn off the cache, if destination in the L1 memory */ if ( (tmp >= (char *)L1_ISRAM) && (tmp < (char *)L1_ISRAM_END) || (tmp >= (char *)DATA_BANKA_SRAM) && (tmp < DATA_BANKA_SRAM_END) @@ -150,7 +150,7 @@ void * memcpy(void * dest,const void *src,size_t count) void *dma_memcpy(void * dest,const void *src,size_t count) { - + *pMDMA_D0_IRQ_STATUS = DMA_DONE | DMA_ERR; /* Copy sram functions from sdram to sram */ @@ -173,7 +173,7 @@ void *dma_memcpy(void * dest,const void *src,size_t count) asm("ssync;"); *pMDMA_D0_CONFIG = ( WNR | DMAEN); - + while(*pMDMA_D0_IRQ_STATUS & DMA_RUN){ *pMDMA_D0_IRQ_STATUS |= (DMA_DONE | DMA_ERR); } diff --git a/lib_blackfin/blackfin_board.h b/lib_blackfin/blackfin_board.h index 35a513fbac..31c16a20fe 100644 --- a/lib_blackfin/blackfin_board.h +++ b/lib_blackfin/blackfin_board.h @@ -38,7 +38,7 @@ extern ulong uboot_end; ulong monitor_flash_len; -#define VERSION_STRING_SIZE 150 /* including 40 bytes buffer to change any string */ +#define VERSION_STRING_SIZE 150 /* including 40 bytes buffer to change any string */ #define VERSION_STRING_FORMAT "%s (%s - %s)\n" #define VERSION_STRING U_BOOT_VERSION, __DATE__, __TIME__ diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c index 7bf63eb0af..55d13fad8c 100644 --- a/lib_blackfin/board.c +++ b/lib_blackfin/board.c @@ -147,7 +147,7 @@ void board_init_f(ulong bootflag) addr = (CFG_GBL_DATA_ADDR + sizeof(gd_t)); /* Align to 4 byte boundary */ - addr &= ~(4 - 1); + addr &= ~(4 - 1); bd = (bd_t*)addr; gd->bd = bd; memset((void *) bd, 0, sizeof(bd_t)); diff --git a/lib_blackfin/cache.c b/lib_blackfin/cache.c index 4213b861e4..847278d226 100644 --- a/lib_blackfin/cache.c +++ b/lib_blackfin/cache.c @@ -26,16 +26,15 @@ */ /* for now: just dummy functions to satisfy the linker */ -extern void blackfin_icache_range(unsigned long *,unsigned long *); -extern void blackfin_dcache_range(unsigned long *,unsigned long *); -void flush_cache(unsigned long dummy1, unsigned long dummy2) +extern void blackfin_icache_range (unsigned long *, unsigned long *); +extern void blackfin_dcache_range (unsigned long *, unsigned long *); +void flush_cache (unsigned long dummy1, unsigned long dummy2) { - if(icache_status()){ - blackfin_icache_flush_range(dummy1,dummy1+dummy2); - } - if(dcache_status()){ - blackfin_dcache_flush_range(dummy1,dummy1+dummy2); - } + if (icache_status ()) { + blackfin_icache_flush_range (dummy1, dummy1 + dummy2); + } + if (dcache_status ()) { + blackfin_dcache_flush_range (dummy1, dummy1 + dummy2); + } return; } - diff --git a/lib_blackfin/muldi3.c b/lib_blackfin/muldi3.c index a5622424fd..1fc34e3d93 100644 --- a/lib_blackfin/muldi3.c +++ b/lib_blackfin/muldi3.c @@ -80,13 +80,13 @@ DItype __muldi3 (DItype u, DItype v) { DIunion w; DIunion uu, vv; - + uu.ll = u, vv.ll = v; /* panic("kernel panic for __muldi3"); */ w.ll = __umulsidi3 (uu.s.low, vv.s.low); w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high + (USItype) uu.s.high * (USItype) vv.s.low); - + return w.ll; } diff --git a/rtc/bf533_rtc.c b/rtc/bf533_rtc.c index 09b8f2157d..948be64102 100644 --- a/rtc/bf533_rtc.c +++ b/rtc/bf533_rtc.c @@ -19,7 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA - * Real Time Clock interface of ADI21535 (Blackfin) for uCLinux + * Real Time Clock interface of ADI21535 (Blackfin) for uCLinux * * Copyright (C) 2003 Motorola Corporation. All rights reserved. * Richard Xiao (A2590C@email.mot.com) @@ -42,7 +42,7 @@ * 1.10b Andrew Morton: SMP lock fix * 1.10c Cesar Barros: SMP locking fixes and cleanup * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit - * 1.10e LG Soft India: Register access is different in BF533. + * 1.10e LG Soft India: Register access is different in BF533. */ #include @@ -54,62 +54,64 @@ #include #include -void rtc_reset(void) +void rtc_reset (void) { return; /* nothing to do */ } /* Wait for pending writes to complete */ -void wait_for_complete(void) +void wait_for_complete (void) { while (!(*(volatile unsigned short *) RTC_ISTAT & 0x8000)) { - printf(""); + printf (""); } *(volatile unsigned short *) RTC_ISTAT = 0x8000; } /* Enable the RTC prescaler enable register */ -void rtc_init() +void rtc_init () { *(volatile unsigned short *) RTC_PREN = 0x1; - wait_for_complete(); + wait_for_complete (); } -/* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers +/* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers * based on this value. */ void rtc_set (struct rtc_time *tmp) { unsigned long n_days_1970 = 0; - unsigned long n_secs_rem = 0; - unsigned long n_hrs = 0; - unsigned long n_mins = 0; - unsigned long n_secs = 0; + unsigned long n_secs_rem = 0; + unsigned long n_hrs = 0; + unsigned long n_mins = 0; + unsigned long n_secs = 0; unsigned long time_in_secs; - if(tmp == NULL) { - printf("Error setting the date/time \n"); + if (tmp == NULL) { + printf ("Error setting the date/time \n"); return; } - time_in_secs = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday,tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + time_in_secs = + mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour, + tmp->tm_min, tmp->tm_sec); /* Compute no. of days since 1970 */ n_days_1970 = (unsigned long) (time_in_secs / (NUM_SECS_IN_DAY)); /* From the remining secs, compute the hrs(0-23), mins(0-59) and secs(0-59) */ - n_secs_rem = (unsigned long)(time_in_secs % (NUM_SECS_IN_DAY)); - n_hrs = n_secs_rem / (NUM_SECS_IN_HOUR); + n_secs_rem = (unsigned long) (time_in_secs % (NUM_SECS_IN_DAY)); + n_hrs = n_secs_rem / (NUM_SECS_IN_HOUR); n_secs_rem = n_secs_rem % (NUM_SECS_IN_HOUR); n_mins = n_secs_rem / (NUM_SECS_IN_MIN); n_secs = n_secs_rem % (NUM_SECS_IN_MIN); - + /* Store the new time in the RTC_STAT register */ *(volatile unsigned long *) RTC_STAT = ((n_days_1970 << DAY_BITS_OFF) | (n_hrs << HOUR_BITS_OFF) | - (n_mins << MIN_BITS_OFF) | (n_secs << SEC_BITS_OFF)); + (n_mins << MIN_BITS_OFF) | (n_secs << SEC_BITS_OFF)); - wait_for_complete(); + wait_for_complete (); } /* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */ @@ -117,16 +119,16 @@ void rtc_get (struct rtc_time *tmp) { unsigned long cur_rtc_stat = 0; unsigned long time_in_sec; - unsigned long tm_sec = 0, tm_min = 0, tm_hour = 0, tm_day = 0; + unsigned long tm_sec = 0, tm_min = 0, tm_hour = 0, tm_day = 0; - if(tmp == NULL) { - printf("Error getting the date/time \n"); + if (tmp == NULL) { + printf ("Error getting the date/time \n"); return; } /* Read the RTC_STAT register */ cur_rtc_stat = *(volatile unsigned long *) RTC_STAT; - + /* Get the secs (0-59), mins (0-59), hrs (0-23) and the days since Jan 1970 */ tm_sec = (cur_rtc_stat >> SEC_BITS_OFF) & 0x3f; tm_min = (cur_rtc_stat >> MIN_BITS_OFF) & 0x3f; @@ -134,10 +136,10 @@ void rtc_get (struct rtc_time *tmp) tm_day = (cur_rtc_stat >> DAY_BITS_OFF) & 0x7fff; /* Calculate the total number of seconds since Jan 1970 */ - time_in_sec = (tm_sec) + - MIN_TO_SECS(tm_min) + - HRS_TO_SECS(tm_hour) + - DAYS_TO_SECS(tm_day); - to_tm(time_in_sec,tmp); + time_in_sec = (tm_sec) + + MIN_TO_SECS (tm_min) + + HRS_TO_SECS (tm_hour) + + DAYS_TO_SECS (tm_day); + to_tm (time_in_sec, tmp); } -#endif /* CONFIG_RTC_BF533 && CFG_CMD_DATE */ +#endif /* CONFIG_RTC_BF533 && CFG_CMD_DATE */ From 74f92e6a3f884b7fe86d2fb2acc114347defb0ae Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 16:05:05 +0100 Subject: [PATCH 067/102] Add crc of data to jffs2 (in jffs2_1pass_build_lists()). Patch by Rick Bronson, 15 Jun 2005 --- CHANGELOG | 3 +++ fs/jffs2/jffs2_1pass.c | 3 ++- fs/jffs2/jffs2_private.h | 12 ++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 57b4e78659..43d0133e46 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add crc of data to jffs2 (in jffs2_1pass_build_lists()). + Patch by Rick Bronson, 15 Jun 2005 + * Coding Style cleanup * Avoid dereferencing NULL in find_cmd() if no valid commands were found diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index 6361d06d20..49c86524c7 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -1171,7 +1171,8 @@ jffs2_1pass_build_lists(struct part_info * part) if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) { /* if its a fragment add it */ if (node->nodetype == JFFS2_NODETYPE_INODE && - inode_crc((struct jffs2_raw_inode *) node)) { + inode_crc((struct jffs2_raw_inode *) node) && + data_crc((struct jffs2_raw_inode *) node)) { if (insert_node(&pL->frag, (u32) part->offset + offset) == NULL) { put_fl_mem(node); diff --git a/fs/jffs2/jffs2_private.h b/fs/jffs2/jffs2_private.h index 65ca6eb98f..3e1fff4739 100644 --- a/fs/jffs2/jffs2_private.h +++ b/fs/jffs2/jffs2_private.h @@ -85,4 +85,16 @@ inode_crc(struct jffs2_raw_inode *node) } } +static inline int +data_crc(struct jffs2_raw_inode *node) +{ + if (node->data_crc != crc32_no_comp(0, (unsigned char *) + ((int) &node->node_crc + sizeof (node->node_crc)), + node->csize)) { + return 0; + } else { + return 1; + } +} + #endif /* jffs2_private.h */ From 23466d6a3304433ba8d7ff10f17260010fcc4580 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 16:14:29 +0100 Subject: [PATCH 068/102] Fix PCIDF calculation in cpu/mpc8260/speed.c for MPC8280EC Patch by KokHow Teh, 16 Jun 2005 --- CHANGELOG | 3 +++ cpu/mpc8260/speed.c | 25 ++++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 43d0133e46..e532b04ed9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix PCIDF calculation in cpu/mpc8260/speed.c for MPC8280EC + Patch by KokHow Teh, 16 Jun 2005 + * Add crc of data to jffs2 (in jffs2_1pass_build_lists()). Patch by Rick Bronson, 15 Jun 2005 diff --git a/cpu/mpc8260/speed.c b/cpu/mpc8260/speed.c index a761a178bc..99afe7609f 100644 --- a/cpu/mpc8260/speed.c +++ b/cpu/mpc8260/speed.c @@ -163,7 +163,7 @@ int prt_8260_clks (void) volatile immap_t *immap = (immap_t *) CFG_IMMR; ulong sccr, dfbrg; - ulong scmr, corecnf, busdf, cpmdf, plldf, pllmf; + ulong scmr, corecnf, busdf, cpmdf, plldf, pllmf, pcidf; corecnf_t *cp; sccr = immap->im_clkrst.car_sccr; @@ -175,6 +175,7 @@ int prt_8260_clks (void) cpmdf = (scmr & SCMR_CPMDF_MSK) >> SCMR_CPMDF_SHIFT; plldf = (scmr & SCMR_PLLDF) ? 1 : 0; pllmf = (scmr & SCMR_PLLMF_MSK) >> SCMR_PLLMF_SHIFT; + pcidf = (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT; cp = &corecnf_tab[corecnf]; @@ -204,8 +205,9 @@ int prt_8260_clks (void) cp->vco_div, cp->freq_60x, cp->freq_core); printf (" - dfbrg %ld, corecnf 0x%02lx, busdf %ld, cpmdf %ld, " - "plldf %ld, pllmf %ld\n", dfbrg, corecnf, busdf, cpmdf, plldf, - pllmf); + "plldf %ld, pllmf %ld, pcidf %ld\n", + dfbrg, corecnf, busdf, cpmdf, + plldf, pllmf, pcidf); printf (" - vco_out %10ld, scc_clk %10ld, brg_clk %10ld\n", gd->vco_out, gd->scc_clk, gd->brg_clk); @@ -215,9 +217,20 @@ int prt_8260_clks (void) if (sccr & SCCR_PCI_MODE) { uint pci_div; + uint pcidf = (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT; - pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) * - ( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1); + if (sccr & SCCR_PCI_MODCK) { + pci_div = 2; + if (pcidf == 9) { + pci_div *= 5; + } else if (pcidf == 0xB) { + pci_div *= 6; + } else { + pci_div *= (pcidf + 1); + } + } else { + pci_div = pcidf + 1; + } printf (" - pci_clk %10ld\n", (gd->cpm_clk * 2) / pci_div); } @@ -225,5 +238,3 @@ int prt_8260_clks (void) return (0); } - -/* ------------------------------------------------------------------------- */ From 953c5b6f8b7b13b8d98227761974c67d72365c5b Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 16:51:59 +0100 Subject: [PATCH 069/102] Adjust "echo" as a default command Patch by Sam Song, 19 Jun 2005 --- CHANGELOG | 3 +++ README | 2 +- common/command.c | 4 ++++ include/cmd_confdefs.h | 1 - include/configs/ISPAN.h | 1 - include/configs/MIP405.h | 1 - include/configs/PIP405.h | 1 - include/configs/RPXsuper.h | 1 - include/configs/Rattler.h | 1 - include/configs/TQM5200.h | 1 - include/configs/gw8260.h | 1 - include/configs/ppmc8260.h | 1 - include/configs/sacsng.h | 2 -- include/configs/sbc8260.h | 2 -- include/configs/utx8245.h | 1 - 15 files changed, 8 insertions(+), 15 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e532b04ed9..18f01cb371 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Adjust "echo" as a default command + Patch by Sam Song, 19 Jun 2005 + * Fix PCIDF calculation in cpu/mpc8260/speed.c for MPC8280EC Patch by KokHow Teh, 16 Jun 2005 diff --git a/README b/README index 6f61008222..962ab52aa1 100644 --- a/README +++ b/README @@ -606,7 +606,7 @@ The following options need to be configured: CFG_CMD_DIAG * Diagnostics CFG_CMD_DOC * Disk-On-Chip Support CFG_CMD_DTT * Digital Therm and Thermostat - CFG_CMD_ECHO * echo arguments + CFG_CMD_ECHO echo arguments CFG_CMD_EEPROM * EEPROM read/write support CFG_CMD_ELF * bootelf, bootvx CFG_CMD_ENV saveenv diff --git a/common/command.c b/common/command.c index 2b4c5547b3..e917975a73 100644 --- a/common/command.c +++ b/common/command.c @@ -42,6 +42,8 @@ U_BOOT_CMD( NULL ); +#if (CONFIG_COMMANDS & CFG_CMD_ECHO) + int do_echo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { @@ -74,6 +76,8 @@ U_BOOT_CMD( " - echo args to console; \\c suppresses newline\n" ); +#endif /* CFG_CMD_ECHO */ + #ifdef CFG_HUSH_PARSER int diff --git a/include/cmd_confdefs.h b/include/cmd_confdefs.h index 9ee4849611..cf36583108 100644 --- a/include/cmd_confdefs.h +++ b/include/cmd_confdefs.h @@ -112,7 +112,6 @@ CFG_CMD_DISPLAY | \ CFG_CMD_DOC | \ CFG_CMD_DTT | \ - CFG_CMD_ECHO | \ CFG_CMD_EEPROM | \ CFG_CMD_ELF | \ CFG_CMD_EXT2 | \ diff --git a/include/configs/ISPAN.h b/include/configs/ISPAN.h index 65056a21ee..706bdb94f5 100644 --- a/include/configs/ISPAN.h +++ b/include/configs/ISPAN.h @@ -109,7 +109,6 @@ #define CONFIG_COMMANDS ( CONFIG_CMD_DFL \ | CFG_CMD_ASKENV \ | CFG_CMD_DHCP \ - | CFG_CMD_ECHO \ | CFG_CMD_IMMAP \ | CFG_CMD_MII \ | CFG_CMD_PING \ diff --git a/include/configs/MIP405.h b/include/configs/MIP405.h index 1f01e7be0b..7e57a0fae1 100644 --- a/include/configs/MIP405.h +++ b/include/configs/MIP405.h @@ -58,7 +58,6 @@ CFG_CMD_CACHE | \ CFG_CMD_DATE | \ CFG_CMD_DHCP | \ - CFG_CMD_ECHO | \ CFG_CMD_EEPROM | \ CFG_CMD_ELF | \ CFG_CMD_FAT | \ diff --git a/include/configs/PIP405.h b/include/configs/PIP405.h index 091b768a99..806e95f480 100644 --- a/include/configs/PIP405.h +++ b/include/configs/PIP405.h @@ -50,7 +50,6 @@ CFG_CMD_PCI | \ CFG_CMD_CACHE | \ CFG_CMD_IRQ | \ - CFG_CMD_ECHO | \ CFG_CMD_EEPROM | \ CFG_CMD_I2C | \ CFG_CMD_REGINFO | \ diff --git a/include/configs/RPXsuper.h b/include/configs/RPXsuper.h index 6ae9403c46..45907aa0e7 100644 --- a/include/configs/RPXsuper.h +++ b/include/configs/RPXsuper.h @@ -154,7 +154,6 @@ #define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ CFG_CMD_IMMAP | \ CFG_CMD_ASKENV | \ - CFG_CMD_ECHO | \ CFG_CMD_I2C | \ CFG_CMD_REGINFO & \ ~CFG_CMD_KGDB ) diff --git a/include/configs/Rattler.h b/include/configs/Rattler.h index a170f290e0..dbc57e8b27 100644 --- a/include/configs/Rattler.h +++ b/include/configs/Rattler.h @@ -127,7 +127,6 @@ #define CONFIG_COMMANDS (CONFIG_CMD_DFL \ | CFG_CMD_DHCP \ - | CFG_CMD_ECHO \ | CFG_CMD_IMMAP \ | CFG_CMD_JFFS2 \ | CFG_CMD_MII \ diff --git a/include/configs/TQM5200.h b/include/configs/TQM5200.h index 5ad1939481..6020998ae2 100644 --- a/include/configs/TQM5200.h +++ b/include/configs/TQM5200.h @@ -161,7 +161,6 @@ CFG_CMD_ASKENV | \ CFG_CMD_DATE | \ CFG_CMD_DHCP | \ - CFG_CMD_ECHO | \ CFG_CMD_EEPROM | \ CFG_CMD_I2C | \ CFG_CMD_JFFS2 | \ diff --git a/include/configs/gw8260.h b/include/configs/gw8260.h index 6c080437ff..4f83b1945d 100644 --- a/include/configs/gw8260.h +++ b/include/configs/gw8260.h @@ -305,7 +305,6 @@ CFG_CMD_BEDBUG | \ CFG_CMD_ELF | \ CFG_CMD_ASKENV | \ - CFG_CMD_ECHO | \ CFG_CMD_REGINFO | \ CFG_CMD_IMMAP | \ CFG_CMD_MII) diff --git a/include/configs/ppmc8260.h b/include/configs/ppmc8260.h index 7579222102..d671dccc19 100644 --- a/include/configs/ppmc8260.h +++ b/include/configs/ppmc8260.h @@ -279,7 +279,6 @@ #define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ CFG_CMD_ELF | \ CFG_CMD_ASKENV | \ - CFG_CMD_ECHO | \ CFG_CMD_REGINFO | \ CFG_CMD_MEMTEST | \ CFG_CMD_MII | \ diff --git a/include/configs/sacsng.h b/include/configs/sacsng.h index 4e0cfdb4c3..97b52fa1ae 100644 --- a/include/configs/sacsng.h +++ b/include/configs/sacsng.h @@ -507,7 +507,6 @@ # define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ CFG_CMD_ELF | \ CFG_CMD_ASKENV | \ - CFG_CMD_ECHO | \ CFG_CMD_I2C | \ CFG_CMD_SPI | \ CFG_CMD_SDRAM | \ @@ -520,7 +519,6 @@ # define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ CFG_CMD_ELF | \ CFG_CMD_ASKENV | \ - CFG_CMD_ECHO | \ CFG_CMD_I2C | \ CFG_CMD_SPI | \ CFG_CMD_SDRAM | \ diff --git a/include/configs/sbc8260.h b/include/configs/sbc8260.h index 180ce057d7..9cf0654be1 100644 --- a/include/configs/sbc8260.h +++ b/include/configs/sbc8260.h @@ -448,7 +448,6 @@ #ifdef CONFIG_ETHER_ON_FCC # define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ CFG_CMD_ASKENV | \ - CFG_CMD_ECHO | \ CFG_CMD_ELF | \ CFG_CMD_I2C | \ CFG_CMD_IMMAP | \ @@ -459,7 +458,6 @@ #else # define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ CFG_CMD_ASKENV | \ - CFG_CMD_ECHO | \ CFG_CMD_ELF | \ CFG_CMD_I2C | \ CFG_CMD_IMMAP | \ diff --git a/include/configs/utx8245.h b/include/configs/utx8245.h index d312b6559a..e5d4397d2c 100644 --- a/include/configs/utx8245.h +++ b/include/configs/utx8245.h @@ -91,7 +91,6 @@ protect on ${u-boot_startaddr} ${u-boot_endaddr}" | CFG_CMD_ENV | CFG_CMD_CONSOLE \ | CFG_CMD_LOADS | CFG_CMD_LOADB \ | CFG_CMD_IMI | CFG_CMD_CACHE \ - | CFG_CMD_RUN | CFG_CMD_ECHO \ | CFG_CMD_REGINFO | CFG_CMD_NET\ | CFG_CMD_DHCP | CFG_CMD_I2C \ | CFG_CMD_DATE) From 993a22756e3545bf11fbe267feadbfdd5b67ffa4 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 16:54:11 +0100 Subject: [PATCH 070/102] Fix bad declaration on pci_cfgfunc_nothing Patch by Sam Song, 19 Jun 2005 --- CHANGELOG | 3 +++ include/pci.h | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 18f01cb371..0b6da7bbd4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix bad declaration on pci_cfgfunc_nothing + Patch by Sam Song, 19 Jun 2005 + * Adjust "echo" as a default command Patch by Sam Song, 19 Jun 2005 diff --git a/include/pci.h b/include/pci.h index 8f19997559..4bb2df27ed 100644 --- a/include/pci.h +++ b/include/pci.h @@ -351,8 +351,8 @@ struct pci_config_table { unsigned long priv[3]; }; -extern void pci_cfgfunc_nothing(struct pci_controller* hose, pci_dev_t dev, - struct pci_config_table *); +extern void pci_cfgfunc_do_nothing(struct pci_controller* hose, pci_dev_t dev, + struct pci_config_table *); extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *); From 0a3471fc780c1a38496c3b99c443ffe3edca4b56 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 16:57:35 +0100 Subject: [PATCH 071/102] Add netconsole and some more commands to RPXlite_DW board Patch by Sam Song, 19 Jun 2005 --- CHANGELOG | 3 +++ include/configs/RPXlite_DW.h | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 0b6da7bbd4..704bb0548e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add netconsole and some more commands to RPXlite_DW board + Patch by Sam Song, 19 Jun 2005 + * Fix bad declaration on pci_cfgfunc_nothing Patch by Sam Song, 19 Jun 2005 diff --git a/include/configs/RPXlite_DW.h b/include/configs/RPXlite_DW.h index 8cd7df1ecf..5d17712f18 100644 --- a/include/configs/RPXlite_DW.h +++ b/include/configs/RPXlite_DW.h @@ -45,7 +45,7 @@ */ /* #define DEBUG 1 */ -/* #ifdef DEPLOYMENT 1 */ +/* #define DEPLOYMENT 1 */ #undef CONFIG_MPC860 #define CONFIG_MPC823 1 /* This is a MPC823e CPU. */ @@ -117,6 +117,36 @@ #define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE) +#if 1 /* Enable this staff could make image enlarge about 25KB. Mask it if you + don't want the advanced function */ + +#ifdef CONFIG_SPLASH_SCREEN +#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ + CFG_CMD_ASKENV | \ + CFG_CMD_BMP | \ + CFG_CMD_JFFS2 | \ + CFG_CMD_PING | \ + CFG_CMD_ELF | \ + CFG_CMD_REGINFO | \ + CFG_CMD_DHCP ) +#else +#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ + CFG_CMD_ASKENV | \ + CFG_CMD_JFFS2 | \ + CFG_CMD_PING | \ + CFG_CMD_ELF | \ + CFG_CMD_REGINFO | \ + CFG_CMD_DHCP ) +#endif /* CONFIG_SPLASH_SCREEN */ + +/* test-only */ +#define CFG_JFFS2_FIRST_BANK 0 /* use for JFFS2 */ +#define CFG_JFFS2_NUM_BANKS 1 /* ! second bank contains U-Boot */ + +#define CONFIG_NETCONSOLE + +#endif /* 1 */ + /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include @@ -446,5 +476,6 @@ #define CONFIG_SERVERIP 172.16.115.6 #define CONFIG_ROOTPATH /workspace/myfilesystem/target/ #define CONFIG_BOOTFILE uImage.rpxusb +#define CONFIG_HOSTNAME LITE_H1_DW #endif /* __CONFIG_H */ From d8169c9f3ba04f5e470008c59afa3161ce683524 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 18:06:37 +0100 Subject: [PATCH 072/102] Fix bad register definitions for LTX971 PHY on MPC85xx boards. Patch by Gerhard Jaeger, 21 Jun 2005 --- CHANGELOG | 3 +++ drivers/tsec.h | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 704bb0548e..272463280b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix bad register definitions for LTX971 PHY on MPC85xx boards. + Patch by Gerhard Jaeger, 21 Jun 2005 + * Add netconsole and some more commands to RPXlite_DW board Patch by Sam Song, 19 Jun 2005 diff --git a/drivers/tsec.h b/drivers/tsec.h index c26fcc0e73..e3bbff03bf 100644 --- a/drivers/tsec.h +++ b/drivers/tsec.h @@ -161,12 +161,12 @@ #define MIIM_DM9161_10BTCSR_INIT 0x7800 /* LXT971 Status 2 registers */ -#define MIIM_LXT971_SR2 17 /* Status Register 2 */ -#define MIIM_LXT971_SR2_SPEED_MASK 0xf000 -#define MIIM_LXT971_SR2_10HDX 0x1000 /* 10 Mbit half duplex selected */ -#define MIIM_LXT971_SR2_10FDX 0x2000 /* 10 Mbit full duplex selected */ -#define MIIM_LXT971_SR2_100HDX 0x4000 /* 100 Mbit half duplex selected */ -#define MIIM_LXT971_SR2_100FDX 0x8000 /* 100 Mbit full duplex selected */ +#define MIIM_LXT971_SR2 0x11 /* Status Register 2 */ +#define MIIM_LXT971_SR2_SPEED_MASK 0x4200 +#define MIIM_LXT971_SR2_10HDX 0x0000 /* 10 Mbit half duplex selected */ +#define MIIM_LXT971_SR2_10FDX 0x0200 /* 10 Mbit full duplex selected */ +#define MIIM_LXT971_SR2_100HDX 0x4000 /* 100 Mbit half duplex selected */ +#define MIIM_LXT971_SR2_100FDX 0x4200 /* 100 Mbit full duplex selected */ #define MIIM_READ_COMMAND 0x00000001 From 034698329067f74b66a457aaf8924f7b054996eb Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 18:09:47 +0100 Subject: [PATCH 073/102] Fix a HW timing issue on 8548 CDS for eTSEC 3 in RGMII mode Patch by Andy Fleming, 14 Jun 2005 --- CHANGELOG | 3 +++ drivers/tsec.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 272463280b..bdd6fc62f7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix a HW timing issue on 8548 CDS for eTSEC 3 in RGMII mode + Patch by Andy Fleming, 14 Jun 2005 + * Fix bad register definitions for LTX971 PHY on MPC85xx boards. Patch by Gerhard Jaeger, 21 Jun 2005 diff --git a/drivers/tsec.h b/drivers/tsec.h index e3bbff03bf..e92b53ad6b 100644 --- a/drivers/tsec.h +++ b/drivers/tsec.h @@ -124,7 +124,7 @@ /* Cicada 8204 Extended PHY Control Register 1 */ #define MIIM_CIS8204_EPHY_CON 0x17 #define MIIM_CIS8204_EPHYCON_INIT 0x0006 -#define MIIM_CIS8204_EPHYCON_RGMII 0x1000 +#define MIIM_CIS8204_EPHYCON_RGMII 0x1100 /* Cicada 8204 Serial LED Control Register */ #define MIIM_CIS8204_SLED_CON 0x1b From 3b2e4fd9b0348d49e7b55a19a0c919f6c83d9a43 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 18:26:46 +0100 Subject: [PATCH 074/102] Add support for the DHCP vendor optional bootfile (#67). Ignores the vendor TFTP server name option (#66). Patch by Murray Jensen, 30 Jun 2005 --- CHANGELOG | 4 ++++ net/bootp.c | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index bdd6fc62f7..82538e9be2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,10 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add support for the DHCP vendor optional bootfile (#67). + Ignores the vendor TFTP server name option (#66). + Patch by Murray Jensen, 30 Jun 2005 + * Fix a HW timing issue on 8548 CDS for eTSEC 3 in RGMII mode Patch by Andy Fleming, 14 Jun 2005 diff --git a/net/bootp.c b/net/bootp.c index 8c56c0845f..669d74a6a5 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -715,7 +715,7 @@ BootpRequest (void) } #if (CONFIG_COMMANDS & CFG_CMD_DHCP) -static void DhcpOptionsProcess (uchar * popt) +static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp) { uchar *end = popt + BOOTP_HDR_SIZE; int oplen, size; @@ -772,6 +772,34 @@ static void DhcpOptionsProcess (uchar * popt) break; case 59: /* Ignore Rebinding Time Option */ break; + case 66: /* Ignore TFTP server name */ + break; + case 67: /* vendor opt bootfile */ + /* + * I can't use dhcp_vendorex_proc here because I need + * to write into the bootp packet - even then I had to + * pass the bootp packet pointer into here as the + * second arg + */ + size = truncate_sz ("Opt Boot File", + sizeof(bp->bp_file), + oplen); + if (bp->bp_file[0] == '\0' && size > 0) { + /* + * only use vendor boot file if we didn't + * receive a boot file in the main non-vendor + * part of the packet - god only knows why + * some vendors chose not to use this perfectly + * good spot to store the boot file (join on + * Tru64 Unix) it seems mind bogglingly crazy + * to me + */ + printf("*** WARNING: using vendor " + "optional boot file\n"); + memcpy(bp->bp_file, popt + 2, size); + bp->bp_file[size] = '\0'; + } + break; default: #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) if (dhcp_vendorex_proc (popt)) @@ -882,7 +910,7 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) dhcp_state = REQUESTING; if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) - DhcpOptionsProcess((u8 *)&bp->bp_vend[4]); + DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp); BootpCopyNetParams(bp); /* Store net params from reply */ @@ -901,7 +929,7 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) char *s; if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) - DhcpOptionsProcess((u8 *)&bp->bp_vend[4]); + DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp); BootpCopyNetParams(bp); /* Store net params from reply */ dhcp_state = BOUND; puts ("DHCP client bound to address "); From 7c60908ffbb59cc461cedc1d1a06153586b5c3ed Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 22:14:20 +0100 Subject: [PATCH 075/102] Fix compile problem --- CHANGELOG | 2 ++ drivers/ks8695eth.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 7906abecd8..f29b08fa02 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix compile problem + * Added PCI support for MPC8349ADS board Patch by Kumar Gala 11 Jan 2006 diff --git a/drivers/ks8695eth.c b/drivers/ks8695eth.c index a0f5be81dd..b598dd7f23 100644 --- a/drivers/ks8695eth.c +++ b/drivers/ks8695eth.c @@ -21,12 +21,13 @@ /****************************************************************************/ #include + +#ifdef CONFIG_DRIVER_KS8695ETH #include #include #include #include -#ifdef CONFIG_DRIVER_KS8695ETH /****************************************************************************/ /* From 8123eee8756dd500267ddfe948090d69886d0fb7 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 22:41:33 +0100 Subject: [PATCH 076/102] Add CPM2 I/O pin functions for MPC85xx processors Patch by Murray Jensen, 08 Jul 2005 --- CHANGELOG | 3 + include/asm-ppc/iopin_85xx.h | 146 +++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 include/asm-ppc/iopin_85xx.h diff --git a/CHANGELOG b/CHANGELOG index f29b08fa02..48d30f69d6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add CPM2 I/O pin functions for MPC85xx processors + Patch by Murray Jensen, 08 Jul 2005 + * Fix compile problem * Added PCI support for MPC8349ADS board diff --git a/include/asm-ppc/iopin_85xx.h b/include/asm-ppc/iopin_85xx.h new file mode 100644 index 0000000000..f854df633a --- /dev/null +++ b/include/asm-ppc/iopin_85xx.h @@ -0,0 +1,146 @@ +/* + * MPC85xx I/O port pin manipulation functions + */ + +#ifndef _ASM_IOPIN_85xx_H_ +#define _ASM_IOPIN_85xx_H_ + +#include +#include + +#ifdef __KERNEL__ + +typedef struct { + u_char port:2; /* port number (A=0, B=1, C=2, D=3) */ + u_char pin:5; /* port pin (0-31) */ + u_char flag:1; /* for whatever */ +} iopin_t; + +#define IOPIN_PORTA 0 +#define IOPIN_PORTB 1 +#define IOPIN_PORTC 2 +#define IOPIN_PORTD 3 + +extern __inline__ void iopin_set_high (iopin_t * iopin) +{ + volatile uint *datp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.pdata; + datp[iopin->port * 8] |= (1 << (31 - iopin->pin)); +} + +extern __inline__ void iopin_set_low (iopin_t * iopin) +{ + volatile uint *datp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.pdata; + datp[iopin->port * 8] &= ~(1 << (31 - iopin->pin)); +} + +extern __inline__ uint iopin_is_high (iopin_t * iopin) +{ + volatile uint *datp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.pdata; + return (datp[iopin->port * 8] >> (31 - iopin->pin)) & 1; +} + +extern __inline__ uint iopin_is_low (iopin_t * iopin) +{ + volatile uint *datp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.pdata; + return ((datp[iopin->port * 8] >> (31 - iopin->pin)) & 1) ^ 1; +} + +extern __inline__ void iopin_set_out (iopin_t * iopin) +{ + volatile uint *dirp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.pdira; + dirp[iopin->port * 8] |= (1 << (31 - iopin->pin)); +} + +extern __inline__ void iopin_set_in (iopin_t * iopin) +{ + volatile uint *dirp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.pdira; + dirp[iopin->port * 8] &= ~(1 << (31 - iopin->pin)); +} + +extern __inline__ uint iopin_is_out (iopin_t * iopin) +{ + volatile uint *dirp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.pdira; + return (dirp[iopin->port * 8] >> (31 - iopin->pin)) & 1; +} + +extern __inline__ uint iopin_is_in (iopin_t * iopin) +{ + volatile uint *dirp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.pdira; + return ((dirp[iopin->port * 8] >> (31 - iopin->pin)) & 1) ^ 1; +} + +extern __inline__ void iopin_set_odr (iopin_t * iopin) +{ + volatile uint *odrp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.podra; + odrp[iopin->port * 8] |= (1 << (31 - iopin->pin)); +} + +extern __inline__ void iopin_set_act (iopin_t * iopin) +{ + volatile uint *odrp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.podra; + odrp[iopin->port * 8] &= ~(1 << (31 - iopin->pin)); +} + +extern __inline__ uint iopin_is_odr (iopin_t * iopin) +{ + volatile uint *odrp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.podra; + return (odrp[iopin->port * 8] >> (31 - iopin->pin)) & 1; +} + +extern __inline__ uint iopin_is_act (iopin_t * iopin) +{ + volatile uint *odrp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.podra; + return ((odrp[iopin->port * 8] >> (31 - iopin->pin)) & 1) ^ 1; +} + +extern __inline__ void iopin_set_ded (iopin_t * iopin) +{ + volatile uint *parp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.ppara; + parp[iopin->port * 8] |= (1 << (31 - iopin->pin)); +} + +extern __inline__ void iopin_set_gen (iopin_t * iopin) +{ + volatile uint *parp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.ppara; + parp[iopin->port * 8] &= ~(1 << (31 - iopin->pin)); +} + +extern __inline__ uint iopin_is_ded (iopin_t * iopin) +{ + volatile uint *parp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.ppara; + return (parp[iopin->port * 8] >> (31 - iopin->pin)) & 1; +} + +extern __inline__ uint iopin_is_gen (iopin_t * iopin) +{ + volatile uint *parp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.ppara; + return ((parp[iopin->port * 8] >> (31 - iopin->pin)) & 1) ^ 1; +} + +extern __inline__ void iopin_set_opt2 (iopin_t * iopin) +{ + volatile uint *sorp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.psora; + sorp[iopin->port * 8] |= (1 << (31 - iopin->pin)); +} + +extern __inline__ void iopin_set_opt1 (iopin_t * iopin) +{ + volatile uint *sorp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.psora; + sorp[iopin->port * 8] &= ~(1 << (31 - iopin->pin)); +} + +extern __inline__ uint iopin_is_opt2 (iopin_t * iopin) +{ + volatile uint *sorp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.psora; + return (sorp[iopin->port * 8] >> (31 - iopin->pin)) & 1; +} + +extern __inline__ uint iopin_is_opt1 (iopin_t * iopin) +{ + volatile uint *sorp = &((immap_t *) CFG_IMMR)->im_cpm.im_cpm_iop.psora; + return ((sorp[iopin->port * 8] >> (31 - iopin->pin)) & 1) ^ 1; +} + +#endif /* __KERNEL__ */ + +#endif /* _ASM_IOPIN_85xx_H_ */ From ca27381df15c99c7b542f847359a8a4543f24d2a Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 22:45:47 +0100 Subject: [PATCH 077/102] Add (some) definitions for the MPC85xx local bus controller Patch by Murray Jensen, 08 Jul 2005 --- CHANGELOG | 3 +++ include/mpc85xx.h | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 48d30f69d6..27ce62c891 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add (some) definitions for the MPC85xx local bus controller + Patch by Murray Jensen, 08 Jul 2005 + * Add CPM2 I/O pin functions for MPC85xx processors Patch by Murray Jensen, 08 Jul 2005 diff --git a/include/mpc85xx.h b/include/mpc85xx.h index 60b6c61fb0..a4d99b2a16 100644 --- a/include/mpc85xx.h +++ b/include/mpc85xx.h @@ -25,4 +25,39 @@ #define SCCR_DFBRG10 0x00000002 /* BRGCLK division by 64 */ #define SCCR_DFBRG11 0x00000003 /* BRGCLK division by 256 */ +/* + * Local Bus Controller - memory controller registers + */ +#define BRx_V 0x00000001 /* Bank Valid */ +#define BRx_MS_GPCM 0x00000000 /* G.P.C.M. Machine Select */ +#define BRx_MS_SDRAM 0x00000000 /* SDRAM Machine Select */ +#define BRx_MS_UPMA 0x00000080 /* U.P.M.A Machine Select */ +#define BRx_MS_UPMB 0x000000a0 /* U.P.M.B Machine Select */ +#define BRx_MS_UPMC 0x000000c0 /* U.P.M.C Machine Select */ +#define BRx_PS_8 0x00000800 /* 8 bit port size */ +#define BRx_PS_32 0x00001800 /* 32 bit port size */ +#define BRx_BA_MSK 0xffff8000 /* Base Address Mask */ + +#define ORxG_EAD 0x00000001 /* External addr latch delay */ +#define ORxG_EHTR 0x00000002 /* Extended hold time on read */ +#define ORxG_TRLX 0x00000004 /* Timing relaxed */ +#define ORxG_SETA 0x00000008 /* External address termination */ +#define ORxG_SCY_10_CLK 0x000000a0 /* 10 clock cycles wait states */ +#define ORxG_SCY_15_CLK 0x000000f0 /* 15 clock cycles wait states */ +#define ORxG_XACS 0x00000100 /* Extra addr to CS setup */ +#define ORxG_ACS_DIV2 0x00000600 /* CS is output 1/2 a clock later*/ +#define ORxG_CSNT 0x00000800 /* Chip Select Negation Time */ + +#define ORxU_BI 0x00000100 /* Burst Inhibit */ +#define ORxU_AM_MSK 0xffff8000 /* Address Mask Mask */ + +#define MxMR_OP_NORM 0x00000000 /* Normal Operation */ +#define MxMR_DSx_2_CYCL 0x00400000 /* 2 cycle Disable Period */ +#define MxMR_OP_WARR 0x10000000 /* Write to Array */ +#define MxMR_BSEL 0x80000000 /* Bus Select */ + +/* helpers to convert values into an OR address mask (GPCM mode) */ +#define P2SZ_TO_AM(s) ((~((s) - 1)) & 0xffff8000) /* must be pow of 2 */ +#define MEG_TO_AM(m) P2SZ_TO_AM((m) << 20) + #endif /* __MPC85xx_H__ */ From be5048f16653787106945122ba043b3a8b42f30c Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 22:50:55 +0100 Subject: [PATCH 078/102] Add Nat Semi DP83865 PHY support to MPC85xx TSEC driver Patch by Murray Jensen, 08 Jul 2005 --- CHANGELOG | 3 +++ drivers/tsec.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/tsec.h | 10 ++++++++++ 3 files changed, 64 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 27ce62c891..d6363d6fb6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add Nat Semi DP83865 PHY support to MPC85xx TSEC driver + Patch by Murray Jensen, 08 Jul 2005 + * Add (some) definitions for the MPC85xx local bus controller Patch by Murray Jensen, 08 Jul 2005 diff --git a/drivers/tsec.c b/drivers/tsec.c index f860dae8b0..4c5e1b5d3a 100644 --- a/drivers/tsec.c +++ b/drivers/tsec.c @@ -940,6 +940,56 @@ static struct phy_info phy_info_lxt971 = { }, }; +/* Parse the DP83865's link and auto-neg status register for speed and duplex + * information */ +uint mii_parse_dp83865_lanr(uint mii_reg, struct tsec_private *priv) +{ + switch (mii_reg & MIIM_DP83865_SPD_MASK) { + + case MIIM_DP83865_SPD_1000: + priv->speed = 1000; + break; + + case MIIM_DP83865_SPD_100: + priv->speed = 100; + break; + + default: + priv->speed = 10; + break; + + } + + if (mii_reg & MIIM_DP83865_DPX_FULL) + priv->duplexity = 1; + else + priv->duplexity = 0; + + return 0; +} + +struct phy_info phy_info_dp83865 = { + 0x20005c7, + "NatSemi DP83865", + 4, + (struct phy_cmd[]) { /* config */ + {MIIM_CONTROL, MIIM_DP83865_CR_INIT, NULL}, + {miim_end,} + }, + (struct phy_cmd[]) { /* startup */ + /* Status is read once to clear old link state */ + {MIIM_STATUS, miim_read, NULL}, + /* Auto-negotiate */ + {MIIM_STATUS, miim_read, &mii_parse_sr}, + /* Read the link and auto-neg status */ + {MIIM_DP83865_LANR, miim_read, &mii_parse_dp83865_lanr}, + {miim_end,} + }, + (struct phy_cmd[]) { /* shutdown */ + {miim_end,} + }, +}; + struct phy_info *phy_info[] = { #if 0 &phy_info_cis8201, @@ -949,6 +999,7 @@ struct phy_info *phy_info[] = { &phy_info_M88E1111S, &phy_info_dm9161, &phy_info_lxt971, + &phy_info_dp83865, NULL }; diff --git a/drivers/tsec.h b/drivers/tsec.h index e92b53ad6b..b55b2992b2 100644 --- a/drivers/tsec.h +++ b/drivers/tsec.h @@ -168,6 +168,16 @@ #define MIIM_LXT971_SR2_100HDX 0x4000 /* 100 Mbit half duplex selected */ #define MIIM_LXT971_SR2_100FDX 0x4200 /* 100 Mbit full duplex selected */ +/* DP83865 Control register values */ +#define MIIM_DP83865_CR_INIT 0x9200 + +/* DP83865 Link and Auto-Neg Status Register */ +#define MIIM_DP83865_LANR 0x11 +#define MIIM_DP83865_SPD_MASK 0x0018 +#define MIIM_DP83865_SPD_1000 0x0010 +#define MIIM_DP83865_SPD_100 0x0008 +#define MIIM_DP83865_DPX_FULL 0x0002 + #define MIIM_READ_COMMAND 0x00000001 #define MRBLR_INIT_SETTINGS PKTSIZE_ALIGN From 763b5f34c36ba461428a72702f5aa21cb1d92e0e Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 23:13:27 +0100 Subject: [PATCH 079/102] Remove board specific configuration includes from the common xilinx ethernet and iic adapter code. Patch by Michael Libeskind, 12 Jul 2005 --- CHANGELOG | 4 ++++ board/xilinx/xilinx_enet/emac_adapter.c | 1 - board/xilinx/xilinx_iic/iic_adapter.c | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d6363d6fb6..f24c4d9483 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,10 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Remove board specific configuration includes from the common xilinx + ethernet and iic adapter code. + Patch by Michael Libeskind, 12 Jul 2005 + * Add Nat Semi DP83865 PHY support to MPC85xx TSEC driver Patch by Murray Jensen, 08 Jul 2005 diff --git a/board/xilinx/xilinx_enet/emac_adapter.c b/board/xilinx/xilinx_enet/emac_adapter.c index 5c492ebbc0..b30e897669 100644 --- a/board/xilinx/xilinx_enet/emac_adapter.c +++ b/board/xilinx/xilinx_enet/emac_adapter.c @@ -39,7 +39,6 @@ #include #include -#include #include "xparameters.h" #include "xemac.h" diff --git a/board/xilinx/xilinx_iic/iic_adapter.c b/board/xilinx/xilinx_iic/iic_adapter.c index f3ecba72dc..163fe1511d 100644 --- a/board/xilinx/xilinx_iic/iic_adapter.c +++ b/board/xilinx/xilinx_iic/iic_adapter.c @@ -40,7 +40,6 @@ #include #include #include -#include #include "xparameters.h" #ifdef CFG_ENV_IS_IN_EEPROM From 84c960ce6dbea55565a7891ff4fe87e08803e9cf Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 23:17:31 +0100 Subject: [PATCH 080/102] Add support for EmbeddedPlanet EP88x boards Patch by Yuli Barcohen, 13 Jul 2005 --- CHANGELOG | 3 + MAKEALL | 20 ++-- Makefile | 3 + board/ep88x/Makefile | 46 +++++++++ board/ep88x/config.mk | 27 ++++++ board/ep88x/ep88x.c | 133 ++++++++++++++++++++++++++ board/ep88x/u-boot.lds | 122 ++++++++++++++++++++++++ include/configs/EP88x.h | 205 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 549 insertions(+), 10 deletions(-) create mode 100644 board/ep88x/Makefile create mode 100644 board/ep88x/config.mk create mode 100644 board/ep88x/ep88x.c create mode 100644 board/ep88x/u-boot.lds create mode 100644 include/configs/EP88x.h diff --git a/CHANGELOG b/CHANGELOG index f24c4d9483..790b391d55 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add support for EmbeddedPlanet EP88x boards + Patch by Yuli Barcohen, 13 Jul 2005 + * Remove board specific configuration includes from the common xilinx ethernet and iic adapter code. Patch by Michael Libeskind, 12 Jul 2005 diff --git a/MAKEALL b/MAKEALL index 582357c71f..68fa954d64 100755 --- a/MAKEALL +++ b/MAKEALL @@ -43,16 +43,16 @@ LIST_8xx=" \ CCM IP860 NETPHONE RPXlite_DW \ cogent_mpc8xx IVML24 NETTA RRvision \ ELPT860 IVML24_128 NETTA2 SM850 \ - ESTEEM192E IVML24_256 NETTA_ISDN SPD823TS \ - ETX094 IVMS8 NETVIA svm_sc8xx \ - FADS823 IVMS8_128 NETVIA_V2 SXNI855T \ - FADS850SAR IVMS8_256 NX823 TOP860 \ - FADS860T KUP4K pcu_e TQM823L \ - FLAGADM KUP4X QS823 TQM823L_LCD \ - FPS850L LANTEC QS850 TQM850L \ - GEN860T lwmon QS860T TQM855L \ - GEN860T_SC MBX quantum TQM860L \ - uc100 \ + EP88x IVML24_256 NETTA_ISDN SPD823TS \ + ESTEEM192E IVMS8 NETVIA svm_sc8xx \ + ETX094 IVMS8_128 NETVIA_V2 SXNI855T \ + FADS823 IVMS8_256 NX823 TOP860 \ + FADS850SAR KUP4K pcu_e TQM823L \ + FADS860T KUP4X QS823 TQM823L_LCD \ + FLAGADM LANTEC QS850 TQM850L \ + FPS850L lwmon QS860T TQM855L \ + GEN860T MBX quantum TQM860L \ + GEN860T_SC uc100 \ v37 \ " diff --git a/Makefile b/Makefile index 65c457e00e..3076d6fe86 100644 --- a/Makefile +++ b/Makefile @@ -441,6 +441,9 @@ cogent_mpc8xx_config: unconfig ELPT860_config: unconfig @./mkconfig $(@:_config=) ppc mpc8xx elpt860 LEOX +EP88x_config: unconfig + @./mkconfig $(@:_config=) ppc mpc8xx ep88x + ESTEEM192E_config: unconfig @./mkconfig $(@:_config=) ppc mpc8xx esteem192e diff --git a/board/ep88x/Makefile b/board/ep88x/Makefile new file mode 100644 index 0000000000..9123a8026d --- /dev/null +++ b/board/ep88x/Makefile @@ -0,0 +1,46 @@ +# +# Copyright (C) 2004 Arabella Software Ltd. +# Yuli Barcohen +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := $(BOARD).o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/ep88x/config.mk b/board/ep88x/config.mk new file mode 100644 index 0000000000..72b326c32e --- /dev/null +++ b/board/ep88x/config.mk @@ -0,0 +1,27 @@ +# +# Copyright (C) 2005 Arabella Software Ltd. +# Yuli Barcohen +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# Embedded Planet EP88x boards +# +TEXT_BASE = 0xFC000000 diff --git a/board/ep88x/ep88x.c b/board/ep88x/ep88x.c new file mode 100644 index 0000000000..5f57f36bbf --- /dev/null +++ b/board/ep88x/ep88x.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2005 Arabella Software Ltd. + * Yuli Barcohen + * + * Support for Embedded Planet EP88x boards. + * Tested on EP88xC with MPC885 CPU, 64MB SDRAM and 16MB flash. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* + * SDRAM uses two Micron chips. + * Minimal CPU frequency is 40MHz. + */ +static uint sdram_table[] = { + /* Single read (offset 0x00 in UPM RAM) */ + 0xEFCBCC04, 0x0F37C804, 0x0EEEC004, 0x01B98404, + 0x1FF74C00, 0xFFFFCC05, 0xFFFFCC05, 0xFFFFCC05, + + /* Burst read (offset 0x08 in UPM RAM) */ + 0xEFCBCC04, 0x0F37C804, 0x0EEEC004, 0x00BDC404, + 0x00FFCC00, 0x00FFCC00, 0x01FB8C00, 0x1FF74C00, + 0xFFFFCC05, 0xFFFFCC05, 0xFFFFCC05, 0xFFFFCC05, + 0xFFFFCC05, 0xFFFFCC05, 0xFFFFCC05, 0xFFFFCC05, + + /* Single write (offset 0x18 in UPM RAM) */ + 0xEFCBCC04, 0x0F37C804, 0x0EEE8002, 0x01B90404, + 0x1FF74C05, 0xFFFFCC05, 0xFFFFCC05, 0xFFFFCC05, + + /* Burst write (offset 0x20 in UPM RAM) */ + 0xEFCBCC04, 0x0F37C804, 0x0EEE8000, 0x00BD4400, + 0x00FFCC00, 0x00FFCC02, 0x01FB8C04, 0x1FF74C05, + 0xFFFFCC05, 0xFFFFCC05, 0xFFFFCC05, 0xFFFFCC05, + 0xFFFFCC05, 0xFFFFCC05, 0xFFFFCC05, 0xFFFFCC05, + + /* Refresh (offset 0x30 in UPM RAM) */ + 0xEFFACC04, 0x0FF5CC04, 0x0FFFCC04, 0x1FFFCC04, + 0xFFFFCC05, 0xFFFFCC05, 0xEFFB8C34, 0x0FF74C34, + 0x0FFACCB4, 0x0FF5CC34, 0x0FFFC034, 0x0FFFC0B4, + + /* Exception (offset 0x3C in UPM RAM) */ + 0x0FEA8034, 0x1FB54034, 0xFFFFCC34, 0xFFFFCC05 +}; + +int board_early_init_f (void) +{ + vu_char *bcsr = (vu_char *)CFG_BCSR; + + bcsr[0] |= 0x0C; /* Turn the LEDs off */ + bcsr[2] |= 0x08; /* Enable flash WE# line - necessary for + flash detection by CFI driver + */ + +#if defined(CONFIG_8xx_CONS_SMC1) + bcsr[6] |= 0x10; /* Enables RS-232 transceiver */ +#endif +#if defined(CONFIG_8xx_CONS_SCC2) + bcsr[7] |= 0x10; /* Enables RS-232 transceiver */ +#endif +#ifdef CONFIG_ETHER_ON_FEC1 + bcsr[8] |= 0xC0; /* Enable Ethernet 1 PHY */ +#endif +#ifdef CONFIG_ETHER_ON_FEC2 + bcsr[8] |= 0x30; /* Enable Ethernet 2 PHY */ +#endif + + return 0; +} + +long int initdram (int board_type) +{ + long int msize; + volatile immap_t *immap = (volatile immap_t *)CFG_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + + upmconfig(UPMA, sdram_table, sizeof(sdram_table) / sizeof(uint)); + + /* Configure SDRAM refresh */ + memctl->memc_mptpr = MPTPR_PTP_DIV2; /* BRGCLK/2 */ + + memctl->memc_mamr = (65 << 24) | CFG_MAMR; /* No refresh */ + udelay(100); + + /* Run MRS pattern from location 0x36 */ + memctl->memc_mar = 0x88; + memctl->memc_mcr = 0x80002236; + udelay(100); + + memctl->memc_mamr |= MAMR_PTAE; /* Enable refresh */ + memctl->memc_or1 = ~(CFG_SDRAM_MAX_SIZE - 1) | OR_CSNT_SAM; + memctl->memc_br1 = CFG_SDRAM_BASE | BR_PS_32 | BR_MS_UPMA | BR_V; + + msize = get_ram_size(CFG_SDRAM_BASE, CFG_SDRAM_MAX_SIZE); + memctl->memc_or1 |= ~(msize - 1); + + return msize; +} + +int checkboard( void ) +{ + vu_char *bcsr = (vu_char *)CFG_BCSR; + + puts("Board: "); + switch (bcsr[15]) { + case 0xE7: + puts("EP88xC 1.0"); + break; + default: + printf("unknown ID=%02X", bcsr[15]); + } + printf(" CPLD revision %d\n", bcsr[14]); + + return 0; +} diff --git a/board/ep88x/u-boot.lds b/board/ep88x/u-boot.lds new file mode 100644 index 0000000000..1d2a7d764b --- /dev/null +++ b/board/ep88x/u-boot.lds @@ -0,0 +1,122 @@ +/* + * (C) Copyright 2001-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Modified by Yuli Barcohen + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + cpu/mpc8xx/start.o (.text) + *(.text) + *(.fixup) + *(.got1) + . = ALIGN(16); + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} +ENTRY(_start) diff --git a/include/configs/EP88x.h b/include/configs/EP88x.h new file mode 100644 index 0000000000..738763b86f --- /dev/null +++ b/include/configs/EP88x.h @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2005 Arabella Software Ltd. + * Yuli Barcohen + * + * Support for Embedded Planet EP88x boards. + * Tested on EP88xC with MPC885 CPU, 64MB SDRAM and 16MB flash. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CONFIG_MPC885 + +#define CONFIG_EP88X /* Embedded Planet EP88x board */ + +#define CONFIG_BOARD_EARLY_INIT_F /* Call board_early_init_f */ + +/* Allow serial number (serial#) and MAC address (ethaddr) to be overwritten */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */ +#define CONFIG_BAUDRATE 38400 + +#define CONFIG_ETHER_ON_FEC1 /* Enable Ethernet on FEC1 */ +#define CONFIG_ETHER_ON_FEC2 /* Enable Ethernet on FEC2 */ +#if defined(CONFIG_ETHER_ON_FEC1) || defined(CONFIG_ETHER_ON_FEC2) +#define CFG_DISCOVER_PHY +#define FEC_ENET +#endif /* CONFIG_FEC_ENET */ + +#define CONFIG_8xx_OSCLK 10000000 /* 10 MHz oscillator on EXTCLK */ +#define CONFIG_8xx_CPUCLK_DEFAULT 100000000 +#define CFG_8xx_CPUCLK_MIN 40000000 +#define CFG_8xx_CPUCLK_MAX 133000000 + +#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ + | CFG_CMD_DHCP \ + | CFG_CMD_IMMAP \ + | CFG_CMD_MII \ + | CFG_CMD_PING \ + ) + +/* This must be included AFTER the definition of CONFIG_COMMANDS */ +#include + +#define CONFIG_BOOTDELAY 5 /* Autoboot after 5 seconds */ +#define CONFIG_BOOTCOMMAND "bootm fe060000" /* Autoboot command */ +#define CONFIG_BOOTARGS "root=/dev/mtdblock1 rw mtdparts=phys:2M(ROM)ro,-(root)" + +#define CONFIG_BZIP2 /* Include support for bzip2 compressed images */ +#undef CONFIG_WATCHDOG /* Disable platform specific watchdog */ + +/*----------------------------------------------------------------------- + * Miscellaneous configurable options + */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#define CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#define CFG_LONGHELP /* #undef to save memory */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* Max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_LOAD_ADDR 0x400000 /* Default load address */ + +#define CFG_HZ 1000 /* Decrementer freq: 1 ms ticks */ + +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/*----------------------------------------------------------------------- + * RAM configuration (note that CFG_SDRAM_BASE must be zero) + */ +#define CFG_SDRAM_BASE 0x00000000 +#define CFG_SDRAM_MAX_SIZE 0x08000000 /* Up to 128 Mbyte */ + +#define CFG_MAMR 0x00805000 + +/* + * 4096 Up to 4096 SDRAM rows + * 1000 factor s -> ms + * 32 PTP (pre-divider from MPTPR) + * 4 Number of refresh cycles per period + * 64 Refresh cycle in ms per number of rows + */ +#define CFG_PTA_PER_CLK ((4096 * 32 * 1000) / (4 * 64)) + +#define CFG_MEMTEST_START 0x00100000 /* memtest works on */ +#define CFG_MEMTEST_END 0x00500000 /* 1 ... 5 MB in SDRAM */ + +#define CFG_RESET_ADDRESS 0x09900000 + +/*----------------------------------------------------------------------- + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ + +#define CFG_MONITOR_BASE TEXT_BASE +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 KB for Monitor */ +#ifdef CONFIG_BZIP2 +#define CFG_MALLOC_LEN (4096 << 10) /* Reserve ~4 MB for malloc() */ +#else +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 KB for malloc() */ +#endif /* CONFIG_BZIP2 */ + +/*----------------------------------------------------------------------- + * Flash organisation + */ +#define CFG_FLASH_BASE 0xFC000000 +#define CFG_FLASH_CFI /* The flash is CFI compatible */ +#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CFG_MAX_FLASH_BANKS 1 /* Max number of flash banks */ +#define CFG_MAX_FLASH_SECT 512 /* Max num of sects on one chip */ + +/* Environment is in flash */ +#define CFG_ENV_IS_IN_FLASH +#define CFG_ENV_SECT_SIZE 0x20000 /* We use one complete sector */ +#define CFG_ENV_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN) + +#define CFG_OR0_PRELIM 0xFC000160 +#define CFG_BR0_PRELIM (CFG_FLASH_BASE | BR_PS_32 | BR_MS_GPCM | BR_V) + +#define CFG_DIRECT_FLASH_TFTP + +/*----------------------------------------------------------------------- + * BCSR + */ +#define CFG_OR3_PRELIM 0xFF0005B0 +#define CFG_BR3_PRELIM (0xFA000000 |BR_PS_16 | BR_MS_GPCM | BR_V) + +#define CFG_BCSR 0xFA400000 + +/*----------------------------------------------------------------------- + * Internal Memory Map Register + */ +#define CFG_IMMR 0xF0000000 + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x2F00 /* End of used area in DPRAM */ +#define CFG_GBL_DATA_SIZE 128 /* Size in bytes reserved for initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +/*----------------------------------------------------------------------- + * Configuration registers + */ +#ifdef CONFIG_WATCHDOG +#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | \ + SYPCR_SWF | SYPCR_SWE | SYPCR_SWRI | \ + SYPCR_SWP) +#else +#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | \ + SYPCR_SWF | SYPCR_SWP) +#endif /* CONFIG_WATCHDOG */ + +#define CFG_SIUMCR (SIUMCR_MLRC01 | SIUMCR_DBGC11) + +/* TBSCR - Time Base Status and Control Register */ +#define CFG_TBSCR (TBSCR_TBF | TBSCR_TBE) + +/* PISCR - Periodic Interrupt Status and Control */ +#define CFG_PISCR PISCR_PS + +/* SCCR - System Clock and reset Control Register */ +#define SCCR_MASK SCCR_EBDF11 +#define CFG_SCCR SCCR_RTSEL + +#define CFG_DER 0 + +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx chips */ + +/*----------------------------------------------------------------------- + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from flash */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#endif /* __CONFIG_H */ From f07217c9e2912af5b2f05d61829f62cc865b481f Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 12 Mar 2006 23:27:46 +0100 Subject: [PATCH 081/102] Fix array overflow with fw_setenv on uninitialised environment Patch by Murray Jensen, 15 Jul 2005 --- CHANGELOG | 3 +++ tools/env/fw_env.c | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 790b391d55..51efb237fb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix array overflow with fw_setenv on uninitialised environment + Patch by Murray Jensen, 15 Jul 2005 + * Add support for EmbeddedPlanet EP88x boards Patch by Yuli Barcohen, 13 Jul 2005 diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 74c0498d5a..f723b5bca1 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -614,8 +614,7 @@ static int env_init (void) if (!crc1_ok) { fprintf (stderr, "Warning: Bad CRC, using default environment\n"); - environment.data = default_environment; - free (addr1); + memcpy(environment.data, default_environment, sizeof default_environment); } } else { flag1 = environment.flags; @@ -652,9 +651,8 @@ static int env_init (void) } else if (!crc1_ok && !crc2_ok) { fprintf (stderr, "Warning: Bad CRC, using default environment\n"); - environment.data = default_environment; + memcpy(environment.data, default_environment, sizeof default_environment); curdev = 0; - free (addr2); free (addr1); } else if (flag1 == active_flag && flag2 == obsolete_flag) { environment.data = addr1; From b38dbd4622a2abeedf9fcb1806958d9afac0bbd4 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Mon, 13 Mar 2006 00:46:05 +0100 Subject: [PATCH 082/102] Fix bug in [id]cache_status commands for MPC85xx processors; should look at LSB of L1CSRn registers to determine if L1 cache is enabled, not the MSB. Patch by Murray Jensen, 19 Jul 2005 --- CHANGELOG | 5 +++++ cpu/mpc85xx/start.S | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 51efb237fb..ac984168d4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,11 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix bug in [id]cache_status commands for MPC85xx processors; + should look at LSB of L1CSRn registers to determine if L1 cache is + enabled, not the MSB. + Patch by Murray Jensen, 19 Jul 2005 + * Fix array overflow with fw_setenv on uninitialised environment Patch by Murray Jensen, 15 Jul 2005 diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S index 7ac65736bc..f96a4c3f8b 100644 --- a/cpu/mpc85xx/start.S +++ b/cpu/mpc85xx/start.S @@ -715,7 +715,7 @@ icache_disable: .globl icache_status icache_status: mfspr r3,L1CSR1 - srwi r3, r3, 31 /* >>31 => select bit 0 */ + andi. r3,r3,1 blr .globl dcache_enable @@ -748,7 +748,7 @@ dcache_disable: .globl dcache_status dcache_status: mfspr r3,L1CSR0 - srwi r3, r3, 31 /* >>31 => select bit 0 */ + andi. r3,r3,1 blr .globl get_pir From c15f80eaefa7ece72272e6f441f0ed36eab14411 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Mon, 13 Mar 2006 00:50:48 +0100 Subject: [PATCH 083/102] Change the sequence of events in soft_i2c.c:send_ack() to keep from incorrectly generating start/stop conditions on the bus. Patch by Andrew Dyer, 26 Jul 2005 --- CHANGELOG | 4 ++++ common/soft_i2c.c | 5 +---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ac984168d4..889cfd5e9e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,10 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Change the sequence of events in soft_i2c.c:send_ack() to keep from + incorrectly generating start/stop conditions on the bus. + Patch by Andrew Dyer, 26 Jul 2005 + * Fix bug in [id]cache_status commands for MPC85xx processors; should look at LSB of L1CSRn registers to determine if L1 cache is enabled, not the MSB. diff --git a/common/soft_i2c.c b/common/soft_i2c.c index 48e3d3e1c2..b3642dafc2 100644 --- a/common/soft_i2c.c +++ b/common/soft_i2c.c @@ -164,13 +164,10 @@ static void send_ack(int ack) volatile immap_t *immr = (immap_t *)CFG_IMMR; #endif - I2C_ACTIVE; I2C_SCL(0); I2C_DELAY; - - I2C_SDA(ack); - I2C_ACTIVE; + I2C_SDA(ack); I2C_DELAY; I2C_SCL(1); I2C_DELAY; From 95515306155b8b7fca1a38f192f23ea49251edf8 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Mon, 13 Mar 2006 01:00:22 +0100 Subject: [PATCH 084/102] au1x00_eth.c: check malloc return value and abort if it failed Patch by Andrew Dyer, 26 Jul 2005 --- CHANGELOG | 3 +++ cpu/mips/au1x00_eth.c | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 889cfd5e9e..8ce3a1bfc4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* au1x00_eth.c: check malloc return value and abort if it failed + Patch by Andrew Dyer, 26 Jul 2005 + * Change the sequence of events in soft_i2c.c:send_ack() to keep from incorrectly generating start/stop conditions on the bus. Patch by Andrew Dyer, 26 Jul 2005 diff --git a/cpu/mips/au1x00_eth.c b/cpu/mips/au1x00_eth.c index 9ce9b35397..078e8328b6 100644 --- a/cpu/mips/au1x00_eth.c +++ b/cpu/mips/au1x00_eth.c @@ -224,10 +224,14 @@ static void au1x00_halt(struct eth_device* dev){ int au1x00_enet_initialize(bd_t *bis){ struct eth_device* dev; - dev = (struct eth_device*) malloc(sizeof *dev); + if ((dev = (struct eth_device*)malloc(sizeof *dev)) == NULL) { + puts ("malloc failed\n"); + return 0; + } + memset(dev, 0, sizeof *dev); - sprintf(dev->name, "Au1X00 ETHERNET"); + sprintf(dev->name, "Au1X00 ethernet"); dev->iobase = 0; dev->priv = 0; dev->init = au1x00_init; From 9a7b408c116e1fcb4de607ddee15834319cd1ea0 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 13 Mar 2006 09:42:28 +0100 Subject: [PATCH 085/102] cpu/ppc4xx/start.S : exceptions are enabled after relocation Patch by Cedric Vincent, 6 June 2005 --- CHANGELOG | 3 +++ cpu/ppc4xx/start.S | 41 ++++++++++++++++++----------------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8ce3a1bfc4..8519b21864 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* cpu/ppc4xx/start.S : exceptions are enabled after relocation + Patch by Cedric Vincent, 6 June 2005 + * au1x00_eth.c: check malloc return value and abort if it failed Patch by Andrew Dyer, 26 Jul 2005 diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 48b430d14d..948de43d14 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -340,23 +340,6 @@ _start: mtspr tcr,r0 /* disable all */ mtspr esr,r0 /* clear exception syndrome register */ mtxer r0 /* clear integer exception register */ -#if !defined(CONFIG_440GX) - lis r1,0x0002 /* set CE bit (Critical Exceptions) */ - ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */ - mtmsr r1 /* change MSR */ -#elif !defined(CONFIG_440EP) && !defined(CONFIG_440GR) - bl __440gx_msr_set - b __440gx_msr_continue - -__440gx_msr_set: - lis r1, 0x0002 /* set CE bit (Critical Exceptions) */ - ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */ - mtspr srr1,r1 - mflr r1 - mtspr srr0,r1 - rfi -__440gx_msr_continue: -#endif /*----------------------------------------------------------------*/ /* Debug setup -- some (not very good) ice's need an event*/ @@ -458,9 +441,6 @@ __440gx_msr_continue: mtspr esr,r0 /* clear Exception Syndrome Reg */ mttcr r0 /* timer control register */ mtexier r0 /* disable all interrupts */ - addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */ - oris r4,r4,0x2 /* set CE bit (Critical Exceptions) */ - mtmsr r4 /* change MSR */ addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */ ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */ mtdbsr r4 /* clear/reset the dbsr */ @@ -571,9 +551,6 @@ __440gx_msr_continue: mttcr r4 /* clear Timer Control Reg */ mtxer r4 /* clear Fixed-Point Exception Reg */ mtevpr r4 /* clear Exception Vector Prefix Reg */ - addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */ - oris r4,r4,0x0002 /* set CE bit (Critical Exceptions) */ - mtmsr r4 /* change MSR */ addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */ /* dbsr is cleared by setting bits to 1) */ mtdbsr r4 /* clear/reset the dbsr */ @@ -1428,6 +1405,24 @@ trap_init: cmplw 0, r7, r8 blt 4b +#if !defined(CONFIG_440_GX) + addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */ + oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */ + mtmsr r7 /* change MSR */ +#else + bl __440gx_msr_set + b __440gx_msr_continue + +__440gx_msr_set: + addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */ + oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */ + mtspr srr1,r7 + mflr r7 + mtspr srr0,r7 + rfi +__440gx_msr_continue: +#endif + mtlr r4 /* restore link register */ blr From f3fecfe6d7cf07a2c5879d64fc1d849a94a0b67d Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 13 Mar 2006 09:43:01 +0100 Subject: [PATCH 086/102] Fix problem with updated PCI code in cpu/ppc4xx/405gp_pci.c Patch by Stefan Roese, 13 Mar 2006 --- CHANGELOG | 3 +++ cpu/ppc4xx/405gp_pci.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 8519b21864..09f1dfa360 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix problem with updated PCI code in cpu/ppc4xx/405gp_pci.c + Patch by Stefan Roese, 13 Mar 2006 + * cpu/ppc4xx/start.S : exceptions are enabled after relocation Patch by Cedric Vincent, 6 June 2005 diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c index f6b29e9d6e..947b85e28a 100644 --- a/cpu/ppc4xx/405gp_pci.c +++ b/cpu/ppc4xx/405gp_pci.c @@ -373,7 +373,7 @@ void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev, { unsigned int cmdstat = 0; - pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io); + pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io); /* always enable io space on vga boards */ pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat); From 15940c9af39deed77f72c7c8ad458b7ffc9c8683 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 13 Mar 2006 11:16:36 +0100 Subject: [PATCH 087/102] Change max size of uncompressed uImage's to 8MByte and add CFG_BOOTM_LEN to adjust this setting. As mentioned by Robin Getz on 2005-05-24 the size of uncompressed uImages was restricted to 4MBytes. This default size is now increased to 8Mbytes and can be overrided by setting CFG_BOOTM_LEN in the board config file. Patch by Stefan Roese, 13 Mar 2006 --- CHANGELOG | 10 ++++++++++ README | 8 +++++++- common/cmd_bootm.c | 8 ++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 09f1dfa360..492fb04521 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,16 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Change max size of uncompressed uImage's to 8MByte and add + CFG_BOOTM_LEN to adjust this setting. + + As mentioned by Robin Getz on 2005-05-24 the size of uncompressed + uImages was restricted to 4MBytes. This default size is now + increased to 8Mbytes and can be overrided by setting CFG_BOOTM_LEN + in the board config file. + + Patch by Stefan Roese, 13 Mar 2006 + * Fix problem with updated PCI code in cpu/ppc4xx/405gp_pci.c Patch by Stefan Roese, 13 Mar 2006 diff --git a/README b/README index c805437cd6..b6cb9810c6 100644 --- a/README +++ b/README @@ -421,7 +421,7 @@ The following options need to be configured: Space should be pre-allocated in the dts for the bd_t. CONFIG_OF_HAS_UBOOT_ENV - + The resulting flat device tree will have a copy of u-boot's environment variables @@ -1734,6 +1734,12 @@ Configuration Settings: - CFG_MALLOC_LEN: Size of DRAM reserved for malloc() use. +- CFG_BOOTM_LEN: + Normally compressed uImages are limited to an + uncompressed size of 8 MBytes. If this is not enough, + you can define CFG_BOOTM_LEN in your board config file + to adjust this setting to your needs. + - CFG_BOOTMAPSZ: Maximum size of memory mapped by the startup code of the Linux kernel; all data that must be processed by diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index a20e5841b7..aeb7842aef 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2002 + * (C) Copyright 2000-2006 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this @@ -140,6 +140,10 @@ static boot_os_Fcn do_bootm_lynxkdi; extern void lynxkdi_boot( image_header_t * ); #endif +#ifndef CFG_BOOTM_LEN +#define CFG_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */ +#endif + image_header_t header; ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ @@ -150,7 +154,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong addr; ulong data, len, checksum; ulong *len_ptr; - uint unc_len = 0x400000; + uint unc_len = CFG_BOOTM_LEN; int i, verify; char *name, *s; int (*appl)(int, char *[]); From 86f5f0342d1d2c787d984ecb9135db993e3a9f6a Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Mon, 13 Mar 2006 12:22:03 +0100 Subject: [PATCH 088/102] Fix CHANGELOG entry (patch date) --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 492fb04521..72a8fff679 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -16,7 +16,7 @@ Changes since U-Boot 1.1.4: Patch by Stefan Roese, 13 Mar 2006 * cpu/ppc4xx/start.S : exceptions are enabled after relocation - Patch by Cedric Vincent, 6 June 2005 + Patch by Cedric Vincent, 06 Jul 2005 * au1x00_eth.c: check malloc return value and abort if it failed Patch by Andrew Dyer, 26 Jul 2005 From ff7fefe6797246b2748530f965f2e41de34a982a Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Mon, 13 Mar 2006 12:37:35 +0100 Subject: [PATCH 089/102] Apply SoC concept to arm926ejs CPUs, i.e. move the SoC specific timer and cpu_reset code from cpu/$(CPU) into the new cpu/$(CPU)/$(SOC) directories Patch by Andreas Engel, 13 Mar 2006 --- CHANGELOG | 5 + Makefile | 6 +- board/versatile/split_by_variant.sh | 2 +- cpu/arm926ejs/interrupts.c | 148 +---------------------- cpu/arm926ejs/omap/Makefile | 43 +++++++ cpu/arm926ejs/omap/reset.S | 45 +++++++ cpu/arm926ejs/omap/timer.c | 177 ++++++++++++++++++++++++++++ cpu/arm926ejs/start.S | 22 ---- cpu/arm926ejs/versatile/Makefile | 43 +++++++ cpu/arm926ejs/versatile/reset.S | 45 +++++++ cpu/arm926ejs/versatile/timer.c | 175 +++++++++++++++++++++++++++ 11 files changed, 540 insertions(+), 171 deletions(-) create mode 100644 cpu/arm926ejs/omap/Makefile create mode 100644 cpu/arm926ejs/omap/reset.S create mode 100644 cpu/arm926ejs/omap/timer.c create mode 100644 cpu/arm926ejs/versatile/Makefile create mode 100644 cpu/arm926ejs/versatile/reset.S create mode 100644 cpu/arm926ejs/versatile/timer.c diff --git a/CHANGELOG b/CHANGELOG index 72a8fff679..1322c854f0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,11 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Apply SoC concept to arm926ejs CPUs, i.e. move the SoC specific + timer and cpu_reset code from cpu/$(CPU) into the new + cpu/$(CPU)/$(SOC) directories + Patch by Andreas Engel, 13 Mar 2006 + * Change max size of uncompressed uImage's to 8MByte and add CFG_BOOTM_LEN to adjust this setting. diff --git a/Makefile b/Makefile index 3076d6fe86..1a0e6c3c15 100644 --- a/Makefile +++ b/Makefile @@ -1514,7 +1514,7 @@ omap1510inn_config : unconfig @./mkconfig $(@:_config=) arm arm925t omap1510inn omap5912osk_config : unconfig - @./mkconfig $(@:_config=) arm arm926ejs omap5912osk + @./mkconfig $(@:_config=) arm arm926ejs omap5912osk NULL omap omap1610inn_config \ omap1610inn_cs0boot_config \ @@ -1534,7 +1534,7 @@ omap1610h2_cs_autoboot_config: unconfig echo "#define CONFIG_CS3_BOOT" >> ./include/config.h ; \ echo "... configured for CS3 boot"; \ fi; - @./mkconfig -a $(call xtract_omap1610xxx,$@) arm arm926ejs omap1610inn + @./mkconfig -a $(call xtract_omap1610xxx,$@) arm arm926ejs omap1610inn NULL omap omap730p2_config \ omap730p2_cs0boot_config \ @@ -1546,7 +1546,7 @@ omap730p2_cs3boot_config : unconfig echo "#define CONFIG_CS3_BOOT" >> ./include/config.h ; \ echo "... configured for CS3 boot"; \ fi; - @./mkconfig -a $(call xtract_omap730p2,$@) arm arm926ejs omap730p2 + @./mkconfig -a $(call xtract_omap730p2,$@) arm arm926ejs omap730p2 NULL omap scb9328_config : unconfig @./mkconfig $(@:_config=) arm arm920t scb9328 NULL imx diff --git a/board/versatile/split_by_variant.sh b/board/versatile/split_by_variant.sh index 35c663e6a5..576f238ade 100755 --- a/board/versatile/split_by_variant.sh +++ b/board/versatile/split_by_variant.sh @@ -36,5 +36,5 @@ fi # --------------------------------------------------------- # Complete the configuration # --------------------------------------------------------- -./mkconfig -a versatile arm arm926ejs versatile +./mkconfig -a versatile arm arm926ejs versatile NULL versatile echo "Variant:: $variant" diff --git a/cpu/arm926ejs/interrupts.c b/cpu/arm926ejs/interrupts.c index 0457bff964..9cac969f64 100644 --- a/cpu/arm926ejs/interrupts.c +++ b/cpu/arm926ejs/interrupts.c @@ -39,16 +39,6 @@ #include #include -#define TIMER_LOAD_VAL 0xffffffff - -/* macro to read the 32 bit timer */ -#ifdef CONFIG_OMAP -#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+8)) -#endif -#ifdef CONFIG_VERSATILE -#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+4)) -#endif - #ifdef CONFIG_USE_IRQ /* enable IRQ interrupts */ void enable_interrupts (void) @@ -188,146 +178,14 @@ void do_irq (struct pt_regs *pt_regs) #else -static ulong timestamp; -static ulong lastdec; - /* nothing really to do with interrupts, just starts up a counter. */ int interrupt_init (void) { -#ifdef CONFIG_OMAP - int32_t val; + extern void timer_init(void); - /* Start the decrementer ticking down from 0xffffffff */ - *((int32_t *) (CFG_TIMERBASE + LOAD_TIM)) = TIMER_LOAD_VAL; - val = MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | (CFG_PVT << MPUTIM_PTV_BIT); - *((int32_t *) (CFG_TIMERBASE + CNTL_TIMER)) = val; -#endif /* CONFIG_OMAP */ + timer_init(); -#ifdef CONFIG_VERSATILE - *(volatile ulong *)(CFG_TIMERBASE + 0) = CFG_TIMER_RELOAD; /* TimerLoad */ - *(volatile ulong *)(CFG_TIMERBASE + 4) = CFG_TIMER_RELOAD; /* TimerValue */ - *(volatile ulong *)(CFG_TIMERBASE + 8) = 0x8C; -#endif /* CONFIG_VERSATILE */ - - /* init the timestamp and lastdec value */ - reset_timer_masked(); - - return (0); -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -/* delay x useconds AND perserve advance timstamp value */ -void udelay (unsigned long usec) -{ - ulong tmo, tmp; - - if(usec >= 1000){ /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - }else{ /* else small number, don't kill it prior to HZ multiply */ - tmo = usec * CFG_HZ; - tmo /= (1000*1000); - } - - tmp = get_timer (0); /* get current timestamp */ - if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */ - reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */ - else - tmo += tmp; /* else, set advancing stamp wake up time */ - - while (get_timer_masked () < tmo)/* loop till event */ - /*NOP*/; -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastdec = READ_TIMER; /* capure current decrementer value time */ - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -ulong get_timer_masked (void) -{ - ulong now = READ_TIMER; /* current tick value */ - - if (lastdec >= now) { /* normal mode (non roll) */ - /* normal mode */ - timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */ - } else { /* we have overflow of the count down timer */ - /* nts = ts + ld + (TLV - now) - * ts=old stamp, ld=time that passed before passing through -1 - * (TLV-now) amount of time after passing though -1 - * nts = new "advancing time stamp"...it could also roll and cause problems. - */ - timestamp += lastdec + TIMER_LOAD_VAL - now; - } - lastdec = now; - - return timestamp; -} - -/* waits specified delay value and resets timestamp */ -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - } else { /* else small number, don't kill it prior to HZ multiply */ - tmo = usec * CFG_HZ; - tmo /= (1000*1000); - } - - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - - tbclk = CFG_HZ; - return tbclk; + return 0; } #endif /* CONFIG_INTEGRATOR */ diff --git a/cpu/arm926ejs/omap/Makefile b/cpu/arm926ejs/omap/Makefile new file mode 100644 index 0000000000..f9d3378197 --- /dev/null +++ b/cpu/arm926ejs/omap/Makefile @@ -0,0 +1,43 @@ +# +# (C) Copyright 2000-2005 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(SOC).a + +OBJS = timer.o +SOBJS = reset.o + +all: .depend $(LIB) + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) $(SOBJS) + +######################################################################### + +.depend: Makefile $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/cpu/arm926ejs/omap/reset.S b/cpu/arm926ejs/omap/reset.S new file mode 100644 index 0000000000..e8989028e2 --- /dev/null +++ b/cpu/arm926ejs/omap/reset.S @@ -0,0 +1,45 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + .align 5 +.globl reset_cpu +reset_cpu: + ldr r1, rstctl1 /* get clkm1 reset ctl */ + mov r3, #0x0 + strh r3, [r1] /* clear it */ + mov r3, #0x8 + strh r3, [r1] /* force dsp+arm reset */ +_loop_forever: + b _loop_forever + +rstctl1: + .word 0xfffece10 diff --git a/cpu/arm926ejs/omap/timer.c b/cpu/arm926ejs/omap/timer.c new file mode 100644 index 0000000000..a2a9133ee0 --- /dev/null +++ b/cpu/arm926ejs/omap/timer.c @@ -0,0 +1,177 @@ +/* + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +#define TIMER_LOAD_VAL 0xffffffff + +/* macro to read the 32 bit timer */ +#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+8)) + +static ulong timestamp; +static ulong lastdec; + +int timer_init (void) +{ + int32_t val; + + /* Start the decrementer ticking down from 0xffffffff */ + *((int32_t *) (CFG_TIMERBASE + LOAD_TIM)) = TIMER_LOAD_VAL; + val = MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | (CFG_PVT << MPUTIM_PTV_BIT); + *((int32_t *) (CFG_TIMERBASE + CNTL_TIMER)) = val; + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +/* delay x useconds AND perserve advance timstamp value */ +void udelay (unsigned long usec) +{ + ulong tmo, tmp; + + if(usec >= 1000){ /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + }else{ /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CFG_HZ; + tmo /= (1000*1000); + } + + tmp = get_timer (0); /* get current timestamp */ + if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */ + reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */ + else + tmo += tmp; /* else, set advancing stamp wake up time */ + + while (get_timer_masked () < tmo)/* loop till event */ + /*NOP*/; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER; /* capure current decrementer value time */ + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; /* current tick value */ + + if (lastdec >= now) { /* normal mode (non roll) */ + /* normal mode */ + timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */ + } else { /* we have overflow of the count down timer */ + /* nts = ts + ld + (TLV - now) + * ts=old stamp, ld=time that passed before passing through -1 + * (TLV-now) amount of time after passing though -1 + * nts = new "advancing time stamp"...it could also roll and cause problems. + */ + timestamp += lastdec + TIMER_LOAD_VAL - now; + } + lastdec = now; + + return timestamp; +} + +/* waits specified delay value and resets timestamp */ +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + } else { /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CFG_HZ; + tmo /= (1000*1000); + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CFG_HZ; + return tbclk; +} diff --git a/cpu/arm926ejs/start.S b/cpu/arm926ejs/start.S index fc6b20b21e..725c6639a1 100644 --- a/cpu/arm926ejs/start.S +++ b/cpu/arm926ejs/start.S @@ -392,25 +392,3 @@ fiq: bl do_fiq #endif - -# ifdef CONFIG_INTEGRATOR - - /* Satisfied by Integrator routine (AP or CP) */ - -#else - - .align 5 -.globl reset_cpu -reset_cpu: - ldr r1, rstctl1 /* get clkm1 reset ctl */ - mov r3, #0x0 - strh r3, [r1] /* clear it */ - mov r3, #0x8 - strh r3, [r1] /* force dsp+arm reset */ -_loop_forever: - b _loop_forever - -rstctl1: - .word 0xfffece10 - -#endif /* #ifdef CONFIG_INTEGRATOR */ diff --git a/cpu/arm926ejs/versatile/Makefile b/cpu/arm926ejs/versatile/Makefile new file mode 100644 index 0000000000..f9d3378197 --- /dev/null +++ b/cpu/arm926ejs/versatile/Makefile @@ -0,0 +1,43 @@ +# +# (C) Copyright 2000-2005 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(SOC).a + +OBJS = timer.o +SOBJS = reset.o + +all: .depend $(LIB) + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) $(SOBJS) + +######################################################################### + +.depend: Makefile $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/cpu/arm926ejs/versatile/reset.S b/cpu/arm926ejs/versatile/reset.S new file mode 100644 index 0000000000..e8989028e2 --- /dev/null +++ b/cpu/arm926ejs/versatile/reset.S @@ -0,0 +1,45 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + .align 5 +.globl reset_cpu +reset_cpu: + ldr r1, rstctl1 /* get clkm1 reset ctl */ + mov r3, #0x0 + strh r3, [r1] /* clear it */ + mov r3, #0x8 + strh r3, [r1] /* force dsp+arm reset */ +_loop_forever: + b _loop_forever + +rstctl1: + .word 0xfffece10 diff --git a/cpu/arm926ejs/versatile/timer.c b/cpu/arm926ejs/versatile/timer.c new file mode 100644 index 0000000000..32872d2b66 --- /dev/null +++ b/cpu/arm926ejs/versatile/timer.c @@ -0,0 +1,175 @@ +/* + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +#define TIMER_LOAD_VAL 0xffffffff + +/* macro to read the 32 bit timer */ +#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+4)) + +static ulong timestamp; +static ulong lastdec; + +/* nothing really to do with interrupts, just starts up a counter. */ +int timer_init (void) +{ + *(volatile ulong *)(CFG_TIMERBASE + 0) = CFG_TIMER_RELOAD; /* TimerLoad */ + *(volatile ulong *)(CFG_TIMERBASE + 4) = CFG_TIMER_RELOAD; /* TimerValue */ + *(volatile ulong *)(CFG_TIMERBASE + 8) = 0x8C; + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +/* delay x useconds AND perserve advance timstamp value */ +void udelay (unsigned long usec) +{ + ulong tmo, tmp; + + if(usec >= 1000){ /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + }else{ /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CFG_HZ; + tmo /= (1000*1000); + } + + tmp = get_timer (0); /* get current timestamp */ + if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */ + reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */ + else + tmo += tmp; /* else, set advancing stamp wake up time */ + + while (get_timer_masked () < tmo)/* loop till event */ + /*NOP*/; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER; /* capure current decrementer value time */ + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; /* current tick value */ + + if (lastdec >= now) { /* normal mode (non roll) */ + /* normal mode */ + timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */ + } else { /* we have overflow of the count down timer */ + /* nts = ts + ld + (TLV - now) + * ts=old stamp, ld=time that passed before passing through -1 + * (TLV-now) amount of time after passing though -1 + * nts = new "advancing time stamp"...it could also roll and cause problems. + */ + timestamp += lastdec + TIMER_LOAD_VAL - now; + } + lastdec = now; + + return timestamp; +} + +/* waits specified delay value and resets timestamp */ +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + } else { /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CFG_HZ; + tmo /= (1000*1000); + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CFG_HZ; + return tbclk; +} From 6e53e27c5017e4a9505dce47b3167501a2c02299 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 14 Mar 2006 15:59:25 +0100 Subject: [PATCH 090/102] Add support for DS1374 RTC chip. --- CHANGELOG | 2 + rtc/Makefile | 2 +- rtc/ds1374.c | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 rtc/ds1374.c diff --git a/CHANGELOG b/CHANGELOG index 1322c854f0..77f1a254d2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add support for DS1374 RTC chip. + * Apply SoC concept to arm926ejs CPUs, i.e. move the SoC specific timer and cpu_reset code from cpu/$(CPU) into the new cpu/$(CPU)/$(SOC) directories diff --git a/rtc/Makefile b/rtc/Makefile index b08057e2f1..2c5d099fee 100644 --- a/rtc/Makefile +++ b/rtc/Makefile @@ -29,7 +29,7 @@ LIB = librtc.a OBJS = date.o \ bf533_rtc.o ds12887.o ds1302.o ds1306.o ds1307.o \ - ds1337.o ds1556.o ds164x.o ds174x.o \ + ds1337.o ds1374.o ds1556.o ds164x.o ds174x.o \ m41t11.o max6900.o m48t35ax.o mc146818.o mk48t59.o \ mpc5xxx.o mpc8xx.o pcf8563.o s3c24x0_rtc.o rs5c372.o diff --git a/rtc/ds1374.c b/rtc/ds1374.c new file mode 100644 index 0000000000..31f06e5874 --- /dev/null +++ b/rtc/ds1374.c @@ -0,0 +1,253 @@ +/* + * (C) Copyright 2001, 2002, 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * Keith Outwater, keith_outwater@mvis.com` + * Steven Scholz, steven.scholz@imc-berlin.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim) + * DS1374 Real Time Clock (RTC). + * + * based on ds1337.c + */ + +#include +#include +#include +#include + +#if (defined(CONFIG_RTC_DS1374)) && (CONFIG_COMMANDS & CFG_CMD_DATE) + +/*---------------------------------------------------------------------*/ +#undef DEBUG_RTC +#define DEBUG_RTC + +#ifdef DEBUG_RTC +#define DEBUGR(fmt,args...) printf(fmt ,##args) +#else +#define DEBUGR(fmt,args...) +#endif +/*---------------------------------------------------------------------*/ + +#ifndef CFG_I2C_RTC_ADDR +# define CFG_I2C_RTC_ADDR 0x68 +#endif + +#if defined(CONFIG_RTC_DS1374) && (CFG_I2C_SPEED > 400000) +# error The DS1374 is specified up to 400kHz in fast mode! +#endif + +/* + * RTC register addresses + */ +#define RTC_TOD_CNT_BYTE0_ADDR 0x00 /* TimeOfDay */ +#define RTC_TOD_CNT_BYTE1_ADDR 0x01 +#define RTC_TOD_CNT_BYTE2_ADDR 0x02 +#define RTC_TOD_CNT_BYTE3_ADDR 0x03 + +#define RTC_WD_ALM_CNT_BYTE0_ADDR 0x04 +#define RTC_WD_ALM_CNT_BYTE1_ADDR 0x05 +#define RTC_WD_ALM_CNT_BYTE2_ADDR 0x06 + +#define RTC_CTL_ADDR 0x07 /* RTC-CoNTrol-register */ +#define RTC_SR_ADDR 0x08 /* RTC-StatusRegister */ +#define RTC_TCS_DS_ADDR 0x09 /* RTC-TrickleChargeSelect DiodeSelect-register */ + +#define RTC_CTL_BIT_AIE (1<<0) /* Bit 0 - Alarm Interrupt enable */ +#define RTC_CTL_BIT_RS1 (1<<1) /* Bit 1/2 - Rate Select square wave output */ +#define RTC_CTL_BIT_RS2 (1<<2) /* Bit 2/2 - Rate Select square wave output */ +#define RTC_CTL_BIT_WDSTR (1<<3) /* Bit 3 - Watchdog Reset Steering */ +#define RTC_CTL_BIT_BBSQW (1<<4) /* Bit 4 - Battery-Backed Square-Wave */ +#define RTC_CTL_BIT_WD_ALM (1<<5) /* Bit 5 - Watchdoc/Alarm Counter Select */ +#define RTC_CTL_BIT_WACE (1<<6) /* Bit 6 - Watchdog/Alarm Counter Enable WACE*/ +#define RTC_CTL_BIT_EN_OSC (1<<7) /* Bit 7 - Enable Oscilator */ + +#define RTC_SR_BIT_AF 0x01 /* Bit 0 = Alarm Flag */ +#define RTC_SR_BIT_OSF 0x80 /* Bit 7 - Osc Stop Flag */ + +typedef unsigned char boolean_t; + +#ifndef TRUE +#define TRUE ((boolean_t)(0==0)) +#endif +#ifndef FALSE +#define FALSE (!TRUE) +#endif + +const char RtcTodAddr[] = { + RTC_TOD_CNT_BYTE0_ADDR, + RTC_TOD_CNT_BYTE1_ADDR, + RTC_TOD_CNT_BYTE2_ADDR, + RTC_TOD_CNT_BYTE3_ADDR +}; + +static uchar rtc_read (uchar reg); +static void rtc_write (uchar reg, uchar val, boolean_t set); +static void rtc_write_raw (uchar reg, uchar val); + +/* + * Get the current time from the RTC + */ +void rtc_get (struct rtc_time *tm){ + + unsigned long time1, time2; + unsigned int limit; + unsigned char tmp; + unsigned int i; + + /* + * Since the reads are being performed one byte at a time, + * there is a chance that a carry will occur during the read. + * To detect this, 2 reads are performed and compared. + */ + limit = 10; + do { + i = 4; + time1 = 0; + while (i--) { + tmp = rtc_read(RtcTodAddr[i]); + time1 = (time1 << 8) | (tmp & 0xff); + } + + i = 4; + time2 = 0; + while (i--) { + tmp = rtc_read(RtcTodAddr[i]); + time2 = (time2 << 8) | (tmp & 0xff); + } + } while ((time1 != time2) && limit--); + + if (time1 != time2) { + printf("can't get consistent time from rtc chip\n"); + } + + DEBUGR ("Get RTC s since 1.1.1970: %d\n", time1); + + to_tm(time1, tm); /* To Gregorian Date */ + + if (rtc_read(RTC_SR_ADDR) & RTC_SR_BIT_OSF) + printf ("### Warning: RTC oscillator has stopped\n"); + + DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, + tm->tm_hour, tm->tm_min, tm->tm_sec); +} + +/* + * Set the RTC + */ +void rtc_set (struct rtc_time *tmp){ + + unsigned long time; + unsigned i; + + DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + if (tmp->tm_year < 1970 || tmp->tm_year > 2069) + printf("WARNING: year should be between 1970 and 2069!\n"); + + time = mktime(tmp->tm_year, tmp->tm_mon, + tmp->tm_mday, tmp->tm_hour, + tmp->tm_min, tmp->tm_sec); + + DEBUGR ("Set RTC s since 1.1.1970: %d (0x%02x)\n", time, time); + + /* write to RTC_TOD_CNT_BYTEn_ADDR */ + for (i = 0; i <= 3; i++) { + rtc_write_raw(RtcTodAddr[i], (unsigned char)(time & 0xff)); + time = time >> 8; + } + + /* Start clock */ + rtc_write(RTC_CTL_ADDR, RTC_CTL_BIT_EN_OSC, FALSE); +} + +/* + * Reset the RTC. We setting the date back to 1970-01-01. + * We also enable the oscillator output on the SQW/OUT pin and program + * it for 32,768 Hz output. Note that according to the datasheet, turning + * on the square wave output increases the current drain on the backup + * battery to something between 480nA and 800nA. + */ +void rtc_reset (void){ + + struct rtc_time tmp; + + /* clear status flags */ + rtc_write (RTC_SR_ADDR, (RTC_SR_BIT_AF|RTC_SR_BIT_OSF), FALSE); /* clearing OSF and AF */ + + /* Initialise DS1374 oriented to MPC8349E-ADS */ + rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_EN_OSC + |RTC_CTL_BIT_WACE + |RTC_CTL_BIT_AIE), FALSE);/* start osc, disable WACE, clear AIE + - set to 0 */ + rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_WD_ALM + |RTC_CTL_BIT_WDSTR + |RTC_CTL_BIT_RS1 + |RTC_CTL_BIT_RS2 + |RTC_CTL_BIT_BBSQW), TRUE);/* disable WD/ALM, WDSTR set to INT-pin, + set BBSQW and SQW to 32k + - set to 1 */ + tmp.tm_year = 1970; + tmp.tm_mon = 1; + tmp.tm_mday= 1; + tmp.tm_hour = 0; + tmp.tm_min = 0; + tmp.tm_sec = 0; + + rtc_set(&tmp); + + printf("RTC: %4d-%02d-%02d %2d:%02d:%02d UTC\n", + tmp.tm_year, tmp.tm_mon, tmp.tm_mday, + tmp.tm_hour, tmp.tm_min, tmp.tm_sec); + + rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAC, TRUE); + rtc_write(RTC_WD_ALM_CNT_BYTE1_ADDR,0xDE, TRUE); + rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAD, TRUE); +} + +/* + * Helper functions + */ +static uchar rtc_read (uchar reg) +{ + return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg)); +} + +static void rtc_write (uchar reg, uchar val, boolean_t set) +{ + if (set == TRUE) { + val |= i2c_reg_read (CFG_I2C_RTC_ADDR, reg); + i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val); + } else { + val = i2c_reg_read (CFG_I2C_RTC_ADDR, reg) & ~val; + i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val); + } +} + +static void rtc_write_raw (uchar reg, uchar val) +{ + i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val); +} +#endif /* (CONFIG_RTC_DS1374) && (CFG_COMMANDS & CFG_CMD_DATE) */ From a7c66ad2e52b49a7cf5efb9665dd0527db96ea29 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 14 Mar 2006 16:01:25 +0100 Subject: [PATCH 091/102] Correct shift offsets in icache_status and dcache_status for MPC83xx. --- CHANGELOG | 2 ++ cpu/mpc83xx/start.S | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 77f1a254d2..e40ba053e9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Correct shift offsets in icache_status and dcache_status for MPC83xx. + * Add support for DS1374 RTC chip. * Apply SoC concept to arm926ejs CPUs, i.e. move the SoC specific diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index 46c748f790..324f6c36fe 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -796,7 +796,7 @@ icache_disable: .globl icache_status icache_status: mfspr r3, HID0 - rlwinm r3, r3, HID0_ICE_SHIFT, 31, 31 + rlwinm r3, r3, (31 - HID0_ICE_SHIFT + 1), 31, 31 blr .globl dcache_enable @@ -828,7 +828,7 @@ dcache_disable: .globl dcache_status dcache_status: mfspr r3, HID0 - rlwinm r3, r3, HID0_DCE_SHIFT, 31, 31 + rlwinm r3, r3, (31 - HID0_DCE_SHIFT + 1), 31, 31 blr .globl get_pvr From cd94ba397ed9c7d06578977d6c34c24732b2a9f1 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 14 Mar 2006 16:02:31 +0100 Subject: [PATCH 092/102] Add Dcbz(), Dcbi() and Dcbf() routines for MPC83xx. --- CHANGELOG | 2 ++ cpu/mpc83xx/start.S | 34 ++++++++++++++++++++++++++++++++++ include/common.h | 3 ++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index e40ba053e9..7a8a2f3851 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add Dcbz(), Dcbi() and Dcbf() routines for MPC83xx. + * Correct shift offsets in icache_status and dcache_status for MPC83xx. * Add support for DS1374 RTC chip. diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index 324f6c36fe..6e02cce799 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -836,6 +836,40 @@ get_pvr: mfspr r3, PVR blr +/*------------------------------------------------------------------------------- */ +/* Function: ppcDcbf */ +/* Description: Data Cache block flush */ +/* Input: r3 = effective address */ +/* Output: none. */ +/*------------------------------------------------------------------------------- */ + .globl ppcDcbf +ppcDcbf: + dcbf r0,r3 + blr + +/*------------------------------------------------------------------------------- */ +/* Function: ppcDcbi */ +/* Description: Data Cache block Invalidate */ +/* Input: r3 = effective address */ +/* Output: none. */ +/*------------------------------------------------------------------------------- */ + .globl ppcDcbi +ppcDcbi: + dcbi r0,r3 + blr + +/*-------------------------------------------------------------------------- + * Function: ppcDcbz + * Description: Data Cache block zero. + * Input: r3 = effective address + * Output: none. + *-------------------------------------------------------------------------- */ + + .globl ppcDcbz +ppcDcbz: + dcbz r0,r3 + blr + /*-------------------------------------------------------------------*/ /* diff --git a/include/common.h b/include/common.h index d2570a803e..5d8b15628b 100644 --- a/include/common.h +++ b/include/common.h @@ -365,7 +365,8 @@ void trap_init (ulong); defined (CONFIG_75x) || \ defined (CONFIG_74xx) || \ defined (CONFIG_MPC8220) || \ - defined(CONFIG_MPC85xx) + defined (CONFIG_MPC85xx) || \ + defined (CONFIG_MPC83XX) unsigned char in8(unsigned int); void out8(unsigned int, unsigned char); unsigned short in16(unsigned int); From e24e0f0744f4d28d7642c88052b712e91dbbf203 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 14 Mar 2006 16:03:46 +0100 Subject: [PATCH 093/102] Add bit definitions for MPC83xx DDR controller registers. --- CHANGELOG | 2 ++ include/asm-ppc/immap_83xx.h | 52 ++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 7a8a2f3851..304ea23f79 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add bit definitions for MPC83xx DDR controller registers. + * Add Dcbz(), Dcbi() and Dcbf() routines for MPC83xx. * Correct shift offsets in icache_status and dcache_status for MPC83xx. diff --git a/include/asm-ppc/immap_83xx.h b/include/asm-ppc/immap_83xx.h index f5fec22c7f..2b2693c32f 100644 --- a/include/asm-ppc/immap_83xx.h +++ b/include/asm-ppc/immap_83xx.h @@ -675,24 +675,76 @@ typedef struct ddr8349{ u8 res9[8]; u32 sdram_clk_cntl; #define DDR_SDRAM_CLK_CNTL_SS_EN 0x80000000 +#define DDR_SDRAM_CLK_CNTL_CLK_ADJUST_025 0x01000000 #define DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05 0x02000000 +#define DDR_SDRAM_CLK_CNTL_CLK_ADJUST_075 0x03000000 +#define DDR_SDRAM_CLK_CNTL_CLK_ADJUST_1 0x04000000 u8 res4[0xCCC]; u32 data_err_inject_hi; /**< Memory Data Path Error Injection Mask High */ u32 data_err_inject_lo; /**< Memory Data Path Error Injection Mask Low */ u32 ecc_err_inject; /**< Memory Data Path Error Injection Mask ECC */ +#define ECC_ERR_INJECT_EMB (0x80000000>>22) /* ECC Mirror Byte */ +#define ECC_ERR_INJECT_EIEN (0x80000000>>23) /* Error Injection Enable */ +#define ECC_ERR_INJECT_EEIM (0xF0000000>>24) /* ECC Erroe Injection Enable */ +#define ECC_ERR_INJECT_EEIM_SHIFT 0 u8 res5[0x14]; u32 capture_data_hi; /**< Memory Data Path Read Capture High */ u32 capture_data_lo; /**< Memory Data Path Read Capture Low */ u32 capture_ecc; /**< Memory Data Path Read Capture ECC */ +#define CAPTURE_ECC_ECE (0xF0000000>>24) +#define CAPTURE_ECC_ECE_SHIFT 0 u8 res6[0x14]; u32 err_detect; /**< Memory Error Detect */ +#define ECC_ERROR_DETECT_MME (0x80000000>>0) /* Multiple Memory Errors */ +#define ECC_ERROR_DETECT_MBE (0x80000000>>28) /* Multiple-Bit Error */ +#define ECC_ERROR_DETECT_SBE (0x80000000>>29) /* Single-Bit ECC Error Pickup */ +#define ECC_ERROR_DETECT_MSE (0x80000000>>31) /* Memory Select Error */ u32 err_disable; /**< Memory Error Disable */ +#define ECC_ERROR_DISABLE_MBED (0x80000000>>28) /* Multiple-Bit ECC Error Disable */ +#define ECC_ERROR_DISABLE_SBED (0x80000000>>29) /* Sinle-Bit ECC Error disable */ +#define ECC_ERROR_DISABLE_MSED (0x80000000>>31) /* Memory Select Error Disable */ +#define ECC_ERROR_ENABLE ~(ECC_ERROR_DISABLE_MSED|ECC_ERROR_DISABLE_SBED|ECC_ERROR_DISABLE_MBED) u32 err_int_en; /**< Memory Error Interrupt Enable */ +#define ECC_ERR_INT_EN_MBEE (0x80000000>>28) /* Multiple-Bit ECC Error Interrupt Enable */ +#define ECC_ERR_INT_EN_SBEE (0x80000000>>29) /* Single-Bit ECC Error Interrupt Enable */ +#define ECC_ERR_INT_EN_MSEE (0x80000000>>31) /* Memory Select Error Interrupt Enable */ +#define ECC_ERR_INT_DISABLE ~(ECC_ERR_INT_EN_MBEE|ECC_ERR_INT_EN_SBEE|ECC_ERR_INT_EN_MSEE) u32 capture_attributes; /**< Memory Error Attributes Capture */ +#define ECC_CAPT_ATTR_BNUM (0xe0000000>>1) /* Data Beat Num */ +#define ECC_CAPT_ATTR_BNUM_SHIFT 28 +#define ECC_CAPT_ATTR_TSIZ (0xc0000000>>6) /* Transaction Size */ +#define ECC_CAPT_ATTR_TSIZ_FOUR_DW 0 +#define ECC_CAPT_ATTR_TSIZ_ONE_DW 1 +#define ECC_CAPT_ATTR_TSIZ_TWO_DW 2 +#define ECC_CAPT_ATTR_TSIZ_THREE_DW 3 +#define ECC_CAPT_ATTR_TSIZ_SHIFT 24 +#define ECC_CAPT_ATTR_TSRC (0xf8000000>>11) /* Transaction Source */ +#define ECC_CAPT_ATTR_TSRC_E300_CORE_DT 0x0 +#define ECC_CAPT_ATTR_TSRC_E300_CORE_IF 0x2 +#define ECC_CAPT_ATTR_TSRC_TSEC1 0x4 +#define ECC_CAPT_ATTR_TSRC_TSEC2 0x5 +#define ECC_CAPT_ATTR_TSRC_USB (0x06|0x07) +#define ECC_CAPT_ATTR_TSRC_ENCRYPT 0x8 +#define ECC_CAPT_ATTR_TSRC_I2C 0x9 +#define ECC_CAPT_ATTR_TSRC_JTAG 0xA +#define ECC_CAPT_ATTR_TSRC_PCI1 0xD +#define ECC_CAPT_ATTR_TSRC_PCI2 0xE +#define ECC_CAPT_ATTR_TSRC_DMA 0xF +#define ECC_CAPT_ATTR_TSRC_SHIFT 16 +#define ECC_CAPT_ATTR_TTYP (0xe0000000>>18) /* Transaction Type */ +#define ECC_CAPT_ATTR_TTYP_WRITE 0x1 +#define ECC_CAPT_ATTR_TTYP_READ 0x2 +#define ECC_CAPT_ATTR_TTYP_R_M_W 0x3 +#define ECC_CAPT_ATTR_TTYP_SHIFT 12 +#define ECC_CAPT_ATTR_VLD (0x80000000>>31) /* Valid */ u32 capture_address; /**< Memory Error Address Capture */ u32 capture_ext_address;/**< Memory Error Extended Address Capture */ u32 err_sbe; /**< Memory Single-Bit ECC Error Management */ +#define ECC_ERROR_MAN_SBET (0xff000000>>8) /* Single-Bit Error Threshold 0..255*/ +#define ECC_ERROR_MAN_SBET_SHIFT 16 +#define ECC_ERROR_MAN_SBEC (0xff000000>>24) /* Single Bit Error Counter 0..255*/ +#define ECC_ERROR_MAN_SBEC_SHIFT 0 u8 res7[0xA4]; u32 debug_reg; u8 res8[0xFC]; From 6d8ae5abb5311bd8e306a5a060dcfbeb0874a169 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 14 Mar 2006 16:12:48 +0100 Subject: [PATCH 094/102] Add sync in do_reset() routine for MPC83xx after RPR register was written to. It is need on some targets when BAT translation is enabled. --- CHANGELOG | 4 ++++ cpu/mpc83xx/cpu.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 304ea23f79..f4819235a8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,10 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add sync in do_reset() routine for MPC83xx after RPR register + was written to. It is need on some targets when BAT translation + is enabled. + * Add bit definitions for MPC83xx DDR controller registers. * Add Dcbz(), Dcbi() and Dcbf() routines for MPC83xx. diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index e49e4fe0ee..63f82422f5 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -93,6 +93,8 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* enable Reset Control Reg */ immap->reset.rpr = 0x52535445; + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); /* confirm Reset Control Reg is enabled */ while(!((immap->reset.rcer) & RCER_CRE)); From 61f25155acd99caef08897da390382d5c7fbfd74 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 14 Mar 2006 16:14:48 +0100 Subject: [PATCH 095/102] Add DMA support for MPC83xx. --- CHANGELOG | 2 + cpu/mpc83xx/cpu.c | 85 +++++++++++++++++++++++++++++++++++ include/asm-ppc/immap_83xx.h | 87 +++++++++++++++++++++++++++++++++++- 3 files changed, 173 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index f4819235a8..81e7cf2615 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add DMA support for MPC83xx. + * Add sync in do_reset() routine for MPC83xx after RPR register was written to. It is need on some targets when BAT translation is enabled. diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index 63f82422f5..f24d3a4b1c 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -191,3 +191,88 @@ ft_cpu_setup(void *blob, bd_t *bd) #endif } #endif + +#if defined(CONFIG_DDR_ECC) +void dma_init(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; + volatile dma8349_t *dma = &immap->dma; + volatile u32 status = swab32(dma->dmasr0); + volatile u32 dmamr0 = swab32(dma->dmamr0); + + debug("DMA-init\n"); + + /* initialize DMASARn, DMADAR and DMAABCRn */ + dma->dmadar0 = (u32)0; + dma->dmasar0 = (u32)0; + dma->dmabcr0 = 0; + + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); + + /* clear CS bit */ + dmamr0 &= ~DMA_CHANNEL_START; + dma->dmamr0 = swab32(dmamr0); + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); + + /* while the channel is busy, spin */ + while(status & DMA_CHANNEL_BUSY) { + status = swab32(dma->dmasr0); + } + + debug("DMA-init end\n"); +} + +uint dma_check(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; + volatile dma8349_t *dma = &immap->dma; + volatile u32 status = swab32(dma->dmasr0); + volatile u32 byte_count = swab32(dma->dmabcr0); + + /* while the channel is busy, spin */ + while (status & DMA_CHANNEL_BUSY) { + status = swab32(dma->dmasr0); + } + + if (status & DMA_CHANNEL_TRANSFER_ERROR) { + printf ("DMA Error: status = %x @ %d\n", status, byte_count); + } + + return status; +} + +int dma_xfer(void *dest, u32 count, void *src) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; + volatile dma8349_t *dma = &immap->dma; + volatile u32 dmamr0; + + /* initialize DMASARn, DMADAR and DMAABCRn */ + dma->dmadar0 = swab32((u32)dest); + dma->dmasar0 = swab32((u32)src); + dma->dmabcr0 = swab32(count); + + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); + + /* init direct transfer, clear CS bit */ + dmamr0 = (DMA_CHANNEL_TRANSFER_MODE_DIRECT | + DMA_CHANNEL_SOURCE_ADDRESS_HOLD_8B | + DMA_CHANNEL_SOURCE_ADRESSS_HOLD_EN); + + dma->dmamr0 = swab32(dmamr0); + + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); + + /* set CS to start DMA transfer */ + dmamr0 |= DMA_CHANNEL_START; + dma->dmamr0 = swab32(dmamr0); + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); + + return ((int)dma_check()); +} +#endif /*CONFIG_DDR_ECC*/ diff --git a/include/asm-ppc/immap_83xx.h b/include/asm-ppc/immap_83xx.h index 2b2693c32f..b0e17ab9be 100644 --- a/include/asm-ppc/immap_83xx.h +++ b/include/asm-ppc/immap_83xx.h @@ -847,10 +847,95 @@ typedef struct spi8349 u8 res1[0xD8]; } spi8349_t; + +/* + * DMA/Messaging Unit + */ typedef struct dma8349 { - u8 fixme[0x300]; + u32 res0[0xC]; /* 0x0-0x29 reseverd */ + u32 omisr; /* 0x30 Outbound message interrupt status register */ + u32 omimr; /* 0x34 Outbound message interrupt mask register */ + u32 res1[0x6]; /* 0x38-0x49 reserved */ + + u32 imr0; /* 0x50 Inbound message register 0 */ + u32 imr1; /* 0x54 Inbound message register 1 */ + u32 omr0; /* 0x58 Outbound message register 0 */ + u32 omr1; /* 0x5C Outbound message register 1 */ + + u32 odr; /* 0x60 Outbound doorbell register */ + u32 res2; /* 0x64-0x67 reserved */ + u32 idr; /* 0x68 Inbound doorbell register */ + u32 res3[0x5]; /* 0x6C-0x79 reserved */ + + u32 imisr; /* 0x80 Inbound message interrupt status register */ + u32 imimr; /* 0x84 Inbound message interrupt mask register */ + u32 res4[0x1E]; /* 0x88-0x99 reserved */ + + u32 dmamr0; /* 0x100 DMA 0 mode register */ + u32 dmasr0; /* 0x104 DMA 0 status register */ + u32 dmacdar0; /* 0x108 DMA 0 current descriptor address register */ + u32 res5; /* 0x10C reserved */ + u32 dmasar0; /* 0x110 DMA 0 source address register */ + u32 res6; /* 0x114 reserved */ + u32 dmadar0; /* 0x118 DMA 0 destination address register */ + u32 res7; /* 0x11C reserved */ + u32 dmabcr0; /* 0x120 DMA 0 byte count register */ + u32 dmandar0; /* 0x124 DMA 0 next descriptor address register */ + u32 res8[0x16]; /* 0x128-0x179 reserved */ + + u32 dmamr1; /* 0x180 DMA 1 mode register */ + u32 dmasr1; /* 0x184 DMA 1 status register */ + u32 dmacdar1; /* 0x188 DMA 1 current descriptor address register */ + u32 res9; /* 0x18C reserved */ + u32 dmasar1; /* 0x190 DMA 1 source address register */ + u32 res10; /* 0x194 reserved */ + u32 dmadar1; /* 0x198 DMA 1 destination address register */ + u32 res11; /* 0x19C reserved */ + u32 dmabcr1; /* 0x1A0 DMA 1 byte count register */ + u32 dmandar1; /* 0x1A4 DMA 1 next descriptor address register */ + u32 res12[0x16];/* 0x1A8-0x199 reserved */ + + u32 dmamr2; /* 0x200 DMA 2 mode register */ + u32 dmasr2; /* 0x204 DMA 2 status register */ + u32 dmacdar2; /* 0x208 DMA 2 current descriptor address register */ + u32 res13; /* 0x20C reserved */ + u32 dmasar2; /* 0x210 DMA 2 source address register */ + u32 res14; /* 0x214 reserved */ + u32 dmadar2; /* 0x218 DMA 2 destination address register */ + u32 res15; /* 0x21C reserved */ + u32 dmabcr2; /* 0x220 DMA 2 byte count register */ + u32 dmandar2; /* 0x224 DMA 2 next descriptor address register */ + u32 res16[0x16];/* 0x228-0x279 reserved */ + + u32 dmamr3; /* 0x280 DMA 3 mode register */ + u32 dmasr3; /* 0x284 DMA 3 status register */ + u32 dmacdar3; /* 0x288 DMA 3 current descriptor address register */ + u32 res17; /* 0x28C reserved */ + u32 dmasar3; /* 0x290 DMA 3 source address register */ + u32 res18; /* 0x294 reserved */ + u32 dmadar3; /* 0x298 DMA 3 destination address register */ + u32 res19; /* 0x29C reserved */ + u32 dmabcr3; /* 0x2A0 DMA 3 byte count register */ + u32 dmandar3; /* 0x2A4 DMA 3 next descriptor address register */ + + u32 dmagsr; /* 0x2A8 DMA general status register */ + u32 res20[0x15];/* 0x2AC-0x2FF reserved */ } dma8349_t; +/* DMAMRn bits */ +#define DMA_CHANNEL_START (0x00000001) /* Bit - DMAMRn CS */ +#define DMA_CHANNEL_TRANSFER_MODE_DIRECT (0x00000004) /* Bit - DMAMRn CTM */ +#define DMA_CHANNEL_SOURCE_ADRESSS_HOLD_EN (0x00001000) /* Bit - DMAMRn SAHE */ +#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_1B (0x00000000) /* 2Bit- DMAMRn SAHTS 1byte */ +#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_2B (0x00004000) /* 2Bit- DMAMRn SAHTS 2bytes */ +#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_4B (0x00008000) /* 2Bit- DMAMRn SAHTS 4bytes */ +#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_8B (0x0000c000) /* 2Bit- DMAMRn SAHTS 8bytes */ +#define DMA_CHANNEL_SNOOP (0x00010000) /* Bit - DMAMRn DMSEN */ + +/* DMASRn bits */ +#define DMA_CHANNEL_BUSY (0x00000004) /* Bit - DMASRn CB */ +#define DMA_CHANNEL_TRANSFER_ERROR (0x00000080) /* Bit - DMASRn TE */ + /* * PCI Software Configuration Registers */ From 4c8d1ecce23b848dee028d223551a8867de627ff Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 14 Mar 2006 16:23:35 +0100 Subject: [PATCH 096/102] Add support for ECC DDR initialization on MPC83xx. --- CHANGELOG | 2 + cpu/mpc83xx/spd_sdram.c | 130 +++++++++++++++++++++++++++++++++------- 2 files changed, 110 insertions(+), 22 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 81e7cf2615..4a263837f8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add support for ECC DDR initialization on MPC83xx. + * Add DMA support for MPC83xx. * Add sync in do_reset() routine for MPC83xx after RPR register diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c index 63dcd664be..06a7da8f06 100644 --- a/cpu/mpc83xx/spd_sdram.c +++ b/cpu/mpc83xx/spd_sdram.c @@ -63,12 +63,16 @@ picos_to_clk(int picos) return clks; } -unsigned int -banksize(unsigned char row_dens) +unsigned int banksize(unsigned char row_dens) { return ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24; } +int read_spd(uint addr) +{ + return ((int) addr); +} + long int spd_sdram(int(read_spd)(uint addr)) { volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; @@ -84,7 +88,7 @@ long int spd_sdram(int(read_spd)(uint addr)) #warning Current spd_sdram does not fit its usage... adjust implementation or API... CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd)); - + if (spd.nrows > 2) { puts("DDR:Only two chip selects are supported on ADS.\n"); return 0; @@ -282,8 +286,13 @@ long int spd_sdram(int(read_spd)(uint addr)) */ #if defined(CONFIG_DDR_ECC) if (spd.config == 0x02) { - ddr->err_disable = 0x0000000d; - ddr->err_sbe = 0x00ff0000; + /* disable error detection */ + ddr->err_disable = ~ECC_ERROR_ENABLE; + + /* set single bit error threshold to maximum value, + * reset counter to zero */ + ddr->err_sbe = (255 << ECC_ERROR_MAN_SBET_SHIFT) | + (0 << ECC_ERROR_MAN_SBEC_SHIFT); } debug("DDR:err_disable=0x%08x\n", ddr->err_disable); debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe); @@ -297,7 +306,8 @@ long int spd_sdram(int(read_spd)(uint addr)) * CLK_ADJST = 2-MCK/MCK_B, is lauched 1/2 of one SDRAM * clock cycle after address/command */ - ddr->sdram_clk_cntl = 0x82000000; + /*ddr->sdram_clk_cntl = 0x82000000;*/ + ddr->sdram_clk_cntl = (DDR_SDRAM_CLK_CNTL_SS_EN|DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05); /* * Figure out the settings for the sdram_cfg register. Build up @@ -324,7 +334,7 @@ long int spd_sdram(int(read_spd)(uint addr)) * If the user wanted ECC (enabled via sdram_cfg[2]) */ if (spd.config == 0x02) { - tmp |= 0x20000000; + tmp |= SDRAM_CFG_ECC_EN; } #endif @@ -347,30 +357,88 @@ long int spd_sdram(int(read_spd)(uint addr)) #if defined(CONFIG_DDR_ECC) +/* + * Use timebase counter, get_timer() is not availabe + * at this point of initialization yet. + */ +static __inline__ unsigned long get_tbms (void) +{ + unsigned long tbl; + unsigned long tbu1, tbu2; + unsigned long ms; + unsigned long long tmp; + + ulong tbclk = get_tbclk(); + + /* get the timebase ticks */ + do { + asm volatile ("mftbu %0":"=r" (tbu1):); + asm volatile ("mftb %0":"=r" (tbl):); + asm volatile ("mftbu %0":"=r" (tbu2):); + } while (tbu1 != tbu2); + + /* convert ticks to ms */ + tmp = (unsigned long long)(tbu1); + tmp = (tmp << 32); + tmp += (unsigned long long)(tbl); + ms = tmp/(tbclk/1000); + + return ms; +} + /* * Initialize all of memory for ECC, then enable errors. */ - -void -ddr_enable_ecc(unsigned int dram_size) +//#define CONFIG_DDR_ECC_INIT_VIA_DMA +void ddr_enable_ecc(unsigned int dram_size) { -#ifndef FIXME - uint *p = 0; - uint i = 0; + uint *p; volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; - volatile ccsr_ddr_t *ddr= &immap->im_ddr; + volatile ddr8349_t *ddr = &immap->ddr; + unsigned long t_start, t_end; +#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA) + uint i; +#endif + debug("Initialize a Cachline in DRAM\n"); + icache_enable(); + +#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA) + /* Initialise DMA for direct Transfers */ dma_init(); +#endif - for (*p = 0; p < (uint *)(8 * 1024); p++) { + t_start = get_tbms(); + +#if !defined(CONFIG_DDR_ECC_INIT_VIA_DMA) + debug("DDR init: Cache flush method\n"); + for (p = 0; p < (uint *)(dram_size); p++) { if (((unsigned int)p & 0x1f) == 0) { ppcDcbz((unsigned long) p); } + + /* write pattern to cache and flush */ *p = (unsigned int)0xdeadbeef; + if (((unsigned int)p & 0x1c) == 0x1c) { ppcDcbf((unsigned long) p); } } +#else + printf("DDR init: DMA method\n"); + for (p = 0; p < (uint *)(8 * 1024); p++) { + /* zero one data cache line */ + if (((unsigned int)p & 0x1f) == 0) { + ppcDcbz((unsigned long)p); + } + + /* write pattern to it and flush */ + *p = (unsigned int)0xdeadbeef; + + if (((unsigned int)p & 0x1c) == 0x1c) { + ppcDcbf((unsigned long)p); + } + } /* 8K */ dma_xfer((uint *)0x2000, 0x2000, (uint *)0); @@ -396,13 +464,31 @@ ddr_enable_ecc(unsigned int dram_size) for (i = 1; i < dram_size / 0x800000; i++) { dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0); } - - /* - * Enable errors for ECC. - */ - ddr->err_disable = 0x00000000; - asm("sync;isync"); #endif -} + t_end = get_tbms(); + icache_disable(); + + debug("\nREADY!!\n"); + debug("ddr init duration: %ld ms\n", t_end - t_start); + + /* Clear All ECC Errors */ + if ((ddr->err_detect & ECC_ERROR_DETECT_MME) == ECC_ERROR_DETECT_MME) + ddr->err_detect |= ECC_ERROR_DETECT_MME; + if ((ddr->err_detect & ECC_ERROR_DETECT_MBE) == ECC_ERROR_DETECT_MBE) + ddr->err_detect |= ECC_ERROR_DETECT_MBE; + if ((ddr->err_detect & ECC_ERROR_DETECT_SBE) == ECC_ERROR_DETECT_SBE) + ddr->err_detect |= ECC_ERROR_DETECT_SBE; + if ((ddr->err_detect & ECC_ERROR_DETECT_MSE) == ECC_ERROR_DETECT_MSE) + ddr->err_detect |= ECC_ERROR_DETECT_MSE; + + /* Disable ECC-Interrupts */ + ddr->err_int_en &= ECC_ERR_INT_DISABLE; + + /* Enable errors for ECC */ + ddr->err_disable &= ECC_ERROR_ENABLE; + + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); +} #endif /* CONFIG_DDR_ECC */ From 991425fe0509b97f94e1177346a41e784e3f05d0 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 14 Mar 2006 16:24:38 +0100 Subject: [PATCH 097/102] Add initial support for MPC8349E MDS board. --- CHANGELOG | 2 + MAKEALL | 2 +- Makefile | 3 + board/mpc8349emds/Makefile | 46 +++ board/mpc8349emds/config.mk | 28 ++ board/mpc8349emds/mpc8349emds.c | 279 +++++++++++++ board/mpc8349emds/u-boot.lds | 123 ++++++ include/configs/MPC8349EMDS.h | 696 ++++++++++++++++++++++++++++++++ 8 files changed, 1178 insertions(+), 1 deletion(-) create mode 100644 board/mpc8349emds/Makefile create mode 100644 board/mpc8349emds/config.mk create mode 100644 board/mpc8349emds/mpc8349emds.c create mode 100644 board/mpc8349emds/u-boot.lds create mode 100644 include/configs/MPC8349EMDS.h diff --git a/CHANGELOG b/CHANGELOG index 4a263837f8..f8134ec274 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add initial support for MPC8349E MDS board. + * Add support for ECC DDR initialization on MPC83xx. * Add DMA support for MPC83xx. diff --git a/MAKEALL b/MAKEALL index 68fa954d64..e377840dd9 100755 --- a/MAKEALL +++ b/MAKEALL @@ -116,7 +116,7 @@ LIST_8260=" \ ######################################################################### LIST_83xx=" \ - MPC8349ADS TQM834x\ + MPC8349ADS TQM834x MPC8349EMDS \ " diff --git a/Makefile b/Makefile index 1a0e6c3c15..869d61f9ca 100644 --- a/Makefile +++ b/Makefile @@ -1293,6 +1293,9 @@ MPC8349ADS_config: unconfig TQM834x_config: unconfig @./mkconfig $(@:_config=) ppc mpc83xx tqm834x +MPC8349EMDS_config: unconfig + @./mkconfig $(@:_config=) ppc mpc83xx mpc8349emds + ######################################################################### ## MPC85xx Systems ######################################################################### diff --git a/board/mpc8349emds/Makefile b/board/mpc8349emds/Makefile new file mode 100644 index 0000000000..38bbb6732e --- /dev/null +++ b/board/mpc8349emds/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := $(BOARD).o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/mpc8349emds/config.mk b/board/mpc8349emds/config.mk new file mode 100644 index 0000000000..edf64d1508 --- /dev/null +++ b/board/mpc8349emds/config.mk @@ -0,0 +1,28 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# MPC8349EMDS +# + +TEXT_BASE = 0xFE000000 diff --git a/board/mpc8349emds/mpc8349emds.c b/board/mpc8349emds/mpc8349emds.c new file mode 100644 index 0000000000..cff4774206 --- /dev/null +++ b/board/mpc8349emds/mpc8349emds.c @@ -0,0 +1,279 @@ +/* + * (C) Copyright 2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_PCI) +#include +#endif +#if defined(CONFIG_SPD_EEPROM) +#include +#endif +int fixed_sdram(void); +void sdram_init(void); + +#if defined(CONFIG_DDR_ECC) && defined(CONFIG_MPC83XX) +void ddr_enable_ecc(unsigned int dram_size); +#endif + +int board_early_init_f (void) +{ + volatile u8* bcsr = (volatile u8*)CFG_BCSR; + + /* Enable flash write */ + bcsr[1] &= ~0x01; + + return 0; +} + +#define ns2clk(ns) (ns / (1000000000 / CONFIG_8349_CLKIN) + 1) + +long int initdram (int board_type) +{ + volatile immap_t *im = (immap_t *)CFG_IMMRBAR; + u32 msize = 0; + + if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im) + return -1; + + /* DDR SDRAM - Main SODIMM */ + im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR; +#if defined(CONFIG_SPD_EEPROM) + + msize = spd_sdram(0); +#else + msize = fixed_sdram(); +#endif + /* + * Initialize SDRAM if it is on local bus. + */ + sdram_init(); + +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + /* + * Initialize and enable DDR ECC. + */ + ddr_enable_ecc(msize * 1024 * 1024); +#endif + puts(" DDR RAM: "); + /* return total bus SDRAM size(bytes) -- DDR */ + return (msize * 1024 * 1024); +} + +#if !defined(CONFIG_SPD_EEPROM) +/************************************************************************* + * fixed sdram init -- doesn't use serial presence detect. + ************************************************************************/ +int fixed_sdram(void) +{ + volatile immap_t *im = (immap_t *)CFG_IMMRBAR; + u32 msize = 0; + u32 ddr_size; + u32 ddr_size_log2; + + msize = CFG_DDR_SIZE; + for (ddr_size = msize << 20, ddr_size_log2 = 0; + (ddr_size > 1); + ddr_size = ddr_size>>1, ddr_size_log2++) { + if (ddr_size & 1) { + return -1; + } + } + im->sysconf.ddrlaw[0].ar = LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE); +#if (CFG_DDR_SIZE != 256) +#warning Currenly any ddr size other than 256 is not supported +#endif + + im->ddr.csbnds[0].csbnds = 0x00100017; + im->ddr.csbnds[1].csbnds = 0x0018001f; + im->ddr.csbnds[2].csbnds = 0x00000007; + im->ddr.csbnds[3].csbnds = 0x0008000f; + im->ddr.cs_config[0] = CFG_DDR_CONFIG; + im->ddr.cs_config[1] = CFG_DDR_CONFIG; + im->ddr.cs_config[2] = CFG_DDR_CONFIG; + im->ddr.cs_config[3] = CFG_DDR_CONFIG; + im->ddr.timing_cfg_1 = + 3 << TIMING_CFG1_PRETOACT_SHIFT | + 7 << TIMING_CFG1_ACTTOPRE_SHIFT | + 3 << TIMING_CFG1_ACTTORW_SHIFT | + 4 << TIMING_CFG1_CASLAT_SHIFT | + 3 << TIMING_CFG1_REFREC_SHIFT | + 3 << TIMING_CFG1_WRREC_SHIFT | + 2 << TIMING_CFG1_ACTTOACT_SHIFT | + 1 << TIMING_CFG1_WRTORD_SHIFT; + im->ddr.timing_cfg_2 = 2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT; + im->ddr.sdram_cfg = + SDRAM_CFG_SREN +#if defined(CONFIG_DDR_2T_TIMING) + | SDRAM_CFG_2T_EN +#endif + | 2 << SDRAM_CFG_SDRAM_TYPE_SHIFT; + im->ddr.sdram_mode = + 0x2000 << SDRAM_MODE_ESD_SHIFT | + 0x0162 << SDRAM_MODE_SD_SHIFT; + + im->ddr.sdram_interval = 0x045B << SDRAM_INTERVAL_REFINT_SHIFT | + 0x0100 << SDRAM_INTERVAL_BSTOPRE_SHIFT; + udelay(200); + + im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN; + + return msize; +} +#endif/*!CFG_SPD_EEPROM*/ + + +int checkboard (void) +{ + puts("Board: Freescale MPC8349EMDS\n"); + return 0; +} + +#if defined(CONFIG_PCI) +/* + * Initialize PCI Devices, report devices found + */ +#ifndef CONFIG_PCI_PNP +static struct pci_config_table pci_mpc8349emds_config_table[] = { + {PCI_ANY_ID,PCI_ANY_ID,PCI_ANY_ID,PCI_ANY_ID, + pci_cfgfunc_config_device, {PCI_ENET0_IOADDR, + PCI_ENET0_MEMADDR, + PCI_COMMON_MEMORY | PCI_COMMAND_MASTER + } }, + {} +} +#endif + +volatile static struct pci_controller hose[] = { + { +#ifndef CONFIG_PCI_PNP + config_table:pci_mpc8349emds_config_table, +#endif + }, + { +#ifndef CONFIG_PCI_PNP + config_table:pci_mpc8349emds_config_table, +#endif + } +}; +#endif /* CONFIG_PCI */ + +void pci_init_board(void) +{ +#ifdef CONFIG_PCI + extern void pci_mpc83xx_init(volatile struct pci_controller *hose); + + pci_mpc83xx_init(hose); +#endif /* CONFIG_PCI */ +} + +/* + * if MPC8349EMDS is soldered with SDRAM + */ +#if defined(CFG_BR2_PRELIM) \ + && defined(CFG_OR2_PRELIM) \ + && defined(CFG_LBLAWBAR2_PRELIM) \ + && defined(CFG_LBLAWAR2_PRELIM) +/* + * Initialize SDRAM memory on the Local Bus. + */ + +void sdram_init(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; + volatile lbus8349_t *lbc= &immap->lbus; + uint *sdram_addr = (uint *)CFG_LBC_SDRAM_BASE; + + puts("\n SDRAM on Local Bus: "); + print_size (CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n"); + + /* + * Setup SDRAM Base and Option Registers, already done in cpu_init.c + */ + + /* setup mtrpt, lsrt and lbcr for LB bus */ + lbc->lbcr = CFG_LBC_LBCR; + lbc->mrtpr = CFG_LBC_MRTPR; + lbc->lsrt = CFG_LBC_LSRT; + asm("sync"); + + /* + * Configure the SDRAM controller Machine Mode Register. + */ + lbc->lsdmr = CFG_LBC_LSDMR_5; /* 0x40636733; normal operation */ + + lbc->lsdmr = CFG_LBC_LSDMR_1; /* 0x68636733; precharge all the banks */ + asm("sync"); + *sdram_addr = 0xff; + udelay(100); + + lbc->lsdmr = CFG_LBC_LSDMR_2; /* 0x48636733; auto refresh */ + asm("sync"); + /*1 times*/ + *sdram_addr = 0xff; + udelay(100); + /*2 times*/ + *sdram_addr = 0xff; + udelay(100); + /*3 times*/ + *sdram_addr = 0xff; + udelay(100); + /*4 times*/ + *sdram_addr = 0xff; + udelay(100); + /*5 times*/ + *sdram_addr = 0xff; + udelay(100); + /*6 times*/ + *sdram_addr = 0xff; + udelay(100); + /*7 times*/ + *sdram_addr = 0xff; + udelay(100); + /*8 times*/ + *sdram_addr = 0xff; + udelay(100); + + /* 0x58636733; mode register write operation */ + lbc->lsdmr = CFG_LBC_LSDMR_4; + asm("sync"); + *sdram_addr = 0xff; + udelay(100); + + lbc->lsdmr = CFG_LBC_LSDMR_5; /* 0x40636733; normal operation */ + asm("sync"); + *sdram_addr = 0xff; + udelay(100); +} +#else +void sdram_init(void) +{ + put("SDRAM on Local Bus is NOT available!\n"); +} +#endif diff --git a/board/mpc8349emds/u-boot.lds b/board/mpc8349emds/u-boot.lds new file mode 100644 index 0000000000..937c87a27c --- /dev/null +++ b/board/mpc8349emds/u-boot.lds @@ -0,0 +1,123 @@ +/* + * (C) Copyright 2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + cpu/mpc83xx/start.o (.text) + *(.text) + *(.fixup) + *(.got1) + . = ALIGN(16); + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} +ENTRY(_start) diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h new file mode 100644 index 0000000000..ef2eced3f3 --- /dev/null +++ b/include/configs/MPC8349EMDS.h @@ -0,0 +1,696 @@ +/* + * (C) Copyright 2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * mpc8349emds board configuration file + * + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define DEBUG +#undef DEBUG + +/* + * High Level Configuration Options + */ +#define CONFIG_E300 1 /* E300 Family */ +#define CONFIG_MPC83XX 1 /* MPC83XX family */ +#define CONFIG_MPC8349 1 /* MPC8349 specific */ +#define CONFIG_MPC8349EMDS 1 /* MPC8349EMDS board specific */ + +/* FIXME: Real PCI support will come in a follow-up update. */ +#undef CONFIG_PCI + +#define PCI_66M +#ifdef PCI_66M +#define CONFIG_83XX_CLKIN 66000000 /* in Hz */ +#else +#define CONFIG_83XX_CLKIN 33000000 /* in Hz */ +#endif + +#ifndef CONFIG_SYS_CLK_FREQ +#ifdef PCI_66M +#define CONFIG_SYS_CLK_FREQ 66000000 +#else +#define CONFIG_SYS_CLK_FREQ 33000000 +#endif +#endif + +#define CONFIG_BOARD_EARLY_INIT_F /* call board_pre_init */ + +#define CFG_IMMRBAR 0xE0000000 + +#undef CFG_DRAM_TEST /* memory test, takes time */ +#define CFG_MEMTEST_START 0x00000000 /* memtest region */ +#define CFG_MEMTEST_END 0x00100000 + +/* + * DDR Setup + */ +#define CONFIG_DDR_ECC /* only for ECC DDR module */ +#define CONFIG_SPD_EEPROM /* use SPD EEPROM for DDR setup*/ + +#define CFG_DDR_BASE 0x00000000 /* DDR is system memory*/ +#define CFG_SDRAM_BASE CFG_DDR_BASE +#define CFG_DDR_SDRAM_BASE CFG_DDR_BASE +#undef CONFIG_DDR_2T_TIMING + +#if defined(CONFIG_SPD_EEPROM) + /* + * Determine DDR configuration from I2C interface. + */ + #define SPD_EEPROM_ADDRESS 0x51 /* DDR DIMM */ +#else + /* + * Manually set up DDR parameters + */ + #define CFG_DDR_SIZE 128 /* Mb */ + #define CFG_DDR_CONFIG (CSCONFIG_EN | CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_9) + #define CFG_DDR_TIMING_1 0x37344321 + #define CFG_DDR_TIMING_2 0x00000800 /* P9-45,may need tuning */ + #define CFG_DDR_CONTROL 0xc2000000 /* unbuffered,no DYN_PWR */ + #define CFG_DDR_MODE 0x00000062 /* DLL,normal,seq,4/2.5 */ + #define CFG_DDR_INTERVAL 0x05200100 /* autocharge,no open page */ +#endif + +/* + * SDRAM on the Local Bus + */ +#define CFG_LBC_SDRAM_BASE 0xF0000000 /* Localbus SDRAM */ +#define CFG_LBC_SDRAM_SIZE 64 /* LBC SDRAM is 64MB */ + +/* + * FLASH on the Local Bus + */ +#define CFG_FLASH_CFI /* use the Common Flash Interface */ +#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CFG_FLASH_BASE 0xFE000000 /* start of FLASH */ +#define CFG_FLASH_SIZE 8 /* flash size in MB */ +/* #define CFG_FLASH_USE_BUFFER_WRITE */ + +#define CFG_BR0_PRELIM (CFG_FLASH_BASE | /* flash Base address */ \ + (2 << BR_PS_SHIFT) | /* 32 bit port size */ \ + BR_V) /* valid */ + +#define CFG_OR0_PRELIM 0xFF806FF7 /* 8 MB flash size */ +#define CFG_LBLAWBAR0_PRELIM CFG_FLASH_BASE /* window base at flash base */ +#define CFG_LBLAWAR0_PRELIM 0x80000016 /* 8 MB window size */ + +#define CFG_MAX_FLASH_BANKS 1 /* number of banks */ +#define CFG_MAX_FLASH_SECT 64 /* sectors per device */ + +#undef CFG_FLASH_CHECKSUM +#define CFG_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ + +#define CFG_MID_FLASH_JUMP 0x7F000000 +#define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ + +#if (CFG_MONITOR_BASE < CFG_FLASH_BASE) +#define CFG_RAMBOOT +#else +#undef CFG_RAMBOOT +#endif + +/* + * BCSR register on local bus 32KB, 8-bit wide for MDS config reg + */ +#define CFG_BCSR 0xF8000000 +#define CFG_LBLAWBAR1_PRELIM CFG_BCSR /* Access window base at BCSR base */ +#define CFG_LBLAWAR1_PRELIM 0x8000000E /* Access window size 32K */ +#define CFG_BR1_PRELIM (CFG_BCSR|0x00000801) /* Port-size=8bit, MSEL=GPCM */ +#define CFG_OR1_PRELIM 0xFFFFE8F0 /* length 32K */ + +#define CONFIG_L1_INIT_RAM +#define CFG_INIT_RAM_LOCK 1 +#define CFG_INIT_RAM_ADDR 0xE8000000 /* Initial RAM address */ +#define CFG_INIT_RAM_END 0x1000 /* End of used area in RAM*/ + +#define CFG_GBL_DATA_SIZE 0x100 /* num bytes initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Mon */ +#define CFG_MALLOC_LEN (128 * 1024) /* Reserved for malloc */ + +/* + * Local Bus LCRR and LBCR regs + * LCRR: DLL bypass, Clock divider is 4 + * External Local Bus rate is + * CLKIN * HRCWL_CSB_TO_CLKIN / HRCWL_LCL_BUS_TO_SCB_CLK / LCRR_CLKDIV + */ +#define CFG_LCRR (LCRR_DBYP | LCRR_CLKDIV_4) +#define CFG_LBC_LBCR 0x00000000 + +#define CFG_LB_SDRAM /* if board has SRDAM on local bus */ + +#ifdef CFG_LB_SDRAM +/* Local bus BR2, OR2 definition for SDRAM if soldered on the MDS board */ +/* + * Base Register 2 and Option Register 2 configure SDRAM. + * The SDRAM base address, CFG_LBC_SDRAM_BASE, is 0xf0000000. + * + * For BR2, need: + * Base address of 0xf0000000 = BR[0:16] = 1111 0000 0000 0000 0 + * port-size = 32-bits = BR2[19:20] = 11 + * no parity checking = BR2[21:22] = 00 + * SDRAM for MSEL = BR2[24:26] = 011 + * Valid = BR[31] = 1 + * + * 0 4 8 12 16 20 24 28 + * 1111 0000 0000 0000 0001 1000 0110 0001 = F0001861 + * + * FIXME: CFG_LBC_SDRAM_BASE should be masked and OR'ed into + * FIXME: the top 17 bits of BR2. + */ + +#define CFG_BR2_PRELIM 0xF0001861 /* Port-size=32bit, MSEL=SDRAM */ +#define CFG_LBLAWBAR2_PRELIM 0xF0000000 +#define CFG_LBLAWAR2_PRELIM 0x80000019 /* 64M */ + +/* + * The SDRAM size in MB, CFG_LBC_SDRAM_SIZE, is 64. + * + * For OR2, need: + * 64MB mask for AM, OR2[0:7] = 1111 1100 + * XAM, OR2[17:18] = 11 + * 9 columns OR2[19-21] = 010 + * 13 rows OR2[23-25] = 100 + * EAD set for extra time OR[31] = 1 + * + * 0 4 8 12 16 20 24 28 + * 1111 1100 0000 0000 0110 1001 0000 0001 = FC006901 + */ + +#define CFG_OR2_PRELIM 0xFC006901 + +#define CFG_LBC_LSRT 0x32000000 /* LB sdram refresh timer, about 6us */ +#define CFG_LBC_MRTPR 0x20000000 /* LB refresh timer prescal, 266MHz/32 */ + +/* + * LSDMR masks + */ +#define CFG_LBC_LSDMR_RFEN (1 << (31 - 1)) +#define CFG_LBC_LSDMR_BSMA1516 (3 << (31 - 10)) +#define CFG_LBC_LSDMR_BSMA1617 (4 << (31 - 10)) +#define CFG_LBC_LSDMR_RFCR5 (3 << (31 - 16)) +#define CFG_LBC_LSDMR_RFCR8 (5 << (31 - 16)) +#define CFG_LBC_LSDMR_RFCR16 (7 << (31 - 16)) +#define CFG_LBC_LSDMR_PRETOACT3 (3 << (31 - 19)) +#define CFG_LBC_LSDMR_PRETOACT6 (5 << (31 - 19)) +#define CFG_LBC_LSDMR_PRETOACT7 (7 << (31 - 19)) +#define CFG_LBC_LSDMR_ACTTORW3 (3 << (31 - 22)) +#define CFG_LBC_LSDMR_ACTTORW7 (7 << (31 - 22)) +#define CFG_LBC_LSDMR_ACTTORW6 (6 << (31 - 22)) +#define CFG_LBC_LSDMR_BL8 (1 << (31 - 23)) +#define CFG_LBC_LSDMR_WRC2 (2 << (31 - 27)) +#define CFG_LBC_LSDMR_WRC3 (3 << (31 - 27)) +#define CFG_LBC_LSDMR_WRC4 (0 << (31 - 27)) +#define CFG_LBC_LSDMR_BUFCMD (1 << (31 - 29)) +#define CFG_LBC_LSDMR_CL3 (3 << (31 - 31)) + +#define CFG_LBC_LSDMR_OP_NORMAL (0 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_ARFRSH (1 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_SRFRSH (2 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_MRW (3 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_PRECH (4 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_PCHALL (5 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_ACTBNK (6 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_RWINV (7 << (31 - 4)) + +#define CFG_LBC_LSDMR_COMMON ( CFG_LBC_LSDMR_RFEN \ + | CFG_LBC_LSDMR_BSMA1516 \ + | CFG_LBC_LSDMR_RFCR8 \ + | CFG_LBC_LSDMR_PRETOACT6 \ + | CFG_LBC_LSDMR_ACTTORW3 \ + | CFG_LBC_LSDMR_BL8 \ + | CFG_LBC_LSDMR_WRC3 \ + | CFG_LBC_LSDMR_CL3 \ + ) + +/* + * SDRAM Controller configuration sequence. + */ +#define CFG_LBC_LSDMR_1 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_PCHALL) +#define CFG_LBC_LSDMR_2 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_ARFRSH) +#define CFG_LBC_LSDMR_3 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_ARFRSH) +#define CFG_LBC_LSDMR_4 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_MRW) +#define CFG_LBC_LSDMR_5 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_NORMAL) +#endif + +/* + * Serial Port + */ +#define CONFIG_CONS_INDEX 1 +#undef CONFIG_SERIAL_SOFTWARE_FIFO +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE 1 +#define CFG_NS16550_CLK get_bus_freq(0) + +#define CFG_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200} + +#define CFG_NS16550_COM1 (CFG_IMMRBAR+0x4500) +#define CFG_NS16550_COM2 (CFG_IMMRBAR+0x4600) + +/* Use the HUSH parser */ +#define CFG_HUSH_PARSER +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif + +/* I2C */ +#define CONFIG_HARD_I2C /* I2C with hardware support*/ +#undef CONFIG_SOFT_I2C /* I2C bit-banged */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F +#define CFG_I2C_NOPROBES {0x69} /* Don't probe these addrs */ +#define CFG_I2C_OFFSET 0x3000 +#define CFG_I2C2_OFFSET 0x3100 + +/* TSEC */ +#define CFG_TSEC1_OFFSET 0x24000 +#define CFG_TSEC1 (CFG_IMMRBAR+CFG_TSEC1_OFFSET) +#define CFG_TSEC2_OFFSET 0x25000 +#define CFG_TSEC2 (CFG_IMMRBAR+CFG_TSEC2_OFFSET) + +/* IO Configuration */ +#define CFG_IO_CONF (\ + IO_CONF_UART |\ + IO_CONF_TSEC1 |\ + IO_CONF_IRQ0 |\ + IO_CONF_IRQ1 |\ + IO_CONF_IRQ2 |\ + IO_CONF_IRQ3 |\ + IO_CONF_IRQ4 |\ + IO_CONF_IRQ5 |\ + IO_CONF_IRQ6 |\ + IO_CONF_IRQ7 ) + +/* + * General PCI + * Addresses are mapped 1-1. + */ +#define CFG_PCI1_MEM_BASE 0x80000000 +#define CFG_PCI1_MEM_PHYS CFG_PCI1_MEM_BASE +#define CFG_PCI1_MEM_SIZE 0x20000000 /* 512M */ +#define CFG_PCI1_IO_BASE 0x00000000 +#define CFG_PCI1_IO_PHYS 0xe2000000 +#define CFG_PCI1_IO_SIZE 0x1000000 /* 16M */ + +#define CFG_PCI2_MEM_BASE 0xA0000000 +#define CFG_PCI2_MEM_PHYS CFG_PCI2_MEM_BASE +#define CFG_PCI2_MEM_SIZE 0x20000000 /* 512M */ +#define CFG_PCI2_IO_BASE 0x00000000 +#define CFG_PCI2_IO_PHYS 0xe3000000 +#define CFG_PCI2_IO_SIZE 0x1000000 /* 16M */ + +#if defined(CONFIG_PCI) + +#define PCI_ALL_PCI1 +#if defined(PCI_64BIT) +#undef PCI_ALL_PCI1 +#undef PCI_TWO_PCI1 +#undef PCI_ONE_PCI1 +#endif + +#define CONFIG_NET_MULTI +#define CONFIG_PCI_PNP /* do pci plug-and-play */ + +#undef CONFIG_EEPRO100 +#undef CONFIG_TULIP + +#if !defined(CONFIG_PCI_PNP) + #define PCI_ENET0_IOADDR 0xFIXME + #define PCI_ENET0_MEMADDR 0xFIXME + #define PCI_IDSEL_NUMBER 0x0c /* slot0->3(IDSEL)=12->15 */ +#endif + +#undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ +#define CFG_PCI_SUBSYS_VENDORID 0x1057 /* Motorola */ + +#endif /* CONFIG_PCI */ + +/* + * TSEC configuration + */ +#define CONFIG_TSEC_ENET /* TSEC ethernet support */ + +#if defined(CONFIG_TSEC_ENET) +#ifndef CONFIG_NET_MULTI +#define CONFIG_NET_MULTI 1 +#endif + +#define CONFIG_GMII 1 /* MII PHY management */ +#define CONFIG_MPC83XX_TSEC1 1 +#define CONFIG_MPC83XX_TSEC1_NAME "TSEC0" +#define CONFIG_MPC83XX_TSEC2 1 +#define CONFIG_MPC83XX_TSEC2_NAME "TSEC1" +#define TSEC1_PHY_ADDR 0 +#define TSEC2_PHY_ADDR 1 +#define TSEC1_PHYIDX 0 +#define TSEC2_PHYIDX 0 + +/* Options are: TSEC[0-1] */ +#define CONFIG_ETHPRIME "TSEC0" + +#endif /* CONFIG_TSEC_ENET */ + +/* + * Configure on-board RTC + */ +#define CONFIG_RTC_DS1374 /* use ds1374 rtc via i2c */ +#define CFG_I2C_RTC_ADDR 0x68 /* at address 0x68 */ + +/* + * Environment + */ +#ifndef CFG_RAMBOOT + #define CFG_ENV_IS_IN_FLASH 1 + #define CFG_ENV_ADDR (CFG_MONITOR_BASE + 0x40000) + #define CFG_ENV_SECT_SIZE 0x20000 /* 128K(one sector) for env */ + #define CFG_ENV_SIZE 0x2000 + +/* Address and size of Redundant Environment Sector */ +#define CFG_ENV_ADDR_REDUND (CFG_ENV_ADDR + CFG_ENV_SECT_SIZE) +#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE) + +#else + #define CFG_NO_FLASH 1 /* Flash is not usable now */ + #define CFG_ENV_IS_NOWHERE 1 /* Store ENV in memory only */ + #define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x1000) + #define CFG_ENV_SIZE 0x2000 +#endif + +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + +#if defined(CFG_RAMBOOT) +#if defined(CONFIG_PCI) +#define CONFIG_COMMANDS ((CONFIG_CMD_DFL \ + | CFG_CMD_PING \ + | CFG_CMD_PCI \ + | CFG_CMD_I2C \ + | CFG_CMD_DATE) \ + & \ + ~(CFG_CMD_ENV \ + | CFG_CMD_LOADS)) +#else +#define CONFIG_COMMANDS ((CONFIG_CMD_DFL \ + | CFG_CMD_PING \ + | CFG_CMD_I2C \ + | CFG_CMD_DATE) \ + & \ + ~(CFG_CMD_ENV \ + | CFG_CMD_LOADS)) +#endif +#else +#if defined(CONFIG_PCI) +#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ + | CFG_CMD_PCI \ + | CFG_CMD_PING \ + | CFG_CMD_I2C \ + | CFG_CMD_DATE \ + ) +#else +#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ + | CFG_CMD_PING \ + | CFG_CMD_I2C \ + | CFG_CMD_MII \ + | CFG_CMD_DATE \ + ) +#endif +#endif + +#include + +#undef CONFIG_WATCHDOG /* watchdog disabled */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_LOAD_ADDR 0x2000000 /* default load address */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + #define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else + #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif + +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_HZ 1000 /* decrementer freq: 1ms ticks */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux*/ + +/* Cache Configuration */ +#define CFG_DCACHE_SIZE 32768 +#define CFG_CACHELINE_SIZE 32 +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CACHELINE_SHIFT 5 /*log base 2 of the above value*/ +#endif + +#define CFG_RCWH_PCIHOST 0x80000000 /* PCIHOST */ + +#if 1 /*528/264*/ +#define CFG_HRCW_LOW (\ + HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\ + HRCWL_DDR_TO_SCB_CLK_1X1 |\ + HRCWL_CSB_TO_CLKIN_4X1 |\ + HRCWL_VCO_1X2 |\ + HRCWL_CORE_TO_CSB_2X1) +#elif 0 /*396/132*/ +#define CFG_HRCW_LOW (\ + HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\ + HRCWL_DDR_TO_SCB_CLK_1X1 |\ + HRCWL_CSB_TO_CLKIN_2X1 |\ + HRCWL_VCO_1X4 |\ + HRCWL_CORE_TO_CSB_3X1) +#elif 0 /*264/132*/ +#define CFG_HRCW_LOW (\ + HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\ + HRCWL_DDR_TO_SCB_CLK_1X1 |\ + HRCWL_CSB_TO_CLKIN_2X1 |\ + HRCWL_VCO_1X4 |\ + HRCWL_CORE_TO_CSB_2X1) +#elif 0 /*132/132*/ +#define CFG_HRCW_LOW (\ + HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\ + HRCWL_DDR_TO_SCB_CLK_1X1 |\ + HRCWL_CSB_TO_CLKIN_2X1 |\ + HRCWL_VCO_1X4 |\ + HRCWL_CORE_TO_CSB_1X1) +#elif 0 /*264/264 */ +#define CFG_HRCW_LOW (\ + HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\ + HRCWL_DDR_TO_SCB_CLK_1X1 |\ + HRCWL_CSB_TO_CLKIN_4X1 |\ + HRCWL_VCO_1X4 |\ + HRCWL_CORE_TO_CSB_1X1) +#endif + +#if defined(PCI_64BIT) +#define CFG_HRCW_HIGH (\ + HRCWH_PCI_HOST |\ + HRCWH_64_BIT_PCI |\ + HRCWH_PCI1_ARBITER_ENABLE |\ + HRCWH_PCI2_ARBITER_DISABLE |\ + HRCWH_CORE_ENABLE |\ + HRCWH_FROM_0X00000100 |\ + HRCWH_BOOTSEQ_DISABLE |\ + HRCWH_SW_WATCHDOG_DISABLE |\ + HRCWH_ROM_LOC_LOCAL_16BIT |\ + HRCWH_TSEC1M_IN_GMII |\ + HRCWH_TSEC2M_IN_GMII ) +#else +#define CFG_HRCW_HIGH (\ + HRCWH_PCI_HOST |\ + HRCWH_32_BIT_PCI |\ + HRCWH_PCI1_ARBITER_ENABLE |\ + HRCWH_PCI2_ARBITER_ENABLE |\ + HRCWH_CORE_ENABLE |\ + HRCWH_FROM_0X00000100 |\ + HRCWH_BOOTSEQ_DISABLE |\ + HRCWH_SW_WATCHDOG_DISABLE |\ + HRCWH_ROM_LOC_LOCAL_16BIT |\ + HRCWH_TSEC1M_IN_GMII |\ + HRCWH_TSEC2M_IN_GMII ) +#endif + +/* System IO Config */ +#define CFG_SICRH SICRH_TSOBI1 +#define CFG_SICRL SICRL_LDP_A + +#define CFG_HID0_INIT 0x000000000 +#define CFG_HID0_FINAL CFG_HID0_INIT + +/* #define CFG_HID0_FINAL (\ + HID0_ENABLE_INSTRUCTION_CACHE |\ + HID0_ENABLE_M_BIT |\ + HID0_ENABLE_ADDRESS_BROADCAST ) */ + + +#define CFG_HID2 HID2_HBE + +/* DDR @ 0x00000000 */ +#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) + +/* PCI @ 0x80000000 */ +#ifdef CONFIG_PCI +#define CFG_IBAT1L (CFG_PCI1_MEM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT1U (CFG_PCI1_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_IBAT2L (CFG_PCI1_MMIO_BASE | BATL_PP_10 | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_IBAT2U (CFG_PCI1_MMIO_BASE | BATU_BL_256M | BATU_VS | BATU_VP) +#else +#define CFG_IBAT1L (0) +#define CFG_IBAT1U (0) +#define CFG_IBAT2L (0) +#define CFG_IBAT2U (0) +#endif + +/* IMMRBAR @ 0xE0000000 */ +#define CFG_IBAT3L (CFG_IMMRBAR | BATL_PP_10 | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_IBAT3U (CFG_IMMRBAR | BATU_BL_1M | BATU_VS | BATU_VP) + +/* stack in DCACHE (no backing mem) @ 0xE8000000 */ +#define CFG_IBAT4L (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT4U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP) + +/* LBC SDRAM @ 0xF0000000 */ +#define CFG_IBAT5L (CFG_LBC_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT5U (CFG_LBC_SDRAM_BASE | BATU_BL_64M | BATU_VS | BATU_VP) + +/* BCSR @ 0xF8000000 */ +#define CFG_IBAT6L (CFG_BCSR | BATL_PP_10 | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_IBAT6U (CFG_BCSR | BATU_BL_128K | BATU_VS | BATU_VP) + +/* FLASH @ 0xFE000000 */ +#define CFG_IBAT7L (CFG_FLASH_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT7U (CFG_FLASH_BASE | BATU_BL_8M | BATU_VS | BATU_VP) + +#define CFG_DBAT0L CFG_IBAT0L +#define CFG_DBAT0U CFG_IBAT0U +#define CFG_DBAT1L CFG_IBAT1L +#define CFG_DBAT1U CFG_IBAT1U +#define CFG_DBAT2L CFG_IBAT2L +#define CFG_DBAT2U CFG_IBAT2U +#define CFG_DBAT3L CFG_IBAT3L +#define CFG_DBAT3U CFG_IBAT3U +#define CFG_DBAT4L CFG_IBAT4L +#define CFG_DBAT4U CFG_IBAT4U +#define CFG_DBAT5L CFG_IBAT5L +#define CFG_DBAT5U CFG_IBAT5U +#define CFG_DBAT6L CFG_IBAT6L +#define CFG_DBAT6U CFG_IBAT6U +#define CFG_DBAT7L CFG_IBAT7L +#define CFG_DBAT7U CFG_IBAT7U + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed of kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + +/* + * Environment Configuration + */ +#define CONFIG_ENV_OVERWRITE + +#if defined(CONFIG_TSEC_ENET) +#define CONFIG_ETHADDR 00:04:9f:ef:23:33 +#define CONFIG_HAS_ETH1 +#define CONFIG_ETH1ADDR 00:E0:0C:00:7E:21 +#endif + +#define CONFIG_IPADDR 192.168.205.5 + +#define CONFIG_HOSTNAME mpc8349emds +#define CONFIG_ROOTPATH /opt/eldk/ppc_6xx +#define CONFIG_BOOTFILE /tftpboot/tqm83xx/uImage + +#define CONFIG_SERVERIP 192.168.1.1 +#define CONFIG_GATEWAYIP 192.168.1.1 +#define CONFIG_NETMASK 255.255.255.0 + +#define CONFIG_LOADADDR 200000 /* default location for tftp and bootm */ + +#define CONFIG_BOOTDELAY 6 /* -1 disables auto-boot */ +#undef CONFIG_BOOTARGS /* the boot command will set bootargs */ + +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_PREBOOT "echo;" \ + "echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \ + "echo" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "netdev=eth0\0" \ + "hostname=mpc8349emds\0" \ + "nfsargs=setenv bootargs root=/dev/nfs rw " \ + "nfsroot=${serverip}:${rootpath}\0" \ + "ramargs=setenv bootargs root=/dev/ram rw\0" \ + "addip=setenv bootargs ${bootargs} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \ + ":${hostname}:${netdev}:off panic=1\0" \ + "addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\0"\ + "flash_nfs=run nfsargs addip addtty;" \ + "bootm ${kernel_addr}\0" \ + "flash_self=run ramargs addip addtty;" \ + "bootm ${kernel_addr} ${ramdisk_addr}\0" \ + "net_nfs=tftp 200000 ${bootfile};run nfsargs addip addtty;" \ + "bootm\0" \ + "rootpath=/opt/eldk/ppc_6xx\0" \ + "bootfile=/tftpboot/mpc8349emds/uImage\0" \ + "load=tftp 100000 /tftpboot/mpc8349emds/u-boot.bin\0" \ + "update=protect off fe000000 fe03ffff; " \ + "era fe000000 fe03ffff; cp.b 100000 fe000000 ${filesize}\0" \ + "upd=run load;run update\0" \ + "" + +#define CONFIG_BOOTCOMMAND "run flash_self" + +#endif /* __CONFIG_H */ From 97f98001a325558020128381e1bebf893c811617 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 16 Mar 2006 14:35:32 +0100 Subject: [PATCH 098/102] Fix DDR ECC bit definitions for MPC83xx. --- CHANGELOG | 2 ++ include/asm-ppc/immap_83xx.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f8134ec274..e8f4f66f18 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Fix DDR ECC bit definitions for MPC83xx. + * Add initial support for MPC8349E MDS board. * Add support for ECC DDR initialization on MPC83xx. diff --git a/include/asm-ppc/immap_83xx.h b/include/asm-ppc/immap_83xx.h index b0e17ab9be..c2b4c5c6ab 100644 --- a/include/asm-ppc/immap_83xx.h +++ b/include/asm-ppc/immap_83xx.h @@ -686,13 +686,13 @@ typedef struct ddr8349{ u32 ecc_err_inject; /**< Memory Data Path Error Injection Mask ECC */ #define ECC_ERR_INJECT_EMB (0x80000000>>22) /* ECC Mirror Byte */ #define ECC_ERR_INJECT_EIEN (0x80000000>>23) /* Error Injection Enable */ -#define ECC_ERR_INJECT_EEIM (0xF0000000>>24) /* ECC Erroe Injection Enable */ +#define ECC_ERR_INJECT_EEIM (0xff000000>>24) /* ECC Erroe Injection Enable */ #define ECC_ERR_INJECT_EEIM_SHIFT 0 u8 res5[0x14]; u32 capture_data_hi; /**< Memory Data Path Read Capture High */ u32 capture_data_lo; /**< Memory Data Path Read Capture Low */ u32 capture_ecc; /**< Memory Data Path Read Capture ECC */ -#define CAPTURE_ECC_ECE (0xF0000000>>24) +#define CAPTURE_ECC_ECE (0xff000000>>24) #define CAPTURE_ECC_ECE_SHIFT 0 u8 res6[0x14]; u32 err_detect; /**< Memory Error Detect */ From d326f4a242971928ef5a6efb411a604b0478ef1c Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 16 Mar 2006 15:19:35 +0100 Subject: [PATCH 099/102] Add command for handling DDR ECC registers on MPC8349EE MDS board. --- CHANGELOG | 2 + board/mpc8349emds/mpc8349emds.c | 327 ++++++++++++++++++++++++++++++++ doc/README.mpc8349emds.ddrecc | 135 +++++++++++++ include/configs/MPC8349EMDS.h | 1 + 4 files changed, 465 insertions(+) create mode 100644 doc/README.mpc8349emds.ddrecc diff --git a/CHANGELOG b/CHANGELOG index e8f4f66f18..9274bdb357 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add command for handling DDR ECC registers on MPC8349EE MDS board. + * Fix DDR ECC bit definitions for MPC83xx. * Add initial support for MPC8349E MDS board. diff --git a/board/mpc8349emds/mpc8349emds.c b/board/mpc8349emds/mpc8349emds.c index cff4774206..a468c5a7b5 100644 --- a/board/mpc8349emds/mpc8349emds.c +++ b/board/mpc8349emds/mpc8349emds.c @@ -29,6 +29,7 @@ #include #include #include +#include #if defined(CONFIG_PCI) #include #endif @@ -277,3 +278,329 @@ void sdram_init(void) put("SDRAM on Local Bus is NOT available!\n"); } #endif + +#if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) +/* + * ECC user commands + */ +void ecc_print_status(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; + volatile ddr8349_t *ddr = &immap->ddr; + + printf("\nECC mode: %s\n\n", (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF"); + + /* Interrupts */ + printf("Memory Error Interrupt Enable:\n"); + printf(" Multiple-Bit Error Interrupt Enable: %d\n", + (ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0); + printf(" Single-Bit Error Interrupt Enable: %d\n", + (ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0); + printf(" Memory Select Error Interrupt Enable: %d\n\n", + (ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0); + + /* Error disable */ + printf("Memory Error Disable:\n"); + printf(" Multiple-Bit Error Disable: %d\n", + (ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0); + printf(" Sinle-Bit Error Disable: %d\n", + (ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0); + printf(" Memory Select Error Disable: %d\n\n", + (ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0); + + /* Error injection */ + printf("Memory Data Path Error Injection Mask High/Low: %08lx %08lx\n", + ddr->data_err_inject_hi, ddr->data_err_inject_lo); + + printf("Memory Data Path Error Injection Mask ECC:\n"); + printf(" ECC Mirror Byte: %d\n", + (ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0); + printf(" ECC Injection Enable: %d\n", + (ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0); + printf(" ECC Error Injection Mask: 0x%02x\n\n", + ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM); + + /* SBE counter/threshold */ + printf("Memory Single-Bit Error Management (0..255):\n"); + printf(" Single-Bit Error Threshold: %d\n", + (ddr->err_sbe & ECC_ERROR_MAN_SBET) >> ECC_ERROR_MAN_SBET_SHIFT); + printf(" Single-Bit Error Counter: %d\n\n", + (ddr->err_sbe & ECC_ERROR_MAN_SBEC) >> ECC_ERROR_MAN_SBEC_SHIFT); + + /* Error detect */ + printf("Memory Error Detect:\n"); + printf(" Multiple Memory Errors: %d\n", + (ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0); + printf(" Multiple-Bit Error: %d\n", + (ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0); + printf(" Single-Bit Error: %d\n", + (ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0); + printf(" Memory Select Error: %d\n\n", + (ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0); + + /* Capture data */ + printf("Memory Error Address Capture: 0x%08lx\n", ddr->capture_address); + printf("Memory Data Path Read Capture High/Low: %08lx %08lx\n", + ddr->capture_data_hi, ddr->capture_data_lo); + printf("Memory Data Path Read Capture ECC: 0x%02x\n\n", + ddr->capture_ecc & CAPTURE_ECC_ECE); + + printf("Memory Error Attributes Capture:\n"); + printf(" Data Beat Number: %d\n", + (ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >> ECC_CAPT_ATTR_BNUM_SHIFT); + printf(" Transaction Size: %d\n", + (ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >> ECC_CAPT_ATTR_TSIZ_SHIFT); + printf(" Transaction Source: %d\n", + (ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >> ECC_CAPT_ATTR_TSRC_SHIFT); + printf(" Transaction Type: %d\n", + (ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >> ECC_CAPT_ATTR_TTYP_SHIFT); + printf(" Error Information Valid: %d\n\n", + ddr->capture_attributes & ECC_CAPT_ATTR_VLD); +} + +int do_ecc ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; + volatile ddr8349_t *ddr = &immap->ddr; + volatile u32 val; + u64 *addr, count, val64; + register u64 *i; + + if (argc > 4) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + if (argc == 2) { + if (strcmp(argv[1], "status") == 0) { + ecc_print_status(); + return 0; + } else if (strcmp(argv[1], "captureclear") == 0) { + ddr->capture_address = 0; + ddr->capture_data_hi = 0; + ddr->capture_data_lo = 0; + ddr->capture_ecc = 0; + ddr->capture_attributes = 0; + return 0; + } + } + + if (argc == 3) { + if (strcmp(argv[1], "sbecnt") == 0) { + val = simple_strtoul(argv[2], NULL, 10); + if (val > 255) { + printf("Incorrect Counter value, should be 0..255\n"); + return 1; + } + + val = (val << ECC_ERROR_MAN_SBEC_SHIFT); + val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET); + + ddr->err_sbe = val; + return 0; + } else if (strcmp(argv[1], "sbethr") == 0) { + val = simple_strtoul(argv[2], NULL, 10); + if (val > 255) { + printf("Incorrect Counter value, should be 0..255\n"); + return 1; + } + + val = (val << ECC_ERROR_MAN_SBET_SHIFT); + val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC); + + ddr->err_sbe = val; + return 0; + } else if (strcmp(argv[1], "errdisable") == 0) { + val = ddr->err_disable; + + if (strcmp(argv[2], "+sbe") == 0) { + val |= ECC_ERROR_DISABLE_SBED; + } else if (strcmp(argv[2], "+mbe") == 0) { + val |= ECC_ERROR_DISABLE_MBED; + } else if (strcmp(argv[2], "+mse") == 0) { + val |= ECC_ERROR_DISABLE_MSED; + } else if (strcmp(argv[2], "+all") == 0) { + val |= (ECC_ERROR_DISABLE_SBED | + ECC_ERROR_DISABLE_MBED | + ECC_ERROR_DISABLE_MSED); + } else if (strcmp(argv[2], "-sbe") == 0) { + val &= ~ECC_ERROR_DISABLE_SBED; + } else if (strcmp(argv[2], "-mbe") == 0) { + val &= ~ECC_ERROR_DISABLE_MBED; + } else if (strcmp(argv[2], "-mse") == 0) { + val &= ~ECC_ERROR_DISABLE_MSED; + } else if (strcmp(argv[2], "-all") == 0) { + val &= ~(ECC_ERROR_DISABLE_SBED | + ECC_ERROR_DISABLE_MBED | + ECC_ERROR_DISABLE_MSED); + } else { + printf("Incorrect err_disable field\n"); + return 1; + } + + ddr->err_disable = val; + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); + return 0; + } else if (strcmp(argv[1], "errdetectclr") == 0) { + val = ddr->err_detect; + + if (strcmp(argv[2], "mme") == 0) { + val |= ECC_ERROR_DETECT_MME; + } else if (strcmp(argv[2], "sbe") == 0) { + val |= ECC_ERROR_DETECT_SBE; + } else if (strcmp(argv[2], "mbe") == 0) { + val |= ECC_ERROR_DETECT_MBE; + } else if (strcmp(argv[2], "mse") == 0) { + val |= ECC_ERROR_DETECT_MSE; + } else if (strcmp(argv[2], "all") == 0) { + val |= (ECC_ERROR_DETECT_MME | + ECC_ERROR_DETECT_MBE | + ECC_ERROR_DETECT_SBE | + ECC_ERROR_DETECT_MSE); + } else { + printf("Incorrect err_detect field\n"); + return 1; + } + + ddr->err_detect = val; + return 0; + } else if (strcmp(argv[1], "injectdatahi") == 0) { + val = simple_strtoul(argv[2], NULL, 16); + + ddr->data_err_inject_hi = val; + return 0; + } else if (strcmp(argv[1], "injectdatalo") == 0) { + val = simple_strtoul(argv[2], NULL, 16); + + ddr->data_err_inject_lo = val; + return 0; + } else if (strcmp(argv[1], "injectecc") == 0) { + val = simple_strtoul(argv[2], NULL, 16); + if (val > 0xff) { + printf("Incorrect ECC inject mask, should be 0x00..0xff\n"); + return 1; + } + val |= (ddr->ecc_err_inject & ~ECC_ERR_INJECT_EEIM); + + ddr->ecc_err_inject = val; + return 0; + } else if (strcmp(argv[1], "inject") == 0) { + val = ddr->ecc_err_inject; + + if (strcmp(argv[2], "en") == 0) + val |= ECC_ERR_INJECT_EIEN; + else if (strcmp(argv[2], "dis") == 0) + val &= ~ECC_ERR_INJECT_EIEN; + else + printf("Incorrect command\n"); + + ddr->ecc_err_inject = val; + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); + return 0; + } else if (strcmp(argv[1], "mirror") == 0) { + val = ddr->ecc_err_inject; + + if (strcmp(argv[2], "en") == 0) + val |= ECC_ERR_INJECT_EMB; + else if (strcmp(argv[2], "dis") == 0) + val &= ~ECC_ERR_INJECT_EMB; + else + printf("Incorrect command\n"); + + ddr->ecc_err_inject = val; + return 0; + } + } + + if (argc == 4) { + if (strcmp(argv[1], "test") == 0) { + addr = (u64 *)simple_strtoul(argv[2], NULL, 16); + count = simple_strtoul(argv[3], NULL, 16); + + if ((u32)addr % 8) { + printf("Address not alligned on double word boundary\n"); + return 1; + } + + disable_interrupts(); + icache_disable(); + + for (i = addr; i < addr + count; i++) { + /* enable injects */ + ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN; + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); + + /* write memory location injecting errors */ + *i = 0x1122334455667788ULL; + __asm__ __volatile__ ("sync"); + + /* disable injects */ + ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN; + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); + + /* read data, this generates ECC error */ + val64 = *i; + __asm__ __volatile__ ("sync"); + + /* disable errors for ECC */ + ddr->err_disable |= ~ECC_ERROR_ENABLE; + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); + + /* re-initialize memory, write the location again + * NOT injecting errors this time */ + *i = 0xcafecafecafecafeULL; + __asm__ __volatile__ ("sync"); + + /* enable errors for ECC */ + ddr->err_disable &= ECC_ERROR_ENABLE; + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("isync"); + } + + icache_enable(); + enable_interrupts(); + + return 0; + } + } + + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; +} + +U_BOOT_CMD( + ecc, 4, 0, do_ecc, + "ecc - support for DDR ECC features\n", + "status - print out status info\n" + "ecc captureclear - clear capture regs data\n" + "ecc sbecnt - set Single-Bit Error counter\n" + "ecc sbethr - set Single-Bit Threshold\n" + "ecc errdisable - clear/set disable Memory Error Disable, flag:\n" + " [-|+]sbe - Single-Bit Error\n" + " [-|+]mbe - Multiple-Bit Error\n" + " [-|+]mse - Memory Select Error\n" + " [-|+]all - all errors\n" + "ecc errdetectclr - clear Memory Error Detect, flag:\n" + " mme - Multiple Memory Errors\n" + " sbe - Single-Bit Error\n" + " mbe - Multiple-Bit Error\n" + " mse - Memory Select Error\n" + " all - all errors\n" + "ecc injectdatahi - set Memory Data Path Error Injection Mask High\n" + "ecc injectdatalo - set Memory Data Path Error Injection Mask Low\n" + "ecc injectecc - set ECC Error Injection Mask\n" + "ecc inject - enable/disable error injection\n" + "ecc mirror - enable/disable mirror byte\n" + "ecc test - test mem region:\n" + " - enables injects\n" + " - writes pattern injecting errors\n" + " - disables injects\n" + " - reads pattern back, generates error\n" + " - re-inits memory" +); +#endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */ diff --git a/doc/README.mpc8349emds.ddrecc b/doc/README.mpc8349emds.ddrecc new file mode 100644 index 0000000000..d8edada565 --- /dev/null +++ b/doc/README.mpc8349emds.ddrecc @@ -0,0 +1,135 @@ + + +Use cases for DDR 'ecc' command: +================================ + +Before executing particular tests reset target board or clear status registers: + +=> ecc captureclear +=> ecc errdetectclr all +=> ecc sbecnt 0 + + +Injecting Single-Bit Errors +--------------------------- + +1. Set 1 bit in Data Path Error Inject Mask + +=> ecc injectdatahi 1 + +2. Run test over some memory region + +=> ecc test 200000 10 + +3. Check ECC status + +=> ecc status +... +Memory Data Path Error Injection Mask High/Low: 00000001 00000000 +... +Memory Single-Bit Error Management (0..255): + Single-Bit Error Threshold: 255 + Single Bit Error Counter: 16 +... +Memory Error Detect: + Multiple Memory Errors: 0 + Multiple-Bit Error: 0 + Single-Bit Error: 0 +... + +16 errors were generated, Single-Bit Error flag was not set as Single Bit Error +Counter did not reach Single-Bit Error Threshold. + +4. Make sure used memory region got re-initialized with 0xcafecafe pattern + +=> md 200000 +00200000: cafecafe cafecafe cafecafe cafecafe ................ +00200010: cafecafe cafecafe cafecafe cafecafe ................ +00200020: cafecafe cafecafe cafecafe cafecafe ................ +00200030: cafecafe cafecafe cafecafe cafecafe ................ +00200040: cafecafe cafecafe cafecafe cafecafe ................ +00200050: cafecafe cafecafe cafecafe cafecafe ................ +00200060: cafecafe cafecafe cafecafe cafecafe ................ +00200070: cafecafe cafecafe cafecafe cafecafe ................ +00200080: deadbeef deadbeef deadbeef deadbeef ................ +00200090: deadbeef deadbeef deadbeef deadbeef ................ + + +Injecting Multiple-Bit Errors +----------------------------- + +1. Set more than 1 bit in Data Path Error Inject Mask + +=> ecc injectdatahi 5 + +2. Run test over some memory region + +=> ecc test 200000 10 + +3. Check ECC status + +=> ecc status +... +Memory Data Path Error Injection Mask High/Low: 00000005 00000000 +... +Memory Error Detect: + Multiple Memory Errors: 1 + Multiple-Bit Error: 1 + Single-Bit Error: 0 +... + +Observe that both Multiple Memory Errors and Multiple-Bit Error flags are set. + +4. Make sure used memory region got re-initialized with 0xcafecafe pattern + +=> md 200000 +00200000: cafecafe cafecafe cafecafe cafecafe ................ +00200010: cafecafe cafecafe cafecafe cafecafe ................ +00200020: cafecafe cafecafe cafecafe cafecafe ................ +00200030: cafecafe cafecafe cafecafe cafecafe ................ +00200040: cafecafe cafecafe cafecafe cafecafe ................ +00200050: cafecafe cafecafe cafecafe cafecafe ................ +00200060: cafecafe cafecafe cafecafe cafecafe ................ +00200070: cafecafe cafecafe cafecafe cafecafe ................ +00200080: deadbeef deadbeef deadbeef deadbeef ................ +00200090: deadbeef deadbeef deadbeef deadbeef ................ + + +Test Single-Bit Error Counter and Threshold +------------------------------------------- + +1. Set 1 bit in Data Path Error Inject Mask + +=> ecc injectdatahi 1 + +2. Enable error injection + +=> ecc inject en + +3. Let u-boot run for a with Single-Bit error injection enabled + +4. Disable error injection + +=> ecc inject dis + +4. Check status + +=> ecc status + +... +Memory Single-Bit Error Management (0..255): + Single-Bit Error Threshold: 255 + Single Bit Error Counter: 60 + +Memory Error Detect: + Multiple Memory Errors: 1 + Multiple-Bit Error: 0 + Single-Bit Error: 1 +... + +Observe that Single-Bit Error is 'on' which means that Single-Bit Error Counter +reached Single-Bit Error Threshold. Multiple Memory Errors bit is also 'on', that +is Counter reached Threshold more than one time (it wraps back after reaching +Threshold). + + diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h index ef2eced3f3..c2bd0f5cea 100644 --- a/include/configs/MPC8349EMDS.h +++ b/include/configs/MPC8349EMDS.h @@ -70,6 +70,7 @@ * DDR Setup */ #define CONFIG_DDR_ECC /* only for ECC DDR module */ +#define CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */ #define CONFIG_SPD_EEPROM /* use SPD EEPROM for DDR setup*/ #define CFG_DDR_BASE 0x00000000 /* DDR is system memory*/ From dc9e499c620a590e0f906e807e24c85807af3338 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Thu, 16 Mar 2006 17:46:46 +0100 Subject: [PATCH 100/102] Support for DDR with 32-data path. Addotional notes on injecting multiple-bit errors. --- board/mpc8349emds/mpc8349emds.c | 48 ++++++++++++-------------- cpu/mpc83xx/spd_sdram.c | 61 ++++++++++++++++++++++++++------- doc/README.mpc8349emds.ddrecc | 21 ++++++++++++ include/configs/MPC8349EMDS.h | 47 +++++++++++++++++-------- include/spd_sdram.h | 2 +- 5 files changed, 126 insertions(+), 53 deletions(-) diff --git a/board/mpc8349emds/mpc8349emds.c b/board/mpc8349emds/mpc8349emds.c index a468c5a7b5..73a33f68ce 100644 --- a/board/mpc8349emds/mpc8349emds.c +++ b/board/mpc8349emds/mpc8349emds.c @@ -63,11 +63,12 @@ long int initdram (int board_type) if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im) return -1; + puts("Initializing\n"); + /* DDR SDRAM - Main SODIMM */ im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR; #if defined(CONFIG_SPD_EEPROM) - - msize = spd_sdram(0); + msize = spd_sdram(); #else msize = fixed_sdram(); #endif @@ -106,45 +107,40 @@ int fixed_sdram(void) return -1; } } + im->sysconf.ddrlaw[0].bar = ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff); im->sysconf.ddrlaw[0].ar = LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE); + #if (CFG_DDR_SIZE != 256) #warning Currenly any ddr size other than 256 is not supported #endif - - im->ddr.csbnds[0].csbnds = 0x00100017; - im->ddr.csbnds[1].csbnds = 0x0018001f; - im->ddr.csbnds[2].csbnds = 0x00000007; - im->ddr.csbnds[3].csbnds = 0x0008000f; - im->ddr.cs_config[0] = CFG_DDR_CONFIG; - im->ddr.cs_config[1] = CFG_DDR_CONFIG; + im->ddr.csbnds[2].csbnds = 0x0000000f; im->ddr.cs_config[2] = CFG_DDR_CONFIG; - im->ddr.cs_config[3] = CFG_DDR_CONFIG; - im->ddr.timing_cfg_1 = - 3 << TIMING_CFG1_PRETOACT_SHIFT | - 7 << TIMING_CFG1_ACTTOPRE_SHIFT | - 3 << TIMING_CFG1_ACTTORW_SHIFT | - 4 << TIMING_CFG1_CASLAT_SHIFT | - 3 << TIMING_CFG1_REFREC_SHIFT | - 3 << TIMING_CFG1_WRREC_SHIFT | - 2 << TIMING_CFG1_ACTTOACT_SHIFT | - 1 << TIMING_CFG1_WRTORD_SHIFT; - im->ddr.timing_cfg_2 = 2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT; + + /* currently we use only one CS, so disable the other banks */ + im->ddr.cs_config[0] = 0; + im->ddr.cs_config[1] = 0; + im->ddr.cs_config[3] = 0; + + im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1; + im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2; + im->ddr.sdram_cfg = SDRAM_CFG_SREN #if defined(CONFIG_DDR_2T_TIMING) | SDRAM_CFG_2T_EN #endif | 2 << SDRAM_CFG_SDRAM_TYPE_SHIFT; - im->ddr.sdram_mode = - 0x2000 << SDRAM_MODE_ESD_SHIFT | - 0x0162 << SDRAM_MODE_SD_SHIFT; +#if defined (CONFIG_DDR_32BIT) + /* for 32-bit mode burst length is 8 */ + im->ddr.sdram_cfg |= (SDRAM_CFG_32_BE | SDRAM_CFG_8_BE); +#endif + im->ddr.sdram_mode = CFG_DDR_MODE; - im->ddr.sdram_interval = 0x045B << SDRAM_INTERVAL_REFINT_SHIFT | - 0x0100 << SDRAM_INTERVAL_BSTOPRE_SHIFT; + im->ddr.sdram_interval = CFG_DDR_INTERVAL; udelay(200); + /* enable DDR controller */ im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN; - return msize; } #endif/*!CFG_SPD_EEPROM*/ diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c index 06a7da8f06..b4012a8ddf 100644 --- a/cpu/mpc83xx/spd_sdram.c +++ b/cpu/mpc83xx/spd_sdram.c @@ -1,4 +1,7 @@ /* + * (C) Copyright 2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * * Copyright 2004 Freescale Semiconductor. * (C) Copyright 2003 Motorola Inc. * Xianghua Xiao (X.Xiao@motorola.com) @@ -73,7 +76,32 @@ int read_spd(uint addr) return ((int) addr); } -long int spd_sdram(int(read_spd)(uint addr)) +#undef SPD_DEBUG +#ifdef SPD_DEBUG +static void spd_debug(spd_eeprom_t *spd) +{ + printf ("\nDIMM type: %-18.18s\n", spd->mpart); + printf ("SPD size: %d\n", spd->info_size); + printf ("EEPROM size: %d\n", 1 << spd->chip_size); + printf ("Memory type: %d\n", spd->mem_type); + printf ("Row addr: %d\n", spd->nrow_addr); + printf ("Column addr: %d\n", spd->ncol_addr); + printf ("# of rows: %d\n", spd->nrows); + printf ("Row density: %d\n", spd->row_dens); + printf ("# of banks: %d\n", spd->nbanks); + printf ("Data width: %d\n", + 256 * spd->dataw_msb + spd->dataw_lsb); + printf ("Chip width: %d\n", spd->primw); + printf ("Refresh rate: %02X\n", spd->refresh); + printf ("CAS latencies: %02X\n", spd->cas_lat); + printf ("Write latencies: %02X\n", spd->write_lat); + printf ("tRP: %d\n", spd->trp); + printf ("tRCD: %d\n", spd->trcd); + printf ("\n"); +} +#endif /* SPD_DEBUG */ + +long int spd_sdram() { volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; volatile ddr8349_t *ddr = &immap->ddr; @@ -85,10 +113,10 @@ long int spd_sdram(int(read_spd)(uint addr)) unsigned char caslat; unsigned int trfc, trfc_clk, trfc_low; -#warning Current spd_sdram does not fit its usage... adjust implementation or API... - CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd)); - +#ifdef SPD_DEBUG + spd_debug(&spd); +#endif if (spd.nrows > 2) { puts("DDR:Only two chip selects are supported on ADS.\n"); return 0; @@ -223,25 +251,31 @@ long int spd_sdram(int(read_spd)(uint addr)) * Only DDR I is supported * DDR I and II have different mode-register-set definition */ - - /* burst length is always 4 */ switch(caslat) { case 2: - ddr->sdram_mode = 0x52; /* 1.5 */ + tmp = 0x50; /* 1.5 */ break; case 3: - ddr->sdram_mode = 0x22; /* 2.0 */ + tmp = 0x20; /* 2.0 */ break; case 4: - ddr->sdram_mode = 0x62; /* 2.5 */ + tmp = 0x60; /* 2.5 */ break; case 5: - ddr->sdram_mode = 0x32; /* 3.0 */ + tmp = 0x30; /* 3.0 */ break; default: puts("DDR:only CAS Latency 1.5, 2.0, 2.5, 3.0 is supported.\n"); return 0; } +#if defined (CONFIG_DDR_32BIT) + /* set burst length to 8 for 32-bit data path */ + tmp |= 0x03; +#else + /* set burst length to 4 - default for 64-bit data path */ + tmp |= 0x02; +#endif + ddr->sdram_mode = tmp; debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode); switch(spd.refresh) { @@ -321,6 +355,10 @@ long int spd_sdram(int(read_spd)(uint addr)) */ tmp = 0xc2000000; +#if defined (CONFIG_DDR_32BIT) + /* in 32-Bit mode burst len is 8 beats */ + tmp |= (SDRAM_CFG_32_BE | SDRAM_CFG_8_BE); +#endif /* * sdram_cfg[3] = RD_EN - registered DIMM enable * A value of 0x26 indicates micron registered DIMMS (micron.com) @@ -350,8 +388,7 @@ long int spd_sdram(int(read_spd)(uint addr)) udelay(500); debug("DDR:sdram_cfg=0x%08x\n", ddr->sdram_cfg); - - return memsize;/*in MBytes*/ + return memsize; /*in MBytes*/ } #endif /* CONFIG_SPD_EEPROM */ diff --git a/doc/README.mpc8349emds.ddrecc b/doc/README.mpc8349emds.ddrecc index d8edada565..401c0b687d 100644 --- a/doc/README.mpc8349emds.ddrecc +++ b/doc/README.mpc8349emds.ddrecc @@ -1,3 +1,24 @@ +Overview +======== + +The overall usage pattern for ECC diagnostic commands is the following: + + * (injecting errors is initially disabled) + + * define inject mask (which tells the DDR controller what type of errors + we'll be injecting: single/multiple bit etc.) + + * enable injecting errors - from now on the controller injects errors as + indicated in the inject mask + +IMPORTANT NOTICE: enabling injecting multiple-bit errors is potentially +dangerous as such errors are NOT corrected by the controller. Therefore caution +should be taken when enabling the injection of multiple-bit errors: it is only +safe when used on a carefully selected memory area and used under control of +the 'ecc test' command (see example 'Injecting Multiple-Bit Errors' below). In +particular, when you simply set the multiple-bit errors in inject mask and +enable injection, U-Boot is very likely to hang quickly as the errors will be +injected when it accesses its code, data etc. Use cases for DDR 'ecc' command: diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h index c2bd0f5cea..39e3d95c30 100644 --- a/include/configs/MPC8349EMDS.h +++ b/include/configs/MPC8349EMDS.h @@ -73,27 +73,46 @@ #define CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */ #define CONFIG_SPD_EEPROM /* use SPD EEPROM for DDR setup*/ +/* + * 32-bit data path mode. + * + * Please note that using this mode for devices with the real density of 64-bit + * effectively reduces the amount of available memory due to the effect of + * wrapping around while translating address to row/columns, for example in the + * 256MB module the upper 128MB get aliased with contents of the lower + * 128MB); normally this define should be used for devices with real 32-bit + * data path. + */ +#undef CONFIG_DDR_32BIT + #define CFG_DDR_BASE 0x00000000 /* DDR is system memory*/ #define CFG_SDRAM_BASE CFG_DDR_BASE #define CFG_DDR_SDRAM_BASE CFG_DDR_BASE #undef CONFIG_DDR_2T_TIMING #if defined(CONFIG_SPD_EEPROM) - /* - * Determine DDR configuration from I2C interface. - */ - #define SPD_EEPROM_ADDRESS 0x51 /* DDR DIMM */ +/* + * Determine DDR configuration from I2C interface. + */ +#define SPD_EEPROM_ADDRESS 0x51 /* DDR DIMM */ #else - /* - * Manually set up DDR parameters - */ - #define CFG_DDR_SIZE 128 /* Mb */ - #define CFG_DDR_CONFIG (CSCONFIG_EN | CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_9) - #define CFG_DDR_TIMING_1 0x37344321 - #define CFG_DDR_TIMING_2 0x00000800 /* P9-45,may need tuning */ - #define CFG_DDR_CONTROL 0xc2000000 /* unbuffered,no DYN_PWR */ - #define CFG_DDR_MODE 0x00000062 /* DLL,normal,seq,4/2.5 */ - #define CFG_DDR_INTERVAL 0x05200100 /* autocharge,no open page */ +/* + * Manually set up DDR parameters + */ +#define CFG_DDR_SIZE 256 /* MB */ +#define CFG_DDR_CONFIG (CSCONFIG_EN | CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_10) +#define CFG_DDR_TIMING_1 0x36332321 +#define CFG_DDR_TIMING_2 0x00000800 /* P9-45,may need tuning */ +#define CFG_DDR_CONTROL 0xc2000000 /* unbuffered,no DYN_PWR */ +#define CFG_DDR_INTERVAL 0x04060100 /* autocharge,no open page */ + +#if defined(CONFIG_DDR_32BIT) +/* set burst length to 8 for 32-bit data path */ +#define CFG_DDR_MODE 0x00000023 /* DLL,normal,seq,4/2.5, 8 burst len */ +#else +/* the default burst length is 4 - for 64-bit data path */ +#define CFG_DDR_MODE 0x00000022 /* DLL,normal,seq,4/2.5, 4 burst len */ +#endif #endif /* diff --git a/include/spd_sdram.h b/include/spd_sdram.h index 4e754ec9e3..a2be96c1aa 100644 --- a/include/spd_sdram.h +++ b/include/spd_sdram.h @@ -1,6 +1,6 @@ #ifndef _SPD_SDRAM_H_ #define _SPD_SDRAM_H_ -long int spd_sdram(int(read_spd)(uint addr)); +long int spd_sdram(void); #endif From 09e4b0c5d3881412519f33d498560a5bbcc82cd9 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Fri, 17 Mar 2006 11:42:53 +0100 Subject: [PATCH 101/102] Add support for Lite5200B board. Patch by Patch by Jose Maria (Txema) Lopez, 16 Jan 2006 --- CHANGELOG | 3 ++ MAKEALL | 7 ++-- Makefile | 14 +++++++ README | 76 ++++++++++++++++++------------------ board/icecube/flash.c | 2 + board/icecube/icecube.c | 13 ++++-- board/icecube/mt46v32m16.h | 37 ++++++++++++++++++ board/mpc8349ads/pci.c | 12 +++--- fs/jffs2/jffs2_private.h | 4 +- include/configs/IceCube.h | 49 ++++++++++++++++++++++- include/configs/RPXlite_DW.h | 58 +++++++++++++-------------- 11 files changed, 192 insertions(+), 83 deletions(-) create mode 100644 board/icecube/mt46v32m16.h diff --git a/CHANGELOG b/CHANGELOG index 1322c854f0..3f969c8bba 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Add support for Lite5200B board. + Patch by Patch by Jose Maria (Txema) Lopez, 16 Jan 2006 + * Apply SoC concept to arm926ejs CPUs, i.e. move the SoC specific timer and cpu_reset code from cpu/$(CPU) into the new cpu/$(CPU)/$(SOC) directories diff --git a/MAKEALL b/MAKEALL index 68fa954d64..72fef88ceb 100755 --- a/MAKEALL +++ b/MAKEALL @@ -25,9 +25,10 @@ LIST_5xx=" \ ######################################################################### LIST_5xxx=" \ - cpci5200 icecube_5100 icecube_5200 EVAL5200 \ - mcc200 o2dnt pf5200 PM520 \ - Total5100 Total5200 Total5200_Rev2 TQM5200_auto \ + cpci5200 EVAL5200 icecube_5100 icecube_5200 \ + lite5200b mcc200 o2dnt pf5200 \ + PM520 Total5100 Total5200 Total5200_Rev2 \ + TQM5200_auto \ " ######################################################################### diff --git a/Makefile b/Makefile index 1a0e6c3c15..a1c663f1d3 100644 --- a/Makefile +++ b/Makefile @@ -303,6 +303,20 @@ icecube_5100_config: unconfig inka4x0_config: unconfig @./mkconfig inka4x0 ppc mpc5xxx inka4x0 +lite5200b_config \ +lite5200b_LOWBOOT_config: unconfig + @ >include/config.h + @ echo "#define CONFIG_MPC5200_DDR" >>include/config.h + @ echo "... DDR memory revision" + @ echo "#define CONFIG_MPC5200" >>include/config.h + @ echo "#define CONFIG_LITE5200B" >>include/config.h + @[ -z "$(findstring LOWBOOT_,$@)" ] || \ + { echo "TEXT_BASE = 0xFF000000" >board/icecube/config.tmp ; \ + echo "... with LOWBOOT configuration" ; \ + } + @ echo "... with MPC5200B processor" + @./mkconfig -a IceCube ppc mpc5xxx icecube + mcc200_config \ mcc200_lowboot_config: unconfig @ >include/config.h diff --git a/README b/README index b6cb9810c6..38fbfbf0f5 100644 --- a/README +++ b/README @@ -261,44 +261,44 @@ The following options need to be configured: PowerPC based boards: --------------------- - CONFIG_ADCIOP CONFIG_GEN860T CONFIG_PCIPPC2 - CONFIG_ADS860 CONFIG_GENIETV CONFIG_PCIPPC6 - CONFIG_AMX860 CONFIG_GTH CONFIG_pcu_e - CONFIG_AP1000 CONFIG_gw8260 CONFIG_PIP405 - CONFIG_AR405 CONFIG_hermes CONFIG_PM826 - CONFIG_BAB7xx CONFIG_hymod CONFIG_ppmc8260 - CONFIG_c2mon CONFIG_IAD210 CONFIG_QS823 - CONFIG_CANBT CONFIG_ICU862 CONFIG_QS850 - CONFIG_CCM CONFIG_IP860 CONFIG_QS860T - CONFIG_CMI CONFIG_IPHASE4539 CONFIG_RBC823 - CONFIG_cogent_mpc8260 CONFIG_IVML24 CONFIG_RPXClassic - CONFIG_cogent_mpc8xx CONFIG_IVML24_128 CONFIG_RPXlite - CONFIG_CPCI405 CONFIG_IVML24_256 CONFIG_RPXsuper - CONFIG_CPCI4052 CONFIG_IVMS8 CONFIG_rsdproto - CONFIG_CPCIISER4 CONFIG_IVMS8_128 CONFIG_sacsng - CONFIG_CPU86 CONFIG_IVMS8_256 CONFIG_Sandpoint8240 - CONFIG_CRAYL1 CONFIG_JSE CONFIG_Sandpoint8245 - CONFIG_CSB272 CONFIG_LANTEC CONFIG_sbc8260 - CONFIG_CU824 CONFIG_lwmon CONFIG_sbc8560 - CONFIG_DASA_SIM CONFIG_MBX CONFIG_SM850 - CONFIG_DB64360 CONFIG_MBX860T CONFIG_SPD823TS - CONFIG_DB64460 CONFIG_MHPC CONFIG_STXGP3 - CONFIG_DU405 CONFIG_MIP405 CONFIG_SXNI855T - CONFIG_DUET_ADS CONFIG_MOUSSE CONFIG_TQM823L - CONFIG_EBONY CONFIG_MPC8260ADS CONFIG_TQM8260 - CONFIG_ELPPC CONFIG_MPC8540ADS CONFIG_TQM850L - CONFIG_ELPT860 CONFIG_MPC8540EVAL CONFIG_TQM855L - CONFIG_ep8260 CONFIG_MPC8560ADS CONFIG_TQM860L - CONFIG_ERIC CONFIG_MUSENKI CONFIG_TTTech - CONFIG_ESTEEM192E CONFIG_MVS1 CONFIG_UTX8245 - CONFIG_ETX094 CONFIG_NETPHONE CONFIG_V37 - CONFIG_EVB64260 CONFIG_NETTA CONFIG_W7OLMC - CONFIG_FADS823 CONFIG_NETVIA CONFIG_W7OLMG - CONFIG_FADS850SAR CONFIG_NX823 CONFIG_WALNUT - CONFIG_FADS860T CONFIG_OCRTC CONFIG_ZPC1900 - CONFIG_FLAGADM CONFIG_ORSG CONFIG_ZUMA - CONFIG_FPS850L CONFIG_OXC - CONFIG_FPS860L CONFIG_PCI405 + CONFIG_ADCIOP CONFIG_GEN860T CONFIG_PCI405 + CONFIG_ADS860 CONFIG_GENIETV CONFIG_PCIPPC2 + CONFIG_AMX860 CONFIG_GTH CONFIG_PCIPPC6 + CONFIG_AP1000 CONFIG_gw8260 CONFIG_pcu_e + CONFIG_AR405 CONFIG_hermes CONFIG_PIP405 + CONFIG_BAB7xx CONFIG_hymod CONFIG_PM826 + CONFIG_c2mon CONFIG_IAD210 CONFIG_ppmc8260 + CONFIG_CANBT CONFIG_ICU862 CONFIG_QS823 + CONFIG_CCM CONFIG_IP860 CONFIG_QS850 + CONFIG_CMI CONFIG_IPHASE4539 CONFIG_QS860T + CONFIG_cogent_mpc8260 CONFIG_IVML24 CONFIG_RBC823 + CONFIG_cogent_mpc8xx CONFIG_IVML24_128 CONFIG_RPXClassic + CONFIG_CPCI405 CONFIG_IVML24_256 CONFIG_RPXlite + CONFIG_CPCI4052 CONFIG_IVMS8 CONFIG_RPXsuper + CONFIG_CPCIISER4 CONFIG_IVMS8_128 CONFIG_rsdproto + CONFIG_CPU86 CONFIG_IVMS8_256 CONFIG_sacsng + CONFIG_CRAYL1 CONFIG_JSE CONFIG_Sandpoint8240 + CONFIG_CSB272 CONFIG_LANTEC CONFIG_Sandpoint8245 + CONFIG_CU824 CONFIG_LITE5200B CONFIG_sbc8260 + CONFIG_DASA_SIM CONFIG_lwmon CONFIG_sbc8560 + CONFIG_DB64360 CONFIG_MBX CONFIG_SM850 + CONFIG_DB64460 CONFIG_MBX860T CONFIG_SPD823TS + CONFIG_DU405 CONFIG_MHPC CONFIG_STXGP3 + CONFIG_DUET_ADS CONFIG_MIP405 CONFIG_SXNI855T + CONFIG_EBONY CONFIG_MOUSSE CONFIG_TQM823L + CONFIG_ELPPC CONFIG_MPC8260ADS CONFIG_TQM8260 + CONFIG_ELPT860 CONFIG_MPC8540ADS CONFIG_TQM850L + CONFIG_ep8260 CONFIG_MPC8540EVAL CONFIG_TQM855L + CONFIG_ERIC CONFIG_MPC8560ADS CONFIG_TQM860L + CONFIG_ESTEEM192E CONFIG_MUSENKI CONFIG_TTTech + CONFIG_ETX094 CONFIG_MVS1 CONFIG_UTX8245 + CONFIG_EVB64260 CONFIG_NETPHONE CONFIG_V37 + CONFIG_FADS823 CONFIG_NETTA CONFIG_W7OLMC + CONFIG_FADS850SAR CONFIG_NETVIA CONFIG_W7OLMG + CONFIG_FADS860T CONFIG_NX823 CONFIG_WALNUT + CONFIG_FLAGADM CONFIG_OCRTC CONFIG_ZPC1900 + CONFIG_FPS850L CONFIG_ORSG CONFIG_ZUMA + CONFIG_FPS860L CONFIG_OXC ARM based boards: ----------------- diff --git a/board/icecube/flash.c b/board/icecube/flash.c index 713011c972..15e86d34f3 100644 --- a/board/icecube/flash.c +++ b/board/icecube/flash.c @@ -23,6 +23,7 @@ #include +#ifndef CFG_FLASH_CFI_DRIVER flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ /* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it @@ -489,3 +490,4 @@ static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data) return (res); } +#endif /*CFG_FLASH_CFI_DRIVER*/ diff --git a/board/icecube/icecube.c b/board/icecube/icecube.c index 1f1a74ce33..44831c625a 100644 --- a/board/icecube/icecube.c +++ b/board/icecube/icecube.c @@ -28,12 +28,15 @@ #include #include -#if defined(CONFIG_MPC5200_DDR) -#include "mt46v16m16-75.h" +#if defined(CONFIG_LITE5200B) +#include "mt46v32m16.h" #else +# if defined(CONFIG_MPC5200_DDR) +# include "mt46v16m16-75.h" +# else #include "mt48lc16m16a2-75.h" +# endif #endif - #ifndef CFG_RAMBOOT static void sdram_start (int hi_addr) { @@ -236,7 +239,9 @@ long int initdram (int board_type) int checkboard (void) { -#if defined(CONFIG_MPC5200) +#if defined (CONFIG_LITE5200B) + puts ("Board: Freescale Lite5200B\n"); +#elif defined(CONFIG_MPC5200) puts ("Board: Motorola MPC5200 (IceCube)\n"); #elif defined(CONFIG_MGT5100) puts ("Board: Motorola MGT5100 (IceCube)\n"); diff --git a/board/icecube/mt46v32m16.h b/board/icecube/mt46v32m16.h new file mode 100644 index 0000000000..de2b48bc60 --- /dev/null +++ b/board/icecube/mt46v32m16.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2004 + * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#define SDRAM_DDR 1 /* is DDR */ + +#if defined(CONFIG_MPC5200) +/* Settings for XLB = 132 MHz */ +#define SDRAM_MODE 0x018D0000 +#define SDRAM_EMODE 0x40090000 +#define SDRAM_CONTROL 0x704f0f00 +#define SDRAM_CONFIG1 0x73722930 +#define SDRAM_CONFIG2 0x47770000 +#define SDRAM_TAPDELAY 0x10000000 + +#else +#error CONFIG_MPC5200 not defined +#endif diff --git a/board/mpc8349ads/pci.c b/board/mpc8349ads/pci.c index 6cafbaa0eb..c5594248d8 100644 --- a/board/mpc8349ads/pci.c +++ b/board/mpc8349ads/pci.c @@ -246,9 +246,9 @@ pci_init_board(void) /* System memory space */ pci_set_region(hose->regions + 3, CONFIG_PCI_SYS_MEM_BUS, - CONFIG_PCI_SYS_MEM_PHYS, - gd->ram_size, - PCI_REGION_MEM | PCI_REGION_MEMORY); + CONFIG_PCI_SYS_MEM_PHYS, + gd->ram_size, + PCI_REGION_MEM | PCI_REGION_MEMORY); hose->region_count = 4; @@ -342,9 +342,9 @@ pci_init_board(void) /* System memory space */ pci_set_region(hose->regions + 3, CONFIG_PCI_SYS_MEM_BUS, - CONFIG_PCI_SYS_MEM_PHYS, - gd->ram_size, - PCI_REGION_MEM | PCI_REGION_MEMORY); + CONFIG_PCI_SYS_MEM_PHYS, + gd->ram_size, + PCI_REGION_MEM | PCI_REGION_MEMORY); hose->region_count = 4; diff --git a/fs/jffs2/jffs2_private.h b/fs/jffs2/jffs2_private.h index 3e1fff4739..46ed644e4d 100644 --- a/fs/jffs2/jffs2_private.h +++ b/fs/jffs2/jffs2_private.h @@ -89,8 +89,8 @@ static inline int data_crc(struct jffs2_raw_inode *node) { if (node->data_crc != crc32_no_comp(0, (unsigned char *) - ((int) &node->node_crc + sizeof (node->node_crc)), - node->csize)) { + ((int) &node->node_crc + sizeof (node->node_crc)), + node->csize)) { return 0; } else { return 1; diff --git a/include/configs/IceCube.h b/include/configs/IceCube.h index afba5c625e..596e52ce3c 100644 --- a/include/configs/IceCube.h +++ b/include/configs/IceCube.h @@ -122,9 +122,13 @@ # define CFG_LOWBOOT16 1 #endif #if (TEXT_BASE == 0xFF800000) /* Boot low with 8 MB Flash */ +#if defined(CONFIG_LITE5200B) +# error CFG_LOWBOOT08 is incompatible with the Lite5200B +#else # define CFG_LOWBOOT 1 # define CFG_LOWBOOT08 1 #endif +#endif /* * Autobooting @@ -160,8 +164,12 @@ /* * IPB Bus clocking configuration. */ -#undef CFG_IPBSPEED_133 /* define for 133MHz speed */ +#if defined(CONFIG_LITE5200B) +#define CFG_IPBSPEED_133 /* define for 133MHz speed */ +#else +#undef CFG_IPBSPEED_133 /* define for 133MHz speed */ #endif +#endif /* CONFIG_MPC5200 */ /* * I2C configuration */ @@ -182,6 +190,20 @@ /* * Flash configuration */ +#if defined(CONFIG_LITE5200B) +#define CFG_FLASH_BASE 0xFE000000 +#define CFG_FLASH_SIZE 0x01000000 +#if !defined(CFG_LOWBOOT) +#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x01760000 + 0x00800000) +#else /* CFG_LOWBOOT */ +#if defined(CFG_LOWBOOT08) +# error CFG_LOWBOOT08 is incompatible with the Lite5200B +#endif +#if defined(CFG_LOWBOOT16) +#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x01060000) +#endif +#endif /* CFG_LOWBOOT */ +#else /* !CONFIG_LITE5200B (IceCube)*/ #define CFG_FLASH_BASE 0xFF000000 #define CFG_FLASH_SIZE 0x01000000 #if !defined(CFG_LOWBOOT) @@ -194,6 +216,7 @@ #define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x00040000) #endif #endif /* CFG_LOWBOOT */ +#endif /* CONFIG_LITE5200B */ #define CFG_MAX_FLASH_BANKS 2 /* max num of memory banks */ #define CFG_MAX_FLASH_SECT 128 /* max num of sects on one chip */ @@ -203,13 +226,23 @@ #undef CONFIG_FLASH_16BIT /* Flash is 8-bit */ +#if defined(CONFIG_LITE5200B) +#define CFG_FLASH_CFI_DRIVER +#define CFG_FLASH_CFI +#define CFG_FLASH_BANKS_LIST {CFG_CS1_START,CFG_CS0_START} +#endif + /* * Environment settings */ #define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_SIZE 0x10000 +#if defined(CONFIG_LITE5200B) +#define CFG_ENV_SECT_SIZE 0x20000 +#else #define CFG_ENV_SECT_SIZE 0x10000 +#endif #define CONFIG_ENV_OVERWRITE 1 /* @@ -246,6 +279,9 @@ */ /* #define CONFIG_FEC_10MBIT 1 */ #define CONFIG_PHY_ADDR 0x00 +#if defined(CONFIG_LITE5200B) +#define CONFIG_FEC_MII100 1 +#endif /* * GPIO configuration @@ -288,6 +324,16 @@ #define CFG_HID0_FINAL 0 #endif +#if defined(CONFIG_LITE5200B) +#define CFG_CS1_START CFG_FLASH_BASE +#define CFG_CS1_SIZE CFG_FLASH_SIZE +#define CFG_CS1_CFG 0x00047800 +#define CFG_CS0_START (CFG_FLASH_BASE + CFG_FLASH_SIZE) +#define CFG_CS0_SIZE CFG_FLASH_SIZE +#define CFG_BOOTCS_START CFG_CS0_START +#define CFG_BOOTCS_SIZE CFG_FLASH_SIZE +#define CFG_BOOTCS_CFG 0x00047800 +#else /* IceCube aka Lite5200 */ #ifdef CONFIG_MPC5200_DDR #define CFG_BOOTCS_START (CFG_CS1_START + CFG_CS1_SIZE) @@ -306,6 +352,7 @@ #define CFG_CS0_SIZE CFG_FLASH_SIZE #endif /* CONFIG_MPC5200_DDR */ +#endif /*CONFIG_LITE5200B */ #define CFG_CS_BURST 0x00000000 #define CFG_CS_DEADCYCLE 0x33333333 diff --git a/include/configs/RPXlite_DW.h b/include/configs/RPXlite_DW.h index 5d17712f18..31025473f4 100644 --- a/include/configs/RPXlite_DW.h +++ b/include/configs/RPXlite_DW.h @@ -45,7 +45,7 @@ */ /* #define DEBUG 1 */ -/* #define DEPLOYMENT 1 */ +/* #define DEPLOYMENT 1 */ #undef CONFIG_MPC860 #define CONFIG_MPC823 1 /* This is a MPC823e CPU. */ @@ -61,23 +61,23 @@ #define CONFIG_BAUDRATE 9600 /* console default baudrate = 9600bps */ #ifdef DEBUG -#define CONFIG_BOOTDELAY -1 /* autoboot disabled */ +#define CONFIG_BOOTDELAY -1 /* autoboot disabled */ #else -#define CONFIG_BOOTDELAY 6 /* autoboot after 6 seconds */ +#define CONFIG_BOOTDELAY 6 /* autoboot after 6 seconds */ #ifdef DEPLOYMENT -#define CONFIG_BOOT_RETRY_TIME -1 +#define CONFIG_BOOT_RETRY_TIME -1 #define CONFIG_AUTOBOOT_KEYED -#define CONFIG_AUTOBOOT_PROMPT "autoboot in %d seconds (stop with 'st')...\n" -#define CONFIG_AUTOBOOT_STOP_STR "st" +#define CONFIG_AUTOBOOT_PROMPT "autoboot in %d seconds (stop with 'st')...\n" +#define CONFIG_AUTOBOOT_STOP_STR "st" #define CONFIG_ZERO_BOOTDELAY_CHECK -#define CONFIG_RESET_TO_RETRY 1 -#define CONFIG_BOOT_RETRY_MIN 1 +#define CONFIG_RESET_TO_RETRY 1 +#define CONFIG_BOOT_RETRY_MIN 1 #endif /* DEPLOYMENT */ #endif /* DEBUG */ /* pre-boot commands */ -#define CONFIG_PREBOOT "setenv stdout serial;setenv stdin serial" +#define CONFIG_PREBOOT "setenv stdout serial;setenv stdin serial" #undef CONFIG_BOOTARGS #define CONFIG_EXTRA_ENV_SETTINGS \ @@ -117,35 +117,35 @@ #define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE) -#if 1 /* Enable this staff could make image enlarge about 25KB. Mask it if you - don't want the advanced function */ +#if 1 /* Enable this stuff could make image enlarge about 25KB. Mask it if you + don't want the advanced function */ -#ifdef CONFIG_SPLASH_SCREEN -#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ +#ifdef CONFIG_SPLASH_SCREEN +#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ CFG_CMD_ASKENV | \ - CFG_CMD_BMP | \ - CFG_CMD_JFFS2 | \ - CFG_CMD_PING | \ - CFG_CMD_ELF | \ + CFG_CMD_BMP | \ + CFG_CMD_JFFS2 | \ + CFG_CMD_PING | \ + CFG_CMD_ELF | \ CFG_CMD_REGINFO | \ - CFG_CMD_DHCP ) + CFG_CMD_DHCP ) #else -#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ - CFG_CMD_ASKENV | \ - CFG_CMD_JFFS2 | \ - CFG_CMD_PING | \ - CFG_CMD_ELF | \ +#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ + CFG_CMD_ASKENV | \ + CFG_CMD_JFFS2 | \ + CFG_CMD_PING | \ + CFG_CMD_ELF | \ CFG_CMD_REGINFO | \ - CFG_CMD_DHCP ) -#endif /* CONFIG_SPLASH_SCREEN */ + CFG_CMD_DHCP ) +#endif /* CONFIG_SPLASH_SCREEN */ /* test-only */ -#define CFG_JFFS2_FIRST_BANK 0 /* use for JFFS2 */ -#define CFG_JFFS2_NUM_BANKS 1 /* ! second bank contains U-Boot */ +#define CFG_JFFS2_FIRST_BANK 0 /* use for JFFS2 */ +#define CFG_JFFS2_NUM_BANKS 1 /* ! second bank contains U-Boot */ #define CONFIG_NETCONSOLE -#endif /* 1 */ +#endif /* 1 */ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include @@ -310,7 +310,7 @@ #if defined(RPXlite_64MHz) #define CFG_SCCR ( SCCR_TBS | SCCR_EBDF01 ) /* %%%SCCR:0x02020000 */ #else -#define CFG_SCCR ( SCCR_TBS | SCCR_EBDF00 ) /* %%%SCCR:0x02000000 */ +#define CFG_SCCR ( SCCR_TBS | SCCR_EBDF00 ) /* %%%SCCR:0x02000000 */ #endif /*----------------------------------------------------------------------- From 7b4fd36b0322ec98836a8459d9be80e2777fdc05 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sat, 18 Mar 2006 23:31:12 +0100 Subject: [PATCH 102/102] Add support for MPC859/866 Rev. A.0 --- cpu/mpc8xx/cpu.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c index 4a32986a2e..c4a0cba13a 100644 --- a/cpu/mpc8xx/cpu.c +++ b/cpu/mpc8xx/cpu.c @@ -69,14 +69,15 @@ static int check_CPU (long clock, uint pvr, uint immr) k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]); m = 0; + suf = ""; /* * Some boards use sockets so different CPUs can be used. * We have to check chip version in run time. */ switch (k) { - case 0x00020001: pre = 'P'; suf = ""; break; - case 0x00030001: suf = ""; break; + case 0x00020001: pre = 'P'; break; + case 0x00030001: break; case 0x00120003: suf = "A"; break; case 0x00130003: suf = "A3"; break; @@ -93,7 +94,11 @@ static int check_CPU (long clock, uint pvr, uint immr) /* this value is not documented anywhere */ case 0x40000000: pre = 'P'; suf = "D"; m = 1; break; /* MPC866P/MPC866T/MPC859T/MPC859DSL/MPC852T */ - case 0x08000003: pre = 'M'; suf = ""; m = 1; + case 0x08010004: /* Rev. A.0 */ + suf = "A"; + /* fall through */ + case 0x08000003: /* Rev. 0.3 */ + pre = 'M'; m = 1; if (id_str == NULL) id_str = # if defined(CONFIG_MPC852T)