]> www.infradead.org Git - users/rw/ppcboot.git/commitdiff
* Patch by Scott McNutt, 27 Aug 2002:
authorwdenk <wdenk>
Wed, 18 Sep 2002 20:50:34 +0000 (20:50 +0000)
committerwdenk <wdenk>
Wed, 18 Sep 2002 20:50:34 +0000 (20:50 +0000)
  1. PCI support added (README.ppc440 has some details).
  2. SPD DRAM initialization added.
  3. Support for Rev B silicon added:
      -Fixed ethernet (errata: requires MAL bursting disabled)
      -Fixed corrupted dcrs: fix strap regs & chip reset(errata)
      -Fixed speed related calculations (Rev B. has addl div by 2)
  4. Flash initialization: added delays to prevent timing
     issues (band-aid) --needs more investigation, but this is
     in the board-specific code.
  5. Fixed do_reset (changed SPRN for 440).
  6. Fixed get_tbclk for 440 (used same style as 405gp).
  7. Initialized all interrupt vector regs (start.S)
  8. Added doc/README.ppc440

* Patch by Keith Outwater, 23 Aug 2002:
  Added support for generic 860T system (GEN860T). See README in
  board/gen860t for details.

* Patch by Scott McNutt, 20 Aug 2002:
  initialize the 440 interrupt vector registers (IVORs) and enable
  the PIT. The PIT is set to interrupt every 10 msec.

* Patch by Kenneth Johansson, 19 Aug 2002:
  add some documentation for jffs2 to make it possible to change the
  partition with code instead of #defines, usage of a global in
  jffs2_1pass.c.

41 files changed:
CHANGELOG
CREDITS
MAINTAINERS
MAKEALL
Makefile
board/ebony/ebony.c
board/ebony/flash.c
board/ebony/init.S
board/gen860t/Makefile [new file with mode: 0644]
board/gen860t/README [new file with mode: 0644]
board/gen860t/beeper.c [new file with mode: 0644]
board/gen860t/beeper.h [new file with mode: 0644]
board/gen860t/config.mk [new file with mode: 0644]
board/gen860t/flash.c [new file with mode: 0644]
board/gen860t/fpga.c [new file with mode: 0644]
board/gen860t/fpga.h [new file with mode: 0644]
board/gen860t/gen860t.c [new file with mode: 0644]
board/gen860t/ioport.c [new file with mode: 0644]
board/gen860t/ioport.h [new file with mode: 0644]
board/gen860t/ppcboot.lds [new file with mode: 0644]
common/cmd_jffs2.c
common/cmd_mii.c
cpu/mpc8xx/fec.c
cpu/ppc4xx/405gp_enet.c
cpu/ppc4xx/405gp_pci.c
cpu/ppc4xx/cpu.c
cpu/ppc4xx/interrupts.c
cpu/ppc4xx/spd_sdram.c
cpu/ppc4xx/speed.c
cpu/ppc4xx/start.S
doc/README.JFFS2 [new file with mode: 0644]
doc/README.Modem [new file with mode: 0644]
doc/README.ppc440 [new file with mode: 0644]
fs/jffs2/jffs2_1pass.c
include/common.h
include/commproc.h
include/configs/EBONY.h
include/configs/GEN860T.h [new file with mode: 0644]
include/jffs2/load_kernel.h
include/ppc440.h
include/status_led.h

index f94744af8ada2eb920b1237fa500b10112141a4c..e4cef161918c01dc8a0af93e6f51c6071637d5b6 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,34 @@ Modifications for 1.2.0:
 
 For details about the current modifications, please see README-WIP
 
+* Patch by Scott McNutt, 27 Aug 2002:
+  1. PCI support added (README.ppc440 has some details).
+  2. SPD DRAM initialization added.
+  3. Support for Rev B silicon added:
+      -Fixed ethernet (errata: requires MAL bursting disabled)
+      -Fixed corrupted dcrs: fix strap regs & chip reset(errata)
+      -Fixed speed related calculations (Rev B. has addl div by 2)
+  4. Flash initialization: added delays to prevent timing
+     issues (band-aid) --needs more investigation, but this is
+     in the board-specific code.
+  5. Fixed do_reset (changed SPRN for 440).
+  6. Fixed get_tbclk for 440 (used same style as 405gp).
+  7. Initialized all interrupt vector regs (start.S)
+  8. Added doc/README.ppc440
+
+* Patch by Keith Outwater, 23 Aug 2002:
+  Added support for generic 860T system (GEN860T). See README in
+  board/gen860t for details.
+
+* Patch by Scott McNutt, 20 Aug 2002:
+  initialize the 440 interrupt vector registers (IVORs) and enable
+  the PIT. The PIT is set to interrupt every 10 msec.
+
+* Patch by Kenneth Johansson, 19 Aug 2002:
+  add some documentation for jffs2 to make it possible to change the
+  partition with code instead of #defines, usage of a global in
+  jffs2_1pass.c.
+
 * Add support for redundand environment, so the previous settins
   don't get lost in case of a power failure right during a "saveenv"
   command.
diff --git a/CREDITS b/CREDITS
index 784b6ea241765997e3f212e1e0369d1be5d89c38..2190f9bc5a3b0b1b299e503bc5c66e64f59e80f1 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -183,6 +183,10 @@ N: Keith Outwater
 E: Keith_Outwater@mvis.com
 D: Support for GEN860T board
 
+N: Keith Outwater
+E: keith_outwater@mvis.com
+D: Support for generic/custom MPC860T board (GEN860T)
+
 N: Frank Panno
 E: fpanno@delphintech.com
 D: Support for Embedded Planet EP8260 Board
index bf821aa8bb61214154ee6b0fa24a893ccec8a839..092d26809dea18cd517497e2ed7a9acdcb8ce6cc 100644 (file)
@@ -160,6 +160,9 @@ Jim Thompson <jim@musenki.com>
        MUSENKI                 MPC8245/8241
        Sandpoint8245           MPC8245
 
+Keith Outwater <keith_outwater@mvis.com> or <outwater@eskimo.com>
+       GEN860T                 MPC860T
+
 -------------------------------------------------------------------------
 
 Unknown / orphaned boards:
diff --git a/MAKEALL b/MAKEALL
index aaaf0b40b242d86a24feb975b70e7244f1278a3e..fc4cea425ba4435975ee93710184cd5e1d35afb5 100755 (executable)
--- a/MAKEALL
+++ b/MAKEALL
@@ -18,15 +18,15 @@ LIST_8xx="  \
        ADS860          AMX860          c2mon           CCM             \
        cogent_mpc8xx   ESTEEM192E      ETX094          FADS823         \
        FADS850SAR      FADS860T        FLAGADM         FPS850L         \
-       GENIETV         GTH             hermes          IAD210          \
-       ICU862_100MHz   IP860           IVML24          IVML24_128      \
-       IVML24_256      IVMS8           IVMS8_128       IVMS8_256       \
-       LANTEC          lwmon           MBX             MBX860T         \
-       MHPC            MVS1            NX823           pcu_e           \
-       R360MPI         RPXClassic      RPXlite         SM850           \
-       SPD823TS        SXNI855T        TQM823L         TQM823L_LCD     \
-       TQM850L         TQM855L         TQM860L         TQM860L_FEC     \
-       TTTech                                                          \
+       GEN860T         GENIETV         GTH             hermes          \
+       IAD210          ICU862_100MHz   IP860           IVML24          \
+       IVML24_128      IVML24_256      IVMS8           IVMS8_128       \
+       IVMS8_256       LANTEC          lwmon           MBX             \
+       MBX860T         MHPC            MVS1            NX823           \
+       pcu_e           R360MPI         RPXClassic      RPXlite         \
+       SM850           SPD823TS        SXNI855T        TQM823L         \
+       TQM823L_LCD     TQM850L         TQM855L         TQM860L         \
+       TQM860L_FEC     TTTech                                          \
 "
 
 #########################################################################
index 1e78ec47defcec8f79fc4239f5a461660bf96be8..666bf047c10ff922d3d8754dd57896755495aea8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -205,6 +205,9 @@ FADS860T_config:    unconfig
 FLAGADM_config:        unconfig
        @./mkconfig $(@:_config=) ppc mpc8xx flagadm
 
+GEN860T_config: unconfig
+       @./mkconfig $(@:_config=) ppc mpc8xx gen860t
+
 GENIETV_config:        unconfig
        @./mkconfig $(@:_config=) ppc mpc8xx genietv
 
index b25975441351b2486271d7b54568ff9d94e7fca9..ca40ce1a9b1d4532ab96dd9bf1c23cd2cdbcacbf 100644 (file)
@@ -199,3 +199,98 @@ long int fixed_sdram (void)
        return (128 * 1024 * 1024);     /* 128 MB                           */
 }
 #endif /* !defined(CONFIG_SPD_EEPROM) */
+
+
+/*************************************************************************
+ *  pci_pre_init
+ *  
+ *  This routine is called just prior to registering the hose and gives
+ *  the board the opportunity to check things. Returning a value of zero
+ *  indicates that things are bad & PCI initialization should be aborted.
+ *  
+ *     Different boards may wish to customize the pci controller structure
+ *     (add regions, override default access routines, etc) or perform
+ *     certain pre-initialization actions.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT)
+int pci_pre_init(gd_t * gd, struct pci_controller * hose )
+{
+    unsigned long strap;
+
+       /*--------------------------------------------------------------------------+
+     * The ebony board is always configured as the host & requires the
+     * PCI arbiter to be enabled.
+        *--------------------------------------------------------------------------*/
+    strap = mfdcr(cpc0_strp1);
+    if( (strap & 0x00100000) == 0 ){
+        printf("PCI: CPC0_STRP1[PAE] not set.\n");
+        return 0;
+    }
+
+    return 1;
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) */
+
+/*************************************************************************
+ *  pci_target_init
+ *
+ *     The bootstrap configuration provides default settings for the pci
+ *     inbound map (PIM). But the bootstrap config choices are limited and
+ *     may not be sufficient for a given board.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT)
+void pci_target_init( gd_t * gd, struct pci_controller * hose )
+{
+       /*--------------------------------------------------------------------------+
+        * Disable everything
+        *--------------------------------------------------------------------------*/
+       out32r( PCIX0_PIM0SA, 0 ); /* disable */
+       out32r( PCIX0_PIM1SA, 0 ); /* disable */
+       out32r( PCIX0_PIM2SA, 0 ); /* disable */
+       out32r( PCIX0_EROMBA, 0 ); /* disable expansion rom */
+
+       /*--------------------------------------------------------------------------+
+        * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440 strapping
+     * options to not support sizes such as 128/256 MB.
+        *--------------------------------------------------------------------------*/
+       out32r( PCIX0_PIM0LAL, CFG_SDRAM_BASE );
+       out32r( PCIX0_PIM0LAH, 0 );
+       out32r( PCIX0_PIM0SA, ~(gd->ram_size - 1) | 1 );
+       
+       out32r( PCIX0_BAR0, 0 );
+       
+       /*--------------------------------------------------------------------------+
+        * Program the board's subsystem id/vendor id
+        *--------------------------------------------------------------------------*/
+    out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
+    out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_DEVICEID );
+
+       out16r( PCIX0_CMD, in16r(PCIX0_CMD) | PCI_COMMAND_MEMORY );
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
+
+
+/*************************************************************************
+ *  is_pci_host
+ *
+ *     This routine is called to determine if a pci scan should be
+ *     performed. With various hardware environments (especially cPCI and
+ *     PPMC) it's insufficient to depend on the state of the arbiter enable
+ *     bit in the strap register, or generic host/adapter assumptions.
+ *
+ *     Rather than hard-code a bad assumption in the general 440 code, the
+ *     440 pci code requires the board to decide at runtime.
+ *
+ *     Return 0 for adapter mode, non-zero for host (monarch) mode.
+ *
+ *     
+ ************************************************************************/
+#if defined(CONFIG_PCI)
+int is_pci_host( gd_t * gd, struct pci_controller *hose)
+{
+    /* The ebony board is always configured as host. */
+    return(1);
+}
+#endif /* defined(CONFIG_PCI) */
index c5b318a8491da01338a76eb8504207fd4026b11e..a669ded59a2b88696635d5f9daf84883ff972a2c 100644 (file)
 #include <ppc4xx.h>
 #include <asm/processor.h>
 
+
+#undef DEBUG
+#ifdef DEBUG
+#define DEBUGF(x...) printf(x)
+#else
+#define DEBUGF(x...)
+#endif /* DEBUG */
+
 #define     BOOT_SMALL_FLASH        32              /* 00100000 */
 #define     FLASH_ONBD_N            2               /* 00000010 */
 #define     FLASH_SRAM_SEL          1               /* 00000001 */
@@ -116,9 +124,8 @@ unsigned long flash_init (void) {
                index += FLASH_SRAM_SEL_VAL;
        } 
 
-#if 0
-       printf("Index: %d\n", index);
-#endif 
+    DEBUGF("\n");
+       DEBUGF("FLASH: Index: %d\n", index);
 
        /* Init: no FLASHes known */
        for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
@@ -264,16 +271,10 @@ void flash_print_info  (flash_info_t *info)
 
                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
                                );
                        }
                printf ("\n");
@@ -297,10 +298,16 @@ void flash_print_info  (flash_info_t *info)
                        ulong base = (ulong)addr;
                        volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
 
+            DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr );
+
                        /* Write auto select command: read Manufacturer ID */
+            udelay(10000);
                        addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+            udelay(1000);
                        addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+            udelay(1000);
                        addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090;
+            udelay(1000);
 
 #ifdef CONFIG_ADCIOP
                        value = addr2[2];
@@ -308,9 +315,8 @@ void flash_print_info  (flash_info_t *info)
                        value = addr2[0];
 #endif
 
