]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Prepare for 0.3.0 release U-Boot-0_3_0
authorwdenk <wdenk>
Tue, 8 Apr 2003 23:25:21 +0000 (23:25 +0000)
committerwdenk <wdenk>
Tue, 8 Apr 2003 23:25:21 +0000 (23:25 +0000)
* Add support for Purple Board (MIPS64 5Kc)

* Add support for MIPS64 5Kc CPUs

17 files changed:
CHANGELOG
board/purple/Makefile [new file with mode: 0644]
board/purple/config.mk [new file with mode: 0644]
board/purple/flash.c [new file with mode: 0644]
board/purple/memsetup.S [new file with mode: 0644]
board/purple/purple.c [new file with mode: 0644]
board/purple/sconsole.c [new file with mode: 0644]
board/purple/sconsole.h [new file with mode: 0644]
board/purple/u-boot.lds [new file with mode: 0644]
common/cmd_boot.c
common/soft_i2c.c
cpu/mips/cache.S
doc/README.Purple [new file with mode: 0644]
drivers/Makefile
drivers/plb2800_eth.c [new file with mode: 0644]
include/configs/purple.h [new file with mode: 0644]
include/version.h

index 793c936fc33f372f23d6387b5a9758a6ca399189..09ee8a92f92e481dc44a1b60e64a4e4c85ae8ece 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,5 @@
 ======================================================================
 ======================================================================
-Changes since U-Boot 0.2.2:
+Changes for U-Boot 0.3.0:
 ======================================================================
 
 * Patch by Arun Dharankar, 4 Apr 2003:
 ======================================================================
 
 * Patch by Arun Dharankar, 4 Apr 2003:
