Commit 33149b88 authored by wdenk's avatar wdenk
Browse files

Patch by Denis Peter, 19 Mai 2003:

add support for the MIP405-3 board
parent 9919f13c
......@@ -2,6 +2,9 @@
Changes since U-Boot 0.3.1:
======================================================================
* Patch by Denis Peter, 19 Mai 2003:
add support for the MIP405-3 board
* Patch by Dave Ellis, 22 May 2003:
Fix problem with only partially cleared .bss segment
......
......@@ -32,6 +32,15 @@
#include <devices.h>
#include <pci.h>
#ifdef CONFIG_PIP405
#include "../pip405/pip405.h"
#include <405gp_pci.h>
#endif
#ifdef CONFIG_MIP405
#include "../mip405/mip405.h"
#include <405gp_pci.h>
#endif
extern int gunzip (void *, int, unsigned char *, int *);
extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
......@@ -363,12 +372,16 @@ void show_stdio_dev(void)
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
int switch_cs(unsigned char boot)
{
unsigned long pbcr;
mtdcr(ebccfga, pb0cr); /* get cs0 config reg */
pbcr = mfdcr(ebccfgd);
if((pbcr&0x00002000)==0) {
unsigned long pbcr;
int mode;
mode=get_boot_mode();
mtdcr(ebccfga, pb0cr);
pbcr = mfdcr (ebccfgd);
if (mode & BOOT_MPS) {
/* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
/* we need only to switch if boot from MPS */
/*printf(" MPS boot mode detected. ");*/
/* printf(" MPS boot mode detected. ");*/
/* printf("cs0 cfg: %lx\n",pbcr); */
if(boot) {
/* switch to boot configuration */
......@@ -388,8 +401,7 @@ int switch_cs(unsigned char boot)
mtdcr(ebccfgd, pbcr);
SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
}
else
{
else {
/* map flash to boot area, */
SW_CS_PRINTF("map Flash to boot area\n");
pbcr&=0x000FFFFF; /*mask base address of the cs0 */
......@@ -412,7 +424,63 @@ int switch_cs(unsigned char boot)
SW_CS_PRINTF("Normal boot, no switching necessary\n");
return 0;
}
}
int get_boot_mode(void)
{
unsigned long pbcr;
int res = 0;
pbcr = mfdcr (strap);
if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
/* boot via MPS or MPS mapping */
res = BOOT_MPS;
if(pbcr & PSR_ROM_LOC)
/* boot via PCI.. */
res |= BOOT_PCI;
return res;
}
/* Setup cs0 parameter finally.
Map the flash high (in boot area)
This code can only be executed from SDRAM (after relocation).
*/
void setup_cs_reloc(void)
{
unsigned long pbcr;
/* Since we are relocated, we can set-up the CS finaly
* but first of all, switch off PCI mapping (in case it was a PCI boot) */
out32r(PMM0MA,0L);
icache_enable (); /* we are relocated */
/* for PCI Boot, we have to set-up the remaining CS correctly */
pbcr = mfdcr (strap);
if(pbcr & PSR_ROM_LOC) {
/* boot via PCI.. */
if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) {
/* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
#ifdef DEBUG
printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B & 0xfff00000));
#endif
mtdcr (ebccfga, pb0ap);
mtdcr (ebccfgd, MPS_AP);
mtdcr (ebccfga, pb0cr);
mtdcr (ebccfgd, MPS_CR_B);
}
else {
/* Flash boot, set up the Flash on CS0 */
#ifdef DEBUG
printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B & 0xfff00000));
#endif
mtdcr (ebccfga, pb0ap);
mtdcr (ebccfgd, FLASH_AP);
mtdcr (ebccfga, pb0cr);
mtdcr (ebccfgd, FLASH_CR_B);
}
}
switch_cs(0); /* map Flash High */
}
#elif defined(CONFIG_VCMA9)
int switch_cs(unsigned char boot)
{
......@@ -425,13 +493,11 @@ int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
ulong size,src,ld_addr;
int result;
backup_t back;
char sw;
src = MULTI_PURPOSE_SOCKET_ADDR;
size = IMAGE_SIZE;
if (strcmp(argv[1], "flash") == 0)
{
sw = switch_cs(0); /* Switch flash to normal location */
#if (CONFIG_COMMANDS & CFG_CMD_FDC)
if (strcmp(argv[2], "floppy") == 0) {
char *local_args[3];
......@@ -450,7 +516,6 @@ int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
result=do_fdcboot(cmdtp, 0, 1, local_args);
}
result=mpl_prg_image(ld_addr);
switch_cs(sw); /* Switch flash back */
return result;
}
#endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
......@@ -463,17 +528,13 @@ int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
result=mpl_prg_image(ld_addr);
switch_cs(sw); /* Switch flash back */
return result;
}
if (strcmp(argv[2], "mps") == 0) {
printf ("\nupdating bootloader image from MSP\n");
printf ("\nupdating bootloader image from MPS\n");
result=mpl_prg(src,size);
switch_cs(sw); /* Switch flash back */
return result;
}
switch_cs(sw); /* Switch flash back */
}
if (strcmp(argv[1], "mem") == 0)
{
......@@ -551,11 +612,12 @@ void video_get_info_str (int line_number, char *info)
DECLARE_GLOBAL_DATA_PTR;
PPC405_SYS_INFO sys_info;
char rev;
int i;
int i,boot;
unsigned long pvr;
char buf[64];
char tmp[16];
unsigned char *s, *e, bc, sw;
char cpustr[16];
unsigned char *s, *e, bc;
switch (line_number)
{
case 2:
......@@ -567,8 +629,13 @@ void video_get_info_str (int line_number, char *info)
case PVR_405GP_RC: rev='C'; break;
case PVR_405GP_RD: rev='D'; break;
case PVR_405GP_RE: rev='E'; break;
case PVR_405GPR_RB: rev='B'; break;
default: rev='?'; break;
}
if(pvr==PVR_405GPR_RB)
sprintf(cpustr,"PPC405GPr %c",rev);
else
sprintf(cpustr,"PPC405GP %c",rev);
/* Board info */
i=0;
s=getenv ("serial#");
......@@ -601,22 +668,21 @@ void video_get_info_str (int line_number, char *info)
}
buf[i++]=0;
}
sprintf (info," %s PPC405GP %c %s MHz (%lu/%lu/%lu MHz)",
buf,rev,
sprintf (info," %s %s %s MHz (%lu/%lu/%lu MHz)",
buf, cpustr,
strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
return;
case 3:
/* Memory Info */
sw = switch_cs (0);
switch_cs (sw);
boot = get_boot_mode();
bc = in8 (CONFIG_PORT_ADDR);
sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
gd->bd->bi_memsize / 0x100000,
gd->bd->bi_flashsize / 0x100000,
bc,
sw ? "MPS boot" : "Flash boot",
(boot & BOOT_MPS) ? "MPS boot" : "Flash boot",
ctfb.modeIdent);
return;
case 1:
......
......@@ -27,11 +27,18 @@
typedef struct {
char signature[4];
char serial_name[17]; /* "MIP405_1000xxxxx" */
char eth_addr[21]; /* "00:60:C2:0a:00:00" */
char eth_addr[21]; /* "00:60:C2:0a:00:00" */
} backup_t;
void get_backup_values(backup_t *buf);
int switch_cs(unsigned char boot);
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
int get_boot_mode(void);
void setup_cs_reloc(void);
#define BOOT_MPS 0x01
#define BOOT_PCI 0x02
#endif
void show_stdio_dev(void);
void check_env(void);
#if (CONFIG_COMMANDS & CFG_CMD_DOC)
......
......@@ -30,7 +30,7 @@
/*
* Modified 3/7/2001
* - adopted for pip405, Denis Peter, MPL AG Switzerland
* - adapted for pip405, Denis Peter, MPL AG Switzerland
* TODO:
* clean-up
*/
......@@ -38,12 +38,6 @@
#include <common.h>
#include <ppc4xx.h>
#include <asm/processor.h>
#ifdef CONFIG_PIP405
#include "../pip405/pip405.h"
#endif
#ifdef CONFIG_MIP405
#include "../mip405/mip405.h"
#endif
#include "common_util.h"
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
......@@ -52,23 +46,10 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
*/
static ulong flash_get_size (vu_long *addr, flash_info_t *info);
static int write_word (flash_info_t *info, ulong dest, ulong data);
static void flash_get_offsets (ulong base, flash_info_t *info);
void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt);
#ifdef CONFIG_ADCIOP
#define ADDR0 0x0aa9
#define ADDR1 0x0556
#define FLASH_WORD_SIZE unsigned char
#endif
#ifdef CONFIG_CPCI405
#define ADDR0 0x5555
#define ADDR1 0x2aaa
#define FLASH_WORD_SIZE unsigned short
#endif
#ifdef CONFIG_PIP405
#define ADDR0 0x5555
#define ADDR1 0x2aaa
......@@ -92,16 +73,17 @@ unsigned long flash_init (void)
{
unsigned long size_b0, size_b1;
int i;
unsigned long pbcr;
unsigned long base_b0, base_b1;
unsigned char rc;
rc=switch_cs(FALSE); /* map Flash High */
if(rc)
printf("(MPS Boot) ");
/* Since we are relocated, we can set-up the CS finally */
setup_cs_reloc();
/* get and display boot mode */
i=get_boot_mode();
if(i & BOOT_PCI)
printf("(PCI Boot %s Map) ",(i & BOOT_MPS) ?
"MPS" : "Flash");
else
printf("(Flash Boot) ");
printf("(%s Boot) ",(i & BOOT_MPS) ?
"MPS" : "Flash");
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
......@@ -115,140 +97,39 @@ unsigned long flash_init (void)
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size_b0, size_b0<<20);
}
/* Only one bank */
if (CFG_MAX_FLASH_BANKS == 1)
{
/* Setup offsets */
/* flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]); */
/* Monitor protection ON by default */
/* protect the bootloader */
/* Monitor protection ON by default */
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
&flash_info[0]);
#endif
size_b1 = 0 ;
flash_info[0].size = size_b0;
}
/* 2 banks */
else
{
size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
/* Re-do sizing to get full correct info */
if (size_b1)
{
mtdcr(ebccfga, pb0cr);
pbcr = mfdcr(ebccfgd);
mtdcr(ebccfga, pb0cr);
base_b1 = -size_b1;
pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
mtdcr(ebccfgd, pbcr);
/* printf("pb1cr = %x\n", pbcr); */
}
if (size_b0)
{
mtdcr(ebccfga, pb1cr);
pbcr = mfdcr(ebccfgd);
mtdcr(ebccfga, pb1cr);
base_b0 = base_b1 - size_b0;
pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
mtdcr(ebccfgd, pbcr);
/* printf("pb0cr = %x\n", pbcr); */
}
size_b0 = flash_get_size((vu_long *)base_b0, &flash_info[0]);
flash_get_offsets (base_b0, &flash_info[0]);
/* monitor protection ON by default */
(void)flash_protect(FLAG_PROTECT_SET,
base_b0+size_b0-CFG_MONITOR_LEN,
base_b0+size_b0-1,
&flash_info[0]);
if (size_b1) {
/* Re-do sizing to get full correct info */
size_b1 = flash_get_size((vu_long *)base_b1, &flash_info[1]);
flash_get_offsets (base_b1, &flash_info[1]);
/* monitor protection ON by default */
(void)flash_protect(FLAG_PROTECT_SET,
base_b1+size_b1-CFG_MONITOR_LEN,
base_b1+size_b1-1,
&flash_info[1]);
/* monitor protection OFF by default (one is enough) */
(void)flash_protect(FLAG_PROTECT_CLEAR,
base_b0+size_b0-CFG_MONITOR_LEN,
base_b0+size_b0-1,
&flash_info[0]);
} else {
flash_info[1].flash_id = FLASH_UNKNOWN;
flash_info[1].sector_count = -1;
}
flash_info[0].size = size_b0;
flash_info[1].size = size_b1;
}/* else 2 banks */
switch_cs(rc); /* switch mode back */
return (size_b0 + size_b1);
}
static void flash_get_offsets (ulong base, flash_info_t *info)
{
return;
}
size_b1 = 0 ;
flash_info[0].size = size_b0;
#if 0
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
/* set up sector start address table */
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
(info->flash_id == FLASH_AM040)){
for (i = 0; i < info->sector_count; i++)
info->start[i] = base + (i * 0x00010000);
}
else {
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00004000;
info->start[2] = base + 0x00006000;
info->start[3] = base + 0x00008000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00010000) - 0x00030000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00004000;
info->start[i--] = base + info->size - 0x00006000;
info->start[i--] = base + info->size - 0x00008000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00010000;
}
}
}
/* include this if you want to test if
the relocation has be done ok.
This will disable both Chipselects */
mtdcr (ebccfga, pb0cr);
mtdcr (ebccfgd, 0L);
mtdcr (ebccfga, pb1cr);
mtdcr (ebccfgd, 0L);
printf("CS0 & CS1 switched off for test\n");
#endif
return (size_b0);
}
#endif
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
int k;
int size;
int erased;
volatile unsigned long *flash;
int k;
int size;
int erased;
volatile unsigned long *flash;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
......@@ -297,40 +178,30 @@ void flash_print_info (flash_info_t *info)
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
/*
* Check if whole sector is erased
*/
/*
* Check if whole sector is erased
*/
if (i != (info->sector_count-1))
size = info->start[i+1] - info->start[i];
size = info->start[i+1] - info->start[i];
else
size = info->start[0] + info->size - info->start[i];
erased = 1;
flash = (volatile unsigned long *)info->start[i];
size = size >> 2; /* divide by 4 for longword access */
for (k=0; k<size; k++)
{
if (*flash++ != 0xffffffff)
{
erased = 0;
size = info->start[0] + info->size - info->start[i];
erased = 1;
flash = (volatile unsigned long *)info->start[i];
size = size >> 2; /* divide by 4 for longword access */
for (k=0; k<size; k++) {
if (*flash++ != 0xffffffff) {
erased = 0;
break;
}
}
}
if ((i % 5) == 0)
printf ("\n ");
#if 0 /* test-only */
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
#else
printf (" %08lX%s%s",
info->start[i],
erased ? " E" : " ",
info->protect[i] ? "RO " : " "
#endif
);
info->protect[i] ? "RO " : " ");
}
printf ("\n");
}
/*-----------------------------------------------------------------------
......@@ -457,21 +328,22 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
}
/* set up sector start address table */
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
(info->flash_id == FLASH_AM040)){
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
(info->flash_id == FLASH_AM040)){
for (i = 0; i < info->sector_count; i++)
info->start[i] = base + (i * 0x00010000);
} else {
}
else {
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00004000;
info->start[2] = base + 0x00006000;
info->start[3] = base + 0x00008000;
for (i = 4; i < info->sector_count; i++)
info->start[i] = base + (i * 0x00010000) - 0x00030000;
}
else {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00004000;
info->start[2] = base + 0x00006000;
info->start[3] = base + 0x00008000;
for (i = 4; i < info->sector_count; i++)
info->start[i] = base + (i * 0x00010000) - 0x00030000;
}
else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
if(info->sector_count==71) {
......@@ -501,52 +373,41 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
/* D0 = 1 if protected */
addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
info->protect[i] = 0;
else
info->protect[i] = addr2[2] & 1;
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
info->protect[i] = 0;
else
info->protect[i] = addr2[2] & 1;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
#if 0 /* test-only */
#ifdef CONFIG_ADCIOP
addr2 = (volatile unsigned char *)info->start[0];
addr2[ADDR0] = 0xAA;
addr2[ADDR1] = 0x55;
addr2[ADDR0] = 0xF0; /* reset bank */
#else
addr2 = (FLASH_WORD_SIZE *)info->start[0];
*addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
#endif
#else /* test-only */
addr2 = (FLASH_WORD_SIZE *)info->start[0];
*addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
#endif /* test-only */
}
return (info->size);
}
int wait_for_DQ7(flash_info_t *info, int sect)
{
ulong start, now, last;
volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
start = get_timer (0);
last = start;
while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
return -1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
last = start;
while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
return -1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;