-#if 0
-                       printf("\nFLASH MANUFACT: %x\n", value);
-#endif
+                       DEBUGF("FLASH MANUFACT: %x\n", value);
+            
                        switch (value) {
                        case (FLASH_WORD_SIZE)AMD_MANUFACT:
                                info->flash_id = FLASH_MAN_AMD;
@@ -335,9 +341,8 @@ void flash_print_info  (flash_info_t *info)
                        value = addr2[1];                       /* device ID            */
 #endif
 
-#if 0
-                       printf("\nFLASH DEVICEID: %x\n", value);
-#endif
+                       DEBUGF("\nFLASH DEVICEID: %x\n", value);
+
                        switch (value) {
                        case (FLASH_WORD_SIZE)AMD_ID_F016D:
                                info->flash_id += FLASH_AMD016;
index d7b75159c1f6f923a9e7b5f6aed8d67f5072041e..bcb09a982d33cc42d38a4ba0c0e7c29361da5263 100644 (file)
@@ -91,6 +91,8 @@ tlbtab:
     tlbentry( CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X )
     tlbentry( CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X )
     tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
+    tlbentry( CFG_PCI_BASE, SZ_256M, 0x00000000, 2, AC_R|AC_W|SA_G|SA_I )
+    tlbentry( CFG_PCI_MEMBASE, SZ_256M, 0x00000000, 3, AC_R|AC_W|SA_G|SA_I )
     tlbtab_end
     
 
diff --git a/board/gen860t/Makefile b/board/gen860t/Makefile
new file mode 100644 (file)
index 0000000..21bf040
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    = lib$(BOARD).a
+
+OBJS   = $(BOARD).o flash.o beeper.o fpga.o ioport.o
+
+$(LIB):        .depend $(OBJS)
+       $(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/gen860t/README b/board/gen860t/README
new file mode 100644 (file)
index 0000000..e522be7
--- /dev/null
@@ -0,0 +1,142 @@
+
+This directory contains board specific code for a generic MPC860T based
+embedded computer, called 'GEN860T'.  The design is generic in the sense that
+common, readily available components are used and that the architecture of the
+system is i(relatively) straightforward:
+
+       One eight bit wide boot (FLASH) memory
+       32 bit main memory using SDRAM
+       DOC 2000+ 
+       Ethernet PHY
+       Some I2C peripheral devices: Atmel AT24C256 EEPROM, Maxim DS1337 RTC.
+       Some other miscellaneous peripherals
+
+NOTE: There are references to a XIlinx FPGA and Mil-Std 1553 databus in this
+port.  I guess the computer is not as generic as I first said 8)  However, 
+these extras can be safely ignored.
+
+Given the GEN860T files, it should be pretty easy to reverse engineer the
+hardware configuration, if that's useful to you.  Hopefully, this code will
+be useful to someone as a basis for a port to a new system or as a head start
+on a custom design.  If you end up using any of this, I would appreciate
+hearing from you, especially if you discover bugs or find ways to improve the
+quality of this ppcboot port.
+
+Here are the salient features of the system:
+Clock                                          :       33 Mhz oscillator
+Processor core frequency       :       66 Mhz  if in 1:2:1 mode; can also run 1:1
+Bus frequency                          :       33 Mhz
+
+Main memory:
+       Type    : SDRAM 
+       Width   : 32 bits
+       Size    : 64 megabytes
+       Chip    : Two Micron MT48LC16M16A2TG-7E
+       CS              : MPC860T CS1*/UPMA
+       UPMA CONNECTIONS:
+               SDRAM A10       : GPLA0*
+               SDRAM CAS*      : GPLA2*
+               SDRAM WE*       : GPLA3*
+               SDRAM RAS*      : GPLA4*
+
+Boot memory:
+       Type    : FLASH
+       Width   : 8 bits
+       Size    : 16 megabytes
+       Chip    : One Intel 28F128J3A (StrataFlash)
+       CS              : MPC860T CS0*/GPCM (this is the "boot" chip select)
+
+EEPROM memory:
+       Type    : Serial I2C EEPROM
+       Width   : 8 bits
+       Size    : 32 kibibytes
+       Chip    : One Atmel AT25C256
+       CS              : 0x50 (external I2C address pins on device are tied to GND)
+
+Filesystem memory:
+       Type    : NAND FLASH (Toshiba)  
+       Width   : 8 bits (i.e. interface to DOC is 8 bits)
+       Size    : 32 megabytes
+       Chip    : One DiskOnCHip Millenium Plus (DOC 2000+)
+       CS              : MPC860T CS2*/GPCM
+
+Network support:
+       MAC             : MPC86OT FEC (Fast Ethernet Controller)
+       PHY             : Intel LXT971A
+       MII Addr: 0x0 (hardwired on the board)
+       MII IRQ :       
+       
+Console:       
+       RS-232 on SMC1 (Maxim MAX3232 LVCMOS-RS232 level shifter)
+
+Real Time Clock:
+       Type    : Low power, I2C interface
+       Chip    : Maxim DS1337
+       CS              : Address 0x68 on I2C bus
+       
+       The MPC860T's internal RTC has a defect in Mask rev D that increases
+       the current drain on the KAPWR line to 10 mA.  Since this is an 
+       unreasonable amount of current draw for a RTC, and Motorola does not
+       plan to fix this in future mask revisions, a serial (I2C) RTC that
+       works has been included instead.  NOTE that the DS1337 can be
+       configured to output a 32768 Hz clock while the main power is on.
+       This clock output has been routed to the MPC860T's EXTAL pin to allow
+       the internal RTC to be used.  NOTE also that due to yet another
+       defect in the rev D mask, the RTC does not operate reliably when the
+       internal RTC divisor is set to use a 32768 Hz reference.  So just use
+       the I2C RTC.
+
+Miscellaneous:
+       Xilinx Virtex FPGA on CS3*/GPCM.
+       Virtex FPGA slave SelectMap interface on cs4*/UPMB.
+       Mil-Std 1553 databus interface on CS5*/GPCM.
+       Audio sounder (beeper) with digital volume control connected to SPKROUT.
+
+Issues:
+       The DOC 2000+ returns 0x40 as its device ID when probed using the method
+       desxribed in the DOC datasheet.  Unfortunately, the ppcboot DOC driver
+       does not recognize this device.  As of this writing, it seems that MTD
+       does not support the DOC 2000+ either.
+       
+Status:
+       Everything appears to work except DOC support. As of this writing, 
+       David Woodhouse has stated on the MTD mailing list that he has no
+       knowledge of the DOC Millineum Plus and therfore there is no support
+       in MTD for this device.  I wish I had known this sooner :(
+       
+The GEN860T board specific files and configuration is based on the work 
+of others who have contributed to ppcboot. The copright and license notices
+of these authors have been retained wherever their code has been reused. 
+All new code to support the GEN860T board is:
+
+       (C) Copyright 2001-2002
+       Keith Outwater (keith_outwater@mvis.com)
+
+and the following license applies:
+
+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,
+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
+
+Thanks to Wolfgang Denk for a great software package and to everyone 
+who contributed to its development.
+
+Keith Outwater
+Sr. Staff Engineer
+Microvision, Inc.
+<keith_outwater@mvis.com>
+<outwater@eskimo.com>
+
+vim: set ts=4 sw=4 tw=78:
+
diff --git a/board/gen860t/beeper.c b/board/gen860t/beeper.c
new file mode 100644 (file)
index 0000000..d3a8141
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * (C) Copyright 2002
+ * Keith Outwater, keith_outwater@mvis.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include <linux/ctype.h>
+
+/*
+ * Basic beeper support for the GEN860T board.  The GEN860T includes
+ * an audio sounder driven by a Phillips TDA8551 amplifier.  The
+ * TDA8551 features a digital volume control which uses a "trinary"
+ * input (high/high-Z/low) to set volume.  The 860's SPKROUT pin
+ * drives the amplifier input.
+ */
+
+
+/*
+ * Initialize beeper-related hardware. Initialize timer 1 for use with
+ * the beeper. Use 66 Mhz internal clock with prescale of 33 to get
+ * 1 uS period per count.
+ * FIXME: we should really compute the prescale based on the reported
+ * core clock frequency.
+ */
+void
+init_beeper(void)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+       immap->im_cpmtimer.cpmt_tgcr &= ~TGCR_RST1 | TGCR_STP1;
+       immap->im_cpmtimer.cpmt_tmr1 = ((33 << TMR_PS_SHIFT) & TMR_PS_MSK)
+                                                                | TMR_OM | TMR_FRR | TMR_ICLK_IN_GEN;
+       immap->im_cpmtimer.cpmt_tcn1 = 0;
+       immap->im_cpmtimer.cpmt_ter1 = 0xffff;
+       immap->im_cpmtimer.cpmt_tgcr |= TGCR_RST1;
+}
+
+
+/*
+ * Set beeper frequency.  Max allowed frequency is 2.5 KHz.  This limit
+ * is mostly arbitrary, but the beeper isn't really much good beyond this
+ * frequency.
+ */
+void
+set_beeper_frequency(uint frequency)
+{
+#define FREQ_LIMIT     2500
+               
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+       
+       /*
+        * Compute timer ticks given desired frequency.  The timer is set up
+        * to count 0.5 uS per tick and it takes two ticks per cycle (Hz).
+        */
+       if (frequency > FREQ_LIMIT) frequency = FREQ_LIMIT;
+       frequency = 1000000/frequency;
+       immap->im_cpmtimer.cpmt_trr1 = (ushort)frequency;
+}
+
+
+/*
+ * Turn the beeper on
+ */
+void
+beeper_on(void)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+       immap->im_cpmtimer.cpmt_tgcr &= ~TGCR_STP1;
+}
+
+
+/*
+ * Turn the beeper off
+ */
+void
+beeper_off(void)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+       
+       immap->im_cpmtimer.cpmt_tgcr |= TGCR_STP1;
+}
+
+
+/*
+ * Increase or decrease the beeper volume.  Volume can be set
+ * from off to full in 64 steps.  To increase volume, the output
+ * pin is actively driven high, then returned to tristate.
+ * To decrease volume, output a low on the port pin (no need to
+ * change pin mode to tristate) then output a high to go back to
+ * tristate.
+ */
+void
+set_beeper_volume(int steps)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+       int i;
+
+       if (steps >= 0) {
+               for (i = 0; i < (steps >= 64 ? 64 : steps); i++) {
+                       immap->im_cpm.cp_pbodr &= ~(0x80000000 >> 19);
+                       udelay(1);
+                       immap->im_cpm.cp_pbodr |= (0x80000000 >> 19);
+                       udelay(1);
+               }
+       }
+       else {
+               for (i = 0; i > (steps <= -64 ? -64 : steps); i--) {
+                       immap->im_cpm.cp_pbdat &= ~(0x80000000 >> 19);
+                       udelay(1);
+                       immap->im_cpm.cp_pbdat |= (0x80000000 >> 19);
+                       udelay(1);
+               }
+       }
+}
+
+
+/*
+ * Check the environment to see if the beeper needs beeping.
+ * Controlled by a sequence of the form:
+ * freq/delta volume/on time/off time;... where:
+ * freq                = frequency in Hz (0 - 2500)
+ * delta volume = volume steps up or down (-64 <= vol <= 64)
+ * on time             = time in mS
+ * off time            = time in mS
+ *
+ * Return 1 on success, 0 on failure
+ */
+int
+do_beeper(char *sequence)
+{
+#define DELIMITER      ';'
+
+int args[4];
+int i;
+int val;
+char *p = sequence;
+char *tp;
+
+       /*
+        * Parse the control sequence.  This is a really simple parser
+        * without any real error checking.  You can probably blow it
+        * up really easily.
+        */
+       if (*p == '\0' || !isdigit(*p)) {
+               printf("%s:%d: null or invalid string (%s)\n",
+                               __FILE__, __LINE__, p);
+               return 0;
+       }
+
+       i = 0;
+       while (*p != '\0') {
+               while (*p != DELIMITER) {
+                       if (i > 3) i = 0;
+                       val = (int) simple_strtol(p, &tp, 0);
+                       if (tp == p) {
+                               printf("%s:%d: no digits or bad format\n",
+                                                               __FILE__,__LINE__);
+                               return 0;
+                       }
+                       else {
+                               args[i] = val;
+                       }
+                       
+                       i++;
+                       if (*tp == DELIMITER)
+                               p = tp;
+                       else
+                               p = ++tp;
+               }
+               p++;
+
+               /*
+                * Well, we got something that has a chance of being correct
+                */
+#if 0
+               for (i = 0; i < 4; i++) {
+                       printf("%s:%d:arg %d = %d\n", __FILE__, __LINE__, i, args[i]);
+               }
+               printf("\n");
+#endif
+               
+               set_beeper_frequency(args[0]);
+               set_beeper_volume(args[1]);
+               beeper_on();
+               udelay(1000 * args[2]);
+               beeper_off();
+               udelay(1000 * args[3]);
+       }
+       return 1;
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
diff --git a/board/gen860t/beeper.h b/board/gen860t/beeper.h
new file mode 100644 (file)
index 0000000..535ee6c
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2002
+ * Keith Outwater, keith_outwater@mvis.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+void init_beeper(void);
+void set_beeper_frequency(uint frequency);
+void beeper_on(void);
+void beeper_off(void);
+void set_beeper_volume(int steps);
+int do_beeper(char *sequence);
+
+/* vim: set ts=4 tw=78 sw=4: */
diff --git a/board/gen860t/config.mk b/board/gen860t/config.mk
new file mode 100644 (file)
index 0000000..7acd904
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# FLASH base address for GEN860T board
+#
+
+TEXT_BASE = 0x40000000
diff --git a/board/gen860t/flash.c b/board/gen860t/flash.c
new file mode 100644 (file)
index 0000000..371d89c
--- /dev/null
@@ -0,0 +1,644 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvsi.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+#if defined(CFG_ENV_IS_IN_FLASH)
+# ifndef  CFG_ENV_ADDR
+#  define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
+# endif
+# ifndef  CFG_ENV_SIZE
+#  define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
+# endif
+# ifndef  CFG_ENV_SECT_SIZE
+#  define CFG_ENV_SECT_SIZE  CFG_ENV_SIZE
+# endif
+#endif
+
+/*
+ * Use buffered writes to flash by default - they are about 32x faster than
+ * single byte writes.
+ */
+#ifndef  CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#define CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#endif
+
+/*
+ * Max time to wait (in mS) for flash device to allocate a write buffer.
+ */
+#ifndef CFG_FLASH_ALLOC_BUFFER_TOUT
+#define CFG_FLASH_ALLOC_BUFFER_TOUT            100
+#endif
+
+/*
+ * These functions support a single Intel StrataFlash device (28F128J3A)
+ * in byte mode only!.  The flash routines are very basic and simple
+ * since there isn't really any remapping necessary.
+ */
+
+/*
+ * Intel SCS (Scalable Command Set) command definitions 
+ * (taken from 28F128J3A datasheet)
+ */
+#define SCS_READ_CMD                           0xff
+#define SCS_READ_ID_CMD                                0x90
+#define SCS_QUERY_CMD                          0x98
+#define SCS_READ_STATUS_CMD                    0x70
+#define SCS_CLEAR_STATUS_CMD           0x50
+#define SCS_WRITE_BUF_CMD                      0xe8
+#define SCS_PROGRAM_CMD                                0x40
+#define SCS_BLOCK_ERASE_CMD                    0x20
+#define SCS_BLOCK_ERASE_RESUME_CMD     0xd0
+#define SCS_PROGRAM_RESUME_CMD         0xd0
+#define SCS_BLOCK_ERASE_SUSPEND_CMD    0xb0
+#define SCS_SET_BLOCK_LOCK_CMD         0x60
+#define SCS_CLR_BLOCK_LOCK_CMD         0x60
+
+/*
+ * SCS status/extended status register bit definitions
+ */
+#define  SCS_SR7                                       0x80
+#define  SCS_XSR7                                      0x80
+
+/*---------------------------------------------------------------------*/
+#if 0
+#define DEBUG_FLASH
+#endif
+
+#ifdef DEBUG_FLASH
+#define PRINTF(fmt,args...) printf(fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS];
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_char *addr, flash_info_t *info);
+static int write_data8 (flash_info_t *info, ulong dest, uchar data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ * Initialize the flash memory.
+ */
+unsigned long
+flash_init (void)
+{
+       volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+       volatile memctl8xx_t *memctl = &immap->im_memctl;
+       unsigned long size_b0;
+       int i;
+
+       for (i= 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+       }
+
+       /*
+        * The gen860t board only has one FLASH memory device, so the 
+        * FLASH Bank configuration is done statically.
+        */
+       PRINTF("\n## Get flash bank 1 size @ 0x%08x\n", FLASH_BASE0_PRELIM);
+       size_b0 = flash_get_size((vu_char *)FLASH_BASE0_PRELIM, &flash_info[0]);
+       if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+               printf ("## Unknown FLASH on Bank 0: "
+                               "ID 0x%lx, Size = 0x%08lx = %ld MB\n",
+                               flash_info[0].flash_id,size_b0, size_b0 << 20);
+       }
+
+       PRINTF("## Before remap:\n"
+                  "  BR0: 0x%08x    OR0: 0x%08x\n  BR1: 0x%08x    OR1: 0x%08x\n",
+                  memctl->memc_br0, memctl->memc_or0,
+                  memctl->memc_br1, memctl->memc_or1);
+
+       /* 
+        * Remap FLASH according to real size
+        */
+       memctl->memc_or0 |= (-size_b0 & 0xFFFF8000);
+       memctl->memc_br0 |= (CFG_FLASH_BASE & BR_BA_MSK);
+
+       PRINTF("## After remap:\n"
+                  "  BR0: 0x%08x    OR0: 0x%08x\n", memctl->memc_br0, memctl->memc_or0);
+
+       /*
+        * Re-do sizing to get full correct info
+        */
+       size_b0 = flash_get_size ((vu_char *)CFG_FLASH_BASE, &flash_info[0]);
+       flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
+       flash_info[0].size = size_b0;
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+       /*
+        * Monitor protection is ON by default
+        */
+       flash_protect(FLAG_PROTECT_SET,
+                         CFG_MONITOR_BASE,
+                         CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
+                         &flash_info[0]);
+#endif
+
+#ifdef CFG_ENV_IS_IN_FLASH
+       /*
+        * Environment protection ON by default
+        */
+       flash_protect(FLAG_PROTECT_SET,
+                         CFG_ENV_ADDR,
+                         CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
+                         &flash_info[0]);
+#endif
+
+       PRINTF("## Final Flash bank size: 0x%08lx\n",size_b0);
+       return (size_b0);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Fill in the FLASH offset table
+ */
+static void
+flash_get_offsets (ulong base, flash_info_t *info)
+{
+       int i;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+               case FLASH_MAN_INTEL:
+               for (i = 0; i < info->sector_count; i++) {
+                               info->start[i] = base;
+                               base += 1024 * 128;
+               }
+               return;
+
+               default:
+                       printf ("Don't know sector offsets for FLASH"
+                               " type 0x%lx\n", info->flash_id);
+           return;
+       }
+}
+
+
+/*-----------------------------------------------------------------------
+ * Display FLASH device info
+ */
+void
+flash_print_info (flash_info_t *info)
+{
+       int i;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("Missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_INTEL:
+                       printf ("Intel ");
+                       break;
+       default:
+                       printf ("Unknown Vendor ");
+                       break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_28F128J3A:
+                       printf ("28F128J3A (128Mbit = 128K x 128)\n");
+                       break;
+       default:
+                       printf ("Unknown Chip Type\n");
+                       break;
+       }
+
+       if (info->size >= (1024 * 1024)) {
+               i = 20;
+       } else {
+               i = 10;
+       }
+       printf ("  Size: %ld %cB in %d Sectors\n",
+                       info->size >> i,
+                       (i == 20) ? 'M' : 'k',
+                       info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+       for (i=0; i<info->sector_count; ++i) {
+               if ((i % 5) == 0)
+                       printf ("\n   ");
+                       printf (" %08lX%s",
+                       info->start[i],
+                       info->protect[i] ? " (RO)" : "     "
+               );
+       }
+       printf ("\n");
+       return;
+}
+
+
+/*-----------------------------------------------------------------------
+ * Get size and other information for a FLASH device.
+ * NOTE: The following code cannot be run from FLASH!
+ */
+static
+ulong flash_get_size (vu_char *addr, flash_info_t *info)
+{
+#define NO_FLASH       0
+
+       vu_char value[2];
+
+       /*
+        * Try to read the manufacturer ID
+        */
+       addr[0] = SCS_READ_CMD;
+       addr[0] = SCS_READ_ID_CMD;
+       value[0] = addr[0];
+       value[1] = addr[2];
+       addr[0] = SCS_READ_CMD;
+
+       PRINTF("Manuf. ID @ 0x%08lx: 0x%02x\n", (ulong)addr, value[0]);
+       switch (value[0]) {
+               case (INTEL_MANUFACT & 0xff):
+                       info->flash_id = FLASH_MAN_INTEL;
+                       break;
+               default:
+                       info->flash_id = FLASH_UNKNOWN;
+                       info->sector_count = 0;
+                       info->size = 0;
+                       return (NO_FLASH);
+       }
+
+       /*
+        * Read the device ID
+        */
+       PRINTF("Device ID @ 0x%08lx: 0x%02x\n", (ulong)(&addr[2]), value[1]);
+       switch (value[1]) {
+               case (INTEL_ID_28F128J3A & 0xff):
+                       info->flash_id += FLASH_28F128J3A;
+                       info->sector_count = 128;
+                       info->size = 16 * 1024 * 1024;
+                       break;
+
+               default:
+                       info->flash_id = FLASH_UNKNOWN;
+                       return (NO_FLASH);
+       }
+
+       if (info->sector_count > CFG_MAX_FLASH_SECT) {
+               printf ("** ERROR: sector count %d > max (%d) **\n",
+                               info->sector_count, CFG_MAX_FLASH_SECT);
+                               info->sector_count = CFG_MAX_FLASH_SECT;
+       }
+       return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Erase the specified sectors in the specified FLASH device
+ */
+int
+flash_erase(flash_info_t *info, int s_first, int s_last)
+{
+       int flag, prot, sect;
+       ulong start, now, last;
+
+       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;
+       }
+
+       if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
+               printf ("Can erase only Intel flash types - aborted\n");
+               return 1;
+       }
+
+       prot = 0;
+       for (sect=s_first; sect<=s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n",
+                               prot);
+       } else {
+               printf ("\n");
+       }
+
+       start = get_timer (0);
+       last  = start;
+
+       /* 
+        * Start erase on unprotected sectors
+        */
+       for (sect = s_first; sect<=s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+                       vu_char *addr = (uchar *)(info->start[sect]);
+                       vu_char status;
+
+                       /*
+                        * Disable interrupts which might cause a timeout
+                        */
+                       flag = disable_interrupts();
+
+                       *addr = SCS_CLEAR_STATUS_CMD;
+                       *addr = SCS_BLOCK_ERASE_CMD;
+                       *addr = SCS_BLOCK_ERASE_RESUME_CMD;
+
+                       /*
+                        * Re-enable interrupts if necessary
+                        */
+                       if (flag)
+                               enable_interrupts();
+
+                       /*
+                        * Wait at least 80us - let's wait 1 ms
+                        */
+                       udelay (1000);
+
+                       while (((status = *addr) & SCS_SR7) != SCS_SR7) {
+                               if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                                       printf ("Timeout\n");
+                                       *addr = SCS_BLOCK_ERASE_SUSPEND_CMD;
+                                       *addr = SCS_READ_CMD;
+                                       return 1;
+                               }
+
+                               /*
+                                * Show that we're waiting
+                                */
+                               if ((now - last) > 1000) {      /* 1 second */
+                                       putc ('.');
+                                       last = now;
+                               }
+                       }
+                       *addr = SCS_READ_CMD;
+               }
+       }
+       printf (" done\n");
+       return 0;
+}
+
+
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+/*
+ * Allocate a flash buffer, fill it with data and write it to the flash.
+ * 0 - OK
+ * 1 - Timeout on buffer request
+ *
+ * NOTE: After the last call to this function, WSM status needs to be checked!
+ */
+static int
+write_flash_buffer8(flash_info_t *info_p, vu_char *src_p, vu_char *dest_p,
+                                   uint count)
+{
+       vu_char *block_addr_p = NULL;
+       vu_char *start_addr_p = NULL;
+       ulong blocksize = info_p->size / (ulong)info_p->sector_count;
+       
+       int i;
+       uint time = get_timer(0);
+
+       PRINTF("%s:%d: src: 0x%p dest: 0x%p  count: %d\n",
+                  __FUNCTION__, __LINE__, src_p, dest_p, count);
+
+       /*
+        * What block are we in? We already know that the source address is
+        * in the flash address range, but we also can't cross a block boundary.
+        * We assume that the block does not cross a boundary (we'll check before
+        * calling this function).
+        */
+       for (i = 0; i < info_p->sector_count; ++i) {
+               if ( ((ulong)dest_p >= info_p->start[i]) && 
+                   ((ulong)dest_p < (info_p->start[i] + blocksize)) ) {
+                       PRINTF("%s:%d: Dest addr 0x%p is in block %d @ 0x%.8lx\n",
+                                  __FUNCTION__, __LINE__, dest_p, i, info_p->start[i]);
+                       block_addr_p = (vu_char *)info_p->start[i];
+                       break;
+               }
+       }
+
+       /*
+        * Request a buffer
+        */
+       *block_addr_p = SCS_WRITE_BUF_CMD;
+       while ((*block_addr_p & SCS_XSR7) != SCS_XSR7) {
+               if (get_timer(time) >  CFG_FLASH_ALLOC_BUFFER_TOUT) {
+                       PRINTF("%s:%d: Buffer allocation timeout @ 0x%p (waited %d mS)\n",
+                                  __FUNCTION__, __LINE__, block_addr_p,
+                                  CFG_FLASH_ALLOC_BUFFER_TOUT);
+                       return 1;
+               }
+               *block_addr_p = SCS_WRITE_BUF_CMD;
+       }
+       
+       /*
+        * Fill the buffer with data
+        */
+       start_addr_p = dest_p;
+       *block_addr_p = count - 1; /* flash device wants count - 1 */   
+       PRINTF("%s:%d: Fill buffer at block addr 0x%p\n",
+                  __FUNCTION__, __LINE__, block_addr_p);
+       for (i = 0; i < count; i++) {
+               *start_addr_p++ = *src_p++;
+       }
+
+       /*
+        * Flush buffer to flash
+        */
+       *block_addr_p = SCS_PROGRAM_RESUME_CMD;
+#if 1
+       time = get_timer(0);
+       while ((*block_addr_p & SCS_SR7) != SCS_SR7) {
+               if (get_timer(time) >  CFG_FLASH_WRITE_TOUT) {
+                       PRINTF("%s:%d: Write timeout @ 0x%p (waited %d mS)\n",
+                                  __FUNCTION__, __LINE__, block_addr_p, CFG_FLASH_WRITE_TOUT);
+                       return 1;
+               }
+       }
+       
+#endif
+       return 0;
+}
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - Flash not identified
+ */
+int
+write_buff(flash_info_t *info_p, uchar *src_p, ulong addr, ulong count)
+{
+       int rc = 0;
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#define FLASH_WRITE_BUF_SIZE   0x00000020      /* 32 bytes */
+       int i;
+       uint bufs;
+       ulong buf_count;
+       vu_char *sp;
+       vu_char *dp;
+#else
+       ulong wp;
+#endif
+
+       PRINTF("\n%s:%d: src: 0x%.8lx dest: 0x%.8lx size: %d (0x%.8lx)\n",
+                  __FUNCTION__, __LINE__, (ulong)src_p, addr, (uint)count, count);
+
+       if (info_p->flash_id == FLASH_UNKNOWN) {
+               return 4;
+       }
+
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+       sp = src_p;
+       dp = (uchar *)addr;
+       
+       /*
+        * For maximum performance, we want to align the start address to
+        * the beginning of a write buffer boundary (i.e. A4-A0 of the 
+        * start address = 0). See how many bytes are required to get to a
+        * write-buffer-aligned address.  If that number is non-zero, do
+        * non buffered writes of the non-aligned data.  By doing non-buffered
+        * writes, we avoid the problem of crossing a block (sector) boundary
+        * with buffered writes.
+        */
+       buf_count = FLASH_WRITE_BUF_SIZE - (addr & (FLASH_WRITE_BUF_SIZE - 1));
+       if (buf_count == FLASH_WRITE_BUF_SIZE) { /* already on a boundary */
+               buf_count = 0;
+       }
+       if (buf_count > count) { /* not a full buffers worth of data to write */
+               buf_count = count;
+       }
+       count -= buf_count;
+
+       PRINTF("%s:%d: Write buffer alignment count = %ld\n",
+                  __FUNCTION__, __LINE__, buf_count);
+       while (buf_count-- >= 1) {
+               if ((rc = write_data8(info_p, (ulong)dp++, *sp++)) != 0)  {
+                       return (rc);
+               }
+       }
+
+       PRINTF("%s:%d: count = %ld\n", __FUNCTION__, __LINE__, count);
+       if (count == 0) { /* all done */
+               PRINTF("%s:%d: Less than 1 buffer (%d) worth of bytes\n",
+                          __FUNCTION__, __LINE__, FLASH_WRITE_BUF_SIZE);
+               return (rc);
+       }
+       
+       /*
+        * Now that we are write buffer aligned, write full or partial buffers.
+        * The fact that we are write buffer aligned automatically avoids 
+        * crossing a block address during a write buffer operation.
+        */
+       bufs = count / FLASH_WRITE_BUF_SIZE;
+       PRINTF("%s:%d: %d (0x%x) buffers to write\n", __FUNCTION__, __LINE__,
+                  bufs, bufs);
+       while (bufs >= 1) {
+               rc = write_flash_buffer8(info_p, sp, dp, FLASH_WRITE_BUF_SIZE);
+               if (rc != 0) {
+                       PRINTF("%s:%d: ** Error writing buf %d\n",
+                                  __FUNCTION__, __LINE__, bufs);
+                       return (rc);
+               }
+               bufs--;
+               sp += FLASH_WRITE_BUF_SIZE;
+               dp += FLASH_WRITE_BUF_SIZE;
+       }
+
+       /*
+        * Do the leftovers
+        */
+       i = count % FLASH_WRITE_BUF_SIZE;
+       PRINTF("%s:%d: %d (0x%x) leftover bytes\n", __FUNCTION__, __LINE__, i, i);
+       if (i > 0) {
+               rc = write_flash_buffer8(info_p, sp, dp, i);
+       }
+
+       sp = (vu_char*)info_p->start[0];
+       *sp = SCS_READ_CMD;
+       return (rc);
+       
+#else
+       wp = addr;
+       while (count-- >= 1) {
+               if((rc = write_data8(info_p, wp++, *src_p++)) != 0)
+                       return (rc);
+       }
+       return 0;
+#endif
+}
+
+
+/*-----------------------------------------------------------------------
+ * Write a byte to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int
+write_data8 (flash_info_t *info, ulong dest, uchar data)
+{
+       vu_char *addr = (vu_char *)dest;
+       vu_char status;
+       ulong start;
+       int flag;
+
+       /* Check if Flash is (sufficiently) erased */
+       if ((*addr & data) != data) {
+               return (2);
+       }
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+       *addr = SCS_PROGRAM_CMD;
+       *addr = data;
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       start = get_timer (0);
+
+       while (((status = *addr) & SCS_SR7) != SCS_SR7) {
+               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                       *addr = SCS_READ_CMD;
+                       return (1);
+               }
+       }
+       *addr = SCS_READ_CMD;
+       return (0);
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
diff --git a/board/gen860t/fpga.c b/board/gen860t/fpga.c
new file mode 100644 (file)
index 0000000..2c6e4f1
--- /dev/null
@@ -0,0 +1,401 @@
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ * Keith Outwater, keith_outwater@mvis.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+/*
+ * Virtex2 FPGA configuration support for the GEN860T computer
+ */
+
+#include <common.h>
+#include <virtex2.h>
+#include <command.h>
+#include "fpga.h"
+
+#if (CONFIG_FPGA)
+
+#if 0
+#define GEN860T_FPGA_DEBUG
+#endif
+
+#ifdef GEN860T_FPGA_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define        PRINTF(fmt,args...)
+#endif
+
+/*
+ * Port bit numbers for the Selectmap controls
+ */
+#define FPGA_INIT_BIT_NUM              22      /* PB22 */
+#define FPGA_RESET_BIT_NUM             11      /* PC11 */
+#define FPGA_DONE_BIT_NUM              16      /* PB16 */
+#define FPGA_PROGRAM_BIT_NUM   7       /* PA7  */
+
+/* Note that these are pointers to code that is in Flash.  They will be
+ * relocated at runtime.
+ */
+Xilinx_Virtex2_Slave_SelectMap_fns fpga_fns = {
+       fpga_pre_config_fn,
+       fpga_pgm_fn,
+       fpga_init_fn,
+       fpga_err_fn,
+       fpga_done_fn,
+       fpga_clk_fn,
+       fpga_cs_fn,
+       fpga_wr_fn,
+       fpga_read_data_fn,
+       fpga_write_data_fn,
+       fpga_busy_fn,
+       fpga_abort_fn,
+       fpga_post_config_fn
+};
+
+Xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
+       { Xilinx_Virtex2,
+         slave_selectmap,
+         XILINX_XC2V3000_SIZE,
+         (void *)&fpga_fns,
+         0
+       }
+};
+
+/*
+ * Display FPGA revision information
+ */
+void
+print_fpga_revision(void)
+{
+       vu_long *rev_p = (vu_long *)0x60000008;
+       
+       printf("FPGA Revision 0x%.8lx"
+                  " (Date %.2lx/%.2lx/%.2lx, Status \"%.1lx\", Version %.3lu)\n",
+                  *rev_p,
+                  ((*rev_p >> 28) & 0xf),
+                  ((*rev_p >> 20) & 0xff),
+                  ((*rev_p >> 12) & 0xff),
+                  ((*rev_p >> 8) & 0xf),
+                  (*rev_p & 0xff));
+}
+
+
+/*
+ * Perform a simple test of the FPGA to processor interface using the FPGA's
+ * inverting bus test register.  The great thing about doing a read/write
+ * test on a register that inverts it's contents is that you avoid any
+ * problems with bus charging.
+ * Return 0 on failure, 1 on success.
+ */
+int
+test_fpga_ibtr(void)
+{
+       vu_long *ibtr_p = (vu_long *)0x60000010;
+       vu_long readback;
+       vu_long compare;
+       int i;
+       int j;
+       int k;
+       int pass = 1;
+       
+       static const ulong bitpattern[] = {
+               0xdeadbeef,     /* magic ID pattern for debug   */
+               0x00000001,     /* single bit                                   */
+               0x00000003,     /* two adjacent bits                    */
+               0x00000007,     /* three adjacent bits                  */
+               0x0000000F,     /* four adjacent bits                   */
+               0x00000005,     /* two non-adjacent bits                */
+               0x00000015,     /* three non-adjacent bits              */
+               0x00000055,     /* four non-adjacent bits               */
+               0xaaaaaaaa,     /* alternating 1/0                              */
+       };
+       
+       for (i = 0; i < 1024; i++) {
+               for (j = 0; j < 31; j++) {
+                       for (k = 0; k < sizeof(bitpattern)/sizeof(bitpattern[0]); k++) {
+                               *ibtr_p = compare = (bitpattern[k] << j);
+                               readback = *ibtr_p;
+                               if (readback != ~compare) {
+                                       printf("%s:%d: FPGA test fail: expected 0x%.8lx"
+                                                  " actual 0x%.8lx\n",
+                                                  __FUNCTION__, __LINE__, ~compare, readback);
+                                       pass = 0;
+                                       break;
+                               }
+                       }
+                       if (!pass) break;
+               }
+               if (!pass) break;
+       }
+       if (pass) {
+               printf("FPGA inverting bus test passed\n");
+               print_fpga_revision();
+       }
+       else {
+               printf("** FPGA inverting bus test failed\n");
+       }
+       return pass;
+}
+
+
+/*
+ * Set the active-low FPGA reset signal.
+ */
+void
+fpga_reset(int assert)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+       PRINTF("%s:%d: RESET ", __FUNCTION__, __LINE__);
+       if (assert) {
+               immap->im_ioport.iop_pcdat &= ~(0x8000 >> FPGA_RESET_BIT_NUM);
+               PRINTF("asserted\n");
+       }
+       else {
+               immap->im_ioport.iop_pcdat |= (0x8000 >> FPGA_RESET_BIT_NUM);
+               PRINTF("deasserted\n");
+       }
+}
+
+
+/*
+ * Initialize the SelectMap interface.  We assume that the mode and the
+ * initial state of all of the port pins have already been set!
+ */
+void
+fpga_selectmap_init(void)
+{
+       PRINTF("%s:%d: Initialize SelectMap interface\n", __FUNCTION__, __LINE__);
+       fpga_pgm_fn(FALSE, FALSE, 0);   /* make sure program pin is inactive */
+}
+
+
+/*
+ * Initialize the fpga.  Return 1 on success, 0 on failure.
+ */
+int 
+gen860t_init_fpga(void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       int i;
+
+       PRINTF("%s:%d: Initialize FPGA interface (relocation offset = 0x%.8lx)\n",
+                       __FUNCTION__, __LINE__, gd->reloc_off);
+       fpga_init(gd->reloc_off);
+       fpga_selectmap_init();
+
+       for(i=0; i < CONFIG_FPGA_COUNT; i++) {
+               PRINTF("%s:%d: Adding fpga %d\n", __FUNCTION__, __LINE__, i);
+               fpga_add(fpga_xilinx, &fpga[i]);
+       }
+       return 1;
+}
+
+
+/*
+ * Set the FPGA's active-low SelectMap program line to the specified level
+ */
+int
+fpga_pgm_fn(int assert, int flush, int cookie)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+       PRINTF("%s:%d: FPGA PROGRAM ", __FUNCTION__, __LINE__);
+
+       if (assert) {
+               immap->im_ioport.iop_padat &= ~(0x8000 >> FPGA_PROGRAM_BIT_NUM);
+               PRINTF("asserted\n");
+       }
+       else {
+               immap->im_ioport.iop_padat |= (0x8000 >> FPGA_PROGRAM_BIT_NUM);
+               PRINTF("deasserted\n");
+       }
+       return assert;
+}
+
+
+/*
+ * Test the state of the active-low FPGA INIT line.  Return 1 on INIT
+ * asserted (low).
+ */
+int
+fpga_init_fn(int cookie)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+       
+       PRINTF("%s:%d: INIT check... ", __FUNCTION__, __LINE__);
+       if(immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_INIT_BIT_NUM)) {
+               PRINTF("high\n");
+               return 0;
+       }
+       else {
+               PRINTF("low\n");
+               return 1;
+       }
+}
+
+
+/*
+ * Test the state of the active-high FPGA DONE pin
+ */
+int
+fpga_done_fn(int cookie)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+       PRINTF("%s:%d: DONE check... ", __FUNCTION__, __LINE__);
+       if (immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_DONE_BIT_NUM)) {
+               PRINTF("high\n");
+               return FPGA_SUCCESS;
+       }
+       else {
+               PRINTF("low\n");
+               return FPGA_FAIL;
+       }
+}
+
+
+/*
+ * Read FPGA SelectMap data.
+ */
+int
+fpga_read_data_fn(unsigned char *data, int cookie)
+{
+       vu_char *p = (vu_char *)SELECTMAP_BASE;
+       
+       *data = *p;
+#if 0
+       PRINTF("%s: Read 0x%x into 0x%p\n", __FUNCTION__, (int)data, data);
+#endif
+       return (int)data;
+}
+
+
+/*
+ * Write data to the FPGA SelectMap port
+ */
+int
+fpga_write_data_fn(unsigned char data, int flush, int cookie)
+{
+       vu_char *p = (vu_char *)SELECTMAP_BASE;
+       
+#if 0
+       PRINTF("%s: Write Data 0x%x\n", __FUNCTION__, (int)data);
+#endif
+       *p = data;
+       return (int)data;
+}
+
+
+/*
+ * Abort and FPGA operation
+ */
+int
+fpga_abort_fn(int cookie)
+{
+       PRINTF("%s:%d: FPGA program sequence aborted\n", 
+                  __FUNCTION__, __LINE__);
+       return FPGA_FAIL;
+}
+
+
+/*
+ * FPGA pre-configuration function. Just make sure that
+ * FPGA reset is asserted to keep the FPGA from starting up after
+ * configuration.
+ */
+int
+fpga_pre_config_fn(int cookie)
+{
+       PRINTF("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__);
+       fpga_reset(TRUE);
+       return 0;
+}
+
+
+/*
+ * FPGA post configuration function. Blip the FPGA reset line and then see if
+ * the FPGA appears to be running.
+ */
+int
+fpga_post_config_fn(int cookie)
+{
+       int rc;
+
+       PRINTF("%s:%d: FPGA post configuration\n", __FUNCTION__, __LINE__);
+       fpga_reset(TRUE);
+       udelay(1000);
+       fpga_reset(FALSE);
+       udelay (1000);
+
+       /*
+        * Use the FPGA,s inverting bus test register to do a simple test of the
+        * processor interface.
+        */
+       rc = test_fpga_ibtr();
+       return rc;
+}
+
+
+/*
+ * Clock, chip select and write signal assert functions and error check 
+ * and busy functions.  These are only stubs because the GEN860T selectmap
+ * interface handles sequencing of control signals automatically (it uses
+ * a memory-mapped interface to the FPGA SelectMap port).  The design of
+ * the interface guarantees that the SelectMap port cannot be overrun so 
+ * no busy check is needed.  A configuration error is signalled by INIT
+ * going low during configuration, so there is no need for a separate error
+ * function.
+ */
+int
+fpga_clk_fn(int assert_clk, int flush, int cookie)
+{
+       return assert_clk;
+}
+
+int
+fpga_cs_fn(int assert_cs, int flush, int cookie)
+{
+       return assert_cs;
+}
+
+int
+fpga_wr_fn(int assert_write, int flush, int cookie)
+{
+       return assert_write;
+}
+
+int
+fpga_err_fn(int cookie)
+{
+       return 0;
+}
+
+int
+fpga_busy_fn(int cookie)
+{
+       return 0;
+}
+#endif
+
+/* vim: set ts=4 tw=78 sw=4: */
diff --git a/board/gen860t/fpga.h b/board/gen860t/fpga.h
new file mode 100644 (file)
index 0000000..01967a4
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ * Keith Outwater, keith_outwater@mvis.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+/*
+ * Virtex2 FPGA configuration support for the GEN860T computer
+ */
+
+extern int gen860t_init_fpga(void);
+extern int fpga_pgm_fn(int assert_pgm, int flush, int cookie);
+extern int fpga_init_fn(int cookie);
+extern int fpga_err_fn(int cookie);
+extern int fpga_done_fn(int cookie);
+extern int fpga_clk_fn(int assert_clk, int flush, int cookie);
+extern int fpga_cs_fn(int assert_cs, int flush, int cookie);
+extern int fpga_wr_fn(int assert_write, int flush, int cookie);
+extern int fpga_read_data_fn(unsigned char *data, int cookie);
+extern int fpga_write_data_fn(unsigned char data, int flush, int cookie);
+extern int fpga_busy_fn(int cookie);
+extern int fpga_abort_fn(int cookie );
+extern int fpga_pre_config_fn(int cookie );
+extern int fpga_post_config_fn(int cookie );
+
+/* vim: set ts=4 sw=4 tw=78: */
diff --git a/board/gen860t/gen860t.c b/board/gen860t/gen860t.c
new file mode 100644 (file)
index 0000000..02f82ab
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <virtex2.h>
+#include <common.h>
+#include <mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include "beeper.h"
+#include "fpga.h"
+#include "ioport.h"
+
+#ifdef CONFIG_STATUS_LED
+#include <status_led.h>
+#endif
+
+#if defined(CFG_CMD_MII) && defined(CONFIG_MII)
+#include <net.h>
+#endif
+
+#if 0
+#define GEN860T_DEBUG
+#endif
+
+#ifdef GEN860T_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define        PRINTF(fmt,args...)
+#endif
+
+/*
+ * The following UPM init tables were generated automatically by
+ * Motorola's MCUINIT program. See the README file for UPM to
+ * SDRAM pin assignments if you want to type this data into
+ * MCUINIT in order to reverse engineer the waveforms.
+ */
+
+/*
+ * UPM initialization tables for MICRON MT48LC16M16A2TG SDRAM devices
+ * (UPMA) and Virtex FPGA SelectMap interface (UPMB).
+ * NOTE that unused areas of the table are used to hold NOP, precharge
+ * and mode register set sequences.
+ *  
+ */
+#define        UPMA_NOP_ADDR                   0x5
+#define        UPMA_PRECHARGE_ADDR             0x6
+#define UPMA_MRS_ADDR                  0x12
+
+#define UPM_SINGLE_READ_ADDR   0x00
+#define UPM_BURST_READ_ADDR            0x08
+#define UPM_SINGLE_WRITE_ADDR  0x18
+#define UPM_BURST_WRITE_ADDR   0x20
+#define        UPM_REFRESH_ADDR                0x30
+
+const uint sdram_upm_table[] = {
+       /* single read   (offset 0x00 in upm ram) */
+       0x0e0fdc04, 0x01adfc04, 0x0fbffc00, 0x1fff5c05,
+       0xffffffff, 0x0fffffcd, 0x0fff0fce, 0xefcfffff,
+       /* burst read    (offset 0x08 in upm ram) */
+       0x0f0fdc04, 0x00fdfc04, 0xf0fffc00, 0xf0fffc00,
+       0xf1fffc00, 0xfffffc00, 0xfffffc05, 0xffffffff,
+       0xffffffff, 0xffffffff, 0x0ffffff4, 0x1f3d5ff4,
+       0xfffffff4, 0xfffffff5, 0xffffffff, 0xffffffff,
+       /* single write  (offset 0x18 in upm ram) */
+       0x0f0fdc04, 0x00ad3c00, 0x1fff5c05, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       /* burst write   (offset 0x20 in upm ram) */
+       0x0f0fdc00, 0x10fd7c00, 0xf0fffc00, 0xf0fffc00,
+       0xf1fffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xfffff7ff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       /* refresh       (offset 0x30 in upm ram) */
+       0x1ffddc84, 0xfffffc04, 0xfffffc04, 0xfffffc84,
+       0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       /* exception     (offset 0x3C in upm ram) */
+   };
+
+const uint selectmap_upm_table[] = {
+       /* single read   (offset 0x00 in upm ram) */
+       0x88fffc06, 0x00fff404, 0x00fffc04, 0x33fffc00,
+       0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff,
+       /* burst read    (offset 0x08 in upm ram) */
+       0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       /* single write  (offset 0x18 in upm ram) */
+       0x88fffc04, 0x00fff400, 0x77fffc05, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       /* burst write   (offset 0x20 in upm ram) */
+       0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       /* refresh       (offset 0x30 in upm ram) */
+       0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       /* exception     (offset 0x3C in upm ram) */
+       0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff
+};
+
+
+/*
+ * Check board identity.  Always successful (gives information only)
+ */
+int
+checkboard(void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+    unsigned char *s;
+    unsigned char buf[64];
+    int i;
+
+    i = getenv_r("board_id", buf, sizeof(buf));
+    s = (i>0) ? buf : NULL;
+
+       if (s) {
+               printf("%s ", s);
+       } else {
+               printf("<unknown> ");
+       }
+
+    i = getenv_r("serial#", buf, sizeof(buf));
+    s = (i>0) ? buf : NULL;
+
+       if (s) {
+               printf("S/N %s\n", s);
+       } else {
+               printf("S/N <unknown>\n");
+       }
+
+    printf("CPU at %s MHz, ",strmhz(buf, gd->cpu_clk));
+       printf("local bus at %s MHz\n", strmhz(buf, gd->bus_clk));
+    return (1);
+}
+
+
+/*
+ * Initialize SDRAM
+ */
+long int 
+initdram(int board_type) 
+{
+    volatile immap_t     *immr  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immr->im_memctl;
+
+    upmconfig(UPMA, 
+                         (uint *)sdram_upm_table,
+                         sizeof(sdram_upm_table) / sizeof(uint)
+                        );
+
+    /*
+     * Setup MAMR register
+     */
+    memctl->memc_mptpr = CFG_MPTPR_1BK_8K;
+    memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
+
+    /*
+     * Map CS1* to SDRAM bank 
+     */
+    memctl->memc_or1 = CFG_OR1;
+    memctl->memc_br1 = CFG_BR1; 
+
+       /*
+        * Perform SDRAM initialization sequence:
+        * 1. Apply at least one NOP command
+        * 2. 100 uS delay (JEDEC standard says 200 uS)
+        * 3. Issue 4 precharge commands
+        * 4. Perform two refresh cycles
+        * 5. Program mode register
+        *  
+        * Program SDRAM for standard operation, sequential burst, burst length
+        * of 4, CAS latency of 2.
+        */
+    memctl->memc_mar = 0x00000000;
+       memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+                                          MCR_MLCF(0) | UPMA_NOP_ADDR;
+       udelay(200);
+    memctl->memc_mar = 0x00000000;
+       memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+                                          MCR_MLCF(4) | UPMA_PRECHARGE_ADDR;
+       
+    memctl->memc_mar = 0x00000000;
+       memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+                                          MCR_MLCF(2) | UPM_REFRESH_ADDR;
+
+    memctl->memc_mar = 0x00000088;
+       memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+                                          MCR_MLCF(1) | UPMA_MRS_ADDR;
+       
+    memctl->memc_mar = 0x00000000;
+       memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+                                          MCR_MLCF(0) | UPMA_NOP_ADDR;
+       /*
+        * Enable refresh
+        */
+    memctl->memc_mamr |= MAMR_PTAE;
+
+    return (SDRAM_SIZE);
+}
+
+
+/*
+ * Disk On Chip (DOC) Millenium initialization.
+ * The DOC lives in the CS2* space
+ */
+#if (CONFIG_COMMANDS & CFG_CMD_DOC)
+extern void 
+doc_probe(ulong physadr);
+
+void
+doc_init(void)
+{
+       printf("Probing at 0x%.8x: ", DOC_BASE);
+       doc_probe(DOC_BASE);
+}
+#endif
+
+
+/*
+ * Miscellaneous intialization
+ */
+int
+misc_init_r (void)
+{
+#define MSB_ONE        0x80000000
+               
+    volatile immap_t     *immr  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immr->im_memctl;
+
+       /*
+        * Set up UPMB to handle the Virtex FPGA SelectMap interface
+        */
+       upmconfig(UPMB, (uint *)selectmap_upm_table, 
+                         sizeof(selectmap_upm_table) / sizeof(uint));
+       
+    memctl->memc_mbmr = 0x0;
+
+       config_mpc8xx_ioports(immr);
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII)
+       mii_init();
+#endif
+
+#if (CONFIG_FPGA)
+       gen860t_init_fpga();
+#endif
+
+       return (0);
+}
+
+
+/*
+ * Final init hook before entering command loop.
+ */
+int
+last_stage_init(void)
+{
+       unsigned char buf[256];
+       int i;
+       
+       /* set LEDs here since status LED init code has already run */
+       status_led_set(STATUS_LED_BIT1, STATUS_LED_ON);
+       status_led_set(STATUS_LED_BIT3, STATUS_LED_ON);
+
+       /*
+        * Turn the beeper volume all the way down in case this is a warm
+        * boot.
+        */
+       set_beeper_volume(-64);
+       init_beeper();
+
+       /*
+        * Read the environment to see what to do with the beeper
+        */
+    i = getenv_r("beeper", buf, sizeof(buf));
+       if (i > 0) {
+               do_beeper(buf);
+       }
+
+       return 0;
+}
+
+/* vim: set ts=4 sw=4 tw=78 : */
diff --git a/board/gen860t/ioport.c b/board/gen860t/ioport.c
new file mode 100644 (file)
index 0000000..34f0917
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include "ioport.h"
+
+#if 0
+#define IOPORT_DEBUG
+#endif
+
+#ifdef  IOPORT_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/*
+ * The ioport configuration table.
+ */
+const mpc8xx_iop_conf_t iop_conf_tab[NUM_PORTS][PORT_BITS] = {
+    /*
+        * Port A configuration
+        * Pin          Signal                          Type    Active          Initial state
+        * PA7          fpgaProgramLowOut       Out             Low                     High
+        */
+    {  /*          conf ppar psor pdir podr pdat pint     function             */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /* No pin                       */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /* No pin                       */
+       /* PA15 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PA14 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PA13 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PA12 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PA11 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PA10 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PA9  */ { 1,   0,   0,   1,   0,   0,   0 }, /* grn bicolor LED 1*/
+       /* PA8  */ { 1,   0,   0,   1,   0,   0,   0 }, /* red bicolor LED 1*/
+       /* PA7  */ { 1,   0,   0,   1,   0,   1,   0 }, /* fpgaProgramLow       */
+       /* PA6  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PA5  */ { 1,   0,   0,   1,   0,   0,   0 }, /* grn bicolor LED 0*/
+       /* PA4  */ { 1,   0,   0,   1,   0,   0,   0 }, /* red bicolor LED 0*/
+       /* PA3  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PA2  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PA1  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PA0  */ { 0,   0,   0,   0,   0,   0,   0 }  /*      */
+    },
+       
+       /*
+        * Pin          Signal                  Type            Active          Initial state
+        * PB14         docBusyLowIn    In                      Low                     X
+        * PB15         gpio1Sig                Out                     High            Low
+        * PB16         fpgaDoneBi              In                      High            X
+        * PB17         swBitOkLowOut   Out                     Low                     Low
+        * PB19         speakerVolSig   Out/Hi-Z        High/Low        High (Hi-Z)
+        * PB22         fpgaInitLowBi   In                      Low                     X
+        * PB23         batteryOkSig    In                      High            X
+     */
+    {  /*          conf ppar psor pdir podr pdat pint    function                      */
+       /* PB31 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PB30 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PB29 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PB28 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PB27 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PB26 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PB25 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PB24 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PB23 */ { 1,   0,   0,   0,   0,   0,   0 }, /* batteryOk            */
+       /* PB22 */ { 1,   0,   0,   0,   0,   0,   0 }, /* fpgaInitLowBi        */
+       /* PB21 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PB20 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PB19 */ { 1,   0,   0,   1,   1,   1,   0 }, /* speakerVol           */
+       /* PB18 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PB17 */ { 1,   0,   0,   1,   0,   0,   0 }, /* swBitOkLow           */
+       /* PB16 */ { 1,   0,   0,   0,   0,   0,   0 }, /* fpgaDone                     */
+       /* PB15 */ { 1,   0,   0,   1,   0,   0,   0 }, /* gpio1                        */
+       /* PB14 */ { 1,   0,   0,   0,   0,   0,   0 }  /* docBusyLow           */
+    },
+
+       /*
+        * Pin          Signal                          Type    Active          Initial state
+        * PC4          i2cBus1EnSig            Out             High            High
+        * PC5          i2cBus2EnSig            Out             High            High
+        * PC6          gpio0Sig                        Out             High            Low
+        * PC8          i2cBus3EnSig            Out             High            High
+        * PC10         i2cBus4EnSig            Out             High            High
+        * PC11         fpgaResetLowOut         Out             Low                     High
+        * PC12         systemBitOkIn           In              High            X
+        * PC15         selfDreqLow                     In              Low                     X
+        */
+    {  /*          conf ppar psor pdir podr pdat pint    function                      */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PC15 */ { 1,   0,   0,   0,   0,   0,   0 }, /* selfDreqLowIn        */
+       /* PC14 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PC13 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PC12 */ { 1,   0,   0,   0,   0,   0,   0 }, /* systemBitOkIn        */
+       /* PC11 */ { 1,   0,   0,   1,   0,   1,   0 }, /* fpgaResetLowOut      */
+       /* PC10 */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus4EnSig         */
+       /* PC9  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PC8  */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus3EnSig         */
+       /* PC7  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PC6  */ { 1,   0,   0,   1,   0,   1,   0 }, /* gpio0                        */
+       /* PC5  */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus2EnSig         */
+       /* PC4  */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus1EnSig         */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }  /*      */
+    },
+       
+    /* Port D configuration */
+    {  /*          conf ppar psor pdir podr pdat pint     function                     */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD15 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD14 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD13 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD12 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD11 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD10 */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD9  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD8  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD7  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD6  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD5  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD4  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* PD3  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*      */
+       /* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }  /*      */
+    }
+};
+
+/*
+ * Configure the MPC8XX I/O ports per the ioport configuration table
+ * (taken from ./cpu/mpc8260/cpu_init.c)
+ */
+void
+config_mpc8xx_ioports(volatile immap_t *immr)
+{
+    int portnum;
+
+    for (portnum = 0; portnum < NUM_PORTS; portnum++) {
+               uint pmsk = 0, ppar = 0, psor = 0, pdir = 0;
+               uint podr = 0, pdat = 0, pint = 0;
+               uint msk = 1;
+               mpc8xx_iop_conf_t *iopc = (mpc8xx_iop_conf_t *)&iop_conf_tab[portnum][0];
+               mpc8xx_iop_conf_t *eiopc = iopc + PORT_BITS;
+
+               /*
+                * For all ports except port B, ignore the two don't care entries
+                * in the configuration tables.
+                */
+               if (portnum != 1) {
+                       iopc = (mpc8xx_iop_conf_t *)&iop_conf_tab[portnum][2];
+               }
+               
+               /*
+                * NOTE: index 0 refers to pin 17, index 17 refers to pin 0
+                */
+               while (iopc < eiopc) {
+               if (iopc->conf) {
+                               pmsk |= msk;
+                               if (iopc->ppar) ppar |= msk;
+                               if (iopc->psor) psor |= msk;
+                               if (iopc->pdir) pdir |= msk;
+                               if (iopc->podr) podr |= msk;
+                               if (iopc->pdat) pdat |= msk;
+                               if (iopc->pint) pint |= msk;
+                   }
+                   msk <<= 1;
+                 iopc++;
+               }
+
+               PRINTF("%s:%d:\n  portnum=%d ", __FUNCTION__, __LINE__, portnum);
+#ifdef IOPORT_DEBUG
+               switch(portnum) {
+                       case 0: printf("(A)\n"); break;
+                       case 1: printf("(B)\n"); break;
+                       case 2: printf("(C)\n"); break;
+                       case 3: printf("(D)\n"); break;
+                       default: printf("(?)\n"); break;
+               }
+#endif
+               PRINTF("  ppar=0x%.8x  pdir=0x%.8x  podr=0x%.8x\n"
+                          "  pdat=0x%.8x  psor=0x%.8x  pint=0x%.8x  pmsk=0x%.8x\n",
+                          ppar, pdir, podr, pdat, psor, pint, pmsk);
+               
+               /*
+                * Have to handle the ioports on a port-by-port basis since there
+                * are three different flavors.
+                */
+               if (pmsk != 0) {
+                   uint tpmsk = ~pmsk;
+
+                       if (0 == portnum) { /* port A */
+                       immr->im_ioport.iop_papar &= tpmsk;
+                       immr->im_ioport.iop_padat = 
+                                       (immr->im_ioport.iop_padat & tpmsk) | pdat;
+                       immr->im_ioport.iop_padir = 
+                                       (immr->im_ioport.iop_padir & tpmsk) | pdir;
+                       immr->im_ioport.iop_paodr = 
+                                       (immr->im_ioport.iop_paodr & tpmsk) | podr;
+                       immr->im_ioport.iop_papar |= ppar;
+                       }
+                       else if (1 == portnum) { /* port B */
+                       immr->im_cpm.cp_pbpar &= tpmsk;
+                       immr->im_cpm.cp_pbdat = (immr->im_cpm.cp_pbdat & tpmsk) | pdat;
+                       immr->im_cpm.cp_pbdir = (immr->im_cpm.cp_pbdir & tpmsk) | pdir;
+                       immr->im_cpm.cp_pbodr = (immr->im_cpm.cp_pbodr & tpmsk) | podr;
+                       immr->im_cpm.cp_pbpar |= ppar;
+                       }
+                       else if (2 == portnum) { /* port C */
+                       immr->im_ioport.iop_pcpar &= tpmsk;
+                       immr->im_ioport.iop_pcdat = 
+                                       (immr->im_ioport.iop_pcdat & tpmsk) | pdat;
+                       immr->im_ioport.iop_pcdir = 
+                                       (immr->im_ioport.iop_pcdir & tpmsk) | pdir;
+                       immr->im_ioport.iop_pcint = 
+                                       (immr->im_ioport.iop_pcint & tpmsk) | pint;
+                       immr->im_ioport.iop_pcso = 
+                                       (immr->im_ioport.iop_pcso & tpmsk) | psor;
+                       immr->im_ioport.iop_pcpar |= ppar;
+                       }
+                       else if (3 == portnum) { /* port D */
+                       immr->im_ioport.iop_pdpar &= tpmsk;
+                       immr->im_ioport.iop_pddat = 
+                                       (immr->im_ioport.iop_pddat & tpmsk) | pdat;
+                       immr->im_ioport.iop_pddir = 
+                                       (immr->im_ioport.iop_pddir & tpmsk) | pdir;
+                       immr->im_ioport.iop_pdpar |= ppar;
+                       }
+               }
+    }
+       
+       PRINTF("%s:%d: Port A:\n  papar=0x%.4x  padir=0x%.4x"
+                  "  paodr=0x%.4x\n  padat=0x%.4x\n", __FUNCTION__, __LINE__,
+                  immr->im_ioport.iop_papar, immr->im_ioport.iop_padir,
+                  immr->im_ioport.iop_paodr, immr->im_ioport.iop_padat);
+       PRINTF("%s:%d: Port B:\n  pbpar=0x%.8x  pbdir=0x%.8x"
+                  "  pbodr=0x%.8x\n  pbdat=0x%.8x\n", __FUNCTION__, __LINE__,
+                  immr->im_cpm.cp_pbpar, immr->im_cpm.cp_pbdir,
+                  immr->im_cpm.cp_pbodr, immr->im_cpm.cp_pbdat);
+       PRINTF("%s:%d: Port C:\n  pcpar=0x%.4x  pcdir=0x%.4x"
+                  "  pcdat=0x%.4x\n  pcso=0x%.4x  pcint=0x%.4x\n  ",
+                  __FUNCTION__, __LINE__, immr->im_ioport.iop_pcpar,
+                  immr->im_ioport.iop_pcdir, immr->im_ioport.iop_pcdat,
+                  immr->im_ioport.iop_pcso, immr->im_ioport.iop_pcint);
+       PRINTF("%s:%d: Port D:\n  pdpar=0x%.4x  pddir=0x%.4x"
+                  "  pddat=0x%.4x\n", __FUNCTION__, __LINE__,
+                  immr->im_ioport.iop_pdpar, immr->im_ioport.iop_pddir,
+                  immr->im_ioport.iop_pddat);
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
diff --git a/board/gen860t/ioport.h b/board/gen860t/ioport.h
new file mode 100644 (file)
index 0000000..34a2d7b
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#define NUM_PORTS      4
+#define PORT_BITS      18
+
+/*
+ * This structure provides configuration information for one port pin.
+ * We include all fields needed to initialize any of the ioports.
+ */
+typedef struct {
+    unsigned char conf:1;      /* If 1, configure this port            */
+    unsigned char ppar:1;      /* Port Pin Assignment Register         */
+    unsigned char psor:1;      /* Port Special Options Register        */
+    unsigned char pdir:1;      /* Port Data Direction Register         */
+    unsigned char podr:1;      /* Port Open Drain Register                     */
+    unsigned char pdat:1;      /* Port Data Register                           */
+    unsigned char pint:1;      /* Port Interrupt Register                      */
+} mpc8xx_iop_conf_t;
+
+extern void config_mpc8xx_ioports(volatile immap_t *immr);
+
+/* vim: set ts=4 tw=78 sw=4: */
diff --git a/board/gen860t/ppcboot.lds b/board/gen860t/ppcboot.lds
new file mode 100644 (file)
index 0000000..054a8cc
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Linker command file for the GEN860T board.
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+SECTIONS
+{
+  /*
+   * Read-only sections, merged into text segment:
+   */
+  . = + SIZEOF_HEADERS;
+  .interp        : { *(.interp)                }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)      }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)      }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)       }
+  .rela.got      : { *(.rela.got)      }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)       }
+  .rela.bss      : { *(.rela.bss)      }
+  .rel.plt       : { *(.rel.plt)       }
+  .rela.plt      : { *(.rela.plt)      }
+  .init          : { *(.init)          }
+  .plt           : { *(.plt)           }
+  .text :
+  {
+    cpu/mpc8xx/start.o         (.text)
+    common/dlmalloc.o          (.text)
+    lib_ppc/ppcstring.o                (.text)
+    lib_generic/vsprintf.o     (.text)
+    lib_generic/crc32.o                (.text)
+    lib_generic/zlib.o         (.text)
+
+/*    . = env_offset;
+    common/environment.o(.text) */
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /*
+   * Read-write section, merged into data segment:
+   */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  
+  _end = . ;
+  PROVIDE (end = .);
+}
+
index b11a5fb3ae650e1cee043e6d53a1c886e9c91765..99271e148ac89514e1f87408cbd19c9b1384deab 100644 (file)
 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
 
 #include <jffs2/jffs2.h>