diff --git a/board/purple/Makefile b/board/purple/Makefile
new file mode 100644 (file)
index 0000000..d1b0056
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# (C) Copyright 2003
+# 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 sconsole.o
+SOBJS  = memsetup.o
+
+$(LIB):        .depend $(OBJS) $(SOBJS)
+       $(AR) crv $@ $^
+
+#########################################################################
+
+.depend:       Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+               $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/purple/config.mk b/board/purple/config.mk
new file mode 100644 (file)
index 0000000..ea478ed
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# (C) Copyright 2003
+# 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
+#
+
+#
+# Purple board with MIPS 5Kc CPU core
+#
+
+# ROM version
+TEXT_BASE = 0xB0000000
+
+# RAM version
+#TEXT_BASE = 0x80100000
diff --git a/board/purple/flash.c b/board/purple/flash.c
new file mode 100644 (file)
index 0000000..56d3acd
--- /dev/null
@@ -0,0 +1,596 @@
+/*
+ * (C) Copyright 2003
+ * 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 <common.h>
+#include <asm/inca-ip.h>
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
+
+typedef unsigned long FLASH_PORT_WIDTH;
+typedef volatile unsigned long FLASH_PORT_WIDTHV;
+
+#define        FLASH_ID_MASK   0xFFFFFFFF
+
+#define FPW    FLASH_PORT_WIDTH
+#define FPWV   FLASH_PORT_WIDTHV
+
+#define ORMASK(size) ((-size) & OR_AM_MSK)
+
+#define FLASH29_REG_ADRS(reg) ((FPWV *)PHYS_FLASH_1 + (reg))
+
+/* FLASH29 command register addresses */
+
+#define FLASH29_REG_FIRST_CYCLE                FLASH29_REG_ADRS (0x1555)
+#define FLASH29_REG_SECOND_CYCLE       FLASH29_REG_ADRS (0x2aaa)
+#define FLASH29_REG_THIRD_CYCLE                FLASH29_REG_ADRS (0x3555)       
+#define        FLASH29_REG_FOURTH_CYCLE        FLASH29_REG_ADRS (0x4555)
+#define        FLASH29_REG_FIFTH_CYCLE         FLASH29_REG_ADRS (0x5aaa)
+#define        FLASH29_REG_SIXTH_CYCLE         FLASH29_REG_ADRS (0x6555)
+
+/* FLASH29 command definitions */
+
+#define        FLASH29_CMD_FIRST               0xaaaaaaaa
+#define        FLASH29_CMD_SECOND              0x55555555
+#define        FLASH29_CMD_FOURTH              0xaaaaaaaa
+#define        FLASH29_CMD_FIFTH               0x55555555
+#define        FLASH29_CMD_SIXTH               0x10101010
+
+#define        FLASH29_CMD_SECTOR              0x30303030
+#define        FLASH29_CMD_PROGRAM             0xa0a0a0a0
+#define        FLASH29_CMD_CHIP_ERASE          0x80808080
+#define        FLASH29_CMD_READ_RESET          0xf0f0f0f0
+#define        FLASH29_CMD_AUTOSELECT          0x90909090
+#define FLASH29_CMD_READ               0x70707070      
+
+#define IN_RAM_CMD_READ                0x1
+#define IN_RAM_CMD_WRITE       0x2
+
+#define FLASH_WRITE_CMD        ((ulong)(flash_write_cmd) & 0x7)+0xbf008000
+#define FLASH_READ_CMD  ((ulong)(flash_read_cmd) & 0x7)+0xbf008000
+
+typedef void (*FUNCPTR_CP)(ulong *source, ulong *destination, ulong nlongs);
+typedef void (*FUNCPTR_RD)(int cmd, FPWV * pFA, char * string, int strLen);
+typedef void (*FUNCPTR_WR)(int cmd, FPWV * pFA, FPW value);
+
+static ulong flash_get_size(FPWV *addr, flash_info_t *info);
+static int write_word(flash_info_t *info, FPWV *dest, FPW data);
+static void flash_get_offsets(ulong base, flash_info_t *info);
+static flash_info_t *flash_get_info(ulong base);
+
+static void load_cmd(ulong cmd);
+static ulong in_ram_cmd = 0;
+
+
+/******************************************************************************
+*
+* Don't change the program architecture
+* This architecture assure the program
+* can be relocated to scratch ram
+*/
+static void flash_read_cmd(int cmd, FPWV * pFA, char * string, int strLen)
+{                                      
+       int i,j;
+       FPW temp,temp1; 
+       FPWV *str;
+
+       str = (FPWV *)string;
+
+       j=  strLen/4;
+       
+       if(cmd == FLASH29_CMD_AUTOSELECT)
+          {
+            *(FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
+            *(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
+            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_AUTOSELECT;
+           }
+
+        if(cmd == FLASH29_CMD_READ)
+           { 
+           i = 0;              
+           while(i<j)  
+            {
+               temp = *pFA++;
+               temp1 = *(int *)0xa0000000;
+                *(int *)0xbf0081f8 = temp1 + temp;
+               *str++ = temp;
+               i++;
+           }           
+           }
+
+         if(cmd == FLASH29_CMD_READ_RESET) 
+         {
+            *(FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
+            *(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
+            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_READ_RESET;
+         }                             
+               
+       *(int *)0xbf0081f8 = *(int *)0xa0000000;        /* dummy read switch back to sdram interface */ 
+}
+
+/******************************************************************************
+*
+* Don't change the program architecture
+* This architecture assure the program
+* can be relocated to scratch ram
+*/
+static void flash_write_cmd(int cmd, FPWV * pFA, FPW value)
+{                                              
+        *(FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
+        *(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
+
+       if (cmd == FLASH29_CMD_SECTOR)
+          {
+            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_CHIP_ERASE;
+            *(FLASH29_REG_FOURTH_CYCLE) = FLASH29_CMD_FOURTH;
+            *(FLASH29_REG_FIFTH_CYCLE)  = FLASH29_CMD_FIFTH;
+            *pFA                       = FLASH29_CMD_SECTOR;
+           }
+
+        if (cmd == FLASH29_CMD_SIXTH)
+           { 
+            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_CHIP_ERASE;
+            *(FLASH29_REG_FOURTH_CYCLE) = FLASH29_CMD_FOURTH;
+            *(FLASH29_REG_FIFTH_CYCLE)  = FLASH29_CMD_FIFTH;
+            *(FLASH29_REG_SIXTH_CYCLE)  = FLASH29_CMD_SIXTH;
+          }
+
+        if (cmd == FLASH29_CMD_PROGRAM)
+           {
+            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_PROGRAM;
+           *pFA = value;
+           }
+
+        if (cmd == FLASH29_CMD_READ_RESET)    
+           {
+            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_READ_RESET;
+           }                           
+               
+       *(int *)0xbf0081f8 = *(int *)0xa0000000;        /* dummy read switch back to sdram interface */ 
+}
+
+static void load_cmd(ulong cmd)
+{
+       ulong *src;
+       ulong *dst;
+       FUNCPTR_CP absEntry;
+       ulong func;
+        
+       if (in_ram_cmd & cmd) return;
+       
+       if (cmd == IN_RAM_CMD_READ)
+       {
+               func = (ulong)flash_read_cmd;
+       }
+       else
+       {
+               func = (ulong)flash_write_cmd;
+       }
+
+       src = (ulong *)(func & 0xfffffff8);
+       dst = (ulong *)0xbf008000;
+       absEntry = (FUNCPTR_CP)(0xbf0081d0);
+       absEntry(src,dst,0x38);
+
+        in_ram_cmd = cmd;
+}
+
+/*-----------------------------------------------------------------------
+ * flash_init()
+ *
+ * sets up flash_info and returns size of FLASH (bytes)
+ */
+unsigned long flash_init (void)
+{
+       unsigned long size = 0;
+       int i;
+        
+        load_cmd(IN_RAM_CMD_READ);
+
+       /* Init: no FLASHes known */
+       for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) {
+               ulong flashbase = PHYS_FLASH_1;
+               ulong * buscon = (ulong *) INCA_IP_EBU_EBU_BUSCON0;
+               
+               /* Disable write protection */
+               *buscon &= ~INCA_IP_EBU_EBU_BUSCON1_WRDIS;
+
+#if 1
+               memset(&flash_info[i], 0, sizeof(flash_info_t));
+#endif
+
+               flash_info[i].size = 
+                       flash_get_size((FPW *)flashbase, &flash_info[i]);
+
+               if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+                       printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n",
+                       i, flash_info[i].size);
+               }
+               
+               size += flash_info[i].size;
+       }
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+       /* monitor protection ON by default */
+       flash_protect(FLAG_PROTECT_SET,
+                     CFG_MONITOR_BASE,
+                     CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+                     flash_get_info(CFG_MONITOR_BASE));
+#endif
+
+#ifdef CFG_ENV_IS_IN_FLASH
+       /* ENV protection ON by default */
+       flash_protect(FLAG_PROTECT_SET,
+                     CFG_ENV_ADDR,
+                     CFG_ENV_ADDR+CFG_ENV_SIZE-1,
+                     flash_get_info(CFG_ENV_ADDR));
+#endif
+
+       return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+       int i;
+
+       if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
+                && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM160B) {
+
+               int bootsect_size[4];   /* number of bytes/boot sector  */
+               int sect_size;          /* number of bytes/regular sector */
+
+               bootsect_size[0] = 0x00008000;
+               bootsect_size[1] = 0x00004000;
+               bootsect_size[2] = 0x00004000;
+               bootsect_size[3] = 0x00010000;
+               sect_size =        0x00020000;
+
+               /* set sector offsets for bottom boot block type        */
+               for (i = 0; i < info->sector_count; i++) {
+                       info->start[i] = base;
+                       base += i < 4 ? bootsect_size[i] : sect_size;
+               }
+       }
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+static flash_info_t *flash_get_info(ulong base)
+{
+       int i;
+       flash_info_t * info;
+       
+       for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
+               info = & flash_info[i];
+               if (info->start[0] <= base && base < info->start[0] + info->size)
+                       break;
+       }
+       
+       return i == CFG_MAX_FLASH_BANKS ? 0 : info;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+void flash_print_info (flash_info_t *info)
+{
+       int i;
+       uchar *boottype;
+       uchar *bootletter;
+       uchar *fmt;
+       uchar botbootletter[] = "B";
+       uchar topbootletter[] = "T";
+       uchar botboottype[] = "bottom boot sector";
+       uchar topboottype[] = "top boot sector";
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:     printf ("AMD ");                break;
+       case FLASH_MAN_BM:      printf ("BRIGHT MICRO ");       break;
+       case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
+       case FLASH_MAN_SST:     printf ("SST ");                break;
+       case FLASH_MAN_STM:     printf ("STM ");                break;
+       case FLASH_MAN_INTEL:   printf ("INTEL ");              break;
+       default:                printf ("Unknown Vendor ");     break;
+       }
+
+       /* check for top or bottom boot, if it applies */
+       if (info->flash_id & FLASH_BTYPE) {
+               boottype = botboottype;
+               bootletter = botbootletter;
+       }
+       else {
+               boottype = topboottype;
+               bootletter = topbootletter;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AM160B:
+               fmt = "29LV160B%s (16 Mbit, %s)\n";
+               break;
+        case FLASH_28F800C3B:
+        case FLASH_28F800C3T:
+               fmt = "28F800C3%s (8 Mbit, %s)\n";
+               break;
+       case FLASH_INTEL800B:
+       case FLASH_INTEL800T:
+               fmt = "28F800B3%s (8 Mbit, %s)\n";
+               break;
+        case FLASH_28F160C3B:
+        case FLASH_28F160C3T:
+               fmt = "28F160C3%s (16 Mbit, %s)\n";
+               break;
+       case FLASH_INTEL160B:
+       case FLASH_INTEL160T:
+               fmt = "28F160B3%s (16 Mbit, %s)\n";
+               break;
+        case FLASH_28F320C3B:
+        case FLASH_28F320C3T:
+               fmt = "28F320C3%s (32 Mbit, %s)\n";
+               break;
+       case FLASH_INTEL320B:
+       case FLASH_INTEL320T:
+               fmt = "28F320B3%s (32 Mbit, %s)\n";
+               break;
+        case FLASH_28F640C3B:
+        case FLASH_28F640C3T:
+               fmt = "28F640C3%s (64 Mbit, %s)\n";
+               break;
+       case FLASH_INTEL640B:
+       case FLASH_INTEL640T:
+               fmt = "28F640B3%s (64 Mbit, %s)\n";
+               break;
+       default:
+               fmt = "Unknown Chip Type\n";
+               break;
+       }
+
+       printf (fmt, bootletter, boottype);
+
+       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");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+ulong flash_get_size (FPWV *addr, flash_info_t *info)
+{
+       FUNCPTR_RD absEntry;
+       FPW retValue;   
+       int flag;
+
+        load_cmd(IN_RAM_CMD_READ);
+       absEntry = (FUNCPTR_RD)FLASH_READ_CMD;
+
+       flag = disable_interrupts();
+       absEntry(FLASH29_CMD_AUTOSELECT,0,0,0);
+       if (flag) enable_interrupts();
+       
+       udelay(100);
+
+       flag = disable_interrupts();
+       absEntry(FLASH29_CMD_READ, addr + 1, (char *)&retValue, sizeof(retValue));
+       absEntry(FLASH29_CMD_READ_RESET,0,0,0);
+       if (flag) enable_interrupts();
+
+       udelay(100);
+
+       switch (retValue) {
+
+       case (FPW)AMD_ID_LV160B:
+               info->flash_id += FLASH_AM160B;
+               info->sector_count = 35;
+               info->size = 0x00400000;
+               break;                          /* => 8 or 16 MB        */
+
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               return (0);                     /* => no or unknown flash */
+       }
+
+       flash_get_offsets((ulong)addr, info);
+
+       return (info->size);
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int    flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+       FPWV *addr;
+       int flag, prot, sect;
+       ulong start, now, last;
+       int rcode = 0;
+       FUNCPTR_WR absEntry;
+
+        load_cmd(IN_RAM_CMD_WRITE);
+       absEntry = (FUNCPTR_WR)FLASH_WRITE_CMD;
+
+       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;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AM160B:
+               break;
+       case FLASH_UNKNOWN:
+       default:
+               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");
+       }
+
+       last  = get_timer(0);
+
+       /* Start erase on unprotected sectors */
+       for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
+
+               if (info->protect[sect] != 0)   /* protected, skip it */
+                       continue;
+
+               /* Disable interrupts which might cause a timeout here */
+               flag = disable_interrupts();
+
+               addr = (FPWV *)(info->start[sect]);
+               absEntry(FLASH29_CMD_SECTOR, addr, 0);
+
+               /* re-enable interrupts if necessary */
+               if (flag)
+                       enable_interrupts();
+
+               start = get_timer(0);
+
+               while ((now = get_timer(start)) <= CFG_FLASH_ERASE_TOUT) {
+
+                       /* show that we're waiting */
+                       if ((get_timer(last)) > CFG_HZ) {/* every second */
+                               putc ('.');
+                               last = get_timer(0);
+                       }
+               }
+
+               flag = disable_interrupts();
+               absEntry(FLASH29_CMD_READ_RESET,0,0);
+               if (flag)
+                       enable_interrupts();
+       }
+
+       printf (" done\n");
+       return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
+    int bytes;   /* number of bytes to program in current word         */
+    int left;    /* number of bytes left to program                    */
+    int i, res;
+
+    for (left = cnt, res = 0;
+        left > 0 && res == 0;
+        addr += sizeof(data), left -= sizeof(data) - bytes) {
+
+        bytes = addr & (sizeof(data) - 1);
+        addr &= ~(sizeof(data) - 1);
+
+       /* combine source and destination data so can program
+        * an entire word of 16 or 32 bits
+        */
+        for (i = 0; i < sizeof(data); i++) {
+            data <<= 8;
+            if (i < bytes || i - bytes >= left )
+               data += *((uchar *)addr + i);
+           else
+               data += *src++;
+       }
+
+       res = write_word(info, (FPWV *)addr, data);
+    }
+
+    return (res);
+}
+
+static int write_word (flash_info_t *info, FPWV *dest, FPW data)
+{
+    int res = 0;       /* result, assume success       */
+    FUNCPTR_WR absEntry;
+    int flag;
+
+    /* Check if Flash is (sufficiently) erased */
+    if ((*dest & data) != data) {
+       return (2);
+    }
+
+    if (info->start[0] != PHYS_FLASH_1)
+    {
+       return (3);
+    }
+
+    load_cmd(IN_RAM_CMD_WRITE);
+    absEntry = (FUNCPTR_WR)FLASH_WRITE_CMD;
+
+    flag = disable_interrupts();
+    absEntry(FLASH29_CMD_PROGRAM,dest,data);
+    if (flag) enable_interrupts();
+
+    udelay(100);
+
+    flag = disable_interrupts();
+    absEntry(FLASH29_CMD_READ_RESET,0,0);
+    if (flag) enable_interrupts();
+
+    return (res);
+}
diff --git a/board/purple/memsetup.S b/board/purple/memsetup.S
new file mode 100644 (file)
index 0000000..55daf8a
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  Memory sub-system initialization code for PURPLE development board.
+ *
+ *  Copyright (c) 2003 Wolfgang Denk <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 <config.h>
+#include <version.h>
+#include <asm/regdef.h>
+
+
+       .globl  memsetup
+memsetup:
+
+       j       ra
+       nop
+
diff --git a/board/purple/purple.c b/board/purple/purple.c
new file mode 100644 (file)
index 0000000..293cc56
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * (C) Copyright 2003
+ * 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 <common.h>
+#include <command.h>
+#include <asm/inca-ip.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/cacheops.h>
+
+#include "sconsole.h"
+
+#define cache_unroll(base,op)                  \
+       __asm__ __volatile__("                  \
+               .set noreorder;                 \
+               .set mips3;                     \
+                cache %1, (%0);                        \
+               .set mips0;                     \
+               .set reorder"                   \
+               :                               \
+               : "r" (base),                   \
+                 "i" (op));
+
+typedef void (*FUNCPTR)(ulong *source, ulong *destination, ulong nlongs);
+
+extern void    asc_serial_init         (void);
+extern void    asc_serial_putc         (char);
+extern void    asc_serial_puts         (const char *);
+extern int     asc_serial_getc         (void);
+extern int     asc_serial_tstc         (void);
+extern void    asc_serial_setbrg       (void);
+
+
+long int initdram(int board_type)
+{
+       /* The only supported number of SDRAM banks is 4.
+        */
+#define CFG_NB 4
+
+       ulong   cfgpb0  = *INCA_IP_SDRAM_MC_CFGPB0;
+       ulong   cfgdw   = *INCA_IP_SDRAM_MC_CFGDW;
+       int     cols    = cfgpb0 & 0xF;
+       int     rows    = (cfgpb0 & 0xF0) >> 4;
+       int     dw      = cfgdw & 0xF;
+       ulong   size    = (1 << (rows + cols)) * (1 << (dw - 1)) * CFG_NB;
+
+       return size;
+}
+
+int checkboard (void)
+{
+
+       unsigned long chipid = *(unsigned long *)0xB800C800;
+
+       printf ("Board: Purple PLB 2800 chip version %ld, ", chipid & 0xF);
+
+       printf("CPU Speed %d MHz\n", CPU_CLOCK_RATE/1000000);
+
+       return 0;
+}
+
+int misc_init_r (void)
+{
+       asc_serial_init ();
+
+       sconsole_putc   = asc_serial_putc;
+       sconsole_puts   = asc_serial_puts;
+       sconsole_getc   = asc_serial_getc;
+       sconsole_tstc   = asc_serial_tstc;
+       sconsole_setbrg = asc_serial_setbrg;
+
+       sconsole_flush ();
+       return (0);
+}
+
+/*******************************************************************************
+*
+* copydwords - copy one buffer to another a long at a time
+*
+* This routine copies the first <nlongs> longs from <source> to <destination>.
+*/
+static void copydwords (ulong *source, ulong *destination, ulong nlongs)
+{
+       ulong temp,temp1;
+       ulong *dstend = destination + nlongs;
+
+       while (destination < dstend)
+       {
+               temp = *source++;
+               /* dummy read from sdram */
+               temp1 = *(ulong *)0xa0000000;
+               /* avoid optimization from compliler */
+               *(ulong *)0xbf0081f8 = temp1 + temp;
+               *destination++ = temp;
+
+       } 
+}
+
+/*******************************************************************************
+*
+* copyLongs - copy one buffer to another a long at a time
+*
+* This routine copies the first <nlongs> longs from <source> to <destination>.
+*/
+static void copyLongs (ulong *source, ulong *destination, ulong nlongs)
+{
+       FUNCPTR absEntry;
+
+       absEntry = (FUNCPTR)(0xbf008000+((ulong)copydwords & 0x7));
+       absEntry(source, destination, nlongs);
+}
+
+/*******************************************************************************
+*
+* programLoad - load program into ram
+*
+* This routine load copydwords into ram
+*
+*/
+static void programLoad(void)
+{
+       FUNCPTR absEntry;
+       ulong *src,*dst;
+
+       src = (ulong *)(TEXT_BASE + 0x428);
+       dst = (ulong *)0xbf0081d0;
+
+       absEntry = (FUNCPTR)(TEXT_BASE + 0x400);   
+       absEntry(src,dst,0x6);          
+
+       src = (ulong *)((ulong)copydwords & 0xfffffff8);
+       dst = (ulong *)0xbf008000;
+
+       absEntry(src,dst,0x38);
+}
+
+/*******************************************************************************
+*
+* copy_code - copy u-boot image from flash to RAM
+*
+* This routine is needed to solve flash problems on this board
+*
+*/
+void copy_code (ulong dest_addr)
+{
+       unsigned long start;
+       unsigned long end;
+
+       /* load copydwords into ram
+        */
+       programLoad();
+
+       /* copy u-boot code
+        */
+       copyLongs((ulong *)CFG_MONITOR_BASE,
+                 (ulong *)dest_addr,
+                 (CFG_MONITOR_LEN + 3) / 4);
+
+
+       /* flush caches
+        */
+
+       start = KSEG0;
+       end = start + CFG_DCACHE_SIZE;
+       while(start < end) {
+               cache_unroll(start,Index_Writeback_Inv_D);
+               start += CFG_CACHELINE_SIZE;
+       }
+
+       start = KSEG0;
+       end = start + CFG_ICACHE_SIZE;
+       while(start < end) {
+               cache_unroll(start,Index_Invalidate_I);
+               start += CFG_CACHELINE_SIZE;
+       }
+}
diff --git a/board/purple/sconsole.c b/board/purple/sconsole.c
new file mode 100644 (file)
index 0000000..f52d50d
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * (C) Copyright 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
+ */
+
+#include <config.h>
+#include <common.h>
+
+#include "sconsole.h"
+
+void   (*sconsole_putc) (char) = 0;
+void   (*sconsole_puts) (const char *) = 0;
+int    (*sconsole_getc) (void) = 0;
+int    (*sconsole_tstc) (void) = 0;
+void   (*sconsole_setbrg) (void) = 0;
+
+int serial_init (void)
+{
+       sconsole_buffer_t *sb = SCONSOLE_BUFFER;
+
+       sb->pos  = 0;
+       sb->size = 0;
+       sb->max_size = CFG_SCONSOLE_SIZE - sizeof (sconsole_buffer_t);
+
+       return (0);
+}
+
+void serial_putc (char c)
+{
+       if (sconsole_putc) {
+               (*sconsole_putc) (c);
+       } else {
+               sconsole_buffer_t *sb = SCONSOLE_BUFFER;
+
+               if (c) {
+                       sb->data[sb->pos++] = c;
+                       if (sb->pos == sb->max_size) {
+                               sb->pos = 0;
+                       }
+                       if (sb->size < sb->max_size) {
+                               sb->size++;
+                       }
+               }
+       }
+}
+
+void serial_puts (const char *s)
+{
+       if (sconsole_puts) {
+               (*sconsole_puts) (s);
+       } else {
+               sconsole_buffer_t *sb = SCONSOLE_BUFFER;
+
+               while (*s) {
+                       sb->data[sb->pos++] = *s++;
+                       if (sb->pos == sb->max_size) {
+                               sb->pos = 0;
+                       }
+                       if (sb->size < sb->max_size) {
+                               sb->size++;
+                       }
+               }
+       }
+}
+
+int serial_getc (void)
+{
+       if (sconsole_getc) {
+               return (*sconsole_getc) ();
+       } else {
+               return 0;
+       }
+}
+
+int serial_tstc (void)
+{
+       if (sconsole_tstc) {
+               return (*sconsole_tstc) ();
+       } else {
+               return 0;
+       }
+}
+
+void serial_setbrg (void)
+{
+       if (sconsole_setbrg) {
+               (*sconsole_setbrg) ();
+       }
+}
+
+void sconsole_flush (void)
+{
+       if (sconsole_putc) {
+               sconsole_buffer_t *sb = SCONSOLE_BUFFER;
+               unsigned int end = sb->pos < sb->size
+                               ? sb->pos + sb->max_size - sb->size
+                               : sb->pos - sb->size;
+
+               while (sb->size) {
+                       (*sconsole_putc) (sb->data[end++]);
+                       if (end == sb->max_size) {
+                               end = 0;
+                       }
+                       sb->size--;
+               }
+       }
+}
diff --git a/board/purple/sconsole.h b/board/purple/sconsole.h
new file mode 100644 (file)
index 0000000..d441f37
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 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
+ */
+
+#ifndef _SCONSOLE_H_
+#define _SCONSOLE_H_
+
+#include <config.h>
+
+typedef struct sconsole_buffer_s
+{
+  unsigned long                size;
+  unsigned long                max_size;
+  unsigned long        pos;
+  char                 data [1];
+} sconsole_buffer_t;
+
+#define SCONSOLE_BUFFER                ((sconsole_buffer_t *) CFG_SCONSOLE_ADDR)
+
+extern void    (* sconsole_putc)       (char);
+extern void    (* sconsole_puts)       (const char *);
+extern int     (* sconsole_getc)       (void);
+extern int     (* sconsole_tstc)       (void);
+extern void    (* sconsole_setbrg)     (void);
+
+extern void    sconsole_flush          (void);
+
+#endif
diff --git a/board/purple/u-boot.lds b/board/purple/u-boot.lds
new file mode 100644 (file)
index 0000000..7508865
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk 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-bigmips", "elf32-bigmips", "elf32-bigmips")
+*/
+OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradbigmips")
+OUTPUT_ARCH(mips)
+ENTRY(_start)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+       .text       :
+       {
+         cpu/mips/start.o              (.text)
+         board/purple/memsetup.o       (.text)
+         cpu/mips/cache.o              (.text)
+         common/main.o                 (.text)
+         common/dlmalloc.o             (.text)
+         common/cmd_boot.o             (.text)
+         lib_generic/zlib.o            (.text)
+         . = DEFINED(env_offset) ? env_offset : .;
+         common/environment.o  (.ppcenv)
+
+         *(.text)
+       }
+
+        . = ALIGN(4);
+        .rodata  : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data  : { *(.data) }
+
+       . = ALIGN(4);
+       .sdata  : { *(.sdata) }
+
+       _gp = ALIGN(16);
+
+       __got_start = .;
+       .got  : { *(.got) }
+       __got_end = .;
+
+       .sdata  : { *(.sdata) }
+
+       uboot_end_data = .;
+       num_got_entries = (__got_end - __got_start) >> 2;
+
+        . = ALIGN(4);
+       .sbss  : { *(.sbss) }
+        .bss  : { *(.bss) }
+       uboot_end = .;
+}
index 09f3f78f4989c815e6331f5cd252b51575c785d8..2fc0729f3f2e7652dcf261842e808d5847e211c7 100644 (file)
@@ -1000,14 +1000,14 @@ static int k_recv (void)
                for (;;) {
                        switch (serial_getc ()) {
                        case START_CHAR:        /* start packet */
                for (;;) {
                        switch (serial_getc ()) {
                        case START_CHAR:        /* start packet */
-                               break;
+                               goto START;
                        case ETX_CHAR:          /* ^C waiting for packet */
                                return (0);
                        default:
                                ;
                        }
                }
                        case ETX_CHAR:          /* ^C waiting for packet */
                                return (0);
                        default:
                                ;
                        }
                }
