From 92c20fbd3a7788c1a154f50a3f44f28a7763f99a Mon Sep 17 00:00:00 2001 From: John Rigby Date: Thu, 30 Oct 2008 16:39:35 -0600 Subject: [PATCH 1/5] ADS5121 DIU Make inclusion of FSL logo optional Make inclusion of FSL logo optional and turn it off by default. Signed-off-by: John Rigby --- board/ads5121/ads5121_diu.c | 4 ++++ include/configs/ads5121.h | 1 + 2 files changed, 5 insertions(+) diff --git a/board/ads5121/ads5121_diu.c b/board/ads5121/ads5121_diu.c index 4f7dda0e3..565b63da4 100644 --- a/board/ads5121/ads5121_diu.c +++ b/board/ads5121/ads5121_diu.c @@ -37,7 +37,11 @@ #include #endif +#ifdef CONFIG_FSL_DIU_LOGO_BMP extern unsigned int FSL_Logo_BMP[]; +#else +#define FSL_Logo_BMP NULL +#endif static int xres, yres; diff --git a/include/configs/ads5121.h b/include/configs/ads5121.h index bb3525f17..bb38be6bf 100644 --- a/include/configs/ads5121.h +++ b/include/configs/ads5121.h @@ -47,6 +47,7 @@ #define CONFIG_E300 1 /* E300 Family */ #define CONFIG_MPC512X 1 /* MPC512X family */ #define CONFIG_FSL_DIU_FB 1 /* FSL DIU */ +#undef CONFIG_FSL_DIU_LOGO_BMP /* Don't include FSL DIU binary bmp */ /* video */ #undef CONFIG_VIDEO From 4c154252c480b13f69ce1b71a9530b0515da76a6 Mon Sep 17 00:00:00 2001 From: John Rigby Date: Wed, 19 Nov 2008 13:57:34 -0700 Subject: [PATCH 2/5] ADS5121 DIU Add diu_bmp_addr env Add support for using a bmp other than FSL_Logo_BMP for the DIU splash screen. Can now set the env var "diu_bmp_addr" to the address of a BMP in flash to use instead of the default FSL_Logo_BMP. Signed-off-by: Martha Marx Signed-off-by: John Rigby --- board/ads5121/ads5121_diu.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/board/ads5121/ads5121_diu.c b/board/ads5121/ads5121_diu.c index 565b63da4..41a135314 100644 --- a/board/ads5121/ads5121_diu.c +++ b/board/ads5121/ads5121_diu.c @@ -65,16 +65,40 @@ void diu_set_pixel_clock(unsigned int pixclock) debug("DIU: Modified value of CLKDVDR = 0x%08x\n", *clkdvdr); } +char *valid_bmp(char *addr) +{ + unsigned long h_addr; + + h_addr = simple_strtoul(addr, NULL, 16); + if (h_addr < CONFIG_SYS_FLASH_BASE || + h_addr >= (CONFIG_SYS_FLASH_BASE + CONFIG_SYS_FLASH_SIZE - 1)) { + printf("bmp addr %lx is not a valid flash address\n", h_addr); + return 0; + } else if ((*(char *)(h_addr) != 'B') || (*(char *)(h_addr+1) != 'M')) { + printf("bmp addr is not a bmp\n"); + return 0; + } else + return (char *)h_addr; +} + int ads5121_diu_init(void) { unsigned int pixel_format; + char *bmp = NULL; + char *bmp_env; xres = 1024; yres = 768; pixel_format = 0x88883316; - return fsl_diu_init(xres, pixel_format, 0, - (unsigned char *)FSL_Logo_BMP); + debug("ads5121_diu_init\n"); + bmp_env = getenv("diu_bmp_addr"); + if (bmp_env) { + bmp = valid_bmp(bmp_env); + } + if (!bmp) + bmp = FSL_Logo_BMP; + return fsl_diu_init(xres, pixel_format, 0, (unsigned char *)bmp); } int ads5121diu_init_show_bmp(cmd_tbl_t *cmdtp, From 14d19cd1bce9a24b1335598f1568140f4950e4d9 Mon Sep 17 00:00:00 2001 From: John Rigby Date: Fri, 23 Jan 2009 10:33:15 -0700 Subject: [PATCH 3/5] ADS5121 Fix rev2 silicon pci iopad config Reset config is not correct Signed-off-by: John Rigby --- board/ads5121/ads5121.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/board/ads5121/ads5121.c b/board/ads5121/ads5121.c index 06109286e..8e2271929 100644 --- a/board/ads5121/ads5121.c +++ b/board/ads5121/ads5121.c @@ -290,17 +290,28 @@ static iopin_t ioregs_init[] = { } }; +static iopin_t rev2_silicon_pci_ioregs_init[] = { + /* FUNC0=PCI Sets next 54 to PCI pads */ + { + IOCTL_PCI_AD31, 54, 0, + IO_PIN_FMUX(0) | IO_PIN_HOLD(0) | IO_PIN_DS(0) + } +}; + int checkboard (void) { ushort brd_rev = *(vu_short *) (CONFIG_SYS_CPLD_BASE + 0x00); uchar cpld_rev = *(vu_char *) (CONFIG_SYS_CPLD_BASE + 0x02); + volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; printf ("Board: ADS5121 rev. 0x%04x (CPLD rev. 0x%02x)\n", brd_rev, cpld_rev); /* initialize function mux & slew rate IO inter alia on IO Pins */ - iopin_initialize(ioregs_init, sizeof(ioregs_init) / sizeof(ioregs_init[0])); + if (SVR_MJREV (im->sysconf.spridr) >= 2) { + iopin_initialize(rev2_silicon_pci_ioregs_init, 1); + } return 0; } From abfbd0ae4967df18102345db4f4b529a13da107b Mon Sep 17 00:00:00 2001 From: Martha Marx Date: Mon, 26 Jan 2009 10:45:07 -0700 Subject: [PATCH 4/5] ADS5121 Add IC Ident Module (IIM) support IIM (IC Identification Module) is the fusebox for the mpc5121. Use #define CONFIG_IIM to turn on the clock for this module use #define CONFIG_CMD_FUSE to add fusebox commands. Fusebox commands include the ability to read the status, read the register cache, override the register cache, program the fuses and sense them. Signed-off-by: Martha Marx Signed-off-by: John Rigby --- board/ads5121/ads5121.c | 3 + cpu/mpc512x/Makefile | 3 + cpu/mpc512x/iim.c | 394 +++++++++++++++++++++++++++++++++++ include/asm-ppc/immap_512x.h | 20 +- include/configs/ads5121.h | 6 + include/mpc512x.h | 24 +++ 6 files changed, 449 insertions(+), 1 deletion(-) create mode 100644 cpu/mpc512x/iim.c diff --git a/board/ads5121/ads5121.c b/board/ads5121/ads5121.c index 8e2271929..ae1ccd944 100644 --- a/board/ads5121/ads5121.c +++ b/board/ads5121/ads5121.c @@ -101,6 +101,9 @@ int board_early_init_f (void) */ im->clk.sccr[0] = SCCR1_CLOCKS_EN; im->clk.sccr[1] = SCCR2_CLOCKS_EN; +#if defined(CONFIG_IIM) || defined(CONFIG_CMD_FUSE) + im->clk.sccr[1] |= CLOCK_SCCR2_IIM_EN; +#endif return 0; } diff --git a/cpu/mpc512x/Makefile b/cpu/mpc512x/Makefile index e8f106074..297d13584 100644 --- a/cpu/mpc512x/Makefile +++ b/cpu/mpc512x/Makefile @@ -26,6 +26,9 @@ LIB = $(obj)lib$(CPU).a START = start.o COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o i2c.o iopin.o +ifdef CONFIG_IIM +COBJS += iim.o +endif SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/mpc512x/iim.c b/cpu/mpc512x/iim.c new file mode 100644 index 000000000..6cdc42259 --- /dev/null +++ b/cpu/mpc512x/iim.c @@ -0,0 +1,394 @@ +/* + * Copyright 2008 Silicon Turnkey Express, Inc. + * Martha Marx + * + * ADS5121 IIM (Fusebox) Interface + * + * 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 + +#ifdef CONFIG_CMD_FUSE + +DECLARE_GLOBAL_DATA_PTR; + +static char cur_bank = '1'; + +char *iim_err_msg(u32 err) +{ + static char *IIM_errs[] = { + "Parity Error in cache", + "Explicit Sense Cycle Error", + "Write to Locked Register Error", + "Read Protect Error", + "Override Protect Error", + "Write Protect Error"}; + + int i; + + if (!err) + return ""; + for (i = 1; i < 8; i++) + if (err & (1 << i)) + printf("IIM - %s\n", IIM_errs[i-1]); + return ""; +} + +int in_range(int n, int min, int max, char *err, char *usg) +{ + if (n > max || n < min) { + printf(err); + printf("Usage:\n%s\n", usg); + return 0; + } + return 1; +} + +int ads5121_fuse_read(int bank, int fstart, int num) +{ + iim512x_t *iim = &((immap_t *) CONFIG_SYS_IMMR)->iim; + u32 *iim_fb, dummy; + int f, ctr; + + out_be32(&iim->err, in_be32(&iim->err)); + if (bank == 0) + iim_fb = (u32 *)&(iim->fbac0); + else + iim_fb = (u32 *)&(iim->fbac1); +/* try a read to see if Read Protect is set */ + dummy = in_be32(&iim_fb[0]); + if (in_be32(&iim->err) & IIM_ERR_RPE) { + printf("\tRead protect fuse is set\n"); + out_be32(&iim->err, IIM_ERR_RPE); + return 0; + } + printf("Reading Bank %d cache\n", bank); + for (f = fstart, ctr = 0; num > 0; ctr++, num--, f++) { + if (ctr % 4 == 0) + printf("F%2d:", f); + printf("\t%#04x", (u8)(iim_fb[f])); + if (ctr % 4 == 3) + printf("\n"); + } + if (ctr % 4 != 0) + printf("\n"); +} + +int ads5121_fuse_override(int bank, int f, u8 val) +{ + iim512x_t *iim = &((immap_t *) CONFIG_SYS_IMMR)->iim; + u32 *iim_fb; + u32 iim_stat; + int i; + + out_be32(&iim->err, in_be32(&iim->err)); + if (bank == 0) + iim_fb = (u32 *)&(iim->fbac0); + else + iim_fb = (u32 *)&(iim->fbac1); +/* try a read to see if Read Protect is set */ + iim_stat = in_be32(&iim_fb[0]); + if (in_be32(&iim->err) & IIM_ERR_RPE) { + printf("Read protect fuse is set on bank %d;" + "Override protect may also be set\n", bank); + printf("An attempt will be made to override\n"); + out_be32(&iim->err, IIM_ERR_RPE); + } + if (iim_stat & IIM_FBAC_FBOP) { + printf("Override protect fuse is set on bank %d\n", bank); + return 1; + } + if (f > IIM_FMAX) /* reset the entire bank */ + for (i = 0; i < IIM_FMAX + 1; i++) + out_be32(&iim_fb[i], 0); + else + out_be32(&iim_fb[f], val); + return 0; +} + +int ads5121_fuse_prog(cmd_tbl_t *cmdtp, int bank, char *fuseno_bitno) +{ + iim512x_t *iim = &((immap_t *) CONFIG_SYS_IMMR)->iim; + int f, i, bitno; + u32 stat, err; + + f = simple_strtol(fuseno_bitno, NULL, 10); + if (f == 0 && fuseno_bitno[0] != '0') + f = -1; + if (!in_range(f, 0, IIM_FMAX, + " must be between 0-31\n\n", cmdtp->usage)) + return 1; + bitno = -1; + for (i = 0; i < 6; i++) { + if (fuseno_bitno[i] == '_') { + bitno = simple_strtol(&(fuseno_bitno[i+1]), NULL, 10); + if (bitno == 0 && fuseno_bitno[i+1] != '0') + bitno = -1; + break; + } + } + if (!in_range(bitno, 0, 7, "Bit number ranges from 0-7\n" + "Example of : \"18_4\" sets bit 4 of row 18\n", + cmdtp->usage)) + return 1; + out_be32(&iim->err, in_be32(&iim->err)); + out_be32(&iim->prg_p, IIM_PRG_P_SET); + out_be32(&iim->ua, IIM_SET_UA(bank, f)); + out_be32(&iim->la, IIM_SET_LA(f, bitno)); +#ifdef DEBUG + printf("Programming disabled with DEBUG defined \n"); + printf(""Set up to pro + printf("iim.ua = %x; iim.la = %x\n", iim->ua, iim->la); +#else + out_be32(&iim->fctl, IIM_FCTL_PROG_PULSE | IIM_FCTL_PROG); + do + udelay(20); + while ((stat = in_be32(&iim->stat)) & IIM_STAT_BUSY); + out_be32(&iim->prg_p, 0); + err = in_be32(&iim->err); + if (stat & IIM_STAT_PRGD) { + if (!(err & (IIM_ERR_WPE | IIM_ERR_WPE))) { + printf("Fuse is successfully set"); + if (err) + printf(" - however there are other errors"); + printf("\n"); + } + iim->stat = 0; + } + if (err) { + iim_err_msg(err); + out_be32(&iim->err, in_be32(&iim->err)); + } +#endif +} + +int ads5121_fuse_sense(int bank, int fstart, int num) +{ + iim512x_t *iim = &((immap_t *) CONFIG_SYS_IMMR)->iim; + u32 iim_fbac; + u32 stat, err, err_hold = 0; + int f, ctr; + + out_be32(&iim->err, in_be32(&iim->err)); + if (bank == 0) + iim_fbac = in_be32(&iim->fbac0); + else + iim_fbac = in_be32(&iim->fbac1); + if (iim_fbac & IIM_FBAC_FBESP) { + printf("\tSense Protect disallows this operation\n"); + out_be32(&iim->err, IIM_FBAC_FBESP); + return 1; + } + err = in_be32(&iim->err); + if (err) { + iim_err_msg(err); + err_hold |= err; + } + if (err & IIM_ERR_RPE) + printf("\tRead protect fuse is set; " + "Sense Protect may be set but will be attempted\n"); + if (err) + out_be32(&iim->err, err); + printf("Sensing fuse(s) on Bank %d\n", bank); + for (f = fstart, ctr = 0; num > 0; ctr++, f++, num--) { + out_be32(&iim->ua, IIM_SET_UA(bank, f)); + out_be32(&iim->la, IIM_SET_LA(f, 0)); + out_be32(&iim->fctl, IIM_FCTL_ESNS_N); + do + udelay(20); + while ((stat = in_be32(&iim->stat)) & IIM_STAT_BUSY); + err = in_be32(&iim->err); + if (err & IIM_ERR_SNSE) { + iim_err_msg(err); + out_be32(&iim->err, IIM_ERR_SNSE); + return 1; + } + if (stat & IIM_STAT_SNSD) { + out_be32(&iim->stat, 0); + if (ctr % 4 == 0) + printf("F%2d:", f); + printf("\t%#04x", (u8)iim->sdat); + if (ctr % 4 == 3) + printf("\n"); + } + if (err) { + err_hold |= err; + out_be32(&iim->err, err); + } + } + if (ctr % 4 != 0) + printf("\n"); + if (err_hold) + iim_err_msg(err_hold); + + return 0; +} + +int ads5121_fuse_stat(int bank) +{ + iim512x_t *iim = &((immap_t *) CONFIG_SYS_IMMR)->iim; + u32 iim_fbac; + u32 err; + + out_be32(&iim->err, in_be32(&iim->err)); + if (bank == 0) + iim_fbac = in_be32(&iim->fbac0); + else + iim_fbac = in_be32(&iim->fbac1); + err = in_be32(&iim->err); + if (err) + iim_err_msg(err); + if (err & IIM_ERR_RPE || iim_fbac & IIM_FBAC_FBRP) { + if (iim_fbac == 0) + printf("Since protection settings can't be read - " + "try sensing fuse row 0;\n"); + return 0; + } + if (iim_fbac & IIM_PROTECTION) + printf("Protection Fuses Bank %d = %#04x:\n", bank, iim_fbac); + else if (!(err & IIM_ERR_RPE)) + printf("No Protection fuses are set\n"); + if (iim_fbac & IIM_FBAC_FBWP) + printf("\tWrite Protect fuse is set\n"); + if (iim_fbac & IIM_FBAC_FBOP) + printf("\tOverride Protect fuse is set\n"); + if (iim_fbac & IIM_FBAC_FBESP) + printf("\tSense Protect Fuse is set\n"); + out_be32(&iim->err, in_be32(&iim->err)); + + return 0; +} + +int do_ads5121_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int frow, n, v, bank; + + if (cur_bank == '0') + bank = 0; + else + bank = 1; + + switch (argc) { + case 0: + case 1: + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + case 2: + if (strncmp(argv[1], "stat", 4) == 0) + return ads5121_fuse_stat(bank); + if (strncmp(argv[1], "read", 4) == 0) + return ads5121_fuse_read(bank, 0, IIM_FMAX + 1); + if (strncmp(argv[1], "sense", 5) == 0) + return ads5121_fuse_sense(bank, 0, IIM_FMAX + 1); + if (strncmp(argv[1], "ovride", 6) == 0) + return ads5121_fuse_override(bank, IIM_FMAX + 1, 0); + if (strncmp(argv[1], "bank", 4) == 0) { + printf("Active Fuse Bank is %c\n", cur_bank); + return 0; + } + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + case 3: + if (strncmp(argv[1], "bank", 4) == 0) { + if (argv[2][0] == '0') + cur_bank = '0'; + else if (argv[2][0] == '1') + cur_bank = '1'; + else { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + printf("Setting Active Fuse Bank to %c\n", cur_bank); + return 0; + } + if (strncmp(argv[1], "prog", 4) == 0) + return ads5121_fuse_prog(cmdtp, bank, argv[2]); + + frow = (int)simple_strtol(argv[2], NULL, 10); + if (frow == 0 && argv[2][0] != '0') + frow = -1; + if (!in_range(frow, 0, IIM_FMAX, + " must be between 0-31\n\n", cmdtp->usage)) + return 1; + if (strncmp(argv[1], "read", 4) == 0) + return ads5121_fuse_read(bank, frow, 1); + if (strncmp(argv[1], "ovride", 6) == 0) + return ads5121_fuse_override(bank, frow, 0); + if (strncmp(argv[1], "sense", 5) == 0) + return ads5121_fuse_sense(bank, frow, 1); + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + case 4: + frow = (int)simple_strtol(argv[2], NULL, 10); + if (frow == 0 && argv[2][0] != '0') + frow = -1; + if (!in_range(frow, 0, IIM_FMAX, + " must be between 0-31\n\n", cmdtp->usage)) + return 1; + if (strncmp(argv[1], "read", 4) == 0) { + n = (int)simple_strtol(argv[3], NULL, 10); + if (!in_range(frow + n, frow + 1, IIM_FMAX + 1, + "+ must be between 1-32\n\n", + cmdtp->usage)) + return 1; + return ads5121_fuse_read(bank, frow, n); + } + if (strncmp(argv[1], "ovride", 6) == 0) { + v = (int)simple_strtol(argv[3], NULL, 10); + return ads5121_fuse_override(bank, frow, v); + } + if (strncmp(argv[1], "sense", 5) == 0) { + n = (int)simple_strtol(argv[3], NULL, 10); + if (!in_range(frow + n, frow + 1, IIM_FMAX + 1, + "+ must be between 1-32\n\n", + cmdtp->usage)) + return 1; + return ads5121_fuse_sense(bank, frow, n); + } + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + default: /* at least 5 args */ + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } +} + +U_BOOT_CMD( + fuse, CONFIG_SYS_MAXARGS, 0, do_ads5121_fuse, + " - Read, Sense, Override or Program Fuses\n", + "bank - sets active Fuse Bank to 0 or 1\n" + " no args shows current active bank\n" + "fuse stat - print active fuse bank's protection status\n" + "fuse read [ []] - print fuse rows starting at \n" + " no args to print entire bank's fuses\n" + "fuse ovride [ []]- override fuses at with \n" + " no defaults to 0 for the row\n" + " no args resets entire bank to 0\n" + " NOTE - settings persist until hard reset\n" + "fuse sense [] - senses current fuse at \n" + " no args for entire bank\n" + "fuse prog - program fuse at row , bit <_bit>\n" + " is 0-31, is 0-7; eg. 13_2 \n" + " WARNING - this is permanent\n" + ); +#endif /* CONFIG_CMD_FUSE */ diff --git a/include/asm-ppc/immap_512x.h b/include/asm-ppc/immap_512x.h index cd9094519..4cef6a83e 100644 --- a/include/asm-ppc/immap_512x.h +++ b/include/asm-ppc/immap_512x.h @@ -415,7 +415,25 @@ typedef struct ioctrl512x { * IIM */ typedef struct iim512x { - u8 fixme[0x1000]; + u32 stat; /* IIM status register */ + u32 statm; /* IIM status IRQ mask */ + u32 err; /* IIM errors register */ + u32 emask; /* IIM error IRQ mask */ + u32 fctl; /* IIM fuse control register */ + u32 ua; /* IIM upper address register */ + u32 la; /* IIM lower address register */ + u32 sdat; /* IIM explicit sense data */ + u8 res0[0x08]; + u32 prg_p; /* IIM program protection register */ + u8 res1[0x10]; + u32 divide; /* IIM divide factor register */ + u8 res2[0x7c0]; + u32 fbac0; /* IIM fuse bank 0 prot (for Freescale use) */ + u32 fb0w0[0x1f]; /* IIM fuse bank 0 data (for Freescale use) */ + u8 res3[0x380]; + u32 fbac1; /* IIM fuse bank 1 protection */ + u32 fb1w1[0x01f]; /* IIM fuse bank 1 data */ + u8 res4[0x380]; } iim512x_t; /* diff --git a/include/configs/ads5121.h b/include/configs/ads5121.h index bb38be6bf..0aca4a52a 100644 --- a/include/configs/ads5121.h +++ b/include/configs/ads5121.h @@ -294,6 +294,11 @@ #define CONFIG_SYS_I2C_NOPROBES {{0,0x69}} /* Don't probe these addrs */ #endif +/* + * IIM - IC Identification Module + */ +#undef CONFIG_IIM + /* * EEPROM configuration */ @@ -349,6 +354,7 @@ #define CONFIG_CMD_REGINFO #define CONFIG_CMD_EEPROM #define CONFIG_CMD_DATE +#undef CONFIG_CMD_FUSE #if defined(CONFIG_PCI) #define CONFIG_CMD_PCI diff --git a/include/mpc512x.h b/include/mpc512x.h index 05a206358..714287c86 100644 --- a/include/mpc512x.h +++ b/include/mpc512x.h @@ -574,6 +574,30 @@ void iopin_initialize(iopin_t *,int); /* Register Offset Base */ #define MPC512X_FEC (CONFIG_SYS_IMMR + 0x02800) +/* IIM control */ +#define IIM_SET_UA(bk, f) ((bk << 3) | (f >> 5)) +#define IIM_SET_LA(f, bit) (((f & 0x0000001f) << 3) | bit) +#define IIM_STAT_BUSY 0x00000080 +#define IIM_STAT_PRGD 0x00000002 +#define IIM_STAT_SNSD 0x00000001 +#define IIM_ERR_WPE 0x00000040 +#define IIM_ERR_OPE 0x00000020 +#define IIM_ERR_RPE 0x00000010 +#define IIM_ERR_WLRE 0x00000008 +#define IIM_ERR_SNSE 0x00000004 +#define IIM_ERR_PARITYE 0x00000002 +#define IIM_PRG_P_SET 0x000000aa +#define IIM_PRG_P_UNSET 0 +#define IIM_FCTL_PROG_PULSE 0x00000020 +#define IIM_FCTL_PROG 0x00000001 +#define IIM_FCTL_ESNS_N 0x00000008 +#define IIM_FBAC_FBWP 0x00000080 +#define IIM_FBAC_FBOP 0x00000040 +#define IIM_FBAC_FBRP 0x00000020 +#define IIM_FBAC_FBESP 0x00000008 +#define IIM_PROTECTION 0x000000e8 +#define IIM_FMAX 31 + /* Number of I2C buses */ #define I2C_BUS_CNT 3 From 70a4da45e16b72e8e5b0baaecdaee9be8619647d Mon Sep 17 00:00:00 2001 From: Ralph Kondziella Date: Mon, 26 Jan 2009 12:34:36 -0700 Subject: [PATCH 5/5] ADS5121 Add PATA support Original patch from Ralph Kondziella plus clean up by Wolfgang Denk plus changes by John Rigby use ips clock not lpc port forward to current u-boot release Signed-off-by: Ralph Kondziella Signed-off-by: Wolfgang Denk Signed-off-by: John Rigby --- board/ads5121/ads5121.c | 104 +++++++++++++++++++++++++++++++++++ common/cmd_ide.c | 4 ++ include/asm-ppc/immap_512x.h | 29 +++++++++- include/configs/ads5121.h | 52 ++++++++++++++++++ include/mpc512x.h | 1 + 5 files changed, 189 insertions(+), 1 deletion(-) diff --git a/board/ads5121/ads5121.c b/board/ads5121/ads5121.c index ae1ccd944..6c40e9441 100644 --- a/board/ads5121/ads5121.c +++ b/board/ads5121/ads5121.c @@ -31,6 +31,8 @@ #include #endif +DECLARE_GLOBAL_DATA_PTR; + /* Clocks in use */ #define SCCR1_CLOCKS_EN (CLOCK_SCCR1_CFG_EN | \ CLOCK_SCCR1_LPC_EN | \ @@ -38,6 +40,7 @@ CLOCK_SCCR1_PSCFIFO_EN | \ CLOCK_SCCR1_DDR_EN | \ CLOCK_SCCR1_FEC_EN | \ + CLOCK_SCCR1_PATA_EN | \ CLOCK_SCCR1_PCI_EN | \ CLOCK_SCCR1_TPR_EN) @@ -326,3 +329,104 @@ void ft_board_setup(void *blob, bd_t *bd) fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); } #endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */ + +#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET) + +void init_ide_reset (void) +{ + volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; + debug ("init_ide_reset\n"); + + /* + * Clear the reset bit to reset the interface + * cf. RefMan MPC5121EE: 28.4.1 Resetting the ATA Bus + */ + immr->pata.pata_ata_control = 0; + udelay(100); + /* Assert the reset bit to enable the interface */ + immr->pata.pata_ata_control = FSL_ATA_CTRL_ATA_RST_B; + udelay(100); + +} + +void ide_set_reset (int idereset) +{ + volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; + debug ("ide_set_reset(%d)\n", idereset); + + if (idereset) { + immr->pata.pata_ata_control = 0; + udelay(100); + } else { + immr->pata.pata_ata_control = FSL_ATA_CTRL_ATA_RST_B; + udelay(100); + } +} + +#define CALC_TIMING(t) (t + period - 1) / period + +int ide_preinit (void) +{ + volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; + long t; + const struct { + short t0; + short t1; + short t2_8; + short t2_16; + short t2i; + short t4; + short t9; + short tA; + } pio_specs = { + .t0 = 600, + .t1 = 70, + .t2_8 = 290, + .t2_16 = 165, + .t2i = 0, + .t4 = 30, + .t9 = 20, + .tA = 50, + }; + union { + u32 config; + struct { + u8 field1; + u8 field2; + u8 field3; + u8 field4; + }bytes; + }cfg; + + debug ("IDE preinit using PATA peripheral at IMMR-ADDR %08x\n", + (u32)&immr->pata); + + /* Set the reset bit to 1 to enable the interface */ + immr->pata.pata_ata_control = FSL_ATA_CTRL_ATA_RST_B; + + /* Init timings : we use PIO mode 0 timings */ + t = 1000000000 / gd->ips_clk; /* period in ns */ + cfg.bytes.field1 = 3; + cfg.bytes.field2 = 3; + cfg.bytes.field3 = (pio_specs.t1 + t) / t; + cfg.bytes.field4 = (pio_specs.t2_8 + t) / t; + + immr->pata.pata_time1 = cfg.config; + + cfg.bytes.field1 = (pio_specs.t2_8 + t) / t; + cfg.bytes.field2 = (pio_specs.tA + t) / t + 2; + cfg.bytes.field3 = 1; + cfg.bytes.field4 = (pio_specs.t4 + t) / t; + + immr->pata.pata_time2 = cfg.config; + + cfg.config = immr->pata.pata_time3; + cfg.bytes.field1 = (pio_specs.t9 + t) / t; + + immr->pata.pata_time3 = cfg.config; + debug ("PATA preinit complete.\n"); + + return 0; +} + +#endif /* defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET) */ diff --git a/common/cmd_ide.c b/common/cmd_ide.c index c9b9a4799..8c6ed35b3 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -45,6 +45,10 @@ #include #endif +#ifdef CONFIG_MPC512X +#include +#endif + #include #include diff --git a/include/asm-ppc/immap_512x.h b/include/asm-ppc/immap_512x.h index 4cef6a83e..808786985 100644 --- a/include/asm-ppc/immap_512x.h +++ b/include/asm-ppc/immap_512x.h @@ -469,7 +469,34 @@ typedef struct lpc512x { * PATA */ typedef struct pata512x { - u8 fixme[0x100]; + /* LOCAL Registers */ + u32 pata_time1; /* Time register 1: PIO and tx timing parameter */ + u32 pata_time2; /* Time register 2: PIO timing parameter */ + u32 pata_time3; /* Time register 3: PIO and MDMA timing parameter */ + u32 pata_time4; /* Time register 4: MDMA and UDMA timing parameter */ + u32 pata_time5; /* Time register 5: UDMA timing parameter */ + u32 pata_time6; /* Time register 6: UDMA timing parameter */ + u32 pata_fifo_data32; /* 32bit wide dataport to/from FIFO */ + u32 pata_fifo_data16; /* 16bit wide dataport to/from FIFO */ + u32 pata_fifo_fill; /* FIFO filling in halfwords (READONLY)*/ + u32 pata_ata_control; /* ATA Interface control register */ + u32 pata_irq_pending; /* Interrupt pending register (READONLY) */ + u32 pata_irq_enable; /* Interrupt enable register */ + u32 pata_irq_clear; /* Interrupt clear register (WRITEONLY)*/ + u32 pata_fifo_alarm; /* fifo alarm threshold */ + u32 res1[0x1A]; + /* DRIVE Registers */ + u32 pata_drive_data; /* drive data register*/ + u32 pata_drive_features;/* drive features register */ + u32 pata_drive_sectcnt; /* drive sector count register */ + u32 pata_drive_sectnum; /* drive sector number register */ + u32 pata_drive_cyllow; /* drive cylinder low register */ + u32 pata_drive_cylhigh; /* drive cylinder high register */ + u32 pata_drive_dev_head;/* drive device head register */ + u32 pata_drive_command; /* write = drive command, read = drive status reg */ + u32 res2[0x06]; + u32 pata_drive_alt_stat;/* write = drive control, read = drive alt status reg */ + u32 res3[0x09]; } pata512x_t; /* diff --git a/include/configs/ads5121.h b/include/configs/ads5121.h index 0aca4a52a..8fda3f29f 100644 --- a/include/configs/ads5121.h +++ b/include/configs/ads5121.h @@ -355,11 +355,19 @@ #define CONFIG_CMD_EEPROM #define CONFIG_CMD_DATE #undef CONFIG_CMD_FUSE +#define CONFIG_CMD_IDE +#define CONFIG_CMD_EXT2 #if defined(CONFIG_PCI) #define CONFIG_CMD_PCI #endif +#if defined(CONFIG_CMD_IDE) +#define CONFIG_DOS_PARTITION +#define CONFIG_MAC_PARTITION +#define CONFIG_ISO_PARTITION +#endif /* defined(CONFIG_CMD_IDE) */ + /* * Watchdog timeout = CONFIG_SYS_WATCHDOG_VALUE * 65536 / IPS clock. * For example, when IPS is set to 66MHz and CONFIG_SYS_WATCHDOG_VALUE is set @@ -496,4 +504,48 @@ #define OF_TBCLK (bd->bi_busfreq / 4) #define OF_STDOUT_PATH "/soc@80000000/serial@11300" +/*----------------------------------------------------------------------- + * IDE/ATA stuff + *----------------------------------------------------------------------- + */ + +#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 */ + +#define CONFIG_IDE_RESET /* reset for IDE supported */ +#define CONFIG_IDE_PREINIT + +#define CONFIG_SYS_IDE_MAXBUS 1 /* max. 1 IDE bus */ +#define CONFIG_SYS_IDE_MAXDEVICE 2 /* max. 1 drive per IDE bus */ + +#define CONFIG_SYS_ATA_IDE0_OFFSET 0x0000 +#define CONFIG_SYS_ATA_BASE_ADDR MPC512X_PATA + +/* Offset for data I/O RefMan MPC5121EE Table 28-10 */ +#define CONFIG_SYS_ATA_DATA_OFFSET (0x00A0) + +/* Offset for normal register accesses */ +#define CONFIG_SYS_ATA_REG_OFFSET (CONFIG_SYS_ATA_DATA_OFFSET) + +/* Offset for alternate registers RefMan MPC5121EE Table 28-23 */ +#define CONFIG_SYS_ATA_ALT_OFFSET (0x00D8) + +/* Interval between registers */ +#define CONFIG_SYS_ATA_STRIDE 4 + +#define ATA_BASE_ADDR MPC512X_PATA + +/* + * Control register bit definitions + */ +#define FSL_ATA_CTRL_FIFO_RST_B 0x80000000 +#define FSL_ATA_CTRL_ATA_RST_B 0x40000000 +#define FSL_ATA_CTRL_FIFO_TX_EN 0x20000000 +#define FSL_ATA_CTRL_FIFO_RCV_EN 0x10000000 +#define FSL_ATA_CTRL_DMA_PENDING 0x08000000 +#define FSL_ATA_CTRL_DMA_ULTRA 0x04000000 +#define FSL_ATA_CTRL_DMA_WRITE 0x02000000 +#define FSL_ATA_CTRL_IORDY_EN 0x01000000 + #endif /* __CONFIG_H */ diff --git a/include/mpc512x.h b/include/mpc512x.h index 714287c86..0f022939d 100644 --- a/include/mpc512x.h +++ b/include/mpc512x.h @@ -573,6 +573,7 @@ void iopin_initialize(iopin_t *,int); /* Register Offset Base */ #define MPC512X_FEC (CONFIG_SYS_IMMR + 0x02800) +#define MPC512X_PATA (CONFIG_SYS_IMMR + 0x10200) /* IIM control */ #define IIM_SET_UA(bk, f) ((bk << 3) | (f >> 5))