-#include <jffs2/load_kernel.h>
 
-static void
-get_part_info(struct part_info *part)
+#ifndef CFG_JFFS_CUSTOM_PART
+
+static struct part_info part;
+
+struct part_info*
+jffs2_part_info(int part_num)
 {
        extern flash_info_t flash_info[];       /* info for FLASH chips */
        int i;
+       
+       if(part.usr_priv==(void*)1)
+               return &part;
+       
+       memset(&part, 0, sizeof(part));
 
-       memset(part, 0, sizeof(*part));
 #if defined(CFG_JFFS2_FIRST_SECTOR)
-       part->offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR];
+       part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR];
 #else
-       part->offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[0];
+       part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[0];
 #endif
 
        /* Figure out flash partition size */
        for (i = CFG_JFFS2_FIRST_BANK; i < CFG_JFFS2_NUM_BANKS+CFG_JFFS2_FIRST_BANK; i++)
-           part->size += flash_info[i].size;
+           part.size += flash_info[i].size;
 
 #if defined(CFG_JFFS2_FIRST_SECTOR) && (CFG_JFFS2_FIRST_SECTOR > 0)
-       part->size -=
+       part.size -=
             flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR] -
             flash_info[CFG_JFFS2_FIRST_BANK].start[0];
 #endif
 
        /* unused in current jffs2 loader */
