Commit 1b33a62b authored by Wolfgang Denk's avatar Wolfgang Denk
Browse files

Merge branch 'master' of git://git.denx.de/u-boot-mpc5xxx

parents 9d8811c5 70a4da45
......@@ -31,6 +31,8 @@
#include <i2c.h>
#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)
......@@ -101,6 +104,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;
}
......@@ -290,17 +296,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;
}
......@@ -312,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) */
......@@ -37,7 +37,11 @@
#include <video_fb.h>
#endif
#ifdef CONFIG_FSL_DIU_LOGO_BMP
extern unsigned int FSL_Logo_BMP[];
#else
#define FSL_Logo_BMP NULL
#endif
static int xres, yres;
......@@ -61,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,
......
......@@ -45,6 +45,10 @@
#include <mpc5xxx.h>
#endif
#ifdef CONFIG_MPC512X
#include <mpc512x.h>
#endif
#include <ide.h>
#include <ata.h>
......
......@@ -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))
......
/*
* Copyright 2008 Silicon Turnkey Express, Inc.
* Martha Marx <mmarx@silicontkx.com>
*
* 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 <common.h>
#include <command.h>
#include <asm/io.h>
#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,
"<frow> 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 <frow_bitno>: \"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,
"<frow> 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,
"<frow> 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,
"<frow>+<n> 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,
"<frow>+<n> 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",