-                       
+START:
                /* get length of packet */
                sum = 0;
                new_char = serial_getc ();
                /* get length of packet */
                sum = 0;
                new_char = serial_getc ();
index 63574044ad0de900897c6d7d02a3a277a3f0886f..dc26d6f508e14b29f54a26887b23b5ea3face007 100644 (file)
@@ -83,8 +83,12 @@ static void send_reset(void)
 #endif
        int j;
 
 #endif
        int j;
 
-       I2C_ACTIVE;
+       I2C_SCL(1);
        I2C_SDA(1);
        I2C_SDA(1);
+#ifdef I2C_INIT
+       I2C_INIT;
+#endif
+       I2C_TRISTATE;
        for(j = 0; j < 9; j++) {
                I2C_SCL(0);
                I2C_DELAY;
        for(j = 0; j < 9; j++) {
                I2C_SCL(0);
                I2C_DELAY;
@@ -262,13 +266,6 @@ static uchar read_byte(int ack)
  */
 void i2c_init (int speed, int slaveaddr)
 {
  */
 void i2c_init (int speed, int slaveaddr)
 {
-#ifdef CONFIG_8xx
-       volatile immap_t *immr = (immap_t *)CFG_IMMR;
-#endif
-
-#ifdef I2C_INIT
-       I2C_INIT;
-#endif
        /*
          * WARNING: Do NOT save speed in a static variable: if the
          * I2C routines are called before RAM is initialized (to read
        /*
          * WARNING: Do NOT save speed in a static variable: if the
          * I2C routines are called before RAM is initialized (to read
index 2715b9b025c06d0802b51dbb14ca820837d48498..55daa89e7290d555622f163e3c1b77ee53aba663 100644 (file)
@@ -250,12 +250,17 @@ dcache_disable:
 * RETURNS: N/A
 *
 */
 * RETURNS: N/A
 *
 */
+#if defined(CONFIG_INCA_IP)
+# define       CACHE_LOCK_SIZE (CFG_DCACHE_SIZE)
+#elif defined(CONFIG_PURPLE)
+# define       CACHE_LOCK_SIZE (CFG_DCACHE_SIZE/2)
+#endif
        .globl  mips_cache_lock
        .ent    mips_cache_lock
 mips_cache_lock:
        .globl  mips_cache_lock
        .ent    mips_cache_lock
 mips_cache_lock:
-       li      a1, K0BASE - CFG_DCACHE_SIZE/2
+       li      a1, K0BASE - CACHE_LOCK_SIZE
        addu    a0, a1
        addu    a0, a1
-       li      a2, CFG_DCACHE_SIZE/2
+       li      a2, CACHE_LOCK_SIZE
        li      a3, CFG_CACHELINE_SIZE
        move    a1, a2
        icacheop(a0,a1,a2,a3,0x1d)
        li      a3, CFG_CACHELINE_SIZE
        move    a1, a2
        icacheop(a0,a1,a2,a3,0x1d)
diff --git a/doc/README.Purple b/doc/README.Purple
new file mode 100644 (file)
index 0000000..9e70004
--- /dev/null
@@ -0,0 +1,52 @@
+Installation Instructions:
+--------------------------
+
+1. Put the s2 switch into the following position:
+
+        1  0
+       ------
+       |x   |
+       |   x|
+       |x   |  
+       |   X|  
+       ------
+
+2. Connect to the serial console and to the BDI. Power on. On the
+   serial line, you should see:
+
+       PURPLE@1.2>
+
+3. Type '8'. No echo will be displayed. In response, you should get:
+
+       7A(pass)
+
+4. From BDI, enter command:
+
+       mmw 0xb800d860 0x0042c7ff
+
+5. Then, from BDI:
+
+       erase 0xB0000000
+       erase 0xB0008000
+       erase 0xB000C000
+       erase 0xB0010000
+       erase 0xB0020000
+
+       prog 0xB0000000 <u-boot.bin> bin
+
+6. Power off. Restore the original S2 switch position. Power on.
+   U-Boot should come up.
+
+
+
+Implementation Notes:
+---------------------
+
+Due to the RAM/flash bus arbitration problem the suggested workaround
+had to be implemented. It works okay. On the downside is that you
+can't really check whether 'erase' is complete by polling flash as it
+is usually done. Instead, the flash driver simply waits for a given
+time and assumes that erase then has passed. This behaviour is
+identical to what the VxWorks driver does; also, the same timeout (6
+seconds) was chosen. Note that this timeout applies for each errase
+operation, i. e. per erased sector.
index 59d753ee44f07d26004fdc4debcb12c12a04a4a6..b3857a754ccc86644bbd14e0489a48de2bdfd08e 100644 (file)
@@ -33,7 +33,8 @@ OBJS  = 3c589.o 5701rls.o at91rm9200_ether.o \
          eepro100.o i8042.o inca-ip_sw.o \
          natsemi.o ns16550.o ns8382x.o ns87308.o \
          pci.o pci_auto.o pci_indirect.o \
          eepro100.o i8042.o inca-ip_sw.o \
          natsemi.o ns16550.o ns8382x.o ns87308.o \
          pci.o pci_auto.o pci_indirect.o \
-         pcnet.o s3c24x0_i2c.o sed13806.o serial.o \
+         pcnet.o plb2800_eth.o \
+         s3c24x0_i2c.o sed13806.o serial.o \
          smc91111.o smiLynxEM.o sym53c8xx.o \
          tigon3.o w83c553f.o
 
          smc91111.o smiLynxEM.o sym53c8xx.o \
          tigon3.o w83c553f.o
 
diff --git a/drivers/plb2800_eth.c b/drivers/plb2800_eth.c
new file mode 100644 (file)
index 0000000..7c7f9f8
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * PLB2800 internal switch ethernet driver.
+ *
+ * (C) Copyright 2003
+ * 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 <common.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
+       && defined(CONFIG_PLB2800_ETHER)
+
+#include <malloc.h>
+#include <net.h>
+#include <asm/addrspace.h>
+
+
+#define NUM_RX_DESC    PKTBUFSRX
+#define TOUT_LOOP      1000000
+
+#define LONG_REF(addr) (*((volatile unsigned long*)addr))
+
+#define CMAC_CRX_CTRL  LONG_REF(0xb800c870)
+#define CMAC_CTX_CTRL  LONG_REF(0xb800c874)
+#define SYS_MAC_ADDR_0 LONG_REF(0xb800c878)
+#define SYS_MAC_ADDR_1 LONG_REF(0xb800c87c)
+#define MIPS_H_MASK    LONG_REF(0xB800C810)
+
+#define MA_LEARN       LONG_REF(0xb8008004)
+#define DA_LOOKUP      LONG_REF(0xb8008008)
+
+#define CMAC_CRX_CTRL_PD       0x00000001
+#define CMAC_CRX_CTRL_CG       0x00000002
+#define CMAC_CRX_CTRL_PL_SHIFT 2
+#define CMAC_CRIT              0x0
+#define CMAC_NON_CRIT          0x1
+#define MBOX_STAT_ID_SHF       28
+#define MBOX_STAT_CP           0x80000000
+#define MBOX_STAT_MB           0x00000001
+#define EN_MA_LEARN            0x02000000
+#define EN_DA_LKUP             0x01000000
+#define MA_DEST_SHF            11 
+#define DA_DEST_SHF            11
+#define DA_STATE_SHF           19
+#define TSTAMP_MS              0x00000000
+#define SW_H_MBOX4_MASK                0x08000000
+#define SW_H_MBOX3_MASK                0x04000000
+#define SW_H_MBOX2_MASK                0x02000000
+#define SW_H_MBOX1_MASK                0x01000000
+
+typedef volatile struct {
+  unsigned int stat;
+  unsigned int cmd;
+  unsigned int cnt;
+  unsigned int adr;
+} mailbox_t;
+
+#define MBOX_REG(mb) ((mailbox_t*)(0xb800c830+(mb<<4)))
+
+typedef volatile struct {
+  unsigned int word0;
+  unsigned int word1;
+  unsigned int word2;
+} mbhdr_t;
+
+#define MBOX_MEM(mb) ((void*)(0xb800a000+((3-mb)<<11)))
+
+
+static int plb2800_eth_init(struct eth_device *dev, bd_t * bis);
+static int plb2800_eth_send(struct eth_device *dev, volatile void *packet,
+                                                 int length);
+static int plb2800_eth_recv(struct eth_device *dev);
+static void plb2800_eth_halt(struct eth_device *dev);
+
+static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr);
+static unsigned char * plb2800_get_mac_addr(void);
+
+static int rx_new;
+static int mac_addr_set = 0;
+
+
+int plb2800_eth_initialize(bd_t * bis)
+{
+       struct eth_device *dev;
+       ulong temp;
+
+#ifdef DEBUG
+       printf("Entered plb2800_eth_initialize()\n");
+#endif
+
+       if (!(dev = (struct eth_device *) malloc (sizeof *dev)))
+       {
+               printf("Failed to allocate memory\n");
+               return 0;
+       }
+       memset(dev, 0, sizeof(*dev));
+
+       sprintf(dev->name, "PLB2800 Switch");
+       dev->init = plb2800_eth_init;
+       dev->halt = plb2800_eth_halt;
+       dev->send = plb2800_eth_send;
+       dev->recv = plb2800_eth_recv;
+
+       eth_register(dev);
+
+       /* bug fix */   
+       *(ulong *)0xb800e800 = 0x838;   
+
+       /* Set MBOX ownership */
+       temp = CMAC_CRIT << MBOX_STAT_ID_SHF;
+       MBOX_REG(0)->stat = temp;
+       MBOX_REG(1)->stat = temp;
+
+       temp = CMAC_NON_CRIT << MBOX_STAT_ID_SHF;       
+       MBOX_REG(2)->stat = temp;
+       MBOX_REG(3)->stat = temp;
+       
+       plb2800_set_mac_addr(dev, plb2800_get_mac_addr());
+
+       /* Disable all Mbox interrupt */
+       temp = MIPS_H_MASK;
+       temp &= ~ (SW_H_MBOX1_MASK | SW_H_MBOX2_MASK | SW_H_MBOX3_MASK | SW_H_MBOX4_MASK) ;                     
+       MIPS_H_MASK = temp;
+
+#ifdef DEBUG
+       printf("Leaving plb2800_eth_initialize()\n");
+#endif
+
+       return 1;
+}
+
+static int plb2800_eth_init(struct eth_device *dev, bd_t * bis)
+{
+#ifdef DEBUG
+       printf("Entering plb2800_eth_init()\n");
+#endif
+
+       plb2800_set_mac_addr(dev, dev->enetaddr);
+
+       rx_new = 0;
+
+#ifdef DEBUG
+       printf("Leaving plb2800_eth_init()\n");
+#endif
+
+       return 0;
+}
+
+
+static int plb2800_eth_send(struct eth_device *dev, volatile void *packet,
+                                                 int length)
+{
+       int                    i;
+       int                    res         = -1;
+       u32                    temp;
+       mailbox_t *            mb          = MBOX_REG(0);
+       char      *            mem         = MBOX_MEM(0);
+
+#ifdef DEBUG
+       printf("Entered plb2800_eth_send()\n");
+#endif
+
+       if (length <= 0)
+       {
+               printf ("%s: bad packet size: %d\n", dev->name, length);
+               goto Done;
+       }
+
+       if (length < 64)
+       {
+               length = 64;
+       }
+
+       temp = CMAC_CRX_CTRL_CG | ((length + 4) << CMAC_CRX_CTRL_PL_SHIFT);
+
+#ifdef DEBUG
+       printf("0 mb->stat = 0x%x\n",  mb->stat);
+#endif
+
+       for(i = 0; mb->stat & (MBOX_STAT_CP | MBOX_STAT_MB); i++)
+       {
+               if (i >= TOUT_LOOP)
+               {
+                       printf("%s: tx buffer not ready\n", dev->name);
+                       printf("1 mb->stat = 0x%x\n",  mb->stat);
+                       goto Done;
+               }
+       }
+
+               /* For some strange reason, memcpy doesn't work, here!
+                */
+       do
+       {
+               int words = (length >> 2) + 1;
+               unsigned int* dst = (unsigned int*)(mem);
+               unsigned int* src = (unsigned int*)(packet);
+               for (i = 0; i < words; i++)
+               {
+                       *dst = *src;
+                       dst++;
+                       src++;
+               };
+       } while(0);
+
+       CMAC_CRX_CTRL = temp;
+       mb->cmd = MBOX_STAT_CP;
+       
+#ifdef DEBUG
+       printf("2 mb->stat = 0x%x\n",  mb->stat);
+#endif
+
+       res = length;
+Done:
+
+#ifdef DEBUG
+       printf("Leaving plb2800_eth_send()\n");
+#endif
+
+       return res;
+}
+
+
+static int plb2800_eth_recv(struct eth_device *dev)
+{
+       int                    length  = 0;
+       mailbox_t            * mbox    = MBOX_REG(3);
+       unsigned char        * hdr     = MBOX_MEM(3);
+       unsigned int           stat;
+
+#ifdef DEBUG
+       printf("Entered plb2800_eth_recv()\n");
+#endif
+
+       for (;;)
+       {
+               stat = mbox->stat;
+
+               if (!(stat & MBOX_STAT_CP))
+               {
+                       break;
+               }
+               
+               length = ((*(hdr + 6) & 0x3f) << 8) + *(hdr + 7);
+               memcpy((void *)NetRxPackets[rx_new], hdr + 12, length);
+
+               stat &= ~MBOX_STAT_CP;
+               mbox->stat = stat;
+#ifdef DEBUG
+               {
+                       int i;
+                       for (i=0;i<length - 4;i++)
+                       {
+                               if (i % 16 == 0) printf("\n%04x: ", i);
+                               printf("%02X ", NetRxPackets[rx_new][i]);
+                       }
+                       printf("\n");
+               }
+#endif
+
+               if (length)
+               {
+#ifdef DEBUG
+                       printf("Received %d bytes\n", length);
+#endif
+                       NetReceive((void*)(NetRxPackets[rx_new]),
+                                   length - 4);
+               }
+               else
+               {
+#if 1
+                       printf("Zero length!!!\n");
+#endif
+               }
+
+               rx_new = (rx_new + 1) % NUM_RX_DESC;
+       }
+
+#ifdef DEBUG
+       printf("Leaving plb2800_eth_recv()\n");
+#endif
+
+       return length;
+}
+
+
+static void plb2800_eth_halt(struct eth_device *dev)
+{
+#ifdef DEBUG
+       printf("Entered plb2800_eth_halt()\n");
+#endif
+
+#ifdef DEBUG
+       printf("Leaving plb2800_eth_halt()\n");
+#endif
+}
+
+static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr)
+{
+       char packet[60];
+       ulong temp;
+       int ix;
+
+       if (mac_addr_set ||
+           NULL == addr || memcmp(addr, "\0\0\0\0\0\0", 6) == 0)
+       {
+               return;
+       }
+       
+       /* send one packet through CPU port
+        * in order to learn system MAC address
+        */             
+
+       /* Set DA_LOOKUP register */
+       temp = EN_MA_LEARN | (0 << DA_STATE_SHF) | (63 << DA_DEST_SHF); 
+       DA_LOOKUP = temp;
+
+       /* Set MA_LEARN register */
+       temp = 50 << MA_DEST_SHF;       /* static entry */
+       MA_LEARN = temp;
+
+       /* set destination address */
+       for (ix=0;ix<6;ix++)
+               packet[ix] = 0xff;
+       /* set source address = system MAC address */
+       for (ix=0;ix<6;ix++)
+               packet[6+ix] = addr[ix];
+
+       /* set type field */
+       packet[12]=0xaa;
+       packet[13]=0x55;
+
+       /* set data field */
+       for(ix=14;ix<60;ix++)
+               packet[ix] = 0x00;
+       
+#ifdef DEBUG
+       for (ix=0;ix<6;ix++)
+               printf("mac_addr[%d]=%02X\n", ix, (unsigned char)packet[6+ix]);
+#endif
+
+       /* set one packet */
+       plb2800_eth_send(dev, packet, sizeof(packet));
+
+       /* delay for a while */
+       for(ix=0;ix<65535;ix++)
+               temp = ~temp;
+
+       /* Set CMAC_CTX_CTRL register */        
+       temp = TSTAMP_MS;       /* no autocast */
+       CMAC_CTX_CTRL = temp;
+         
+       /* Set DA_LOOKUP register */
+       temp = EN_DA_LKUP;
+       DA_LOOKUP = temp;
+
+       mac_addr_set = 1;
+}
+
+static unsigned char * plb2800_get_mac_addr(void)
+{
+       static unsigned char addr[6];
+       char *tmp, *end;
+       int i;
+       
+       tmp = getenv ("ethaddr");
+       if (NULL == tmp) return NULL;
+       
+       for (i=0; i<6; i++) {
+               addr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
+               if (tmp)
+                       tmp = (*end) ? end+1 : end;
+       }
+
+       return addr;
+}
+
+#endif /* CONFIG_PLB2800_ETHER */
diff --git a/include/configs/purple.h b/include/configs/purple.h
new file mode 100644 (file)
index 0000000..69f343c
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * (C) Copyright 2003
+ * 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
+ */
+
+/*
+ * This file contains the configuration parameters for the PURPLE board.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_MIPS32          1       /* MIPS 5Kc CPU core    */
+#define CONFIG_PURPLE          1       /* on a PURPLE Board    */
+
+#define CPU_CLOCK_RATE 125000000   /* 125 MHz clock for the MIPS core */
+#define ASC_CLOCK_RATE  62500000   /* 62.5 MHz ASC clock              */
+
+#define INFINEON_EBU_BOOTCFG   0xE0CC
+
+#define CONFIG_STACKSIZE       (128 * 1024)
+
+#define CONFIG_BOOTDELAY       5       /* autoboot after 5 seconds     */
+
+#define CONFIG_BAUDRATE                19200
+
+/* valid baudrates */
+#define CFG_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200 }
+
+#define        CONFIG_TIMESTAMP                /* Print image info with timestamp */
+
+#define CONFIG_PREBOOT "echo;" \
+       "echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \
+       "echo"
+
+#undef CONFIG_BOOTARGS
+
+#define        CONFIG_EXTRA_ENV_SETTINGS                                       \
+       "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\0"                          \
+       "addmisc=setenv bootargs $(bootargs) "                          \
+               "console=ttyS0,$(baudrate) "                            \
+               "ethaddr=$(ethaddr) "                                   \
+               "panic=1\0"                                             \
+       "flash_nfs=run nfsargs addip addmisc;"                          \
+               "bootm $(kernel_addr)\0"                                \
+       "flash_self=run ramargs addip addmisc;"                         \
+               "bootm $(kernel_addr) $(ramdisk_addr)\0"                \
+       "net_nfs=tftp 80500000 $(bootfile);"                            \
+               "run nfsargs addip addmisc;bootm\0"                     \
+       "rootpath=/opt/eldk/mips_5KC\0"                                 \
+       "bootfile=/tftpboot/purple/uImage\0"                            \
+       "kernel_addr=B0040000\0"                                        \
+       "ramdisk_addr=B0100000\0"                                       \
+       "u-boot=/tftpboot/purple/u-boot.bin\0"                          \
+       "load=tftp 80500000 $(u-boot)\0"                                \
+       "update=protect off 1:0-4;era 1:0-4;"                           \
+               "cp.b 80500000 B0000000 $(filesize)\0"                  \
+       ""
+#define CONFIG_BOOTCOMMAND     "run flash_self"
+
+#define CONFIG_COMMANDS        (CONFIG_CMD_DFL | CFG_CMD_ELF)
+#include <cmd_confdefs.h>
+
+#define CFG_SDRAM_BASE         0x80000000
+
+#define CFG_INIT_SP_OFFSET      0x400000
+
+#define CFG_MALLOC_LEN         128*1024
+
+#define CFG_BOOTPARAMS_LEN     128*1024
+
+/*
+ * Miscellaneous configurable options
+ */
+#define        CFG_LONGHELP                            /* undef to save memory      */
+#define        CFG_PROMPT              "PURPLE # "     /* 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_HZ                 (CPU_CLOCK_RATE/2)
+#define        CFG_MAXARGS             16              /* max number of command args*/
+
+#define        CFG_LOAD_ADDR           0x80500000      /* default load address */
+
+#define CFG_MEMTEST_START      0x80200000
+#define CFG_MEMTEST_END                0x80800000
+
+#define        CONFIG_MISC_INIT_R
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CFG_MAX_FLASH_BANKS    1       /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT     (35)    /* max number of sectors on one chip */
+
+#define PHYS_FLASH_1           0xb0000000 /* Flash Bank #1 */
+
+/* The following #defines are needed to get flash environment right */
+#define        CFG_MONITOR_BASE        TEXT_BASE
+#define        CFG_MONITOR_LEN         (192 << 10)
+
+#define CFG_FLASH_BASE         PHYS_FLASH_1
+
+/* timeout values are in ticks */
+#define CFG_FLASH_ERASE_TOUT   (6 * CFG_HZ) /* Timeout for Flash Erase */
+#define CFG_FLASH_WRITE_TOUT   (6 * CFG_HZ) /* Timeout for Flash Write */
+
+#define        CFG_ENV_IS_IN_FLASH     1
+
+/* Address and size of Primary Environment Sector      */
+#define CFG_ENV_ADDR           0xB0008000
+#define CFG_ENV_SIZE           0x4000
+
+#define CONFIG_FLASH_32BIT
+#define CONFIG_NR_DRAM_BANKS   1
+
+#define CONFIG_PLB2800_ETHER
+#define CONFIG_NET_MULTI
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE                16384
+#define CFG_ICACHE_SIZE                16384
+#define CFG_CACHELINE_SIZE     32
+
+/*
+ * Temporary buffer for serial data until the real serial driver
+ * is initialised (memtest will destroy this buffer)
+ */
+#define CFG_SCONSOLE_ADDR     CFG_SDRAM_BASE
+#define CFG_SCONSOLE_SIZE     0x0002000
+
+#endif /* __CONFIG_H */
index 042befe04addcfe286bc0a57c07e237932f69bba..a17d2c8008acb79deaee0d2a950de51ca9c5ee05 100644 (file)
@@ -24,6 +24,6 @@
 #ifndef        __VERSION_H__
 #define        __VERSION_H__
 
 #ifndef        __VERSION_H__
 #define        __VERSION_H__
 
-#define        U_BOOT_VERSION  "U-Boot 0.2.3"
+#define        U_BOOT_VERSION  "U-Boot 0.3.0"
 
 #endif /* __VERSION_H__ */
 
 #endif /* __VERSION_H__ */