-       part->erasesize = 0;
+       part.erasesize = 0;
+
+       /* Mark the struct as ready */
+       part.usr_priv=(void*)1;
+
+       return &part;
 }
+#endif /* ifndef CFG_JFFS_CUSTOM_PART */
 
 int
 do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-       struct part_info part;
        char *filename = "vmlinuz";
        ulong offset = CFG_LOAD_ADDR;
        int size;
@@ -78,10 +90,8 @@ do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                filename = argv[2];
        }
 
-       get_part_info(&part);
-
        printf("### JFFS2 loading '%s' to 0x%lx\n", filename, offset);
-       size = jffs2_1pass_load((char *)offset, &part, filename);
+       size = jffs2_1pass_load((char *)offset, jffs2_part_info(0), filename);
 
        if (size > 0) {
            printf("### JFFS2 load compleate: %d bytes loaded to 0x%lx\n",
@@ -95,15 +105,13 @@ do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 int
 do_jffs2_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-       struct part_info part;
        char *filename = "/";
        int ret;
 
        if (argc == 2)
            filename = argv[1];
 
-       get_part_info(&part);
-       ret = jffs2_1pass_ls(&part, filename);
+       ret = jffs2_1pass_ls(jffs2_part_info(0), filename);
 
        return (ret == 1);
 }
@@ -111,11 +119,9 @@ do_jffs2_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 int
 do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-       struct part_info part;
        int ret;
 
-       get_part_info(&part);
-       ret = jffs2_1pass_info(&part);
+       ret = jffs2_1pass_info(jffs2_part_info(0));
 
        return (ret == 1);
 }
index 6e07eb3d9a88faac5d050b9b6a338e42b8186f09..b5963f12e690c6fe36d0084cd3aa4cd80ce57e8f 100644 (file)
@@ -56,7 +56,7 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
        int             rcode = 0;
 
 #ifdef CONFIG_MPC860
-       mii_init (bd);
+       mii_init ();
 #endif
 
        /*
index 64cdafd2d7a94477feb87738449b6f7e147e4ed8..d943fa9ac7bc820f18a044807cbf132e9164298b 100644 (file)
@@ -563,8 +563,11 @@ static int mii_init_done = 0;
  * This function is a subset of eth_init
  ****************************************************************************
  */
-void mii_init (bd_t *bd)
+void mii_init (void)
 {
+       DECLARE_GLOBAL_DATA_PTR;
+       bd_t *bd = gd->bd;
+
        volatile immap_t *immr = (immap_t *) CFG_IMMR;
        volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
        int i;
index 2116fab1dbb3e6ab7373e72f6288bbc366487550..146342669095f32d5235c8cdef5b7127beff35ec 100644 (file)
@@ -298,7 +298,14 @@ int eth_init (bd_t * bis)
        }
 
        /* set the Mal configuration reg */
+#if defined(CONFIG_440)
+       /* Errata 1.12: MAL_1 -- Disable MAL bursting */
+       if( get_pvr() == PVR_440GP_RB )
+           mtdcr (malmcr, MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
+       else
+#else
        mtdcr (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
+#endif
 
        /* Free "old" buffers */
        if (alloc_tx_buf) free(alloc_tx_buf);
index 1c01315a68795d7c65a6128924f372293ae43dce..efd1a915c76183a1f7c125341230bf8165a28d58 100644 (file)
 #include <common.h>
 #include <command.h>
 #include <cmd_boot.h>
+#if !defined(CONFIG_440)
 #include <405gp_pci.h>
+#endif
 #include <asm/processor.h>
 #include <pci.h>
 
-#if defined(CONFIG_405GP) || defined(CONFIG_440)
+#if defined(CONFIG_405GP)
 
 #ifdef CONFIG_PCI
 
@@ -387,3 +389,114 @@ void pci_init(void)
 #endif /* CONFIG_PCI */
 
 #endif /* CONFIG_405GP */
+
+/*-----------------------------------------------------------------------------+
+ * CONFIG_440
+ *-----------------------------------------------------------------------------*/
+#if defined(CONFIG_440) && defined(CONFIG_PCI)
+
+static struct pci_controller ppc440_hose = {0};
+
+
+void pci_440_init(gd_t *gd, struct pci_controller *hose)
+{
+       int reg_num = 0;
+    unsigned long strap;
+
+       /*--------------------------------------------------------------------------+
+        * The PCI initialization sequence enable bit must be set ... if not abort
+     * pci setup since updating the bit requires chip reset.
+        *--------------------------------------------------------------------------*/
+    strap = mfdcr(cpc0_strp1);
+    if( (strap & 0x00040000) == 0 ){
+        printf("PCI: CPC0_STRP1[PISE] not set.\n");
+        printf("PCI: Configuration aborted.\n");
+        return;
+    }
+
+       /*--------------------------------------------------------------------------+
+        * PCI controller init
+        *--------------------------------------------------------------------------*/
+       hose->first_busno = 0;
+       hose->last_busno = 0xff;
+       
+       pci_set_region(hose->regions + reg_num++, 
+                      0x00000000,
+                          PCIX0_IOBASE,
+                          0x10000,
+                          PCI_REGION_IO);
+       
+       pci_set_region(hose->regions + reg_num++, 
+                      CFG_PCI_TARGBASE,
+                          CFG_PCI_MEMBASE,
+                          0x10000000,
+                          PCI_REGION_MEM );
+       hose->region_count = reg_num;
+
+       pci_setup_indirect(hose, PCIX0_CFGADR, PCIX0_CFGDATA);
+
+#if defined(CFG_PCI_PRE_INIT)
+    /* Let board change/modify hose & do initial checks */
+    if( pci_pre_init( gd, hose ) == 0 ){
+        printf("PCI: Board-specific initialization failed.\n");
+        printf("PCI: Configuration aborted.\n");
+        return;
+    }
+#endif
+
+       pci_register_hose( hose );
+
+       /*--------------------------------------------------------------------------+
+        * PCI target init 
+        *--------------------------------------------------------------------------*/
+#if defined(CFG_PCI_TARGET_INIT)
+       pci_target_init(gd, hose);                /* Let board setup pci target */
+#else
+    out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
+    out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_ID );
+    out16r( PCIX0_CLS, 0x00060000 ); /* Bridge, host bridge */
+#endif
+    
+    out32r( PCIX0_BRDGOPT1, 0x10000060 );               /* PLB Rq pri highest   */
+    out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 1 ); /* Enable host config   */
+    
+       /*--------------------------------------------------------------------------+
+        * PCI master init: default is one 256MB region for PCI memory:
+        * 0x3_00000000 - 0x3_0FFFFFFF  ==> CFG_PCI_MEMBASE
+        *--------------------------------------------------------------------------*/
+#if defined(CFG_PCI_MASTER_INIT)
+       pci_master_init(gd, hose);          /* Let board setup pci master */
+#else
+       out32r( PCIX0_POM0SA, 0 ); /* disable */
+       out32r( PCIX0_POM1SA, 0 ); /* disable */
+       out32r( PCIX0_POM2SA, 0 ); /* disable */
+       out32r( PCIX0_POM0LAL, 0x00000000 );
+       out32r( PCIX0_POM0LAH, 0x00000003 );
+       out32r( PCIX0_POM0PCIAL, CFG_PCI_MEMBASE );
+       out32r( PCIX0_POM0PCIAH, 0x00000000 );
+       out32r( PCIX0_POM0SA, 0xf0000001 ); /* 256MB, enabled */
+    out32r( PCIX0_STS, in32r( PCIX0_STS ) & ~0x0000fff8 );
+#endif
+
+       /*--------------------------------------------------------------------------+
+        * PCI host configuration -- we don't make any assumptions here ... the
+     * _board_must_indicate_ what to do -- there's just too many runtime
+     * scenarios in environments like cPCI, PPMC, etc. to make a determination
+     * based on hard-coded values or state of arbiter enable.
+        *--------------------------------------------------------------------------*/
+    if( is_pci_host(gd, hose) ){
+#ifdef CONFIG_PCI_SCAN_SHOW
+        printf("PCI:   Bus Dev VenId DevId Class Int\n");
+#endif
+        out16r( PCIX0_CMD, in16r( PCIX0_CMD ) | PCI_COMMAND_MASTER);
+        hose->last_busno = pci_hose_scan(hose);
+    }
+}
+
+
+void pci_init(gd_t *gd)
+{
+       pci_440_init( gd, &ppc440_hose );
+}
+
+#endif /* CONFIG_440 & CONFIG_PCI */
index 591d37f3436b8c3e0d190ae2e04966cc01bb0af1..d8602d3f79d17af8fd73140057703f33592ea2a1 100644 (file)
 #include <ppc4xx.h>
 
 
+#if defined(CONFIG_440)
+static int do_chip_reset( unsigned long sys0, unsigned long sys1 );
+#endif
+
 /* ------------------------------------------------------------------------- */
 
 int checkcpu (void)
@@ -138,6 +142,13 @@ int checkcpu (void)
        {
         case PVR_440GP_RB:
                putc('B');
+        /* See errata 1.12: CHIP_4 */
+        if(   ( mfdcr(cpc0_sys0) != mfdcr(cpc0_strp0) )
+            ||( mfdcr(cpc0_sys1) != mfdcr(cpc0_strp1) ) ){
+            puts("\n\t CPC0_SYSx DCRs corrupted. Resetting chip ...\n");
+            udelay( 1000 * 1000 ); /* Give time for serial buf to clear */
+            do_chip_reset( mfdcr(cpc0_strp0), mfdcr(cpc0_strp1) );
+        }
                break;
         case PVR_440GP_RC:
                putc('C');
@@ -162,10 +173,31 @@ int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
          * Initiate system reset in debug control register DBCR
          */
        __asm__ __volatile__("lis   3, 0x3000" ::: "r3");
+#if defined(CONFIG_440)
+       __asm__ __volatile__("mtspr 0x134, 3");
+#else
        __asm__ __volatile__("mtspr 0x3f2, 3");
+#endif
        return 1;
 }
 
+#if defined(CONFIG_440)
+static
+int do_chip_reset( unsigned long sys0, unsigned long sys1 )
+{
+    /* Changes to cpc0_sys0 and cpc0_sys1 require chip
+     * reset.
+     */
+    mtdcr( cntrl0, mfdcr(cntrl0) | 0x80000000 ); /* Set SWE */
+    mtdcr( cpc0_sys0, sys0 );
+    mtdcr( cpc0_sys1, sys1 );
+    mtdcr( cntrl0, mfdcr(cntrl0) & ~0x80000000 ); /* Clr SWE */
+    mtspr( dbcr0, 0x20000000);  /* Reset the chip */
+    
+    return 1;
+}
+#endif
+
 
 /*
  * Get timebase clock frequency
@@ -173,8 +205,10 @@ int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
 unsigned long get_tbclk (void)
 {
 #if defined(CONFIG_440)
-       /* FIXME: This should be done like 405GP */
-       return(400 * 1000 * 1000 ); /* Assume 400 MHz for now */
+    sys_info_t  sys_info;
+
+       get_sys_info(&sys_info);
+       return (sys_info.freqProcessor);
 #endif
     
 #if defined(CONFIG_405GP) || defined(CONFIG_405CR)
index c9311c36f116da3fbbec7760ea9b20e5bf9694f4..0867de43225fef6743fba350687760f8bb3ea356 100644 (file)
@@ -158,14 +158,14 @@ int interrupt_init(void)
         */
 #if defined(CONFIG_440)
        val = mfspr( tcr );
-       val &= (~0x04400000);         /* clear DIS & ARE */
+       val &= (~0x04400000);           /* clear DIS & ARE */
        mtspr( tcr, val );
-       mtspr( dec, 0 );              /* Prevent exception after TSR clear*/
-       mtspr( decar, 0 );            /* clear reload */
-       mtspr( tsr, 0x08000000 );     /* clear DEC status */
-       val = gd->bd->bi_intfreq/1000;
-       mtspr( decar, val );          /* Set auto-reload value */
-       mtspr( dec, val );            /* Set inital val */
+       mtspr( dec, 0 );                /* Prevent exception after TSR clear*/
+       mtspr( decar, 0 );              /* clear reload */
+       mtspr( tsr, 0x08000000 );       /* clear DEC status */
+       val = gd->bd->bi_intfreq/100;   /* 10 msec */
+       mtspr( decar, val );            /* Set auto-reload value */
+       mtspr( dec, val );              /* Set inital val */
 #else
        set_pit(gd->bd->bi_intfreq / 1000);
 #endif
@@ -181,11 +181,9 @@ int interrupt_init(void)
        /*
         * Enable PIT
         */
-#if !defined(CONFIG_440)
        val = mfspr(tcr);
        val |= 0x04400000;
        mtspr(tcr, val);
-#endif
 
        /*
         * Set EVPR to 0
@@ -231,7 +229,8 @@ void external_interrupt(struct pt_regs *regs)
                        irq_vecs[vec].count++;
 
                        if (irq_vecs[vec].handler != NULL) {
-                               (*irq_vecs[vec].handler)(irq_vecs[vec].arg);      /* call isr */
+                               /* call isr */
+                               (*irq_vecs[vec].handler)(irq_vecs[vec].arg);
                        } else {
                                mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> vec));
                                printf ("Masking bogus interrupt vector 0x%x\n", vec);
@@ -274,7 +273,8 @@ void uic1_interrupt( void * parms)
                        irq_vecs1[vec].count++;
 
                        if (irq_vecs1[vec].handler != NULL) {
-                               (*irq_vecs1[vec].handler)(irq_vecs1[vec].arg);      /* call isr */
+                               /* call isr */
+                               (*irq_vecs1[vec].handler)(irq_vecs1[vec].arg);
                        } else {
                                mtdcr(uic1er, mfdcr(uic1er) & ~(0x80000000 >> vec));
                                printf ("Masking bogus interrupt vector (uic1) 0x%x\n", vec);
@@ -306,14 +306,14 @@ irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
 {
        struct irq_action *irqa = irq_vecs;
        int   i = vec;
-  
+
 #if defined(CONFIG_440)
        if (vec > 31) {
                i = vec - 32;
                irqa = irq_vecs1;
        }
 #endif
-  
+
        if (irqa[i].handler != NULL) {
                printf ("Interrupt vector %d: handler 0x%x replacing 0x%x\n",
                        vec, (uint)handler, (uint)irqa[i].handler);
@@ -337,26 +337,26 @@ irq_free_handler(int vec)
 {
        struct irq_action *irqa = irq_vecs;
        int   i = vec;
-  
+
 #if defined(CONFIG_440)
        if (vec > 31) {
                irqa = irq_vecs1;
                i = vec - 32;
        }
 #endif
-  
+
 #if 0
        printf ("Free interrupt for vector %d ==> %p\n",
                vec, irq_vecs[vec].handler);
 #endif
-  
+
 #if defined(CONFIG_440)
        if (vec > 31)
                mtdcr(uic1er, mfdcr(uic1er) & ~(0x80000000 >> i));
        else
 #endif
                mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> i));
-  
+
        irqa[i].handler = NULL;
        irqa[i].arg     = NULL;
 }
@@ -424,11 +424,11 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
        for (vec=0; vec<32; vec++) {
                if (irq_vecs[vec].handler != NULL) {
-                       printf("%02d  %08lx  %08lx  %d\n",
-                              vec,
-                              (ulong)irq_vecs[vec].handler,
-                              (ulong)irq_vecs[vec].arg,
-                              irq_vecs[vec].count);
+                       printf ("%02d  %08lx  %08lx  %d\n",
+                               vec,
+                               (ulong)irq_vecs[vec].handler,
+                               (ulong)irq_vecs[vec].arg,
+                               irq_vecs[vec].count);
                }
        }
 
@@ -439,9 +439,9 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        for (vec=0; vec<32; vec++)
        {
                if (irq_vecs1[vec].handler != NULL)
-                       printf("%02d  %08lx  %08lx  %d\n",
-                              vec+31, (ulong)irq_vecs1[vec].handler,
-                              (ulong)irq_vecs1[vec].arg, irq_vecs1[vec].count);
+                       printf ("%02d  %08lx  %08lx  %d\n",
+                               vec+31, (ulong)irq_vecs1[vec].handler,
+                               (ulong)irq_vecs1[vec].arg, irq_vecs1[vec].count);
        }
        printf("\n");
 #endif
index 61097c61274dacb030804e20bcdc451bbfdcb293..2bbfdd502024f013bfda7acb27cafb0271f4c950 100644 (file)
  * running out of cache memory during serial/console init, then running
  * this code later.
  *
+ * (C) Copyright 2002
+ * Jun Gu, Artesyn Technology, jung@artesyncp.com
+ * Support for IBM 440 based on OpenBIOS draminit.c from IBM.
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -38,6 +42,8 @@
 
 #ifdef CONFIG_SPD_EEPROM
 
+#ifndef  CONFIG_440              /* for 405 WALNUT board */
 #define  SDRAM0_CFG_DCE          0x80000000
 #define  SDRAM0_CFG_SRE          0x40000000
 #define  SDRAM0_CFG_PME          0x20000000
@@ -437,4 +443,1311 @@ int spd_read(uint addr)
                return 0;
 }
 
-#endif /* CONFIG_DIMM_EEPROM */
+#else                             /* CONFIG_440 */
+
+/*-----------------------------------------------------------------------------
+|  Memory Controller Options 0
++-----------------------------------------------------------------------------*/
+#define SDRAM_CFG0_DCEN           0x80000000  /* SDRAM Controller Enable      */
+#define SDRAM_CFG0_MCHK_MASK      0x30000000  /* Memory data errchecking mask */
+#define SDRAM_CFG0_MCHK_NON       0x00000000  /* No ECC generation            */
+#define SDRAM_CFG0_MCHK_GEN       0x20000000  /* ECC generation               */
+#define SDRAM_CFG0_MCHK_CHK       0x30000000  /* ECC generation and checking  */
+#define SDRAM_CFG0_RDEN           0x08000000  /* Registered DIMM enable       */
+#define SDRAM_CFG0_PMUD           0x04000000  /* Page management unit         */
+#define SDRAM_CFG0_DMWD_MASK      0x02000000  /* DRAM width mask              */
+#define SDRAM_CFG0_DMWD_32        0x00000000  /* 32 bits                      */
+#define SDRAM_CFG0_DMWD_64        0x02000000  /* 64 bits                      */
+#define SDRAM_CFG0_UIOS_MASK      0x00C00000  /* Unused IO State              */
+#define SDRAM_CFG0_PDP            0x00200000  /* Page deallocation policy     */
+
+/*-----------------------------------------------------------------------------
+|  Memory Controller Options 1
++-----------------------------------------------------------------------------*/
+#define SDRAM_CFG1_SRE            0x80000000  /* Self-Refresh Entry           */
+#define SDRAM_CFG1_PMEN           0x40000000  /* Power Management Enable      */
+
+/*-----------------------------------------------------------------------------+
+|  SDRAM DEVPOT Options
++-----------------------------------------------------------------------------*/
+#define SDRAM_DEVOPT_DLL          0x80000000
+#define SDRAM_DEVOPT_DS           0x40000000
+
+/*-----------------------------------------------------------------------------+
+|  SDRAM MCSTS Options
++-----------------------------------------------------------------------------*/
+#define SDRAM_MCSTS_MRSC          0x80000000
+#define SDRAM_MCSTS_SRMS          0x40000000
+#define SDRAM_MCSTS_CIS           0x20000000
+
+/*-----------------------------------------------------------------------------
+|  SDRAM Refresh Timer Register
++-----------------------------------------------------------------------------*/
+#define SDRAM_RTR_RINT_MASK       0xFFFF0000
+#define SDRAM_RTR_RINT_ENCODE(n)  (((n) << 16) & SDRAM_RTR_RINT_MASK)
+#define sdram_HZ_to_ns(hertz)     (1000000000/(hertz))
+
+/*-----------------------------------------------------------------------------+
+|  SDRAM UABus Base Address Reg
++-----------------------------------------------------------------------------*/
+#define SDRAM_UABBA_UBBA_MASK     0x0000000F
+/*-----------------------------------------------------------------------------+
+|  Memory Bank 0-7 configuration
++-----------------------------------------------------------------------------*/
+#define SDRAM_BXCR_SDBA_MASK      0xff800000      /* Base address             */
+#define SDRAM_BXCR_SDSZ_MASK      0x000e0000      /* Size                     */
+#define SDRAM_BXCR_SDSZ_8         0x00020000      /*   8M                     */
+#define SDRAM_BXCR_SDSZ_16        0x00040000      /*  16M                     */
+#define SDRAM_BXCR_SDSZ_32        0x00060000      /*  32M                     */
+#define SDRAM_BXCR_SDSZ_64        0x00080000      /*  64M                     */
+#define SDRAM_BXCR_SDSZ_128       0x000a0000      /* 128M                     */
+#define SDRAM_BXCR_SDSZ_256       0x000c0000      /* 256M                     */
+#define SDRAM_BXCR_SDSZ_512       0x000e0000      /* 512M                     */
+#define SDRAM_BXCR_SDAM_MASK      0x0000e000      /* Addressing mode          */
+#define SDRAM_BXCR_SDAM_1         0x00000000      /*   Mode 1                 */
+#define SDRAM_BXCR_SDAM_2         0x00002000      /*   Mode 2                 */
+#define SDRAM_BXCR_SDAM_3         0x00004000      /*   Mode 3                 */
+#define SDRAM_BXCR_SDAM_4         0x00006000      /*   Mode 4                 */
+#define SDRAM_BXCR_SDBE           0x00000001      /* Memory Bank Enable       */
+
+/*-----------------------------------------------------------------------------+
+|  SDRAM TR0 Options
++-----------------------------------------------------------------------------*/
+#define SDRAM_TR0_SDWR_MASK       0x80000000
+#define   SDRAM_TR0_SDWR_2_CLK    0x00000000
+#define   SDRAM_TR0_SDWR_3_CLK    0x80000000
+#define SDRAM_TR0_SDWD_MASK       0x40000000
+#define   SDRAM_TR0_SDWD_0_CLK    0x00000000
+#define   SDRAM_TR0_SDWD_1_CLK    0x40000000
+#define SDRAM_TR0_SDCL_MASK       0x01800000
+#define   SDRAM_TR0_SDCL_2_0_CLK  0x00800000
+#define   SDRAM_TR0_SDCL_2_5_CLK  0x01000000
+#define   SDRAM_TR0_SDCL_3_0_CLK  0x01800000
+#define SDRAM_TR0_SDPA_MASK       0x000C0000
+#define   SDRAM_TR0_SDPA_2_CLK    0x00040000
+#define   SDRAM_TR0_SDPA_3_CLK    0x00080000
+#define   SDRAM_TR0_SDPA_4_CLK    0x000C0000
+#define SDRAM_TR0_SDCP_MASK       0x00030000
+#define   SDRAM_TR0_SDCP_2_CLK    0x00000000
+#define   SDRAM_TR0_SDCP_3_CLK    0x00010000
+#define   SDRAM_TR0_SDCP_4_CLK    0x00020000
+#define   SDRAM_TR0_SDCP_5_CLK    0x00030000
+#define SDRAM_TR0_SDLD_MASK       0x0000C000
+#define   SDRAM_TR0_SDLD_1_CLK    0x00000000
+#define   SDRAM_TR0_SDLD_2_CLK    0x00004000
+#define SDRAM_TR0_SDRA_MASK       0x0000001C
+#define   SDRAM_TR0_SDRA_6_CLK    0x00000000
+#define   SDRAM_TR0_SDRA_7_CLK    0x00000004
+#define   SDRAM_TR0_SDRA_8_CLK    0x00000008
+#define   SDRAM_TR0_SDRA_9_CLK    0x0000000C
+#define   SDRAM_TR0_SDRA_10_CLK   0x00000010
+#define   SDRAM_TR0_SDRA_11_CLK   0x00000014
+#define   SDRAM_TR0_SDRA_12_CLK   0x00000018
+#define   SDRAM_TR0_SDRA_13_CLK   0x0000001C
+#define SDRAM_TR0_SDRD_MASK       0x00000003
+#define   SDRAM_TR0_SDRD_2_CLK    0x00000001
+#define   SDRAM_TR0_SDRD_3_CLK    0x00000002
+#define   SDRAM_TR0_SDRD_4_CLK    0x00000003
+
+/*-----------------------------------------------------------------------------+
+|  SDRAM TR1 Options
++-----------------------------------------------------------------------------*/
+#define SDRAM_TR1_RDSS_MASK         0xC0000000
+#define   SDRAM_TR1_RDSS_TR0        0x00000000
+#define   SDRAM_TR1_RDSS_TR1        0x40000000
+#define   SDRAM_TR1_RDSS_TR2        0x80000000
+#define   SDRAM_TR1_RDSS_TR3        0xC0000000
+#define SDRAM_TR1_RDSL_MASK         0x00C00000
+#define   SDRAM_TR1_RDSL_STAGE1     0x00000000
+#define   SDRAM_TR1_RDSL_STAGE2     0x00400000
+#define   SDRAM_TR1_RDSL_STAGE3     0x00800000
+#define SDRAM_TR1_RDCD_MASK         0x00000800
+#define   SDRAM_TR1_RDCD_RCD_0_0    0x00000000
+#define   SDRAM_TR1_RDCD_RCD_1_2    0x00000800
+#define SDRAM_TR1_RDCT_MASK         0x000001FF
+#define   SDRAM_TR1_RDCT_ENCODE(x)  (((x) << 0) & SDRAM_TR1_RDCT_MASK)
+#define   SDRAM_TR1_RDCT_DECODE(x)  (((x) & SDRAM_TR1_RDCT_MASK) >> 0)
+#define   SDRAM_TR1_RDCT_MIN        0x00000000
+#define   SDRAM_TR1_RDCT_MAX        0x000001FF
+
+/*-----------------------------------------------------------------------------+
+|  SDRAM WDDCTR Options
++-----------------------------------------------------------------------------*/
+#define SDRAM_WDDCTR_WRCP_MASK       0xC0000000
+#define   SDRAM_WDDCTR_WRCP_0DEG     0x00000000
+#define   SDRAM_WDDCTR_WRCP_90DEG    0x40000000
+#define   SDRAM_WDDCTR_WRCP_180DEG   0x80000000
+#define SDRAM_WDDCTR_DCD_MASK        0x000001FF
+
+/*-----------------------------------------------------------------------------+
+|  SDRAM CLKTR Options
++-----------------------------------------------------------------------------*/
+#define SDRAM_CLKTR_CLKP_MASK       0xC0000000
+#define   SDRAM_CLKTR_CLKP_0DEG     0x00000000
+#define   SDRAM_CLKTR_CLKP_90DEG    0x40000000
+#define   SDRAM_CLKTR_CLKP_180DEG   0x80000000
+#define SDRAM_CLKTR_DCDT_MASK       0x000001FF
+
+/*-----------------------------------------------------------------------------+
+|  SDRAM DLYCAL Options
++-----------------------------------------------------------------------------*/
+#define SDRAM_DLYCAL_DLCV_MASK      0x000003FC
+#define   SDRAM_DLYCAL_DLCV_ENCODE(x) (((x)<<2) & SDRAM_DLYCAL_DLCV_MASK)
+#define   SDRAM_DLYCAL_DLCV_DECODE(x) (((x) & SDRAM_DLYCAL_DLCV_MASK)>>2)
+
+/*-----------------------------------------------------------------------------+
+|  General Definition
++-----------------------------------------------------------------------------*/
+#define DEFAULT_SPD_ADDR1   0x53
+#define DEFAULT_SPD_ADDR2   0x52
+#define ONE_BILLION         1000000000
+#define MAXBANKS            4               /* at most 4 dimm banks */
+#define MAX_SPD_BYTES       256
+#define NUMHALFCYCLES       4
+#define NUMMEMTESTS         8
+#define NUMMEMWORDS         8
+#define MAXBXCR             4 
+#define TRUE                1
+#define FALSE               0
+
+const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = { 
+    {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 
+     0xFFFFFFFF, 0xFFFFFFFF}, 
+    {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 
+     0x00000000, 0x00000000}, 
+    {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, 
+     0x55555555, 0x55555555}, 
+    {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, 
+     0xAAAAAAAA, 0xAAAAAAAA}, 
+    {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, 
+     0x5A5A5A5A, 0x5A5A5A5A}, 
+    {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, 
+     0xA5A5A5A5, 0xA5A5A5A5}, 
+    {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, 
+     0x55AA55AA, 0x55AA55AA}, 
+    {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, 
+     0xAA55AA55, 0xAA55AA55} 
+};
+
+
+unsigned char spd_read(uchar chip, uint addr);
+
+void get_spd_info(unsigned long* dimm_populated, 
+                  unsigned char* iic0_dimm_addr,
+                  unsigned long  num_dimm_banks);
+
+void check_mem_type
+                 (unsigned long* dimm_populated,
+                  unsigned char* iic0_dimm_addr,
+                  unsigned long  num_dimm_banks);
+
+void check_volt_type
+                 (unsigned long* dimm_populated,
+                  unsigned char* iic0_dimm_addr,
+                  unsigned long  num_dimm_banks);
+
+void program_cfg0(unsigned long* dimm_populated,
+                  unsigned char* iic0_dimm_addr,
+                  unsigned long  num_dimm_banks);
+
+void program_cfg1(unsigned long* dimm_populated,
+                  unsigned char* iic0_dimm_addr,
+                  unsigned long  num_dimm_banks);
+
+void program_rtr (unsigned long* dimm_populated,
+                  unsigned char* iic0_dimm_addr,
+                  unsigned long  num_dimm_banks);
+
+void program_tr0 (unsigned long* dimm_populated,
+                  unsigned char* iic0_dimm_addr,
+                  unsigned long  num_dimm_banks);
+
+void program_tr1 (void);
+
+void program_ecc (unsigned long  num_bytes);
+
+unsigned 
+long  program_bxcr(unsigned long* dimm_populated,
+                   unsigned char* iic0_dimm_addr,
+                   unsigned long  num_dimm_banks);
+
+/*
+ * This function is reading data from the DIMM module EEPROM over the SPD bus
+ * and uses that to program the sdram controller.
+ * 
+ * This works on boards that has the same schematics that the IBM walnut has.
+ *
+ * BUG: Don't handle ECC memory
+ * BUG: A few values in the TR register is currently hardcoded
+ */
+
+long int spd_sdram(void) {
+    unsigned char iic0_dimm_addr[] = SPD_EEPROM_ADDRESS;
+    unsigned long dimm_populated[sizeof(iic0_dimm_addr)];
+    unsigned long total_size;
+    unsigned long cfg0;
+    unsigned long mcsts;
+    unsigned long num_dimm_banks;               /* on board dimm banks */
+
+    num_dimm_banks = sizeof(iic0_dimm_addr);     
+
+       /*
+        * Make sure I2C controller is initialized
+        * before continuing.
+        */
+       i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+    /*
+     * Read the SPD information using I2C interface. Check to see if the
+     * DIMM slots are populated.
+     */
+    get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+    /*
+     * Check the memory type for the dimms plugged. 
+     */
+    check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+    /*
+     * Check the voltage type for the dimms plugged. 
+     */
+    check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+    /*
+     * program 440GP SDRAM controller options (SDRAM0_CFG0)
+     */
+    program_cfg0(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+    
+    /*
+     * program 440GP SDRAM controller options (SDRAM0_CFG1)
+     */
+    program_cfg1(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+    /*
+     * program SDRAM refresh register (SDRAM0_RTR)
+     */ 
+    program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+    /*
+     * program SDRAM Timing Register 0 (SDRAM0_TR0) 
+     */ 
+    program_tr0(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+    /*
+     * program the BxCR registers to find out total sdram installed
+     */ 
+    total_size = program_bxcr(dimm_populated, iic0_dimm_addr, 
+        num_dimm_banks); 
+
+    /*
+     * program SDRAM Clock Timing Register (SDRAM0_CLKTR)
+     */ 
+    mtsdram(mem_clktr, 0x40000000);
+
+    /*
+     * delay to ensure 200 usec has elapsed
+     */ 
+    udelay(400);
+
+    /*
+     * enable the memory controller
+     */ 
+    mfsdram(mem_cfg0, cfg0);
+    mtsdram(mem_cfg0, cfg0 | SDRAM_CFG0_DCEN);
+
+    /*
+     * wait for SDRAM_CFG0_DC_EN to complete
+     */ 
+    while(1) {
+        mfsdram(mem_mcsts, mcsts);
+        if ((mcsts & SDRAM_MCSTS_MRSC) != 0) {
+            break;
+        }
+    }
+
+    /*
+     * program SDRAM Timing Register 1, adding some delays
+     */ 
+    program_tr1();
+
+    /*
+     * if ECC is enabled, initialize parity bits
+     */ 
+
+       return total_size;
+}
+
+unsigned char spd_read(uchar chip, uint addr) {
+       unsigned char data[2];
+
+       if (i2c_read(chip, addr, 1, data, 1) == 0)
+               return data[0];
+       else
+               return 0;
+}
+
+void get_spd_info(unsigned long*   dimm_populated, 
+                  unsigned char*   iic0_dimm_addr,
+                  unsigned long    num_dimm_banks)
+{
+    unsigned long dimm_num;
+    unsigned long dimm_found;
+    unsigned char num_of_bytes;
+    unsigned char total_size;
+    
+    dimm_found = FALSE;
+    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+        num_of_bytes = 0;
+        total_size = 0;
+
+        num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0);
+        total_size = spd_read(iic0_dimm_addr[dimm_num], 1);
+
+        if ((num_of_bytes != 0) && (total_size != 0)) {
+            dimm_populated[dimm_num] = TRUE;
+            dimm_found = TRUE;
+#if 0
+            printf("DIMM slot %lu: populated\n", dimm_num);
+#endif
+        } 
+        else {
+            dimm_populated[dimm_num] = FALSE;
+#if 0
+            printf("DIMM slot %lu: Not populated\n", dimm_num);
+#endif
+        }
+    }
+
+    if (dimm_found == FALSE) {
+        printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n");
+        hang();
+    }
+}
+
+void check_mem_type(unsigned long*   dimm_populated,
+                    unsigned char*   iic0_dimm_addr,
+                    unsigned long    num_dimm_banks)
+{
+    unsigned long dimm_num;
+    unsigned char dimm_type;
+
+    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+        if (dimm_populated[dimm_num] == TRUE) {
+            dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2);
+            switch (dimm_type) {
+            case 7:
+#if 0
+                printf("DIMM slot %lu: DDR SDRAM detected\n", dimm_num);
+#endif
+                break;
+            default:
+                printf("ERROR: Unsupported DIMM detected in slot %lu.\n", 
+                    dimm_num);
+                printf("Only DDR SDRAM DIMMs are supported.\n");
+                printf("Replace the DIMM module with a supported DIMM.\n\n");
+                hang();
+                break;
+            }
+        }
+    }
+}
+
+
+void check_volt_type(unsigned long*   dimm_populated,
+                     unsigned char*   iic0_dimm_addr,
+                     unsigned long    num_dimm_banks)
+{
+    unsigned long dimm_num;
+    unsigned long voltage_type;
+
+    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+        if (dimm_populated[dimm_num] == TRUE) {
+            voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8);
+            if (voltage_type != 0x04) {
+                printf("ERROR: DIMM %lu with unsupported voltage level.\n",
+                    dimm_num);
+                hang();
+            }
+            else {
+#if 0
+                printf("DIMM %lu voltage level supported.\n", dimm_num);
+#endif
+            }
+            break;
+        }
+    }
+}
+
+void program_cfg0(unsigned long* dimm_populated,
+                  unsigned char* iic0_dimm_addr,
+                  unsigned long  num_dimm_banks)
+{
+    unsigned long dimm_num;
+    unsigned long cfg0;
+    unsigned long ecc_enabled; 
+    unsigned char ecc; 
+    unsigned char attributes; 
+    unsigned long data_width;
+    unsigned long dimm_32bit;
+    unsigned long dimm_64bit;
+
+    /*
+     * get Memory Controller Options 0 data
+     */
+    mfsdram(mem_cfg0, cfg0);
+
+    /*
+     * clear bits
+     */
+    cfg0 &= ~(SDRAM_CFG0_DCEN | SDRAM_CFG0_MCHK_MASK | 
+              SDRAM_CFG0_RDEN | SDRAM_CFG0_PMUD | 
+              SDRAM_CFG0_DMWD_MASK | 
+              SDRAM_CFG0_UIOS_MASK | SDRAM_CFG0_PDP);
+
+
+    /*
+     * FIXME: assume the DDR SDRAMs in both banks are the same
+     */
+    ecc_enabled = TRUE;
+    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+        if (dimm_populated[dimm_num] == TRUE) {
+            ecc = spd_read(iic0_dimm_addr[dimm_num], 11);
+            if (ecc != 0x02) {
+                ecc_enabled = FALSE;
+            }
+
+            /*
+             * program Registered DIMM Enable
+             */
+            attributes = spd_read(iic0_dimm_addr[dimm_num], 21);
+            if ((attributes & 0x02) != 0x00) {
+                cfg0 |= SDRAM_CFG0_RDEN;
+            }
+
+            /*
+             * program DDR SDRAM Data Width
+             */
+            data_width = 
+                (unsigned long)spd_read(iic0_dimm_addr[dimm_num],6) +
+                (((unsigned long)spd_read(iic0_dimm_addr[dimm_num],7)) << 8);
+            if (data_width == 64 || data_width == 72) {
+                dimm_64bit = TRUE;
+                cfg0 |= SDRAM_CFG0_DMWD_64;
+            }
+            else if (data_width == 32 || data_width == 40) {
+                dimm_32bit = TRUE;
+                cfg0 |= SDRAM_CFG0_DMWD_32;
+            }
+            else {
+                printf("WARNING: DIMM with datawidth of %lu bits.\n", 
+                    data_width);
+                printf("Only DIMMs with 32 or 64 bit datawidths supported.\n");
+                hang();
+            }
+            break;
+        }
+    }
+
+    /*
+     * program Memory Data Error Checking
+     */
+    if (ecc_enabled == TRUE) {
+        cfg0 |= SDRAM_CFG0_MCHK_GEN;
+    }
+    else {
+        cfg0 |= SDRAM_CFG0_MCHK_NON;
+    }
+
+    /*
+     * program Page Management Unit
+     */
+    cfg0 |= SDRAM_CFG0_PMUD;
+
+    /*
+     * program Memory Controller Options 0
+     * Note: DCEN must be enabled after all DDR SDRAM controller 
+     * configuration registers get initialized.
+     */
+    mtsdram(mem_cfg0, cfg0);
+}
+
+void program_cfg1(unsigned long* dimm_populated,
+                  unsigned char* iic0_dimm_addr,
+                  unsigned long  num_dimm_banks)
+{
+    unsigned long cfg1;
+    mfsdram(mem_cfg1, cfg1);
+
+    /*
+     * Self-refresh exit, disable PM
+     */
+    cfg1 &= ~(SDRAM_CFG1_SRE | SDRAM_CFG1_PMEN);
+
+    /*
+     * program Memory Controller Options 1
+     */
+    mtsdram(mem_cfg1, cfg1);
+}
+
+void program_rtr (unsigned long* dimm_populated,
+                  unsigned char* iic0_dimm_addr,
+                  unsigned long  num_dimm_banks)
+{
+    unsigned long dimm_num;
+    unsigned long bus_period_x_10;
+    unsigned long refresh_rate = 0;
+    unsigned char refresh_rate_type;
+    unsigned long refresh_interval;
+    unsigned long sdram_rtr;
+    PPC440_SYS_INFO sys_info;
+
+    /*
+     * get the board info
+     */
+    get_sys_info(&sys_info);
+    bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
+    
+    
+    for (dimm_num = 0;  dimm_num < num_dimm_banks; dimm_num++) {
+        if (dimm_populated[dimm_num] == TRUE) {
+            refresh_rate_type = 0x7F & spd_read(iic0_dimm_addr[dimm_num], 12);  
+            switch (refresh_rate_type) {
+            case 0x00:
+                refresh_rate = 15625;
+                break;
+            case 0x011:
+                refresh_rate = 15625/4;
+                break;
+            case 0x02:
+                refresh_rate = 15625/2;
+                break;
+            case 0x03:
+                refresh_rate = 15626*2;
+                break;
+            case 0x04:
+                refresh_rate = 15625*4;
+                break;
+            case 0x05:
+                refresh_rate = 15625*8;
+                break;
+            default:
+                printf("ERROR: DIMM %lu, unsupported refresh rate/type.\n", 
+                    dimm_num);
+                printf("Replace the DIMM module with a supported DIMM.\n");
+                break;
+            }
+
+            break;
+        }
+    }
+
+    refresh_interval = refresh_rate * 10 / bus_period_x_10;
+    sdram_rtr = (refresh_interval & 0x3ff8) <<  16;
+
+    /*
+     * program Refresh Timer Register (SDRAM0_RTR)
+     */
+    mtsdram(mem_rtr, sdram_rtr);
+}
+
+void program_tr0 (unsigned long* dimm_populated,
+                  unsigned char* iic0_dimm_addr,
+                  unsigned long  num_dimm_banks)
+{
+    unsigned long dimm_num;
+    unsigned long tr0;
+    unsigned char wcsbc;
+    unsigned char t_rp_ns;
+    unsigned char t_rcd_ns;
+    unsigned char t_ras_ns;
+    unsigned long t_rp_clk;
+    unsigned long t_ras_rcd_clk;
+    unsigned long t_rcd_clk;
+    unsigned long t_rfc_clk;
+    unsigned long plb_check;
+    unsigned char cas_bit;
+    unsigned long cas_index;
+    unsigned char cas_2_0_available;
+    unsigned char cas_2_5_available;
+    unsigned char cas_3_0_available;
+    unsigned long cycle_time_ns_x_10[3];
+    unsigned long tcyc_3_0_ns_x_10;
+    unsigned long tcyc_2_5_ns_x_10;
+    unsigned long tcyc_2_0_ns_x_10;
+    unsigned long tcyc_reg;
+    unsigned long bus_period_x_10;
+    PPC440_SYS_INFO sys_info;
+    unsigned long residue;
+
+    /*
+     * get the board info
+     */
+    get_sys_info(&sys_info);
+    bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
+    
+    /*
+     * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits
+     */
+    mfsdram(mem_tr0, tr0);
+    tr0 &= ~(SDRAM_TR0_SDWR_MASK | SDRAM_TR0_SDWD_MASK | 
+             SDRAM_TR0_SDCL_MASK | SDRAM_TR0_SDPA_MASK | 
+             SDRAM_TR0_SDCP_MASK | SDRAM_TR0_SDLD_MASK | 
+             SDRAM_TR0_SDRA_MASK | SDRAM_TR0_SDRD_MASK);
+
+    /*
+     * initialization
+     */
+    wcsbc = 0;
+    t_rp_ns = 0;
+    t_rcd_ns = 0;
+    t_ras_ns = 0;
+    cas_2_0_available = TRUE;
+    cas_2_5_available = TRUE;
+    cas_3_0_available = TRUE;
+    tcyc_2_0_ns_x_10 = 0;
+    tcyc_2_5_ns_x_10 = 0;
+    tcyc_3_0_ns_x_10 = 0;
+
+    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+        if (dimm_populated[dimm_num] == TRUE) {
+            wcsbc = spd_read(iic0_dimm_addr[dimm_num], 15);
+            t_rp_ns  = spd_read(iic0_dimm_addr[dimm_num], 27) >> 2;
+            t_rcd_ns = spd_read(iic0_dimm_addr[dimm_num], 29) >> 2;
+            t_ras_ns = spd_read(iic0_dimm_addr[dimm_num], 30);
+            cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18);
+
+            for (cas_index = 0; cas_index < 3; cas_index++) {
+                switch (cas_index) {
+                case 0:
+                    tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9);
+                    break;
+                case 1:
+                    tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 23);
+                    break;
+                default:
+                    tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 25);
+                    break;
+                }
+                if ((tcyc_reg & 0x0F) >= 10) {
+                    printf("ERROR: Tcyc incorrect for DIMM in slot %lu\n", 
+                        dimm_num);
+                    hang();
+                }
+
+                cycle_time_ns_x_10[cas_index] = 
+                    (((tcyc_reg & 0xF0) >> 4) * 10) + (tcyc_reg & 0x0F);
+            }
+
+            cas_index = 0;
+
+            if ((cas_bit & 0x80) != 0) {
+                cas_index += 3; 
+            }
+            else if ((cas_bit & 0x40) != 0) {
+                cas_index += 2;
+            }
+            else if ((cas_bit & 0x20) != 0) {
+                cas_index += 1;
+            }
+
+            if (((cas_bit & 0x10) != 0) && (cas_index < 3)) {
+                tcyc_3_0_ns_x_10 = cycle_time_ns_x_10[cas_index];
+                cas_index++; 
+            }
+            else {
+                if (cas_index != 0) {
+                    cas_index++;
+                }
+                cas_3_0_available = FALSE;
+            }
+
+            if (((cas_bit & 0x08) != 0) || (cas_index < 3)) {
+                tcyc_2_5_ns_x_10 = cycle_time_ns_x_10[cas_index];
+                cas_index++; 
+            }
+            else {
+                if (cas_index != 0) {
+                    cas_index++;
+                }
+                cas_2_5_available = FALSE;
+            }
+
+            if (((cas_bit & 0x04) != 0) || (cas_index < 3)) {
+                tcyc_2_0_ns_x_10 = cycle_time_ns_x_10[cas_index];
+                cas_index++; 
+            }
+            else {
+                if (cas_index != 0) {
+                    cas_index++;
+                }
+                cas_2_0_available = FALSE;
+            }
+            
+            break;
+        }
+    }
+
+    /*
+     * Program SD_WR and SD_WCSBC fields
+     */
+    tr0 |= SDRAM_TR0_SDWR_2_CLK;                /* Write Recovery: 2 CLK */
+    switch (wcsbc) {
+    case 0:
+        tr0 |= SDRAM_TR0_SDWD_0_CLK;
+        break;
+    default:
+        tr0 |= SDRAM_TR0_SDWD_1_CLK;
+        break;
+    }
+
+    /*
+     * Program SD_CASL field
+     */
+    if ((cas_2_0_available == TRUE) && 
+        (bus_period_x_10 >= tcyc_2_0_ns_x_10)) {
+        tr0 |= SDRAM_TR0_SDCL_2_0_CLK;
+    }
+    else if((cas_2_5_available == TRUE) &&
+        (bus_period_x_10 >= tcyc_2_5_ns_x_10)) {
+        tr0 |= SDRAM_TR0_SDCL_2_5_CLK;
+    }
+    else if((cas_3_0_available == TRUE) &&
+        (bus_period_x_10 >= tcyc_3_0_ns_x_10)) {
+        tr0 |= SDRAM_TR0_SDCL_3_0_CLK;
+    }
+    else {
+        printf("ERROR: No supported CAS latency with the installed DIMMs.\n");
+        printf("Only CAS latencies of 2.0, 2.5, and 3.0 are supported.\n");
+        printf("Make sure the PLB speed is within the supported range.\n");
+        hang();
+    }
+
+    /*
+     * Calculate Trp in clock cycles and round up if necessary 
+     * Program SD_PTA field
+     */
+    t_rp_clk = sys_info.freqPLB * t_rp_ns / ONE_BILLION;
+    plb_check = ONE_BILLION * t_rp_clk / t_rp_ns;
+    if (sys_info.freqPLB != plb_check) {
+        t_rp_clk++;
+    }
+    switch ((unsigned long)t_rp_clk) {
+    case 0:
+    case 1:
+    case 2:
+        tr0 |= SDRAM_TR0_SDPA_2_CLK;
+        break;
+    case 3:
+        tr0 |= SDRAM_TR0_SDPA_3_CLK;
+        break;
+    default:
+        tr0 |= SDRAM_TR0_SDPA_4_CLK;
+        break;
+    }
+
+    /*
+     * Program SD_CTP field
+     */
+    t_ras_rcd_clk = sys_info.freqPLB * (t_ras_ns - t_rcd_ns) / ONE_BILLION;
+    plb_check = ONE_BILLION * t_ras_rcd_clk / (t_ras_ns - t_rcd_ns);
+    if (sys_info.freqPLB != plb_check) {
+        t_ras_rcd_clk++;
+    }
+    switch (t_ras_rcd_clk) {
+    case 0:
+    case 1:
+    case 2:
+      tr0 |= SDRAM_TR0_SDCP_2_CLK;
+      break;
+    case 3:
+      tr0 |= SDRAM_TR0_SDCP_3_CLK;
+      break;
+    case 4: 
+      tr0 |= SDRAM_TR0_SDCP_4_CLK;
+      break;
+    default:
+      tr0 |= SDRAM_TR0_SDCP_5_CLK;
+      break;
+    }
+
+    /*
+     * Program SD_LDF field
+     */
+    tr0 |= SDRAM_TR0_SDLD_2_CLK;
+
+    /*
+     * Program SD_RFTA field
+     * FIXME tRFC hardcoded as 75 nanoseconds
+     */
+    t_rfc_clk = sys_info.freqPLB / (ONE_BILLION / 75);
+    residue = sys_info.freqPLB % (ONE_BILLION / 75);
+    if (residue >= (ONE_BILLION / 150)) {
+        t_rfc_clk++;
+    }
+    switch (t_rfc_clk) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+        tr0 |= SDRAM_TR0_SDRA_6_CLK;
+        break;
+    case 7: 
+        tr0 |= SDRAM_TR0_SDRA_7_CLK;
+        break;
+    case 8:
+        tr0 |= SDRAM_TR0_SDRA_8_CLK;
+        break;
+    case 9:
+        tr0 |= SDRAM_TR0_SDRA_9_CLK;
+        break;
+    case 10:
+        tr0 |= SDRAM_TR0_SDRA_10_CLK;
+        break;
+    case 11:
+        tr0 |= SDRAM_TR0_SDRA_11_CLK;
+        break;
+    case 12:
+        tr0 |= SDRAM_TR0_SDRA_12_CLK;
+        break;
+    default:
+        tr0 |= SDRAM_TR0_SDRA_13_CLK;
+        break;
+    }
+    /*
+     * Program SD_RCD field
+     */
+    t_rcd_clk = sys_info.freqPLB * t_rcd_ns / ONE_BILLION;
+    plb_check = ONE_BILLION * t_rcd_clk / t_rcd_ns;
+    if (sys_info.freqPLB != plb_check) {
+        t_rcd_clk++;
+    }
+    switch (t_rcd_clk) {
+    case 0:
+    case 1:
+    case 2:
+        tr0 |= SDRAM_TR0_SDRD_2_CLK;
+        break;
+    case 3:
+        tr0 |= SDRAM_TR0_SDRD_3_CLK;
+        break;
+    default:
+        tr0 |= SDRAM_TR0_SDRD_4_CLK;
+        break;
+    }
+
+#if 0
+    printf("tr0: %x\n", tr0);
+#endif
+    mtsdram(mem_tr0, tr0);
+}
+
+void program_tr1 (void)
+{
+    unsigned long tr0;
+    unsigned long tr1;
+    unsigned long cfg0;
+    unsigned long ecc_temp;
+    unsigned long dlycal;
+    unsigned long dly_val;
+    unsigned long i, j, k;
+    unsigned long bxcr_num;
+    unsigned long max_pass_length;
+    unsigned long current_pass_length;
+    unsigned long current_fail_length;
+    unsigned long current_start;
+    unsigned long rdclt;
+    unsigned long rdclt_offset;
+    long max_start;
+    long max_end;
+    long rdclt_average;
+    unsigned char window_found;
+    unsigned char fail_found;
+    unsigned char pass_found;
+    unsigned long * membase;
+    PPC440_SYS_INFO sys_info;
+
+    /*
+     * get the board info
+     */
+    get_sys_info(&sys_info);
+
+    /*
+     * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits
+     */
+    mfsdram(mem_tr1, tr1);
+    tr1 &= ~(SDRAM_TR1_RDSS_MASK | SDRAM_TR1_RDSL_MASK | 
+             SDRAM_TR1_RDCD_MASK | SDRAM_TR1_RDCT_MASK);
+
+    mfsdram(mem_tr0, tr0);
+    if (((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) && 
+       (sys_info.freqPLB > 100000000)) {
+        tr1 |= SDRAM_TR1_RDSS_TR2;
+        tr1 |= SDRAM_TR1_RDSL_STAGE3;
+        tr1 |= SDRAM_TR1_RDCD_RCD_1_2;
+    }
+    else {
+        tr1 |= SDRAM_TR1_RDSS_TR1;
+        tr1 |= SDRAM_TR1_RDSL_STAGE2;
+        tr1 |= SDRAM_TR1_RDCD_RCD_0_0;
+    }
+
+    /*
+     * save CFG0 ECC setting to a temporary variable and turn ECC off
+     */
+    mfsdram(mem_cfg0, cfg0);
+    ecc_temp = cfg0 & SDRAM_CFG0_MCHK_MASK;
+    mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_NON);
+
+    /*
+     * get the delay line calibration register value
+     */
+    mfsdram(mem_dlycal, dlycal);
+    dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2;
+
+    max_pass_length = 0;
+    max_start = 0;
+    max_end = 0;
+    current_pass_length = 0;
+    current_fail_length = 0;
+    current_start = 0;
+    rdclt_offset = 0;
+    window_found = FALSE;
+    fail_found = FALSE;
+    pass_found = FALSE;
+#ifdef DEBUG
+    printf("Starting memory test ");
+#endif
+    for (k = 0; k < NUMHALFCYCLES; k++) {
+        for (rdclt = 0; rdclt < dly_val; rdclt++)  {
+            /*
+             * Set the timing reg for the test.
+             */
+            mtsdram(mem_tr1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt)));
+    
+            for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) {
+                mtdcr(memcfga, mem_b0cr + (bxcr_num<<2));
+                if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) {
+                    /* Bank is enabled */
+                    membase = (unsigned long*)
+                        (mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK);
+
+                    /*
+                     * Run the short memory test
+                     */
+                    for (i = 0; i < NUMMEMTESTS; i++) {
+                        for (j = 0; j < NUMMEMWORDS; j++) {
+                            membase[j] = test[i][j];
+                            ppcDcbf((unsigned long)&(membase[j]));
+                        }
+
+                        for (j = 0; j < NUMMEMWORDS; j++) {
+                            if (membase[j] != test[i][j]) {
+                                ppcDcbf((unsigned long)&(membase[j]));
+                                break;
+                            }
+                            ppcDcbf((unsigned long)&(membase[j]));
+                        } 
+
+                        if (j < NUMMEMWORDS) {
+                            break;
+                        }
+                    }
+
+                    /*
+                     * see if the rdclt value passed
+                     */
+                    if (i < NUMMEMTESTS) {
+                        break;
+                    }
+                }
+            }
+
+            if (bxcr_num == MAXBXCR) {
+                if (fail_found == TRUE) {
+                    pass_found = TRUE;
+                    if (current_pass_length == 0) {
+                        current_start = rdclt_offset + rdclt;
+                    }
+
+                    current_fail_length = 0;
+                    current_pass_length++;
+
+                    if (current_pass_length > max_pass_length) {
+                        max_pass_length = current_pass_length;
+                        max_start = current_start;
+                        max_end = rdclt_offset + rdclt;
+                    }
+                }
+            }
+            else {
+                current_pass_length = 0;
+                current_fail_length++;
+
+                if (current_fail_length >= (dly_val>>2)) {
+                    if (fail_found == FALSE) {
+                        fail_found = TRUE;
+                    }
+                    else if (pass_found == TRUE) {
+                        window_found = TRUE;
+                        break;
+                    }
+                }
+            }
+        }
+#ifdef DEBUG
+        printf(".");
+#endif
+        if (window_found == TRUE) {
+            break;
+        }
+
+        tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;
+        rdclt_offset += dly_val;
+    }
+#ifdef DEBUG
+    printf("\n");
+#endif
+
+    /*
+     * make sure we find the window
+     */
+    if (window_found == FALSE) {
+       printf("ERROR: Cannot determine a common read delay.\n");
+       hang();
+    } 
+
+    /*
+     * restore the orignal ECC setting
+     */
+    mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | ecc_temp);
+    /*
+     * set the SDRAM TR1 RDCD value
+     */
+    tr1 &= ~SDRAM_TR1_RDCD_MASK;
+    if ((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) {
+        tr1 |= SDRAM_TR1_RDCD_RCD_1_2;
+    }
+    else {
+        tr1 |= SDRAM_TR1_RDCD_RCD_0_0;
+    }
+
+    /*
+     * set the SDRAM TR1 RDCLT value
+     */
+    tr1 &= ~SDRAM_TR1_RDCT_MASK;
+    while (max_end >= (dly_val<<1)) {
+        max_end -= (dly_val<<1);
+        max_start -= (dly_val<<1);
+    }
+    
+    rdclt_average = ((max_start + max_end) >> 1);
+    if (rdclt_average >= 0x60)
+        while(1);
+    
+    if (rdclt_average < 0) {
+        rdclt_average = 0;
+    }
+
+    if (rdclt_average >= dly_val) {
+        rdclt_average -= dly_val;
+        tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;
+    }
+    tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average);
+
+#if 0
+    printf("tr1: %x\n", tr1);
+#endif
+    /*
+     * program SDRAM Timing Register 1 TR1
+     */
+    mtsdram(mem_tr1, tr1);
+}
+
+unsigned long program_bxcr(unsigned long* dimm_populated,
+                           unsigned char* iic0_dimm_addr,
+                           unsigned long  num_dimm_banks)
+{
+    unsigned long dimm_num;
+    unsigned long bxcr_num;
+    unsigned long bank_base_addr;
+    unsigned long bank_size_bytes;
+    unsigned long cr;
+    unsigned long i;
+    unsigned long temp;
+    unsigned char num_row_addr;
+    unsigned char num_col_addr;
+    unsigned char num_banks;
+    unsigned char bank_size_id;
+
+    
+    /*
+     * Set the BxCR regs.  First, wipe out the bank config registers.
+     */ 
+    for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) {  
+        mtdcr(memcfga, mem_b0cr + (bxcr_num << 2));
+        mtdcr(memcfgd, 0x00000000);
+    }
+    
+    /*
+     * reset the bank_base address
+     */ 
+    bank_base_addr = CFG_SDRAM_BASE;
+    
+    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+        if (dimm_populated[dimm_num] == TRUE) {
+            num_row_addr = spd_read(iic0_dimm_addr[dimm_num], 3);
+            num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4);
+            num_banks    = spd_read(iic0_dimm_addr[dimm_num], 5);
+            bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31);
+
+            /*
+             * Set the SDRAM0_BxCR regs
+             */
+            cr = 0;
+            bank_size_bytes = 4 * 1024 * 1024 * bank_size_id;
+            switch (bank_size_id) {
+            case 0x02:
+                cr |= SDRAM_BXCR_SDSZ_8;
+                break;
+            case 0x04:
+                cr |= SDRAM_BXCR_SDSZ_16;
+                break;
+            case 0x08:
+                cr |= SDRAM_BXCR_SDSZ_32;
+                break;
+            case 0x10:
+                cr |= SDRAM_BXCR_SDSZ_64;
+                break;
+            case 0x20:
+                cr |= SDRAM_BXCR_SDSZ_128;
+                break;
+            case 0x40:
+                cr |= SDRAM_BXCR_SDSZ_256;
+                break;
+            case 0x80:
+                cr |= SDRAM_BXCR_SDSZ_512;
+                break;
+            default:
+                printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n", 
+                    dimm_num);  
+                printf("ERROR: Unsupported value for the banksize: %d.\n", 
+                   bank_size_id);
+                printf("Replace the DIMM module with a supported DIMM.\n\n");
+                hang();
+            }
+
+            switch (num_col_addr) {
+            case 0x08:
+                cr |= SDRAM_BXCR_SDAM_1;
+                break;
+            case 0x09:
+                cr |= SDRAM_BXCR_SDAM_2;
+                break;
+            case 0x0A:
+                cr |= SDRAM_BXCR_SDAM_3;
+                break;
+            case 0x0B:
+                cr |= SDRAM_BXCR_SDAM_4;
+                break;
+            default:
+                printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n", 
+                   dimm_num);  
+                printf("ERROR: Unsupported value for number of "
+                   "column addresses: %d.\n", num_col_addr);
+                printf("Replace the DIMM module with a supported DIMM.\n\n");
+                hang();
+            }
+
+            /*
+             * enable the bank
+             */
+            cr |= SDRAM_BXCR_SDBE;
+            /*------------------------------------------------------------------
+            | This next section is hardware dependent and must be programmed 
+            | to match the hardware.
+            +-----------------------------------------------------------------*/
+            if (dimm_num == 0) {
+                for (i = 0; i < num_banks; i++) {
+                    mtdcr(memcfga, mem_b0cr + (i << 2));
+                    temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | 
+                                              SDRAM_BXCR_SDSZ_MASK | 
+                                              SDRAM_BXCR_SDAM_MASK |
+                                              SDRAM_BXCR_SDBE);
+                    cr |= temp;
+                    cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; 
+                    mtdcr(memcfgd, cr);
+                    bank_base_addr += bank_size_bytes;
+                }
+            }
+            else {
+                for (i = 0; i < num_banks; i++) {
+                    mtdcr(memcfga, mem_b2cr + (i << 2));
+                    temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK |
+                                              SDRAM_BXCR_SDSZ_MASK | 
+                                              SDRAM_BXCR_SDAM_MASK |
+                                              SDRAM_BXCR_SDBE);
+                    cr |= temp;
+                    cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; 
+                    mtdcr(memcfgd, cr);
+                    bank_base_addr += bank_size_bytes;
+                }
+            }
+        }
+    }
+
+    return(bank_base_addr);
+}
+
+void program_ecc (unsigned long  num_bytes) 
+{
+    unsigned long bank_base_addr;
+    unsigned long current_address;
+    unsigned long end_address;
+    unsigned long address_increment;
+    unsigned long cfg0;
+
+    /*
+     * get Memory Controller Options 0 data
+     */
+    mfsdram(mem_cfg0, cfg0);
+
+    /*
+     * reset the bank_base address
+     */ 
+    bank_base_addr = CFG_SDRAM_BASE;
+
+    if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) {
+        mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | 
+            SDRAM_CFG0_MCHK_GEN);
+
+        if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32) {
+            address_increment = 4;
+        }
+        else {
+            address_increment = 8;
+        }
+
+        current_address = (unsigned long)(bank_base_addr);
+        end_address = (unsigned long)(bank_base_addr) + num_bytes;
+
+        while (current_address < end_address) {
+            *((unsigned long*)current_address) = 0x00000000;
+            current_address += address_increment;
+        } 
+
+        mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | 
+            SDRAM_CFG0_MCHK_CHK);
+    }
+}
+
+#endif /* CONFIG_440 */
+
+#endif /* CONFIG_SPD_EEPROM */
index ac8f835b5b5c0526896a2944d28b4c3a8c55d2fe..26d21908789b1f5ed6c50343eff4b98c3ab4517a 100644 (file)
@@ -208,21 +208,21 @@ ulong get_PCI_freq (void)
 #elif defined(CONFIG_440)
 void get_sys_info (sys_info_t * sysInfo)
 {
-       unsigned long sys0;
+       unsigned long strp0;
        unsigned long temp;
        unsigned long m;
 
        /* Extract configured divisors */
-       sys0 = mfdcr( cpc0_sys0 );
-       sysInfo->pllFwdDivA = 8 - ((sys0 & PLLSYS0_FWD_DIV_A_MASK) >> 15);
-       sysInfo->pllFwdDivB = 8 - ((sys0 & PLLSYS0_FWD_DIV_B_MASK) >> 12);
-       temp = (sys0 & PLLSYS0_FB_DIV_MASK) >> 18;
+       strp0 = mfdcr( cpc0_strp0 );
+       sysInfo->pllFwdDivA = 8 - ((strp0 & PLLSYS0_FWD_DIV_A_MASK) >> 15);
+       sysInfo->pllFwdDivB = 8 - ((strp0 & PLLSYS0_FWD_DIV_B_MASK) >> 12);
+       temp = (strp0 & PLLSYS0_FB_DIV_MASK) >> 18;
        sysInfo->pllFbkDiv = temp ? temp : 16;
-       sysInfo->pllOpbDiv = 1 + ((sys0 & PLLSYS0_OPB_DIV_MASK) >> 10);
-       sysInfo->pllExtBusDiv = 1 + ((sys0 & PLLSYS0_EPB_DIV_MASK) >> 8);
+       sysInfo->pllOpbDiv = 1 + ((strp0 & PLLSYS0_OPB_DIV_MASK) >> 10);
+       sysInfo->pllExtBusDiv = 1 + ((strp0 & PLLSYS0_EPB_DIV_MASK) >> 8);
 
        /* Calculate 'M' based on feedback source */
-       if( sys0 & PLLSYS0_EXTSL_MASK )
+       if( strp0 & PLLSYS0_EXTSL_MASK )
                m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
        else
                m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivA;
@@ -231,6 +231,8 @@ void get_sys_info (sys_info_t * sysInfo)
        sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
        sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
        sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB;
+    if( get_pvr() == PVR_440GP_RB ) /* Rev B divs an extra 2 -- geez! */
+        sysInfo->freqPLB >>= 1;
        sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
        sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
     
index ab9e5589e7e30498286b9c5307f16bb42f3a9aba..559ff3c062a0181cadc12c4e49998e99b14ef409 100644 (file)
@@ -194,10 +194,36 @@ _start_440:
        ori     r1,r1,0x6000    /* cache touch */
        mtspr   ccr0,r1
 
-       /* set up interrupt vectors */
-       mtspr   ivpr,r0
-       li      r1,0x500
-       mtspr   ivor4,r1
+       /*----------------------------------------------------------------*/
+       /* Setup interrupt vectors */
+       /*----------------------------------------------------------------*/
+       mtspr   ivpr,r0         /* Vectors start at 0x0000_0000 */
+       li      r1,0x0100
+       mtspr   ivor0,r1        /* Critical input */
+       li      r1,0x0200
+       mtspr   ivor1,r1        /* Machine check */
+       li      r1,0x0300
+       mtspr   ivor2,r1        /* Data storage */
+       li      r1,0x0400
+       mtspr   ivor3,r1        /* Instruction storage */
+       li      r1,0x0500
+       mtspr   ivor4,r1        /* External interrupt */
+       li      r1,0x0600
+       mtspr   ivor5,r1        /* Alignment */
+       li      r1,0x0700
+       mtspr   ivor6,r1        /* Program check */
+       li      r1,0x0800
+       mtspr   ivor7,r1        /* Floating point unavailable */
+       li      r1,0x0c00
+       mtspr   ivor8,r1        /* System call */
+       li      r1,0x1000
+       mtspr   ivor10,r1       /* Decrementer (PIT for 440) */
+       li      r1,0x1400
+       mtspr   ivor13,r1       /* Data TLB error */
+       li      r1,0x1300
+       mtspr   ivor14,r1       /* Instr TLB error */
+       li      r1,0x2000
+       mtspr   ivor15,r1       /* Debug */
        
        /*----------------------------------------------------------------*/
        /* Configure cache regions  */
diff --git a/doc/README.JFFS2 b/doc/README.JFFS2
new file mode 100644 (file)
index 0000000..f9663c3
--- /dev/null
@@ -0,0 +1,68 @@
+JFFS2 options and usage.
+-----------------------
+
+JFFS2 in ppcboot is a read only implementation of the file system in
+Linux with the same name. To use JFFS2 define CFG_CMD_JFFS2.
+
+The module adds three new commands.
+fsload  - load binary file from a file system image    
+fsinfo  - print information about file systems
+ls      - list files in a directory
+
+
+There is two ways for JFFS2 to find the disk. The default way uses
+the flash_info structure to find the start of a JFFS2 disk (called
+partition in the code) and you can change where the partition is with
+two defines.
+
+CFG_JFFS2_FIRST_BANK
+       defined the first flash bank to use
+
+CFG_JFFS2_FIRST_SECTOR
+       defines the first sector to use
+
+
+The second way is to define CFG_JFFS_CUSTOM_PART and implement the
+jffs2_part_info(int part_num) function in your board specific files.
+In this mode CFG_JFFS2_FIRST_BANK and CFG_JFFS2_FIRST_SECTOR is not
+used.
+
+The input is a partition number starting with 0. 
+Return a pointer to struct part_info or NULL for error;
+
+Ex jffs2_part_info() for one partition.
+---
+#if defined CFG_JFFS_CUSTOM_PART
+#include <jffs2/jffs2.h>
+
+static struct part_info part;
+
+struct part_info*
+jffs2_part_info(int part_num)
+{
+       if(part_num==0){
+               if(part.usr_priv==(void*)1)
+                       return &part;
+               
+               memset(&part, 0, sizeof(part));
+               part.offset=(char*)0xFF800000;
+               part.size=1024*1024*8;
+               
+               /* Mark the struct as ready */
+               part.usr_priv=(void*)1;
+               
+               return &part;
+       }       
+       return 0;
+}
+#endif
+---
+
+TODO.
+
+        Add a new command so it's actually possible to change
+       partition.
+
+        Remove the assumption that JFFS can dereference a pointer
+        into the disk. The current code do not work with memory holes
+        or hardware with a sliding window (PCMCIA).
diff --git a/doc/README.Modem b/doc/README.Modem
new file mode 100644 (file)
index 0000000..11142d6
--- /dev/null
@@ -0,0 +1,73 @@
+How to configure modem support in PPCBoot : 
+
+1. Define modem initialization strings:
+---------------------------------------
+
+The modem initialization strings have following format: 
+
+       mdm_init1=<AT-command> 
+       mdm_init2=<AT-command> 
+       ... 
+
+Turning off modem verbose responses with ATV0 or ATQ1 is not allowed;
+PPCBoot analyzes only verbose (not numeric) result codes. Modem local
+command echo can be turned off (ATE0).
+
+2. RTS/CTS hardware flow control:
+---------------------------------
+
+You may wish to enable RTS/CTS hardware flow control, if the board's
+UART driver supports it (see CONFIG_HWFLOW compile-time flag in
+config/<board>.h). This is controlled by the 'mdm_flow_control'
+environment variable:
+
+       'mdm_flow_control=rts/cts'  - to enable RTS/CTS flow control. 
+       'mdm_flow_control=none '    - to disable. 
+  
+
+The following are the examples using a Rockwell OEM modem
+configuration:
+
+SAMSUNG # setenv mdm_init1 ATZ                 - reset the modem to
+                                                 the factory defaults.
+SAMSUNG # setenv mdm_init2 ATS0=1               - set modem into
+                                                 answer mode. 
+SAMSUNG # setenv mdm_flow_control rts/cts       - enable serial port
+                                                 flow control 
+SAMSUNG # saveenv 
+
+The example above initializes modem into answer mode to wait for the
+incoming call. RTS/CTS flow control is enabled for the serial port.
+(The RTS/CTS flow control is enabled by default on the modem).
+
+
+SAMSUNG # setenv mdm_init1 ATZ 
+SAMSUNG # setenv mdm_init2 ATS39=0+IFC=0,0     - disable modem
+                                                 RTS/CTS flow control 
+SAMSUNG # setenv mdm_init3 ATDT1643973         -  dial out the number 
+SAMSUNG # setenv mdm_flow_control none 
+SAMSUNG # saveenv 
+
+The example above initializes modem to dial-up connection on the
+number 1643973. Flow control is disabled.
+
+Note that flow control must be turned both off or both on for the
+board serial port and for the modem.
+
+
+If the connection was set up successfully, the PPCBoot prompt appears
+on the terminal console. If not (PPCBoot modem was configured for
+originating the call and connection was not established) - the board
+should be reset for another dial-up try.
+
+
+Note on the SMDK2400 board: 
+---------------------------
+
+Since the board serial ports does not have DTR signal wired, modem
+should be told to ignore port DTR setting prior to connection to the
+SMDK board, and this setting should be stored in modem NVRAM. For the
+Rockwell OEM modem this can to be done with the following command:
+
+AT&D0&W 
+
diff --git a/doc/README.ppc440 b/doc/README.ppc440
new file mode 100644 (file)
index 0000000..815b963
--- /dev/null
@@ -0,0 +1,176 @@
+                           PowerPC 440
+
+                    Last Update: August 27, 2002
+=======================================================================
+
+
+OVERVIEW
+============
+
+Support for the ppc440 is contained in the cpu/ppc44x directory
+and enabled via the CONFIG_440 flag. It is largely based on the
+405gp code. A sample board support implementation is contained
+in the board/ebony directory.
+
+All testing was performed using the IBM Ebony board using both
+Rev B and Rev C silicon. However, since the Rev B. silicon has
+extensive errata, support for Rev B. is minimal (it boots and
+features such as i2c, pci, tftpboot, etc. seem to work ok).
+The expectation is that all new board designs will be using
+Rev C or later parts -- if not, you're in for a rough ride ;-)
+
+The ppc440 port does a fair job of keeping "board-specific" code
+out of the "cpu-specific" source. The goal of course was to
+provide mechanisms for each board to customize without having
+to clutter the cpu-specific source with a lot of ifdefs. Many
+of these mechanisms are described in the following sections.
+
+
+MEMORY MANAGEMENT
+=================
+
+The ppc440 doesn't run in "real mode". The MMU must be active
+at all times. Additionally, the 440 implements a 36-bit physical
+memory space that gets mapped into the PowerPC 32-bit virtual
+address space. So things like memory-mapped peripherals, etc must
+all be mapped in. Once this is done, the 32-bit virtual address
+space is then viewed as though it were physical memory.
+
+However, this means that memory, peripherals, etc can be configured
+to appear (mostly) anywhere in the virtual address space. Each board
+must define its own mappings using the tlbtab (see board/ebony/init.S).
+The actual TLB setup is performed by the cpu-specific code.
+
+Although each board is free to define its own mappings, there are
+several definitions to be aware of. These definitions may be used in
+the cpu-specific code (vs. board-specific code), so you should
+at least review these before deciding to make any changes ... it
+will probably save you some headaches ;-)
+
+CFG_SDRAM_BASE - The virtual address where SDRAM is mapped (always 0)
+
+CFG_FLASH_BASE - The virtual address where FLASH is mapped.
+
+CFG_PCI_MEMBASE - The virtual address where PCI-bus memory is mapped.
+    This mapping provides access to PCI-bus memory.
+
+CFG_PERIPHERAL_BASE - The virtual address where the 440 memory-mapped
+    peripherals are mapped. (e.g. -- UART registers, IIC registers, etc).
+
+CFG_ISRAM_BASE - The virtual address where the 440 internal SRAM is
+    mapped. The internal SRAM is equivalent to 405gp OCM and is used
+    for the initial stack.
+
+CFG_PCI_BASE - The virtual address where the 440 PCI-x bridge config
+    registers are mapped.
+
+CFG_PCI_TARGBASE - The PCI address that is mapped to the virtual address
+    defined by CFG_PCI_MEMBASE.
+
+
+UART / SERIAL
+=================
+
+The UART port works fine when an external serial clock is provided
+(like the one on the Ebony board) and when using internal clocking.
+This is controlled with the CFG_EXT_SERIAL_CLOCK flag. When using
+internal clocking, the "ideal baud rate" settings in the 440GP
+user manual are automatically calculated.
+
+CONFIG_SERIAL_SOFTWARE_FIFO enables interrupt-driven serial operation.
+But the last time I checked, interrupts were initialized after the
+serial port causing the interrupt handler to be removed from the
+handler table. This will probably be fixed soon ... or fix it
+yourself and submit a patch :-)
+
+
+DDR SDRAM CONTROLLER
+====================
+
+SDRAM controller intialization using Serial Presence Detect (SPD) is
+now supported (thanks Jun). It is enabled by defining CONFIG_SPD_EEPROM.
+The i2c eeprom addresses are controlled by the SPD_EEPROM_ADDRESS macro.
+
+NOTE: The SPD_EEPROM_ADDRESS macro is defined differently than for other
+processors. Traditionally, it defined a single address. For the 440 it
+defines an array of addresses to support multiple banks. Address order
+is significant: the addresses are used in order to program the BankN
+registers. For example, two banks with i2c addresses of 0x53 (bank 0)
+and 0x52 (bank 1) would be defined as follows:
+
+#define SPD_EEPROM_ADDRESS {0x53,0x52}
+
+
+PCI-X BRIDGE
+====================
+
+PCI is an area that requires lots of flexibility since every board has
+its own set of constraints and configuration. This section describes the
+440 implementation.
+
+CPC0_STRP1[PISE] -- if the PISE strap bit is not asserted, PCI init
+is aborted and an indication is printed. This is NOT considered an
+error -- only an indication that PCI shouldn't be initialized. This
+gives you a chance to edit the i2c bootstrap eeproms using the i2c
+utilities once you get to the ppcboot command prompt. NOTE: the default
+440 bootstrap options (not using i2c eeprom) negates this bit.
+
+The cpu-specific code sets up a default pci_controller structure
+that maps in a single PCI I/O space and PCI memory space. The I/O
+space begins at PCI I/O address 0 and the PCI memory space is
+256 MB starting at PCI address CFG_PCI_TARGBASE. After the
+pci_controller structure is initialized, the cpu-specific code will
+call the routine pci_pre_init() if the CFG_PCI_PRE_INIT flag is
+defined. This routine is implemented by board-specific code & is where
+the board can over-ride/extend the default pci_controller structure
+settings and do other pre-initialization task. If pci_pre_init()
+returns a value of zero, PCI initialization is aborted; otherwise the
+controller structure is registered and initialization continues.
+
+The default PCI target configuration is minimal -- it assumes that the
+strapping registers are set as necessary. Since the strapping bits
+provide very limited flexibility, you may want to customize the boards
+target configuration. If CFG_PCI_TARGET_INIT is defined, the cpu-specific
+code will call the routine pci_target_init() which you must implement
+in your board-specific code.
+
+Target initialization is completed by the cpu-specific code by
+initializing the subsystem id and subsystem vendor id, and then ensuring
+that the enable host configuration bit in the PCIX0_BRDGOPT2 is set. 
+
+The default PCI master initialization maps in 256 MB of pci memory
+starting at PCI address CFG_PCI_MEMBASE. To customize this, define
+PCI_MASTER_INIT. This will call the routine pci_master_init() in your
+board-specific code rather than performing the default master
+initialization.
+
+The decision to perform PCI host configuration must often be determined
+at run time. The ppc440 port differs from most other implementations in
+that it requires the board to determine its host configuration at run
+time rather than by using compile-time flags. This shouldn't create a
+large impact on the board-specific code since the board only needs to
+implement a single routine that returns a zero or non-zero value:
+is_pci_host().
+
+Justification for this becomes clear when considering systems running
+in a cPCI environment:
+
+1. Arbiter strapping: Many cPCI boards provide an external arbiter (often
+part of the PCI-to-PCI bridge). Even though the arbiter is external (the
+arbiter strapping is negated), the CPU may still be required to perform
+PCI bus configuration.
+
+2. Host only: PPMC boards must sample the MONARCH# signal at run-time.
+Depending on the configuration of the carrier, the board must determine
+if it should configure the PCI bus at run-time. In addition, access to
+the MONARCH#signal is board-specific (e.g. via custom FPGA, etc).
+
+In any event, the is_pci_host() routine gives each board the opportunity
+to decide at run-time. If your board is always configured a certain way,
+then just hardcode a return of 1 or 0 as appropriate.
+
+
+
+Regards,
+--Scott
+<smcnutt@artesyncp.com>
index 368ce3bcb97e2fdb8ee011898a2ddc21b9406aec..d12cdbdd3fac47827d394e444a320d54219b7a55 100644 (file)
@@ -100,8 +100,7 @@ static char *compr_names[] = {
 
 static char spinner[] = { '|', '\\', '-', '/' };
 
-static struct b_lists g_1PassList;
-
+#define DEBUG
 #ifdef  DEBUG
 # define DEBUGF(fmt,args...)   printf(fmt ,##args)
 #else
@@ -195,16 +194,19 @@ jffs2_scan_empty(u32 start_offset, struct part_info *part)
 }
 
 static u32
-jffs_init_1pass_list(void)
+jffs_init_1pass_list(struct part_info *part)
 {
-       g_1PassList.dirListHead = g_1PassList.dirListTail = NULL;
-       g_1PassList.fragListHead = g_1PassList.fragListTail = NULL;
-       g_1PassList.dirListCount = 0;
-       g_1PassList.dirListMemBase = 0;
-       g_1PassList.fragListCount = 0;
-       g_1PassList.fragListMemBase = 0;
-       g_1PassList.partOffset = 0x0;
-
+       if ( 0 != ( part->jffs2_priv=malloc(sizeof(struct b_lists)))){
+               struct b_lists *pL =(struct b_lists *)part->jffs2_priv;    
+       
+               pL->dirListHead = pL->dirListTail = NULL;
+               pL->fragListHead = pL->fragListTail = NULL;
+               pL->dirListCount = 0;
+               pL->dirListMemBase = 0;
+               pL->fragListCount = 0;
+               pL->fragListMemBase = 0;
+               pL->partOffset = 0x0;
+       }
        return 0;
 }
 
@@ -668,17 +670,22 @@ jffs2_1pass_search_list_inodes(struct b_lists * pL, const char *fname, u32 pino)
 }
 
 unsigned char
-jffs2_1pass_rescan_needed(struct part_info *part, struct b_lists *pL)
+jffs2_1pass_rescan_needed(struct part_info *part)
 {
-       unsigned char ret = 0;
        struct b_node *b;
        struct jffs2_unknown_node *node;
+       struct b_lists *pL=(struct b_lists *)part->jffs2_priv;
 
+       if (part->jffs2_priv == 0){
+               DEBUGF ("rescan: First time in use\n");
+               return 1;
+       }
        // if we have no list, we need to rescan
        if (pL->fragListCount == 0) {
                DEBUGF ("rescan: fraglist zero\n");
                return 1;
        }
+
        // or if we are scanninga new partition
        if (pL->partOffset != part->offset) {
                DEBUGF ("rescan: different partition\n");
@@ -694,12 +701,13 @@ jffs2_1pass_rescan_needed(struct part_info *part, struct b_lists *pL)
                }
                b = b->next;
        }
-       return ret;
+       return 0;
 }
 
 static u32
-jffs2_1pass_build_lists(struct part_info * part, struct b_lists * pL)
+jffs2_1pass_build_lists(struct part_info * part)
 {
+       struct b_lists *pL;
        struct jffs2_unknown_node *node;
        u32 offset;
        u32 max = part->size - sizeof(struct jffs2_raw_inode);
@@ -716,7 +724,8 @@ jffs2_1pass_build_lists(struct part_info * part, struct b_lists * pL)
        // if we are building a list we need to refresh the cache.
        // note that since we don't free our memory, eventually this will be bad.
        // but we're a bootldr so what the hell.
-       jffs_init_1pass_list();
+       jffs_init_1pass_list(part);
+       pL=(struct b_lists *)part->jffs2_priv;
        pL->partOffset = part->offset;
        offset = 0;
        printf("Scanning JFFS2 FS:   ");
@@ -890,15 +899,13 @@ jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL)
 static struct b_lists *
 jffs2_get_list(struct part_info * part, const char *who)
 {
-       struct b_lists *pl = &g_1PassList;
-
-       if (jffs2_1pass_rescan_needed(part, pl)) {
-               if (!jffs2_1pass_build_lists(part, pl)) {
+       if (jffs2_1pass_rescan_needed(part)) {
+               if (!jffs2_1pass_build_lists(part)) {
                        printf("%s: Failed to scan JFFSv2 file structure\n", who);
                        return NULL;
                }
        }
-       return pl;
+       return (struct b_lists *)part->jffs2_priv;
 }
 
 
@@ -969,7 +976,7 @@ u32
 jffs2_1pass_info(struct part_info * part)
 {
        struct b_jffs2_info info;
-       struct b_lists *pl = &g_1PassList;
+       struct b_lists *pl;
        int i;
 
        if (! (pl  = jffs2_get_list(part, "info")))
index c8dc5e75827d4d197ce7539c6ff5cc89604bc01e..463dfea10083b60c786b8e9351117564be060ddb 100644 (file)
@@ -38,6 +38,9 @@ typedef volatile unsigned char        vu_char;
 #include <linux/string.h>
 #include <asm/ptrace.h>
 #include <stdarg.h>
+#if defined(CONFIG_PCI) && defined(CONFIG_440)
+#include <pci.h>
+#endif
 #ifdef CONFIG_8xx
 #include <asm/8xx_immap.h>
 #elif defined(CONFIG_8260)
@@ -135,37 +138,29 @@ void inline setenv   (char *, char *);
 void    pci_init      (void);
 void    pciinfo       (int, int);
 
+#if defined(CONFIG_PCI) && defined(CONFIG_440)
+#   if defined(CFG_PCI_PRE_INIT)
+    int    pci_pre_init        (gd_t *, struct pci_controller * );
+#   endif
+#   if defined(CFG_PCI_TARGET_INIT)
+       void    pci_target_init      (gd_t *, struct pci_controller *);
+#   endif
+#   if defined(CFG_PCI_MASTER_INIT)
+       void    pci_master_init      (gd_t *, struct pci_controller *);
+#   endif
+    int     is_pci_host         (gd_t *, struct pci_controller *);
+#endif
+
 int    misc_init_f   (void);
 int    misc_init_r   (void);
 
 /* $(BOARD)/$(BOARD).c */
 void   reset_phy     (void);
 
-#if defined(CONFIG_CANBT)      || \
-    defined(CONFIG_CCM)                || \
-    defined(CONFIG_CPCI405)    || \
-    defined(CONFIG_CPCIISER4)  || \
-    defined(CONFIG_DU405)      || \
-    defined(CONFIG_HYMOD)      || \
-    defined(CONFIG_IP860)      || \
-    defined(CONFIG_LWMON)      || \
-    defined(CONFIG_OCRTC)      || \
-    defined(CONFIG_ORSG)       || \
-    defined(CONFIG_PCU_E)      || \
-    defined(CONFIG_PCI405)     || \
-    defined(CONFIG_PIP405)     || \
-    defined(CONFIG_MIP405)     || \
-    defined(CONFIG_PM826)      || \
-    defined(CONFIG_SXNI855T)   || \
-    defined(CONFIG_TQM8260)    || \
-    defined(CONFIG_CPU86)      || \
-    defined(CONFIG_W7O)                || \
-    defined(CONFIG_WALNUT405)
 /* $(BOARD)/eeprom.c */
 void eeprom_init  (void);
 int  eeprom_read  (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt);
 int  eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt);
-#endif
 #ifdef CONFIG_LWMON
 extern uchar pic_read  (uchar reg);
 extern void  pic_write (uchar reg, uchar val);
@@ -336,6 +331,9 @@ uint        dpram_alloc_align(uint size,uint align);
 void   post_word_store (ulong);
 ulong  post_word_load (void);
 
+/* $(CPU)/.../<eth> */
+void mii_init (void);
+
 /* $(CPU)/.../lcd.c */
 #ifdef CONFIG_LCD
 ulong  lcd_setmem (ulong);
index 4fbade694fad8777932d589aa1a2281d428476e5..fb866dfd9238027d866632517c207680f954d602 100644 (file)
@@ -734,6 +734,27 @@ typedef struct scc_enet {
 #define SICR_ENET_CLKRT        ((uint)0x00002600)
 #endif /* CONFIG_FPS850L */
 
+/*** GEN860T **********************************************************/
+#if defined(CONFIG_GEN860T)
+#undef SCC_ENET
+#define        FEC_ENET
+#define PD_MII_TXD1    ((ushort)0x1000)        /* PD  3        */
+#define PD_MII_TXD2    ((ushort)0x0800)        /* PD  4        */
+#define PD_MII_TXD3    ((ushort)0x0400)        /* PD  5        */
+#define PD_MII_RX_DV   ((ushort)0x0200)        /* PD  6        */
+#define PD_MII_RX_ERR  ((ushort)0x0100)        /* PD  7        */
+#define PD_MII_RX_CLK  ((ushort)0x0080)        /* PD  8        */
+#define PD_MII_TXD0    ((ushort)0x0040)        /* PD  9        */
+#define PD_MII_RXD0    ((ushort)0x0020)        /* PD 10        */
+#define PD_MII_TX_ERR  ((ushort)0x0010)        /* PD 11        */
+#define PD_MII_MDC     ((ushort)0x0008)        /* PD 12        */
+#define PD_MII_RXD1    ((ushort)0x0004)        /* PD 13        */
+#define PD_MII_RXD2    ((ushort)0x0002)        /* PD 14        */
+#define PD_MII_RXD3    ((ushort)0x0001)        /* PD 15        */
+#define PD_MII_MASK    ((ushort)0x1FFF)        /* PD 3-15      */
+#endif /* CONFIG_GEN860T */
+
 /***  GENIETV  ********************************************************/
 
 #if defined(CONFIG_GENIETV)
index 1bb766172458c97f7c366289b69011aeb3fd53cb..b97a1f204884488b010400e04e1e8a3ddce92647 100644 (file)
 #define CFG_SDRAM_BASE     0x00000000      /* _must_ be 0              */
 #define CFG_FLASH_BASE     0xff800000      /* start of FLASH           */
 #define CFG_MONITOR_BASE    0xfff80000     /* start of monitor         */
+#define CFG_PCI_MEMBASE            0x80000000      /* mapped pci memory        */
 #define CFG_PERIPHERAL_BASE 0xe0000000     /* internal peripherals     */
 #define CFG_ISRAM_BASE     0xc0000000      /* internal SRAM            */
+#define CFG_PCI_BASE       0xd0000000      /* internal PCI regs        */
 
 #define CFG_FPGA_BASE      (CFG_PERIPHERAL_BASE + 0x08300000)
 #define CFG_NVRAM_BASE_ADDR (CFG_PERIPHERAL_BASE + 0x08000000)
@@ -59,7 +61,7 @@
 #define CFG_GBL_DATA_OFFSET    (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
 #define CFG_INIT_SP_OFFSET     CFG_GBL_DATA_OFFSET
 
-#define CFG_MONITOR_LEN            (192 * 1024)    /* Reserve 192 kB for Mon   */
+#define CFG_MONITOR_LEN            (256 * 1024)    /* Reserve 192 kB for Mon   */
 #define CFG_MALLOC_LEN     (128 * 1024)    /* Reserve 128 kB for malloc*/
 
 /*-----------------------------------------------------------------------
 #define CFG_FLASH_ERASE_TOUT   120000  /* Timeout for Flash Erase (in ms)      */
 #define CFG_FLASH_WRITE_TOUT   500     /* Timeout for Flash Write (in ms)      */
 
+/*-----------------------------------------------------------------------
+ * DDR SDRAM
+ *----------------------------------------------------------------------*/
+#define CONFIG_SPD_EEPROM               /* Use SPD EEPROM for setup     */
+#define SPD_EEPROM_ADDRESS {0x53,0x52}  /* SPD i2c spd addresses        */
+
 /*-----------------------------------------------------------------------
  * Environment
  *----------------------------------------------------------------------*/
 
 
 #define CONFIG_COMMANDS               (CONFIG_CMD_DFL  | \
+                               CFG_CMD_PCI     | \
                                CFG_CMD_IRQ     | \
                                CFG_CMD_I2C     | \
                                CFG_CMD_KGDB    | \
 
 #undef CONFIG_WATCHDOG                 /* watchdog disabled            */
 
-#undef CONFIG_SPD_EEPROM       /* don't use SPD EEPROM for setup    */
-
 /*
  * Miscellaneous configurable options
  */
  * PCI stuff
  *-----------------------------------------------------------------------
  */
-#if 0
-#define PCI_HOST_ADAPTER 0             /* configure ar pci adapter     */
-#define PCI_HOST_FORCE 1               /* configure as pci host        */
-#define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
-
-#define CONFIG_PCI                     /* include pci support          */
-#define CONFIG_PCI_HOST PCI_HOST_FORCE /* select pci host function     */
-#define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
-                                       /* resource configuration       */
-
-#define CFG_PCI_SUBSYS_VENDORID 0x0000 /* PCI Vendor ID: to-do!!!      */
-#define CFG_PCI_SUBSYS_DEVICEID 0x0000 /* PCI Device ID: to-do!!!      */
-#define CFG_PCI_PTM1LA 0x00000000      /* point to sdram               */
-#define CFG_PCI_PTM1MS 0x80000001      /* 2GB, enable hard-wired to 1  */
-#define CFG_PCI_PTM1PCI 0x00000000     /* Host: use this pci address   */
-#define CFG_PCI_PTM2LA 0x00000000      /* disabled                     */
-#define CFG_PCI_PTM2MS 0x00000000      /* disabled                     */
-#define CFG_PCI_PTM2PCI 0x04000000     /* Host: use this pci address   */
-#endif
+/* General PCI */
+#define CONFIG_PCI                                 /* include pci support              */
+#define CONFIG_PCI_PNP                         /* do pci plug-and-play         */
+#define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup  */
+#define CFG_PCI_TARGBASE    0x80000000  /* PCIaddr mapped to CFG_PCI_MEMBASE */
+
+/* Board-specific PCI */
+#define CFG_PCI_PRE_INIT                /* enable board pci_pre_init()  */
+#define CFG_PCI_TARGET_INIT                /* let board init pci target    */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x1014  /* IBM */
+#define CFG_PCI_SUBSYS_DEVICEID 0xcafe  /* Whatever */
 
 /*
  * For booting Linux, the board info and command line data
 #define CFG_CACHELINE_SHIFT    5       /* log base 2 of the above value        */
 #endif
 
-
-/* Configuration Port location */
-#define CONFIG_PORT_ADDR       0xF0000500
-
-/*-----------------------------------------------------------------------
- * Definitions for Serial Presence Detect EEPROM address
- * (to get SDRAM settings)
- */
-#define SPD_EEPROM_ADDRESS     0x50
-
 /*
  * Internal Definitions
  *
diff --git a/include/configs/GEN860T.h b/include/configs/GEN860T.h
new file mode 100644 (file)
index 0000000..d35f944
--- /dev/null
@@ -0,0 +1,720 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * board/config_GEN860T.h - board specific configuration options
+ */
+
+#ifndef __CONFIG_GEN860T_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_MPC860
+#define CONFIG_GEN860T
+
+/*
+ * Identify the board
+ */
+#define CONFIG_IDENT_STRING                            " GEN860T"
+
+/*
+ * Don't depend on the RTC clock to determine clock frequency -
+ * the 860's internal rtc uses a 32.768 KHz clock which is
+ * generated by the DS1337 - and the DS1337 clock can be turned off.
+ */
+#define        CONFIG_8xx_GCLK_FREQ                    66600000
+
+/*
+ * The RS-232 console port is on SMC1
+ */
+#define        CONFIG_8xx_CONS_SMC1
+#define CONFIG_BAUDRATE                                        38400
+
+/*
+ * Set allowable console baud rates
+ */
+#define CFG_BAUDRATE_TABLE                             { 9600,         \
+                                                                                 19200,        \
+                                                                                 38400,        \
+                                                                                 57600,        \
+                                                                                 115200,       \
+                                                                               }
+
+/*
+ * Print console information
+ */
+#undef  CFG_CONSOLE_INFO_QUIET
+
+/*
+ * Set the autoboot delay in seconds.  A delay of -1 disables autoboot
+ */
+#define CONFIG_BOOTDELAY                               5
+
+/*
+ * Pass the clock frequency to the Linux kernel in units of MHz
+ */
+#define        CONFIG_CLOCKS_IN_MHZ
+
+#define CONFIG_PREBOOT         \
+       "echo;echo"
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND     \
+       "bootp;" \
+       "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
+       "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \
+       "bootm"
+
+/*
+ * Turn off echo for serial download by default.  Allow baud rate to be changed
+ * for downloads
+ */
+#undef CONFIG_LOADS_ECHO
+#define        CFG_LOADS_BAUD_CHANGE
+
+/*
+ * Set default load address for tftp network downloads
+ */
+#define        CFG_TFTP_LOADADDR                               0x01000000
+
+/*
+ * Turn off the watchdog timer
+ */
+#undef CONFIG_WATCHDOG
+
+/*
+ * Do not reboot if a panic occurs
+ */
+#define CONFIG_PANIC_HANG
+
+/*
+ * Enable the status LED
+ */
+#define        CONFIG_STATUS_LED
+
+/*
+ * Reset address. We pick an address such that when an instruction
+ * is executed at that address, a machine check exception occurs
+ */
+#define CFG_RESET_ADDRESS                              ((ulong) -1)
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_MASK                              ( CONFIG_BOOTP_DEFAULT          | \
+                                                                                 CONFIG_BOOTP_BOOTFILESIZE   \
+                                                                               )
+
+/*
+ * The GEN860T network interface uses the on-chip 10/100 FEC with
+ * an Intel LXT971A PHY connected to the 860T's MII. The PHY's
+ * MII address is hardwired on the board to zero.
+ */
+#define CONFIG_FEC_ENET
+#define CFG_DISCOVER_PHY
+#define CONFIG_MII
+#define CONFIG_PHY_ADDR                        0
+
+/*
+ * Set default IP stuff just to get bootstarp entries into the
+ * environment so that we can autoscript the full default environment.
+ */
+#define CONFIG_ETHADDR                                 9a:52:63:15:85:25
+#define CONFIG_SERVERIP                                        10.0.4.200
+#define CONFIG_IPADDR                                  10.0.4.111
+
+/*
+ * This board has a 32 kibibyte EEPROM (Atmel AT24C256) connected to
+ * the MPC860T I2C interface.
+ */
+#define CFG_I2C_EEPROM_ADDR                            0x50
+#define CFG_EEPROM_PAGE_WRITE_BITS             6               /* 64 byte pages                */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 12              /* 10 mS w/ 20% margin  */
+#define        CFG_I2C_EEPROM_ADDR_LEN                 2               /* need 16 bit address  */
+#define CFG_ENV_EEPROM_SIZE                            (32 * 1024)
+
+/*
+ * Man, that hardware I2C is slow!
+ */
+#undef CONFIG_HARD_I2C
+#define CONFIG_SOFT_I2C
+
+/*
+ * Configure software I2C support (taken from IP860 BSP).
+ * The I2C bus is connected to the GEN860T's 'dedicated' I2C
+ * pins, i.e. PB26 and PB27
+ */
+#define PB_SCL                         0x00000020              /* PB 26                                        */
+#define PB_SDA                         0x00000010              /* PB 27                                        */
+
+#define I2C_INIT                       (immr->im_cpm.cp_pbdir |=  PB_SCL)
+#define I2C_ACTIVE                     (immr->im_cpm.cp_pbdir |=  PB_SDA)
+#define I2C_TRISTATE           (immr->im_cpm.cp_pbdir &= ~PB_SDA)
+#define I2C_READ                       ((immr->im_cpm.cp_pbdat & PB_SDA) != 0)
+#define I2C_SDA(bit)           if(bit) immr->im_cpm.cp_pbdat |=  PB_SDA; \
+                                                               else    immr->im_cpm.cp_pbdat &= ~PB_SDA
+#define I2C_SCL(bit)           if(bit) immr->im_cpm.cp_pbdat |=  PB_SCL; \
+                                                               else    immr->im_cpm.cp_pbdat &= ~PB_SCL
+#define I2C_DELAY                      udelay(5)               /* 1/4 I2C clock duration       */
+
+#define        CFG_I2C_SPEED           100000                  /* clock speed in Hz            */
+#define CFG_I2C_SLAVE          0xFE                    /* I2C slave address            */
+
+/*
+ * Allow environment overwrites by anyone
+ */
+#define CONFIG_ENV_OVERWRITE
+
+/*
+ * The MPC860's internal RTC is horribly broken in rev D masks. Three
+ * internal MPC860T circuit nodes were inadvertently left floating; this
+ * causes KAPWR current in power down mode to be three orders of magnitude
+ * higher than specified in the datasheet (from 10 uA to 10 mA).  No
+ * reasonable battery can keep that kind RTC running during powerdown for any
+ * length of time, so we use an external RTC on the I2C bus instead.
+ */
+#undef CONFIG_RTC_MPC8xx
+#define CONFIG_RTC_DS1337
+#define CFG_I2C_RTC_ADDR                               0x68
+
+/*
+ * Allow partial commands to be matched to uniqueness.
+ */
+#define CFG_MATCH_PARTIAL_CMD
+
+/*
+ * List of available monitor commands.  Use the system default list
+ * plus add some of the "non-standard" commands back in.
+ * See ./cmd_confdefs.h
+ */
+#define CONFIG_COMMANDS              ( CONFIG_CMD_DFL  | \
+                                                               CFG_CMD_ASKENV  | \
+                                                               CFG_CMD_DHCP    | \
+                                                               CFG_CMD_I2C             | \
+                                                               CFG_CMD_DOC             | \
+                                                               CFG_CMD_EEPROM  | \
+                                                               CFG_CMD_REGINFO | \
+                                                               CFG_CMD_IMMAP   | \
+                                                               CFG_CMD_ELF             | \
+                                                               CFG_CMD_DATE    | \
+                                                               CFG_CMD_DATE    | \
+                                                               CFG_CMD_FPGA    | \
+                                                               CFG_CMD_MII     | \
+                                                               CFG_CMD_BEDBUG  \
+                                                     )
+
+/*
+ * There is no IDE/PCMCIA hardware support on the board.
+ */
+#undef  CONFIG_IDE_PCMCIA
+#undef  CONFIG_IDE_LED
+#undef  CONFIG_IDE_RESET
+
+/*
+ * Enable the call to misc_init_r() for miscellaneous platform
+ * dependent initialization.
+ */
+#define CONFIG_MISC_INIT_R
+
+/*
+ * Enable call to last_stage_init() so we can twiddle some LEDS :)
+ */
+#define CONFIG_LAST_STAGE_INIT
+
+/*
+ * Virtex2 FPGA configuration support
+ */
+#define CONFIG_FPGA_COUNT              1
+#define CONFIG_FPGA                            CFG_XILINX_VIRTEX2
+#define CFG_FPGA_PROG_FEEDBACK
+
+
+/************************************************************************
+ * This must be included AFTER the definition of any CONFIG_COMMANDS
+ */
+#include <cmd_confdefs.h>
+
+/*
+ * Verbose help from command monitor.
+ */
+#define        CFG_LONGHELP
+#define        CFG_PROMPT                      "gen860t> "
+
+/*
+ * Use the "hush" command parser
+ */
+#define        CFG_HUSH_PARSER
+#define        CFG_PROMPT_HUSH_PS2     "> "
+
+/*
+ * Set buffer size for console I/O
+ */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define        CFG_CBSIZE                      1024
+#else
+#define        CFG_CBSIZE                      256
+#endif
+
+/*
+ * Print buffer size
+ */
+#define        CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
+
+/*
+ * Maximum number of arguments that a command can accept
+ */
+#define        CFG_MAXARGS                     16
+
+/*
+ * Boot argument buffer size
+ */
+#define CFG_BARGSIZE           CFG_CBSIZE
+
+/*
+ * Default memory test range
+ */
+#define CFG_MEMTEST_START      0x0100000
+#define CFG_MEMTEST_END                (CFG_MEMTEST_START  + (128 * 1024))
+
+/*
+ * Select the more full-featured memory test
+ */
+#define        CFG_ALT_MEMTEST
+
+/*
+ * Default load address
+ */
+#define        CFG_LOAD_ADDR           0x01000000
+
+/*
+ * Set decrementer frequency (1 ms ticks)
+ */
+#define        CFG_HZ                          1000
+
+/*
+ * Device memory map (after SDRAM remap to 0x0):
+ *
+ * CS          Device                          Base Addr       Size
+ * ----------------------------------------------------
+ * CS0*                Flash                           0x40000000      64 M
+ * CS1*                SDRAM                           0x00000000      16 M
+ * CS2*                Disk-On-Chip            0x50000000      32 K
+ * CS3*                FPGA                            0x60000000      64 M
+ * CS4*                SelectMap                       0x70000000      32 K
+ * CS5*                Mil-Std 1553 I/F        0x80000000      32 K
+ * CS6*                Unused
+ * CS7*                Unused
+ * IMMR                860T Registers          0xfff00000
+ */
+
+/*
+ * Base addresses and block sizes
+ */
+#define CFG_IMMR                       0xFF000000
+
+#define SDRAM_BASE                     0x00000000
+#define SDRAM_SIZE                     (64 * 1024 * 1024)
+
+#define FLASH_BASE                     0x40000000
+#define FLASH_SIZE                     (16 * 1024 * 1024)
+
+#define DOC_BASE                       0x50000000
+#define DOC_SIZE                       (32 * 1024)
+
+#define FPGA_BASE                      0x60000000
+#define FPGA_SIZE                      (64 * 1024 * 1024)
+
+#define SELECTMAP_BASE         0x70000000
+#define SELECTMAP_SIZE         (32 * 1024)
+
+#define M1553_BASE                     0x80000000
+#define M1553_SIZE                     (64 * 1024)
+
+/*
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+#define CFG_INIT_RAM_ADDR              CFG_IMMR
+#define        CFG_INIT_RAM_END                0x2F00  /* End of used area in DPRAM            */
+#define        CFG_INIT_DATA_SIZE              64      /* # bytes reserved for initial data*/
+#define CFG_GBL_DATA_OFFSET            (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE)
+#define        CFG_INIT_SP_OFFSET              CFG_GBL_DATA_OFFSET
+
+/*
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define        CFG_SDRAM_BASE                  SDRAM_BASE
+
+/*
+ * FLASH organization
+ */
+#define CFG_FLASH_BASE                 FLASH_BASE
+#define CFG_FLASH_SIZE                 FLASH_SIZE
+#define CFG_FLASH_SECT_SIZE            (128 * 1024)
+#define CFG_MAX_FLASH_BANKS            1
+#define CFG_MAX_FLASH_SECT             128
+
+/*
+ * The timeout values are for an entire chip and are in milliseconds.
+ * Yes I know that the write timeout is huge.  Accroding to the
+ * datasheet a single byte takes 630 uS (round to 1 ms) max at worst
+ * case VCC and temp after 100K programming cycles.  It works out
+ * to 280 minutes (might as well be forever).
+ */
+#define CFG_FLASH_ERASE_TOUT   (CFG_MAX_FLASH_SECT * 5000)
+#define CFG_FLASH_WRITE_TOUT   (CFG_MAX_FLASH_SECT * 128 * 1024 * 1)
+
+/*
+ * Allow direct writes to FLASH from tftp transfers (** dangerous **)
+ */
+#define        CFG_DIRECT_FLASH_TFTP
+
+/*
+ * Reserve memory for ppcboot.
+ */
+#define CFG_MAX_PPCBOOT_SECT   3
+
+#if defined(DEBUG)
+#define        CFG_MONITOR_LEN         (512 * 1024)
+#else
+#define        CFG_MONITOR_LEN         (256 * 1024)
+#endif
+
+#define CFG_MONITOR_BASE       CFG_FLASH_BASE
+
+/*
+ * Select environment placement.  NOTE that ppcboot.lds must
+ * be edited if this is changed!
+ */
+#undef CFG_ENV_IS_IN_FLASH
+#define CFG_ENV_IS_IN_EEPROM
+
+#if defined(CFG_ENV_IS_IN_EEPROM)
+#define CFG_ENV_SIZE                   (2 * 1024)
+#define CFG_ENV_OFFSET                 (CFG_ENV_EEPROM_SIZE - (8 * 1024))
+#else
+#define CFG_ENV_SIZE                   (4 * 1024)
+#define CFG_ENV_OFFSET                 (CFG_MAX_PPCBOOT_SECT * CFG_FLASH_SECT_SIZE)
+#endif
+
+/*
+ * Reserve memory for malloc()
+ */
+#define        CFG_MALLOC_LEN          (128 * 1024)
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define        CFG_BOOTMAPSZ           (8 * 1024 * 1024)
+
+/*
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE             16      /* For all MPC8xx CPUs                          */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT            4       /* log base 2 of above value            */
+#endif
+
+/*------------------------------------------------------------------------
+ * SYPCR - System Protection Control                           UM 11-9
+ * -----------------------------------------------------------------------
+ * SYPCR can only be written once after reset!
+ *
+ * Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze
+ */
+#if defined(CONFIG_WATCHDOG)
+#define CFG_SYPCR      ( SYPCR_SWTC    | \
+                                         SYPCR_BMT     | \
+                                         SYPCR_BME     | \
+                                         SYPCR_SWF     | \
+                                         SYPCR_SWE     | \
+                                         SYPCR_SWRI    | \
+                                         SYPCR_SWP               \
+                                       )
+#else
+#define CFG_SYPCR      ( SYPCR_SWTC    | \
+                                         SYPCR_BMT     | \
+                                         SYPCR_BME     | \
+                                         SYPCR_SWF     | \
+                                         SYPCR_SWP               \
+                                       )
+#endif
+
+/*-----------------------------------------------------------------------
+ * SIUMCR - SIU Module Configuration                                                   UM 11-6
+ *-----------------------------------------------------------------------
+ * Set debug pin mux, enable SPKROUT and GPLB5*.
+ */
+#define CFG_SIUMCR     ( SIUMCR_DBGC11 | \
+                                         SIUMCR_DBPC11 | \
+                                         SIUMCR_MLRC11 | \
+                                         SIUMCR_GB5E     \
+                                       )
+
+/*-----------------------------------------------------------------------
+ * TBSCR - Time Base Status and Control                                                        UM 11-26
+ *-----------------------------------------------------------------------
+ * Clear Reference Interrupt Status, Timebase freeze enabled
+ */
+#define CFG_TBSCR      ( TBSCR_REFA | \
+                                         TBSCR_REFB | \
+                                         TBSCR_TBF        \
+                                       )
+
+/*-----------------------------------------------------------------------
+ * RTCSC - Real-Time Clock Status and Control Register                 UM 11-27
+ *-----------------------------------------------------------------------
+ */
+#define CFG_RTCSC      ( RTCSC_SEC     | \
+                                         RTCSC_ALR | \
+                                         RTCSC_RTF | \
+                                         RTCSC_RTE       \
+                                       )
+
+/*-----------------------------------------------------------------------
+ * PISCR - Periodic Interrupt Status and Control                               UM 11-31
+ *-----------------------------------------------------------------------
+ * Clear Periodic Interrupt Status, Interrupt Timer freezing enabled
+ */
+#define CFG_PISCR      ( PISCR_PS              | \
+                                         PISCR_PITF      \
+                                       )
+
+/*-----------------------------------------------------------------------
+ * PLPRCR - PLL, Low-Power, and Reset Control Register                 UM 15-30
+ *-----------------------------------------------------------------------
+ * Reset PLL lock status sticky bit, timer expired status bit and timer
+ * interrupt status bit. Set MF for 1:2:1 mode.
+ */
+#define CFG_PLPRCR     ( ((0x1 << PLPRCR_MF_SHIFT) & PLPRCR_MF_MSK)    | \
+                                         PLPRCR_SPLSS  | \
+                                         PLPRCR_TEXPS  | \
+                                         PLPRCR_TMIST    \
+                                       )
+
+/*-----------------------------------------------------------------------
+ * SCCR - System Clock and reset Control Register                              UM 15-27
+ *-----------------------------------------------------------------------
+ * Set clock output, timebase and RTC source and divider,
+ * power management and some other internal clocks
+ */
+#define SCCR_MASK   SCCR_EBDF11
+
+#define CFG_SCCR       ( SCCR_TBS                      |       /* timebase = GCLK/2    */ \
+                                         SCCR_COM00            |       /* full strength CLKOUT */ \
+                                         SCCR_DFSYNC00         |       /* SYNCLK / 1 (normal)  */ \
+                                         SCCR_DFBRG00          |       /* BRGCLK / 1 (normal)  */ \
+                                         SCCR_DFNL000          | \
+                                         SCCR_DFNH000            \
+                                       )
+
+/*-----------------------------------------------------------------------
+ * DER - Debug Enable Register                                                                 UM 37-46
+ *-----------------------------------------------------------------------
+ * Mask all events that can cause entry into debug mode
+ */
+#define CFG_DER                                0
+
+/*
+ * Initialize Memory Controller:
+ *
+ * BR0 and OR0 (FLASH memory)
+ */
+#define FLASH_BASE0_PRELIM     FLASH_BASE
+
+/*
+ * Flash address mask
+ */
+#define CFG_PRELIM_OR_AM       0xfe000000
+
+/*
+ * FLASH timing:
+ * 33 Mhz bus with ACS = 11, TRLX = 1, CSNT = 1, SCY = 3, EHTR = 1
+ */
+#define CFG_OR_TIMING_FLASH    ( OR_CSNT_SAM   | \
+                                                         OR_ACS_DIV2   | \
+                                                         OR_BI                 | \
+                                                         OR_SCY_2_CLK  | \
+                                                         OR_TRLX               | \
+                                                         OR_EHTR                 \
+                                                       )
+
+#define CFG_OR0_PRELIM ( CFG_PRELIM_OR_AM              | \
+                                                 CFG_OR_TIMING_FLASH     \
+                                               )
+
+#define CFG_BR0_PRELIM ( (FLASH_BASE0_PRELIM & BR_BA_MSK)      | \
+                                                 BR_MS_GPCM                                            | \
+                                                 BR_PS_8                                                       | \
+                                                 BR_V                                                            \
+                                               )
+
+/*
+ * SDRAM configuration
+ */
+#define CFG_OR1_AM     0xfc000000
+#define CFG_OR1                ( (CFG_OR1_AM & OR_AM_MSK)      | \
+                                         OR_CSNT_SAM                             \
+                                       )
+
+#define CFG_BR1                ( (SDRAM_BASE & BR_BA_MSK)      | \
+                                         BR_MS_UPMA                            | \
+                                         BR_PS_32                                      | \
+                                         BR_V                                            \
+                                       )
+
+/*
+ * Refresh rate 7.8 us (= 64 ms / 8K = 31.2 uS quad bursts) for one bank
+ * of 256 MBit SDRAM
+ */
+#define CFG_MPTPR_1BK_8K       MPTPR_PTP_DIV16
+
+/*
+ * Periodic timer for refresh @ 33 MHz system clock
+ */
+#define CFG_MAMR_PTA   64
+
+/*
+ * MAMR settings for SDRAM
+ */
+#define CFG_MAMR_8COL  ( (CFG_MAMR_PTA << MAMR_PTA_SHIFT)      | \
+                                                 MAMR_PTAE                             | \
+                                                 MAMR_AMA_TYPE_1                       | \
+                                                 MAMR_DSA_1_CYCL                       | \
+                                                 MAMR_G0CLA_A10                        | \
+                                                 MAMR_RLFA_1X                          | \
+                                                 MAMR_WLFA_1X                          | \
+                                                 MAMR_TLFA_4X                            \
+                                               )
+
+/*
+ * CS2* configuration for Disk On Chip:
+ * 33 MHz bus with TRLX=1, ACS=11, CSNT=1, EBDF=1, SCY=2, EHTR=1,
+ * no burst.
+ */
+#define CFG_OR2_PRELIM         ( (0xffff0000 & OR_AM_MSK)      | \
+                                                 OR_CSNT_SAM                           | \
+                                                 OR_ACS_DIV2                           | \
+                                                 OR_BI                                         | \
+                                                 OR_SCY_2_CLK                          | \
+                                                 OR_TRLX                                       | \
+                                                 OR_EHTR                                         \
+                                               )
+
+#define CFG_BR2_PRELIM ( (DOC_BASE & BR_BA_MSK)        | \
+                                                 BR_PS_8                                       | \
+                                                 BR_MS_GPCM                            | \
+                                                 BR_V                                            \
+                                               )
+
+/*
+ * CS3* configuration for FPGA:
+ * 33 MHz bus with SCY=15, no burst.
+ * The FPGA uses TA and TEA to terminate bus cycles, but we
+ * clear SETA and set the cycle length to a large number so that
+ * the cycle will still complete even if there is a configuration
+ * error that prevents TA from asserting on FPGA accesss.
+ */
+#define CFG_OR3_PRELIM ( (0xfc000000 & OR_AM_MSK)  | \
+                                                 OR_SCY_15_CLK                         | \
+                                                 OR_BI                                           \
+                                               )
+
+#define CFG_BR3_PRELIM ( (FPGA_BASE & BR_BA_MSK)       | \
+                                                 BR_PS_32                                      | \
+                                                 BR_MS_GPCM                            | \
+                                                 BR_V                                            \
+                                               )
+/*
+ * CS4* configuration for FPGA SelectMap configuration interface.
+ * 33 MHz bus, UPMB, no burst. Do not assert GPLB5 on falling edge
+ * of GCLK1_50
+ */
+#define CFG_OR4_PRELIM ( (0xffff0000 & OR_AM_MSK)      | \
+                                                 OR_G5LS                                               | \
+                                                 OR_BI                                                   \
+                                               )
+
+#define CFG_BR4_PRELIM ( (SELECTMAP_BASE & BR_BA_MSK)  | \
+                                                 BR_PS_8                                               | \
+                                                 BR_MS_UPMB                                    | \
+                                                 BR_V                                                    \
+                                               )
+
+/*
+ * CS5* configuration for Mil-Std 1553 databus interface.
+ * 33 MHz bus, GPCM, no burst.
+ * The 1553 interface  uses TA and TEA to terminate bus cycles,
+ * but we clear SETA and set the cycle length to a large number so that
+ * the cycle will still complete even if there is a configuration
+ * error that prevents TA from asserting on FPGA accesss.
+ */
+#define CFG_OR5_PRELIM ( (0xffff0000 & OR_AM_MSK)  | \
+                                                 OR_SCY_15_CLK                         | \
+                                                 OR_EHTR                                       | \
+                                                 OR_TRLX                                       | \
+                                                 OR_CSNT_SAM                           | \
+                                                 OR_BI                                           \
+                                               )
+
+#define CFG_BR5_PRELIM ( (M1553_BASE & BR_BA_MSK)      | \
+                                                 BR_PS_16                                      | \
+                                                 BR_MS_GPCM                            | \
+                                                 BR_V                                            \
+                                               )
+
+/*
+ * Boot Flags
+ */
+#define        BOOTFLAG_COLD   0x01    /* Normal Power-On: Boot from FLASH     */
+#define BOOTFLAG_WARM  0x02    /* Software reboot                                      */
+
+/*
+ * Disk On Chip (millenium) configuration
+ */
+#define CFG_MAX_DOC_DEVICE     1
+#undef CFG_DOC_SUPPORT_2000
+#define CFG_DOC_SUPPORT_MILLENNIUM
+#undef CFG_DOC_PASSIVE_PROBE
+
+/*
+ * FEC interrupt assignment
+ */
+#define FEC_INTERRUPT   SIU_LEVEL1
+
+/*
+ * Sanity checks
+ */
+#if defined(CONFIG_SCC1_ENET) && defined(CONFIG_FEC_ENET)
+#error Both CONFIG_SCC1_ENET and CONFIG_FEC_ENET configured
+#endif
+
+#endif /* __CONFIG_GEN860T_H */
+
+/* vim: set ts=4 tw=78 ai shiftwidth=4: */
index 99a843dd8c17847ec0ca883c1a942ec454575ac1..1799afe8e22e57e132306dbfd8b4da27dabc3945 100644 (file)
@@ -37,8 +37,17 @@ struct part_info {
 
        /* Where in memory does this partition start? */
        char *offset;
+
+       /* used by jffs2 set to NULL */
+       void *jffs2_priv;
+
+       /* private filed used by user */
+       void *usr_priv;
 };
 
+struct part_info*
+jffs2_part_info(int part_num);
+
 struct kernel_loader {
 
        /* Return true if there is a kernel contained at src */
index 361e3f4df37473c317588b71ecb8f0f2324f06bf..0f41738b7530668c0e7bf5468f3843c0fe37c309 100644 (file)
 #define cpc0_cust0  (CNTRL_DCR_BASE+0x32)   /* Customer configuration reg 0 */
 #define cpc0_cust1  (CNTRL_DCR_BASE+0x33)   /* Customer configuration reg 1 */
 
+#define cpc0_strp0     (CNTRL_DCR_BASE+0x34)   /* Power-on config reg 0 (RO)   */
+#define cpc0_strp1     (CNTRL_DCR_BASE+0x35)   /* Power-on config reg 1 (RO)   */
+#define cpc0_strp2     (CNTRL_DCR_BASE+0x36)   /* Power-on config reg 2 (RO)   */
+#define cpc0_strp3     (CNTRL_DCR_BASE+0x37)   /* Power-on config reg 3 (RO)   */
+
 #define cntrl0      (CNTRL_DCR_BASE+0x3b)   /* Control 0 register           */
 #define cntrl1      (CNTRL_DCR_BASE+0x3a)   /* Control 1 register           */
 
 #define                MODEM_STATUS    0x06
 #define                SCRATCH         0x07
 
+/*-----------------------------------------------------------------------------
+| PCI Internal Registers et. al. (accessed via plb)
++----------------------------------------------------------------------------*/
+#define                PCIX0_CFGADR            (CFG_PCI_BASE + 0x0ec00000)
+#define                PCIX0_CFGDATA           (CFG_PCI_BASE + 0x0ec00004)
+#define                PCIX0_CFGBASE           (CFG_PCI_BASE + 0x0ec80000)
+#define                PCIX0_IOBASE            (CFG_PCI_BASE + 0x08000000)
+
+#define                PCIX0_VENDID            (PCIX0_CFGBASE + PCI_VENDOR_ID )
+#define                PCIX0_DEVID                     (PCIX0_CFGBASE + PCI_DEVICE_ID )
+#define                PCIX0_CMD                       (PCIX0_CFGBASE + PCI_COMMAND )
+#define                PCIX0_STATUS            (PCIX0_CFGBASE + PCI_STATUS )
+#define                PCIX0_REVID                     (PCIX0_CFGBASE + PCI_REVISION_ID )
+#define                PCIX0_CLS                       (PCIX0_CFGBASE + PCI_CLASS_CODE)
+#define                PCIX0_CACHELS           (PCIX0_CFGBASE + PCI_CACHE_LINE_SIZE )
+#define                PCIX0_LATTIM            (PCIX0_CFGBASE + PCI_LATENCY_TIMER )
+#define                PCIX0_HDTYPE            (PCIX0_CFGBASE + PCI_HEADER_TYPE )
+#define                PCIX0_BIST                      (PCIX0_CFGBASE + PCI_BIST )
+#define                PCIX0_BAR0                      (PCIX0_CFGBASE + PCI_BASE_ADDRESS_0 )
+#define                PCIX0_BAR1                      (PCIX0_CFGBASE + PCI_BASE_ADDRESS_1 )
+#define                PCIX0_BAR2                      (PCIX0_CFGBASE + PCI_BASE_ADDRESS_2 )
+#define                PCIX0_BAR3                      (PCIX0_CFGBASE + PCI_BASE_ADDRESS_3 )
+#define                PCIX0_BAR4                      (PCIX0_CFGBASE + PCI_BASE_ADDRESS_4 )
+#define                PCIX0_BAR5                      (PCIX0_CFGBASE + PCI_BASE_ADDRESS_5 )
+#define                PCIX0_CISPTR            (PCIX0_CFGBASE + PCI_CARDBUS_CIS )
+#define                PCIX0_SBSYSVID          (PCIX0_CFGBASE + PCI_SUBSYSTEM_VENDOR_ID )
+#define                PCIX0_SBSYSID           (PCIX0_CFGBASE + PCI_SUBSYSTEM_ID )
+#define                PCIX0_EROMBA            (PCIX0_CFGBASE + PCI_ROM_ADDRESS )
+#define                PCIX0_CAP                       (PCIX0_CFGBASE + PCI_CAPABILITY_LIST )
+#define                PCIX0_RES0                      (PCIX0_CFGBASE + 0x0035 )
+#define                PCIX0_RES1                      (PCIX0_CFGBASE + 0x0036 )
+#define                PCIX0_RES2                      (PCIX0_CFGBASE + 0x0038 )
+#define                PCIX0_INTLN                     (PCIX0_CFGBASE + PCI_INTERRUPT_LINE )
+#define                PCIX0_INTPN                     (PCIX0_CFGBASE + PCI_INTERRUPT_PIN )
+#define                PCIX0_MINGNT            (PCIX0_CFGBASE + PCI_MIN_GNT )
+#define                PCIX0_MAXLTNCY          (PCIX0_CFGBASE + PCI_MAX_LAT )
+
+#define     PCIX0_BRDGOPT1      (PCIX0_CFGBASE + 0x0040)
+#define     PCIX0_BRDGOPT2      (PCIX0_CFGBASE + 0x0044)
+
+#define                PCIX0_POM0LAL           (PCIX0_CFGBASE + 0x0068)
+#define                PCIX0_POM0LAH           (PCIX0_CFGBASE + 0x006c)
+#define                PCIX0_POM0SA            (PCIX0_CFGBASE + 0x0070)
+#define                PCIX0_POM0PCIAL         (PCIX0_CFGBASE + 0x0074)
+#define                PCIX0_POM0PCIAH         (PCIX0_CFGBASE + 0x0078)
+#define                PCIX0_POM1LAL           (PCIX0_CFGBASE + 0x007c)
+#define                PCIX0_POM1LAH           (PCIX0_CFGBASE + 0x0080)
+#define                PCIX0_POM1SA            (PCIX0_CFGBASE + 0x0084)
+#define                PCIX0_POM1PCIAL         (PCIX0_CFGBASE + 0x0088)
+#define                PCIX0_POM1PCIAH         (PCIX0_CFGBASE + 0x008c)
+#define                PCIX0_POM2SA            (PCIX0_CFGBASE + 0x0090)
+
+#define                PCIX0_PIM0SA            (PCIX0_CFGBASE + 0x0098)
+#define                PCIX0_PIM0LAL           (PCIX0_CFGBASE + 0x009c)
+#define                PCIX0_PIM0LAH           (PCIX0_CFGBASE + 0x00a0)
+#define                PCIX0_PIM1SA            (PCIX0_CFGBASE + 0x00a4)
+#define                PCIX0_PIM1LAL           (PCIX0_CFGBASE + 0x00a8)
+#define                PCIX0_PIM1LAH           (PCIX0_CFGBASE + 0x00ac)
+#define                PCIX0_PIM2SA            (PCIX0_CFGBASE + 0x00b0)
+#define                PCIX0_PIM2LAL           (PCIX0_CFGBASE + 0x00b4)
+#define                PCIX0_PIM2LAH           (PCIX0_CFGBASE + 0x00b8)
+
+#define     PCIX0_STS           (PCIX0_CFGBASE + 0x00e0)
 
 /*
  * Macros for accessing the indirect EBC registers
index 1c0ebbbf1912ba43980a8ca7e64779b5617030d1..7c86ae142af9c817c7e715b746b21dad32f77cb3 100644 (file)
@@ -88,6 +88,30 @@ void status_led_set  (int led, int state);
 
 # define STATUS_LED_BOOT       0               /* LED 0 used for boot status */
 
+/*****  GEN860T  *********************************************************/
+#elif defined(CONFIG_GEN860T)
+# define STATUS_LED_PAR                        im_ioport.iop_papar
+# define STATUS_LED_DIR                        im_ioport.iop_padir
+# define STATUS_LED_ODR                        im_ioport.iop_paodr
+# define STATUS_LED_DAT                        im_ioport.iop_padat
+
+# define STATUS_LED_BIT                        0x0800  /* Red LED 0 is on PA.4 */
+# define STATUS_LED_PERIOD             (CFG_HZ / 2)
+# define STATUS_LED_STATE              STATUS_LED_BLINKING
+# define STATUS_LED_BIT1               0x0400  /* Grn LED 1 is on PA.5 */
+# define STATUS_LED_PERIOD1            (CFG_HZ / 2)
+# define STATUS_LED_STATE1             STATUS_LED_BLINKING
+# define STATUS_LED_BIT2               0x0080  /* Red LED 2 is on PA.8 */
+# define STATUS_LED_PERIOD2            (CFG_HZ / 2)
+# define STATUS_LED_STATE2             STATUS_LED_BLINKING
+# define STATUS_LED_BIT3               0x0040  /* Grn LED 3 is on PA.9 */
+# define STATUS_LED_PERIOD3            (CFG_HZ / 2)
+# define STATUS_LED_STATE3             STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE             1       /* LED on for bit == 1  */
+# define STATUS_LED_BOOT               0       /* Boot status on LED 1 */
+
 /*****  IVMS8  **********************************************************/
 #elif defined(CONFIG_IVMS8)