]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' into hpc2
authorroy zang <tie-fei.zang@freescale.com>
Thu, 4 Jan 2007 03:10:05 +0000 (11:10 +0800)
committerZang Tiefei <roy@bus.ap.freescale.net>
Thu, 4 Jan 2007 03:10:05 +0000 (11:10 +0800)
24 files changed:
MAKEALL
Makefile
README
board/mpc7448hpc2/Makefile [new file with mode: 0644]
board/mpc7448hpc2/asm_init.S [new file with mode: 0644]
board/mpc7448hpc2/config.mk [new file with mode: 0644]
board/mpc7448hpc2/mpc7448hpc2.c [new file with mode: 0644]
board/mpc7448hpc2/tsi108_init.c [new file with mode: 0644]
board/mpc7448hpc2/u-boot.lds [new file with mode: 0644]
cpu/74xx_7xx/cpu.c
cpu/74xx_7xx/cpu_init.c
cpu/74xx_7xx/speed.c
doc/README.mpc7448hpc2 [new file with mode: 0644]
drivers/Makefile
drivers/cfi_flash.c
drivers/tsi108_eth.c [new file with mode: 0644]
drivers/tsi108_i2c.c [new file with mode: 0644]
drivers/tsi108_pci.c [new file with mode: 0644]
include/74xx_7xx.h
include/asm-ppc/global_data.h
include/configs/mpc7448hpc2.h [new file with mode: 0644]
include/tsi108.h [new file with mode: 0644]
lib_ppc/extable.c
net/eth.c

diff --git a/MAKEALL b/MAKEALL
index d2159ef0c9bfd26288baaa086438522df405e13b..a4a5fac5e3b9350607d68718a6ec4a3be782bdbd 100755 (executable)
--- a/MAKEALL
+++ b/MAKEALL
@@ -152,6 +152,7 @@ LIST_85xx=" \
 LIST_74xx="    \
        DB64360         DB64460         EVB64260        P3G4            \
        p3m7448         PCIPPC2         PCIPPC6         ZUMA            \
+       mpc7448hpc2
 "
 
 LIST_7xx="     \
index b145be43f4c8e7e8f4ad0dc471ac1abd9e21312d..0928b3a19e2d2381eaa3fee47ced006d4ba90c84 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1751,6 +1751,9 @@ EVB64260_config   \
 EVB64260_750CX_config: unconfig
        @$(MKCONFIG) EVB64260 ppc 74xx_7xx evb64260
 
+mpc7448hpc2_config:  unconfig
+       @$(MKCONFIG) $(@:_config=) ppc 74xx_7xx mpc7448hpc2
+
 P3G4_config: unconfig
        @$(MKCONFIG) $(@:_config=) ppc 74xx_7xx evb64260
 
diff --git a/README b/README
index ecfd1f82f0987a708f58ccadaaeee5ebb94377f4..a8eaa5f2b1a7a521007d239f4ec32938f698a9c0 100644 (file)
--- a/README
+++ b/README
@@ -2371,17 +2371,17 @@ configurations; the following names are supported:
        csb272_config           lwmon_config            sbc8260_config
        CU824_config            MBX860T_config          sbc8560_33_config
        DUET_ADS_config         MBX_config              sbc8560_66_config
-       EBONY_config            MPC8260ADS_config       SM850_config
-       ELPT860_config          MPC8540ADS_config       SPD823TS_config
-       ESTEEM192E_config       MPC8540EVAL_config      stxgp3_config
-       ETX094_config           MPC8560ADS_config       SXNI855T_config
-       FADS823_config          NETVIA_config           TQM823L_config
-       FADS850SAR_config       omap1510inn_config      TQM850L_config
-       FADS860T_config         omap1610h2_config       TQM855L_config
-       FPS850L_config          omap1610inn_config      TQM860L_config
-                               omap5912osk_config      walnut_config
-                               omap2420h4_config       Yukon8220_config
-                                                       ZPC1900_config
+       EBONY_config            mpc7448hpc2_config      SM850_config
+       ELPT860_config          MPC8260ADS_config       SPD823TS_config
+       ESTEEM192E_config       MPC8540ADS_config       stxgp3_config
+       ETX094_config           MPC8540EVAL_config      SXNI855T_config
+       FADS823_config          NMPC8560ADS_config      TQM823L_config
+       FADS850SAR_config       NETVIA_config           TQM850L_config
+       FADS860T_config         omap1510inn_config      TQM855L_config
+       FPS850L_config          omap1610h2_config       TQM860L_config
+                               omap1610inn_config      walnut_config
+                               omap5912osk_config      Yukon8220_config
+                               omap2420h4_config       ZPC1900_config
 
 Note: for some board special configuration names may exist; check if
       additional information is available from the board vendor; for
diff --git a/board/mpc7448hpc2/Makefile b/board/mpc7448hpc2/Makefile
new file mode 100644 (file)
index 0000000..e3d757d
--- /dev/null
@@ -0,0 +1,52 @@
+#
+# (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    = $(obj)lib$(BOARD).a
+
+COBJS  := $(BOARD).o tsi108_init.o
+SOBJS  := asm_init.o
+
+SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+SOBJS  := $(addprefix $(obj),$(SOBJS))
+
+$(LIB):        $(obj).depend $(OBJS) $(SOBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+.PHONY: distclean
+distclean:     clean
+       rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude ($obj).depend
+
+#########################################################################
diff --git a/board/mpc7448hpc2/asm_init.S b/board/mpc7448hpc2/asm_init.S
new file mode 100644 (file)
index 0000000..a7a40a1
--- /dev/null
@@ -0,0 +1,918 @@
+/*
+ * (C) Copyright 2004-05;  Tundra Semiconductor Corp.
+ *
+ * Added automatic detect of SDC settings
+ * Copyright (c) 2005 Freescale Semiconductor, Inc.
+ * Maintainer tie-fei.zang@freescale.com
+ *
+ * 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
+ */
+
+/*
+ * FILENAME: asm_init.s
+ *
+ * Originator: Alex Bounine
+ *
+ * DESCRIPTION:
+ * Initialization code for the Tundra Tsi108 bridge chip
+ *
+ */
+
+#include <config.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/processor.h>
+
+#include <tsi108.h>
+
+/*
+ * Build Configuration Options
+ */
+
+/* #define DISABLE_PBM         disables usage of PB Master */
+/* #define SDC_HARDCODED_INIT  config SDRAM controller with hardcoded values */
+/* #define SDC_AUTOPRECH_EN    enable SDRAM auto precharge */
+
+/*
+ * Hardcoded SDC settings
+ */
+
+#ifdef SDC_HARDCODED_INIT
+
+/* Micron MT9HTF6472AY-40EA1 : Unbuffered, 512MB, 400, CL3, Single Rank */
+
+#define VAL_SD_REFRESH (0x61A)
+#define VAL_SD_TIMING  (0x0308336b)
+#define VAL_SD_D0_CTRL (0x07100021)    /* auto-precharge disabled */
+#define VAL_SD_D0_BAR  (0x0FE00000)    /* 512MB @ 0x00000000 */
+#define VAL_SD_D1_CTRL (0x07100021)    /* auto-precharge disabled */
+#define VAL_SD_D1_BAR  (0x0FE00200)    /* 512MB @ 0x20000000 */
+
+#endif /* SDC_HARDCODED_INIT */
+
+/*
+ CPU Configuration:
+
+ CPU Address and Data Parity enables.
+
+#define CPU_AP
+#define CPU_DP
+*/
+
+/*
+ * Macros
+ * !!! Attention !!! Macros LOAD_PTR, LOAD_U32 and LOAD_MEM defined below are
+ * expected to work correctly for the CSR space within 32KB range.
+ *
+ * LOAD_PTR and LOAD_U32 - load specified register with a 32 bit constant.
+ * These macros are absolutely identical except their names. This difference
+ * is provided intentionally for better readable code.
+ */
+
+#define LOAD_PTR(reg,const32) \
+       addis reg,r0,const32@h; ori reg,reg,const32@l
+
+#define LOAD_U32(reg,const32) \
+       addis reg,r0,const32@h; ori reg,reg,const32@l
+
+/* LOADMEM initializes a register with the contents of a specified 32-bit
+ * memory location, usually a CSR value.
+ */
+
+#define LOAD_MEM(reg,addr32) \
+       addis reg,r0,addr32@ha; lwz reg,addr32@l(reg)
+
+#ifndef SDC_HARDCODED_INIT
+sdc_clk_sync:
+       /* MHz: 0,0,183,100,133,167,200,233 */
+       .long   0, 0, 6, 10, 8, 6, 5, 4         /* nSec */
+#endif
+
+/*
+ * board_asm_init() - early initialization function. Coded to be portable to
+ * dual-CPU configuration.
+ * Checks CPU number and performs board HW initialization if called for CPU0.
+ * Registers used: r3,r4,r5,r6,r19,r29
+ *
+ * NOTE: For dual-CPU configuration only CPU0 is allowed to configure Tsi108
+ * and the rest of the board. Current implementation demonstrates two
+ * possible ways to identify CPU number:
+ * - for MPC74xx platform: uses MSSCR0[ID] bit as defined in UM.
+ * - for PPC750FX/GX boards: uses WHO_AM_I bit reported by Tsi108.
+ */
+
+       .globl board_asm_init
+board_asm_init:
+       mflr    r19     /* Save LR to be able return later. */
+       bl      icache_enable   /* Enable icache to reduce reads from flash. */
+
+/* Initialize pointer to Tsi108 register space */
+
+       LOAD_PTR(r29,CFG_TSI108_CSR_RST_BASE)/* r29 - pointer to tsi108 CSR space */
+       ori r4,r29,TSI108_PB_REG_OFFSET
+
+/* Check Processor Version Number */
+
+       mfspr   r3, PVR
+       rlwinm  r3,r3,16,16,23  /* get ((Processor Version Number) & 0xFF00) */
+
+       cmpli   0,0,r3,0x8000   /* MPC74xx */
+       bne     cont_brd_init
+
+       /*
+        * For MPC744x/5x enable extended BATs[4-7]
+        * Sri: Set HIGH_BAT_EN and XBSEN, and SPD =1
+        * to disable prefetch
+        */
+
+       mfspr   r5, HID0
+       oris    r5, r5, 0x0080  /* Set HID0[HIGH_BAT_EN] bit #8 */
+       ori     r5, r5, 0x0380  /* Set SPD,XBSEN,SGE bits #22,23,24 */
+       mtspr   HID0, r5
+       isync
+       sync
+
+       /* Adding code to disable external interventions in MPX bus mode */
+       mfspr   r3, 1014
+       oris    r3, r3, 0x0100  /* Set the EIDIS bit in MSSCR0:  bit 7 */
+       mtspr   1014, r3
+       isync
+       sync
+
+       /* Sri: code to enable FP unit */
+       mfmsr   r3
+       ori     r3, r3, 0x2000
+       mtmsr   r3
+       isync
+       sync
+
+       /* def CONFIG_DUAL_CPU
+        * For MPC74xx processor, use MSSCR0[ID] bit to identify CPU number.
+        */
+#if(1)
+       mfspr   r3,1014         /* read MSSCR0 */
+       rlwinm. r3,r3,27,31,31  /* get processor ID number */
+       mtspr   SPRN_PIR,r3     /* Save CPU ID */
+       sync
+       bne     init_done
+       b       do_tsi108_init
+
+cont_brd_init:
+
+       /* An alternative method of checking the processor number (in addition
+        * to configuration using MSSCR0[ID] bit on MPC74xx).
+        * Good for IBM PPC750FX/GX.
+        */
+
+       lwz     r3,PB_BUS_MS_SELECT(r4) /* read PB_ID register */
+       rlwinm. r3,r3,24,31,31          /* get processor ID number */
+       bne init_done
+#else
+
+cont_brd_init:
+
+#endif /* CONFIG_DUAL_CPU */
+
+       /* Initialize Tsi108 chip */
+
+do_tsi108_init:
+
+       /*
+        * Adjust HLP/Flash parameters. By default after reset the HLP port is
+        * set to support slow devices. Better performance can be achived when
+        * an optimal parameters are used for specific EPROM device.
+        * NOTE: This should be performed ASAP for the emulation platform
+        * because it has 5MHz HLP clocking.
+        */
+
+#ifdef CONFIG_TSI108EMU
+       ori     r4,r29,TSI108_HLP_REG_OFFSET
+       LOAD_U32(r5,0x434422c0)
+       stw     r5,0x08(r4)     /* set HLP B0_CTRL0 */
+       sync
+       LOAD_U32(r5,0xd0012000)
+       stw     r5,0x0c(r4)             /* set HLP B0_CTRL1 */
+       sync
+#endif
+
+       /* Initialize PB interface. */
+
+       ori r4,r29,TSI108_PB_REG_OFFSET
+
+#if (CFG_TSI108_CSR_BASE != CFG_TSI108_CSR_RST_BASE)
+       /* Relocate (if required) Tsi108 registers. Set new value for
+        * PB_REG_BAR:
+        * Note we are in the 32-bit address mode.
+        */
+       LOAD_U32(r5,(CFG_TSI108_CSR_BASE | 0x01)) /* PB_REG_BAR: BA + EN */
+       stw     r5,PB_REG_BAR(r4)
+       andis.  r29,r5,0xFFFF
+       sync
+       ori     r4,r29,TSI108_PB_REG_OFFSET
+#endif
+
+       /* Set PB Slave configuration register */
+
+       LOAD_U32(r5,0x00002481) /* PB_SCR: TEA enabled,AACK delay = 1 */
+       lwz     r3, PB_RSR(r4)  /* get PB bus mode */
+       xori    r3,r3,0x0001    /* mask PB_BMODE: r3 -> (0 = 60X, 1 = MPX) */
+       rlwimi  r5,r3,14,17,17  /* for MPX: set DTI_MODE bit */
+       stw     r5,PB_SCR(r4)
+       sync
+
+       /* Configure PB Arbiter */
+
+       lwz     r5,PB_ARB_CTRL(r4)      /* Read PB Arbiter Control Register */
+       li      r3, 0x00F0              /* ARB_PIPELINE_DEP mask */
+#ifdef DISABLE_PBM
+       ori     r3,r3,0x1000    /* add PBM_EN to clear (enabled by default) */
+#endif
+       andc    r5,r5,r3        /* Clear the masked bit fields */
+       ori     r5,r5,0x0001    /* Set pipeline depth */
+       stw     r5,PB_ARB_CTRL(r4)
+
+#if (0)        /* currently using the default settings for PBM after reset */
+       LOAD_U32(r5,0x)         /* value for PB_MCR */
+       stw     r5,PB_MCR(r4)
+       sync
+
+       LOAD_U32(r5,0x)         /* value for PB_MCMD */
+       stw     r5,PB_MCMD(r4)
+       sync
+#endif
+
+       /* Disable or enable PVT based on processor bus frequency
+        * 1. Read CG_PWRUP_STATUS register field bits 18,17,16
+        * 2. See if the value is < or > 133mhz (18:16 = 100)
+        * 3. If > enable PVT
+        */
+
+       LOAD_U32(r3,0xC0002234)
+       lwz     r3,0(r3)
+       rlwinm  r3,r3,16,29,31
+
+       cmpi    0,0,r3,0x0004
+       bgt     sdc_init
+
+#ifndef CONFIG_TSI108EMU
+       /* FIXME: Disable PB calibration control for any real Tsi108 board */
+       li      r5,0x0101       /* disable calibration control */
+       stw     r5,PB_PVT_CTRL2(r4)
+       sync
+#endif
+
+       /* Initialize SDRAM controller. */
+
+sdc_init:
+
+#ifndef SDC_HARDCODED_INIT
+       /* get SDC clock prior doing sdram controller autoconfig */
+       ori     r4,r29,TSI108_CLK_REG_OFFSET    /* r4 - ptr to CG registers */
+       lwz     r3, CG_PWRUP_STATUS(r4)         /* get CG configuration */
+       rlwinm  r3,r3,12,29,31                  /* r3 - SD clk */
+       lis     r5,sdc_clk_sync@h
+       ori     r5,r5,sdc_clk_sync@l
+       /* Sri:  At this point check if r3 = 001. If yes,
+        * the memory frequency should be same as the
+        * MPX bus frequency
+        */
+       cmpi    0,0,r3,0x0001
+       bne     get_nsec
+       lwz     r6, CG_PWRUP_STATUS(r4)
+       rlwinm  r6,r6,16,29,31
+       mr      r3,r6
+
+get_nsec:
+       rlwinm  r3,r3,2,0,31
+       lwzx    r9,r5,r3        /* get SD clk rate in nSec */
+       /* ATTN: r9 will be used by SPD routine */
+#endif /* !SDC_HARDCODED_INIT */
+
+       ori     r4,r29,TSI108_SD_REG_OFFSET /* r4 - ptr to SDRAM registers */
+
+       /* Initialize SDRAM controller. SDRAM Size = 512MB, One DIMM. */
+
+       LOAD_U32(r5,0x00)
+       stw     r5,SD_INT_ENABLE(r4) /* Ensure that interrupts are disabled */
+#ifdef ENABLE_SDRAM_ECC
+       li      r5, 0x01
+#endif /* ENABLE_SDRAM_ECC */
+       stw     r5,SD_ECC_CTRL(r4)      /* Enable/Disable ECC */
+       sync
+
+#ifdef SDC_HARDCODED_INIT /* config sdram controller with hardcoded values */
+
+       /* First read the CG_PWRUP_STATUS register to get the
+        * memory speed from bits 22,21,20
+        */
+
+       LOAD_U32(r3,0xC0002234)
+       lwz     r3,0(r3)
+       rlwinm  r3,r3,12,29,31
+
+       /* Now first check for 166, then 200, or default */
+
+       cmpi    0,0,r3,0x0005
+       bne     check_for_200mhz
+
+       /* set values for 166 Mhz memory speed
+        * Set refresh rate and timing parameters
+        */
+       LOAD_U32(r5,0x00000515)
+       stw     r5,SD_REFRESH(r4)
+       LOAD_U32(r5,0x03073368)
+       stw     r5,SD_TIMING(r4)
+       sync
+
+       /* Initialize DIMM0 control and BAR registers */
+       LOAD_U32(r5,VAL_SD_D0_CTRL)     /* auto-precharge disabled */
+#ifdef SDC_AUTOPRECH_EN
+       oris    r5,r5,0x0001            /* set auto precharge EN bit */
+#endif
+       stw     r5,SD_D0_CTRL(r4)
+       LOAD_U32(r5,VAL_SD_D0_BAR)
+       stw     r5,SD_D0_BAR(r4)
+       sync
+
+       /* Initialize DIMM1 control and BAR registers
+        * (same as dimm 0, next 512MB, disabled)
+        */
+       LOAD_U32(r5,VAL_SD_D1_CTRL)     /* auto-precharge disabled */
+#ifdef SDC_AUTOPRECH_EN
+       oris    r5,r5,0x0001    /* set auto precharge EN bit */
+#endif
+       stw     r5,SD_D1_CTRL(r4)
+       LOAD_U32(r5,VAL_SD_D1_BAR)
+       stw     r5,SD_D1_BAR(r4)
+       sync
+
+       b       sdc_init_done
+
+check_for_200mhz:
+
+       cmpi    0,0,r3,0x0006
+       bne     set_default_values
+
+       /* set values for 200Mhz memory speed
+        * Set refresh rate and timing parameters
+        */
+       LOAD_U32(r5,0x0000061a)
+       stw     r5,SD_REFRESH(r4)
+       LOAD_U32(r5,0x03083348)
+       stw     r5,SD_TIMING(r4)
+       sync
+
+       /* Initialize DIMM0 control and BAR registers */
+       LOAD_U32(r5,VAL_SD_D0_CTRL)     /* auto-precharge disabled */
+#ifdef SDC_AUTOPRECH_EN
+       oris    r5,r5,0x0001            /* set auto precharge EN bit */
+#endif
+       stw     r5,SD_D0_CTRL(r4)
+       LOAD_U32(r5,VAL_SD_D0_BAR)
+       stw     r5,SD_D0_BAR(r4)
+       sync
+
+       /* Initialize DIMM1 control and BAR registers
+        * (same as dimm 0, next 512MB, disabled)
+        */
+       LOAD_U32(r5,VAL_SD_D1_CTRL)     /* auto-precharge disabled */
+#ifdef SDC_AUTOPRECH_EN
+       oris    r5,r5,0x0001            /* set auto precharge EN bit */
+#endif
+       stw     r5,SD_D1_CTRL(r4)
+       LOAD_U32(r5,VAL_SD_D1_BAR)
+       stw     r5,SD_D1_BAR(r4)
+       sync
+
+       b       sdc_init_done
+
+set_default_values:
+
+       /* Set refresh rate and timing parameters */
+       LOAD_U32(r5,VAL_SD_REFRESH)
+       stw     r5,SD_REFRESH(r4)
+       LOAD_U32(r5,VAL_SD_TIMING)
+       stw     r5,SD_TIMING(r4)
+       sync
+
+       /* Initialize DIMM0 control and BAR registers */
+       LOAD_U32(r5,VAL_SD_D0_CTRL)     /* auto-precharge disabled */
+#ifdef SDC_AUTOPRECH_EN
+       oris    r5,r5,0x0001            /* set auto precharge EN bit */
+#endif
+       stw     r5,SD_D0_CTRL(r4)
+       LOAD_U32(r5,VAL_SD_D0_BAR)
+       stw     r5,SD_D0_BAR(r4)
+       sync
+
+       /* Initialize DIMM1 control and BAR registers
+        * (same as dimm 0, next 512MB, disabled)
+        */
+       LOAD_U32(r5,VAL_SD_D1_CTRL)     /* auto-precharge disabled */
+#ifdef SDC_AUTOPRECH_EN
+       oris    r5,r5,0x0001            /* set auto precharge EN bit */
+#endif
+       stw     r5,SD_D1_CTRL(r4)
+       LOAD_U32(r5,VAL_SD_D1_BAR)
+       stw     r5,SD_D1_BAR(r4)
+       sync
+#else /* !SDC_HARDCODED_INIT */
+       bl      tsi108_sdram_spd        /* automatically detect SDC settings */
+#endif /* SDC_HARDCODED_INIT */
+
+sdc_init_done:
+
+#ifdef DISABLE_PBM
+       LOAD_U32(r5,0x00000030)         /* PB_EN + OCN_EN */
+#else
+       LOAD_U32(r5,0x00000230)         /* PB_EN + OCN_EN + PB/OCN=80/20 */
+#endif /* DISABLE_PBM */
+
+#ifdef CONFIG_TSI108EMU
+       oris    r5,r5,0x0010            /* set EMULATION_MODE bit */
+#endif
+
+       stw     r5,SD_CTRL(r4)
+       eieio
+       sync
+
+       /* Enable SDRAM access */
+
+       oris    r5,r5,0x8000            /* start SDC: set SD_CTRL[ENABLE] bit */
+       stw     r5,SD_CTRL(r4)
+       sync
+
+wait_init_complete:
+       lwz     r5,SD_STATUS(r4)
+       andi.   r5,r5,0x0001
+       /* wait until SDRAM initialization is complete */
+       beq     wait_init_complete
+
+       /* Map SDRAM into the processor bus address space */
+
+       ori     r4,r29,TSI108_PB_REG_OFFSET
+
+       /* Setup BARs associated with direct path PB<->SDRAM */
+
+       /* PB_SDRAM_BAR1:
+        * provides a direct path to the main system memory (cacheable SDRAM)
+        */
+
+       /* BA=0,Size=512MB, ENable, No Addr.Translation */
+       LOAD_U32(r5, 0x00000011)
+       stw     r5,PB_SDRAM_BAR1(r4)
+       sync
+
+       /* Make sure that PB_SDRAM_BAR1 decoder is set
+        * (to allow following immediate read from SDRAM)
+        */
+       lwz     r5,PB_SDRAM_BAR1(r4)
+       sync
+
+       /* PB_SDRAM_BAR2:
+        * provides non-cacheable alias (via the direct path) to main
+        * system memory.
+        * Size = 512MB, ENable, Addr.Translation - ON,
+        * BA = 0x0_40000000, TA = 0x0_00000000
+        */
+
+       LOAD_U32(r5, 0x40010011)
+       stw     r5,PB_SDRAM_BAR2(r4)
+       sync
+
+       /* Make sure that PB_SDRAM_BAR2 decoder is set
+        * (to allow following immediate read from SDRAM)
+        */
+       lwz     r5,PB_SDRAM_BAR2(r4)
+       sync
+
+init_done:
+
+       /* All done. Restore LR and return. */
+       mtlr    r19
+       blr
+
+#if (0)
+       /*
+        * init_cpu1
+        * This routine enables CPU1 on the dual-processor system.
+        * Now there is only one processor in the system
+        */
+
+       .global enable_cpu1
+enable_cpu1:
+
+       lis     r3,Tsi108_Base@ha       /* Get Grendel CSR Base Addr */
+       addi    r3,r3,Tsi108_Base@l
+       lwz     r3,0(r3)                /* R3 = CSR Base Addr */
+       ori     r4,r3,TSI108_PB_REG_OFFSET
+       lwz     r3,PB_ARB_CTRL(r4)      /* Read PB Arbiter Control Register */
+       ori     r3,r3,0x0200            /* Set M1_EN bit */
+       stw     r3,PB_ARB_CTRL(r4)
+
+       blr
+#endif
+
+       /*
+        * enable_EI
+        * Enable CPU core external interrupt
+        */
+
+       .global enable_EI
+enable_EI:
+       mfmsr   r3
+       ori     r3,r3,0x8000    /* set EE bit */
+       mtmsr   r3
+       blr
+
+       /*
+        * disable_EI
+        * Disable CPU core external interrupt
+        */
+
+       .global disable_EI
+disable_EI:
+       mfmsr   r3
+       li      r4,-32768       /* aka "li  r4,0x8000" */
+       andc    r3,r3,r4        /* clear EE bit */
+       mtmsr   r3
+       blr
+
+#ifdef ENABLE_SDRAM_ECC
+       /* enables SDRAM ECC  */
+
+       .global enable_ECC
+enable_ECC:
+       ori     r4,r29,TSI108_SD_REG_OFFSET
+       lwz     r3,SD_ECC_CTRL(r4)      /* Read SDRAM ECC Control Register */
+       ori     r3,r3,0x0001            /* Set ECC_EN bit */
+       stw     r3,SD_ECC_CTRL(r4)
+       blr
+
+       /*
+        * clear_ECC_err
+        * Clears all pending SDRAM ECC errors
+        * (normally after SDRAM scrubbing/initialization)
+        */
+
+       .global clear_ECC_err
+clear_ECC_err:
+       ori r4,r29,TSI108_SD_REG_OFFSET
+       ori r3,r0,0x0030        /* ECC_UE_INT + ECC_CE_INT bits */
+       stw r3,SD_INT_STATUS(r4)
+       blr
+
+#endif /* ENABLE_SDRAM_ECC */
+
+#ifndef SDC_HARDCODED_INIT
+
+       /* SDRAM SPD Support */
+#define        SD_I2C_CTRL1    (0x400)
+#define        SD_I2C_CTRL2    (0x404)
+#define SD_I2C_RD_DATA (0x408)
+#define SD_I2C_WR_DATA (0x40C)
+
+       /*
+        * SDRAM SPD Support Macros
+        */
+
+#define SPD_DIMM0      (0x00000100)
+#define SPD_DIMM1      (0x00000200)    /* SPD_DIMM1 was 0x00000000 */
+
+#define SPD_RDIMM                      (0x01)
+#define SPD_UDIMM                      (0x02)
+
+#define SPD_CAS_3                      0x8
+#define SPD_CAS_4                      0x10
+#define SPD_CAS_5                      0x20
+
+#define ERR_NO_DIMM_FOUND              (0xdb0)
+#define ERR_TRAS_FAIL                  (0xdb1)
+#define ERR_TRCD_FAIL                  (0xdb2)
+#define ERR_TRP_FAIL                   (0xdb3)
+#define ERR_TWR_FAIL                   (0xdb4)
+#define ERR_UNKNOWN_PART               (0xdb5)
+#define ERR_NRANK_INVALID              (0xdb6)
+#define ERR_DIMM_SIZE                  (0xdb7)
+#define ERR_ADDR_MODE                  (0xdb8)
+#define ERR_RFRSH_RATE                 (0xdb9)
+#define ERR_DIMM_TYPE                  (0xdba)
+#define ERR_CL_VALUE                   (0xdbb)
+#define ERR_TRFC_FAIL                  (0xdbc)
+
+/* READ_SPD requirements:
+ * byte - byte address in SPD device (0 - 255)
+ * r3 = will return data read from I2C Byte location
+ * r4 - unchanged (SDC base addr)
+ * r5 - clobbered in routine (I2C status)
+ * r10 - number of DDR slot where first SPD device is detected
+ */
+
+#define READ_SPD(byte_num)             \
+       addis   r3, 0, byte_num@l;      \
+       or      r3, r3, r10;            \
+       ori     r3, r3, 0x0A;           \
+       stw     r3, SD_I2C_CTRL1(r4);   \
+       li      r3, I2C_CNTRL2_START;   \
+       stw     r3, SD_I2C_CTRL2(r4);   \
+       eieio;                          \
+       sync;                           \
+       li      r3, 0x100;              \
+1:;                                    \
+       addic.  r3, r3, -1;             \
+       bne     1b;                     \
+2:;                                    \
+       lwz     r5, SD_I2C_CTRL2(r4);   \
+       rlwinm. r3,r5,0,23,23;          \
+       bne     2b;                     \
+       rlwinm. r3,r5,0,3,3;            \
+       lwz     r3,SD_I2C_RD_DATA(r4)
+
+#define SPD_MIN_RFRSH  (0x80)
+#define SPD_MAX_RFRSH  (0x85)
+
+refresh_rates: /* in nSec */
+       .long   15625   /* Normal (0x80) */
+       .long   3900    /* Reduced 0.25x (0x81) */
+       .long   7800    /* Reduced 0.5x (0x82) */
+       .long   31300   /* Extended 2x (0x83) */
+       .long   62500   /* Extended 4x (0x84) */
+       .long   125000  /* Extended 8x (0x85) */
+
+/*
+ * tsi108_sdram_spd
+ *
+ * Inittializes SDRAM Controller using DDR2 DIMM Serial Presence Detect data
+ * Uses registers: r4 - SDC base address (not changed)
+ *                                r9 - SDC clocking period in nSec
+ * Changes registers: r3,r5,r6,r7,r8,r10,r11
+ */
+
+tsi108_sdram_spd:
+
+       li      r10,SPD_DIMM0
+       xor     r11,r11,r11             /* DIMM Base Address: starts from 0 */
+
+do_first_dimm:
+
+       /* Program Refresh Rate Register */
+
+       READ_SPD(12)                    /* get Refresh Rate */
+       beq     check_next_slot
+       li      r5, ERR_RFRSH_RATE
+       cmpi    0,0,r3,SPD_MIN_RFRSH
+       ble     spd_fail
+       cmpi    0,0,r3,SPD_MAX_RFRSH
+       bgt     spd_fail
+       addi    r3,r3,-SPD_MIN_RFRSH
+       rlwinm  r3,r3,2,0,31
+       lis     r5,refresh_rates@h
+       ori     r5,r5,refresh_rates@l
+       lwzx    r5,r5,r3                /* get refresh rate in nSec */
+       divwu   r5,r5,r9                /* calculate # of SDC clocks */
+       stw     r5,SD_REFRESH(r4)       /* Set refresh rate */
+       sync
+
+       /* Program SD Timing Register */
+
+       li      r7, 0           /* clear r7 prior parameter collection */
+
+       READ_SPD(20)            /* get DIMM type: Registered or Unbuffered */
+       beq     spd_read_fail
+       li      r5, ERR_DIMM_TYPE
+       cmpi    0,0,r3,SPD_UDIMM
+       beq     do_cl
+       cmpi    0,0,r3,SPD_RDIMM
+       bne     spd_fail
+       oris    r7,r7,0x1000    /* set SD_TIMING[DIMM_TYPE] bit */
+
+do_cl:
+       READ_SPD(18)            /* Get CAS Latency */
+       beq     spd_read_fail
+       li      r5,ERR_CL_VALUE
+       andi.   r6,r3,SPD_CAS_3
+       beq     cl_4
+       li      r6,3
+       b       set_cl
+cl_4:
+       andi.   r6,r3,SPD_CAS_4
+       beq     cl_5
+       li      r6,4
+       b       set_cl
+cl_5:
+       andi.   r6,r3,SPD_CAS_5
+       beq     spd_fail
+       li      r6,5
+set_cl:
+       rlwimi  r7,r6,24,5,7
+
+       READ_SPD(30)            /* Get tRAS */
+       beq     spd_read_fail
+       divwu   r6,r3,r9
+       mullw   r8,r6,r9
+       subf.   r8,r8,r3
+       beq     set_tras
+       addi    r6,r6,1
+set_tras:
+       li r5,ERR_TRAS_FAIL
+       cmpi    0,0,r6,0x0F     /* max supported value */
+       bgt     spd_fail
+       rlwimi  r7,r6,16,12,15
+
+       READ_SPD(29)    /* Get tRCD */
+       beq     spd_read_fail
+       /* right shift tRCD by 2 bits as per DDR2 spec */
+       rlwinm  r3,r3,30,2,31
+       divwu   r6,r3,r9
+       mullw   r8,r6,r9
+       subf.   r8,r8,r3
+       beq     set_trcd
+       addi    r6,r6,1
+set_trcd:
+       li      r5,ERR_TRCD_FAIL
+       cmpi    0,0,r6,0x07     /* max supported value */
+       bgt     spd_fail
+       rlwimi  r7,r6,12,17,19
+
+       READ_SPD(27)    /* Get tRP value */
+       beq     spd_read_fail
+       rlwinm  r3,r3,30,2,31   /* right shift tRP by 2 bits as per DDR2 spec */
+       divwu   r6,r3,r9
+       mullw   r8,r6,r9
+       subf.   r8,r8,r3
+       beq     set_trp
+       addi    r6,r6,1
+set_trp:
+       li      r5,ERR_TRP_FAIL
+       cmpi    0,0,r6,0x07     /* max supported value */
+       bgt     spd_fail
+       rlwimi  r7,r6,8,21,23
+
+       READ_SPD(36)    /* Get tWR value */
+       beq     spd_read_fail
+       rlwinm  r3,r3,30,2,31   /* right shift tWR by 2 bits as per DDR2 spec */
+       divwu   r6,r3,r9
+       mullw   r8,r6,r9
+       subf.   r8,r8,r3
+       beq     set_twr
+       addi    r6,r6,1
+set_twr:
+       addi    r6,r6,-1        /* Tsi108 SDC always gives one extra clock */
+       li      r5,ERR_TWR_FAIL
+       cmpi    0,0,r6,0x07     /* max supported value */
+       bgt     spd_fail
+       rlwimi  r7,r6,5,24,26
+
+       READ_SPD(42)    /* Get tRFC */
+       beq     spd_read_fail
+       li      r5, ERR_TRFC_FAIL
+       /* Tsi108 spec: tRFC=(tRFC + 1)/2 */
+       addi    r3,r3,1
+       rlwinm. r3,r3,31,1,31   /* divide by 2 */
+       beq     spd_fail
+       divwu   r6,r3,r9
+       mullw   r8,r6,r9
+       subf.   r8,r8,r3
+       beq     set_trfc
+       addi    r6,r6,1
+set_trfc:
+       cmpi    0,0,r6,0x1F     /* max supported value */
+       bgt     spd_fail
+       rlwimi  r7,r6,0,27,31
+
+       stw     r7,SD_TIMING(r4)
+       sync
+
+       /*
+        * The following two registers are set on per-DIMM basis.
+        * The SD_REFRESH and SD_TIMING settings are common for both DIMMS
+        */
+
+do_each_dimm:
+
+       /* Program SDRAM DIMM Control Register */
+
+       li      r7, 0           /* clear r7 prior parameter collection */
+
+       READ_SPD(13)            /* Get Primary SDRAM Width */
+       beq     spd_read_fail
+       cmpi    0,0,r3,4        /* Check for 4-bit SDRAM */
+       beq     do_nbank
+       oris    r7,r7,0x0010    /* Set MEM_WIDTH bit */
+
+do_nbank:
+       READ_SPD(17)            /* Get Number of banks on SDRAM device */
+       beq     spd_read_fail
+       /* Grendel only distinguish betw. 4 or 8-bank memory parts */
+       li      r5,ERR_UNKNOWN_PART     /* non-supported memory part */
+       cmpi    0,0,r3,4
+       beq     do_nrank
+       cmpi    0,0,r3,8
+       bne     spd_fail
+       ori     r7,r7,0x1000
+
+do_nrank:
+       READ_SPD(5)             /* Get # of Ranks */
+       beq     spd_read_fail
+       li      r5,ERR_NRANK_INVALID
+       andi.   r6,r3,0x7       /* Use bits [2..0] only */
+       beq     do_addr_mode
+       cmpi    0,0,r6,1
+       bgt     spd_fail
+       rlwimi  r7,r6,8,23,23
+
+do_addr_mode:
+       READ_SPD(4)             /* Get # of Column Addresses */
+       beq     spd_read_fail
+       li      r5, ERR_ADDR_MODE
+       andi.   r3,r3,0x0f      /* cut off reserved bits */
+       cmpi    0,0,r3,8
+       ble     spd_fail
+       cmpi    0,0,r3,15
+       bgt     spd_fail
+       addi    r6,r3,-8        /* calculate ADDR_MODE parameter */
+       rlwimi  r7,r6,4,24,27   /* set ADDR_MODE field */
+
+set_dimm_ctrl:
+#ifdef SDC_AUTOPRECH_EN
+       oris    r7,r7,0x0001    /* set auto precharge EN bit */
+#endif
+       ori     r7,r7,1         /* set ENABLE bit */
+       cmpi    0,0,r10,SPD_DIMM0
+       bne     1f
+       stw     r7,SD_D0_CTRL(r4)
+       sync
+       b       set_dimm_bar
+1:
+       stw     r7,SD_D1_CTRL(r4)
+       sync
+
+
+       /* Program SDRAM DIMMx Base Address Register */
+
+set_dimm_bar:
+       READ_SPD(5)             /* get # of Ranks */
+       beq     spd_read_fail
+       andi.   r7,r3,0x7
+       addi    r7,r7,1
+       READ_SPD(31)            /* Read DIMM rank density */
+       beq     spd_read_fail
+       rlwinm  r5,r3,27,29,31
+       rlwinm  r6,r3,3,24,28
+       or      r5,r6,r5        /* r5 = Normalized Rank Density byte */
+       lis     r8, 0x0080      /* 128MB >> 4 */
+       mullw   r8,r8,r5        /* r8 = (rank_size >> 4) */
+       mullw   r8,r8,r7        /* r8 = (DIMM_size >> 4) */
+       neg     r7,r8
+       rlwinm  r7,r7,28,4,31
+       or      r7,r7,r11       /* set ADDR field */
+       rlwinm  r8,r8,12,20,31
+       add     r11,r11,r8      /* set Base Addr for next DIMM */
+
+       cmpi    0,0,r10,SPD_DIMM0
+       bne     set_dimm1_size
+       stw     r7,SD_D0_BAR(r4)
+       sync
+       li      r10,SPD_DIMM1
+       READ_SPD(0)
+       bne do_each_dimm
+       b spd_done
+
+set_dimm1_size:
+       stw     r7,SD_D1_BAR(r4)
+       sync
+spd_done:
+       blr
+
+check_next_slot:
+       cmpi    0,0,r10,SPD_DIMM1
+       beq     spd_read_fail
+       li      r10,SPD_DIMM1
+       b       do_first_dimm
+spd_read_fail:
+       ori     r3,r0,0xdead
+       b       err_hung
+spd_fail:
+       li      r3,0x0bad
+       sync
+err_hung:      /* hang here for debugging */
+       nop
+       nop
+       b       err_hung
+
+#endif /* !SDC_HARDCODED_INIT */
diff --git a/board/mpc7448hpc2/config.mk b/board/mpc7448hpc2/config.mk
new file mode 100644 (file)
index 0000000..2e58858
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# Copyright (c) 2005 Freescale Semiconductor, Inc.
+#
+# 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 address
+TEXT_BASE = 0xFF000000
+# RAM address
+#TEXT_BASE = 0x00400000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -maltivec -mabi=altivec -msoft-float
diff --git a/board/mpc7448hpc2/mpc7448hpc2.c b/board/mpc7448hpc2/mpc7448hpc2.c
new file mode 100644 (file)
index 0000000..d4a047c
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * (C) Copyright 2005 Freescale Semiconductor, Inc.
+ *
+ * Roy Zang <tie-fei.zang@freescale.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
+ *
+ * modifications for the Tsi108 Emul Board by avb@Tundra
+ */
+
+/*
+ * board support/init functions for the
+ * Freescale MPC7448 HPC2 (High-Performance Computing 2 Platform).
+ */
+
+#include <common.h>
+#include <74xx_7xx.h>
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+extern void ft_cpu_setup (void *blob, bd_t *bd);
+#endif
+
+#undef DEBUG
+
+extern void flush_data_cache (void);
+extern void invalidate_l1_instruction_cache (void);
+extern void tsi108_init_f (void);
+
+int display_mem_map (void);
+
+void after_reloc (ulong dest_addr)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       
+       /*
+        * Jump to the main U-Boot board init code
+        */
+       board_init_r ((gd_t *) gd, dest_addr);
+       /* NOTREACHED */
+}
+
+/*
+ * Check Board Identity:
+ * report board type
+ */
+
+int checkboard (void)
+{
+       int l_type = 0;
+
+       printf ("BOARD: %s\n", CFG_BOARD_NAME);
+       return (l_type);
+}
+
+/*
+ * Read Processor ID:
+ *
+ * report calling processor number
+ */
+
+int read_pid (void)
+{
+       return 0;               /* we are on single CPU platform for a while */
+}
+
+long int dram_size (int board_type)
+{
+       return 0x20000000;      /* 256M bytes */
+}
+
+long int initdram (int board_type)
+{
+       return dram_size (board_type);
+}
+
+#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+void
+ft_board_setup (void *blob, bd_t *bd)
+{
+       u32 *p;
+       int len;
+
+       ft_cpu_setup (blob, bd);
+
+       p = ft_get_prop (blob, "/memory/reg", &len);
+       if (p != NULL) {
+               *p++ = cpu_to_be32 (bd->bi_memstart);
+               *p = cpu_to_be32 (bd->bi_memsize);
+       }
+}
+#endif
diff --git a/board/mpc7448hpc2/tsi108_init.c b/board/mpc7448hpc2/tsi108_init.c
new file mode 100644 (file)
index 0000000..e3b09cf
--- /dev/null
@@ -0,0 +1,665 @@
+/*****************************************************************************
+ * (C) Copyright 2003;  Tundra Semiconductor Corp.
+ *
+ * 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
+ *****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * FILENAME: tsi108_init.c
+ *
+ * Originator: Alex Bounine
+ *
+ * DESCRIPTION:
+ * Initialization code for the Tundra Tsi108 bridge chip
+ *---------------------------------------------------------------------------*/
+
+#include <common.h>
+#include <74xx_7xx.h>
+#include <config.h>
+#include <version.h>
+#include <asm/processor.h>
+#include <tsi108.h>
+
+extern void mpicInit (int verbose);
+
+/*
+ * Configuration Options
+ */
+
+typedef struct {
+       ulong upper;
+       ulong lower;
+} PB2OCN_LUT_ENTRY;
+
+PB2OCN_LUT_ENTRY pb2ocn_lut1[32] = {
+       /* 0 - 7 */
+       {0x00000000, 0x00000201}, /* PBA=0xE000_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xE100_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xE200_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xE300_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xE400_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xE500_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xE600_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xE700_0000 -> PCI/X (Byte-Swap) */
+
+       /* 8 - 15 */
+       {0x00000000, 0x00000201}, /* PBA=0xE800_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xE900_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xEA00_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xEB00_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xEC00_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xED00_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xEE00_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xEF00_0000 -> PCI/X (Byte-Swap) */
+
+       /* 16 - 23 */
+       {0x00000000, 0x00000201}, /* PBA=0xF000_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xF100_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xF200_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xF300_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xF400_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xF500_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xF600_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xF700_0000 -> PCI/X (Byte-Swap) */
+       /* 24 - 31 */
+       {0x00000000, 0x00000201}, /* PBA=0xF800_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xF900_0000 -> PCI/X (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xFA00_0000 -> PCI/X  PCI I/O (Byte-Swap) */
+       {0x00000000, 0x00000201}, /* PBA=0xFB00_0000 -> PCI/X  PCI Config (Byte-Swap) */
+
+       {0x00000000, 0x02000240}, /* PBA=0xFC00_0000 -> HLP */
+       {0x00000000, 0x01000240}, /* PBA=0xFD00_0000 -> HLP */
+       {0x00000000, 0x03000240}, /* PBA=0xFE00_0000 -> HLP */
+       {0x00000000, 0x00000240}  /* PBA=0xFF00_0000 -> HLP : (Translation Enabled + Byte-Swap)*/
+};
+
+#ifdef CFG_CLK_SPREAD
+typedef struct {
+       ulong ctrl0;
+       ulong ctrl1;
+} PLL_CTRL_SET;
+
+/*
+ * Clock Generator SPLL0 initialization values
+ * PLL0 configuration table for various PB_CLKO freq.
+ * Uses pre-calculated values for Fs = 30 kHz, D = 0.5%
+ * Fout depends on required PB_CLKO. Based on Fref = 33 MHz
+ */
+
+static PLL_CTRL_SET pll0_config[8] = {
+       {0x00000000, 0x00000000},       /* 0: bypass */
+       {0x00000000, 0x00000000},       /* 1: reserved */
+       {0x00430044, 0x00000043},       /* 2: CG_PB_CLKO = 183 MHz */
+       {0x005c0044, 0x00000039},       /* 3: CG_PB_CLKO = 100 MHz */
+       {0x005c0044, 0x00000039},       /* 4: CG_PB_CLKO = 133 MHz */
+       {0x004a0044, 0x00000040},       /* 5: CG_PB_CLKO = 167 MHz */
+       {0x005c0044, 0x00000039},       /* 6: CG_PB_CLKO = 200 MHz */
+       {0x004f0044, 0x0000003e}        /* 7: CG_PB_CLKO = 233 MHz */
+};
+#endif /* CFG_CLK_SPREAD */
+
+/*
+ * Prosessor Bus Clock (in MHz) defined by CG_PB_SELECT
+ * (based on recommended Tsi108 reference clock 33MHz)
+ */
+static int pb_clk_sel[8] = { 0, 0, 183, 100, 133, 167, 200, 233 };
+
+/*
+ * get_board_bus_clk ()
+ *
+ * returns the bus clock in Hz.
+ */
+unsigned long get_board_bus_clk (void)
+{
+       ulong i;
+
+       /* Detect PB clock freq. */
+       i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PWRUP_STATUS);
+       i = (i >> 16) & 0x07;   /* Get PB PLL multiplier */
+
+       return pb_clk_sel[i] * 1000000;
+}
+
+/*
+ * board_early_init_f ()
+ *
+ * board-specific initialization executed from flash
+ */
+
+int board_early_init_f (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       ulong i;
+
+       gd->mem_clk = 0;
+       i = in32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
+                       CG_PWRUP_STATUS);
+       i = (i >> 20) & 0x07;   /* Get GD PLL multiplier */
+       switch (i) {
+       case 0: /* external clock */
+               printf ("Using external clock\n");
+               break;
+       case 1: /* system clock */
+               gd->mem_clk = gd->bus_clk;
+               break;
+       case 4: /* 133 MHz */
+       case 5: /* 166 MHz */
+       case 6: /* 200 MHz */
+               gd->mem_clk = pb_clk_sel[i] * 1000000;
+               break;
+       default:
+               printf ("Invalid DDR2 clock setting\n");
+               return -1;
+       }
+       printf ("BUS: %d MHz\n", get_board_bus_clk() / 1000000);
+       printf ("MEM: %d MHz\n", gd->mem_clk / 1000000);
+       return 0;
+}
+
+/*
+ * board_early_init_r() - Tsi108 initialization function executed right after
+ * relocation. Contains code that cannot be executed from flash.
+ */
+
+int board_early_init_r (void)
+{
+       ulong temp, i;
+       ulong reg_val;
+       volatile ulong *reg_ptr;
+       
+       reg_ptr =
+               (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + 0x900);
+
+       for (i = 0; i < 32; i++) {
+               *reg_ptr++ = 0x00000201;        /* SWAP ENABLED */
+               *reg_ptr++ = 0x00;
+       }
+
+       __asm__ __volatile__ ("eieio");
+       __asm__ __volatile__ ("sync");
+
+       /* Setup PB_OCN_BAR2: size 256B + ENable @ 0x0_80000000 */
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR2,
+               0x80000001);
+       __asm__ __volatile__ ("sync");
+
+       /* Make sure that OCN_BAR2 decoder is set (to allow following immediate
+        * read from SDRAM)
+        */
+
+       temp = in32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR2);
+       __asm__ __volatile__ ("sync");
+
+       /*
+        * Remap PB_OCN_BAR1 to accomodate PCI-bus aperture and EPROM into the
+        * processor bus address space. Immediately after reset LUT and address
+        * translation are disabled for this BAR. Now we have to initialize LUT
+        * and switch from the BOOT mode to the normal operation mode.
+        *
+        * The aperture defined by PB_OCN_BAR1 startes at address 0xE0000000
+        * and covers 512MB of address space. To allow larger aperture we also
+        * have to relocate register window of Tsi108
+        *
+        * Initialize LUT (32-entries) prior switching PB_OCN_BAR1 from BOOT
+        * mode.
+        *
+        * initialize pointer to LUT associated with PB_OCN_BAR1
+        */
+       reg_ptr =
+               (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + 0x800);
+
+       for (i = 0; i < 32; i++) {
+               *reg_ptr++ = pb2ocn_lut1[i].lower;
+               *reg_ptr++ = pb2ocn_lut1[i].upper;
+       }
+
+       __asm__ __volatile__ ("sync");
+
+       /* Base addresses for CS0, CS1, CS2, CS3 */
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_ADDR,
+               0x00000000);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_ADDR,
+               0x00100000);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_ADDR,
+               0x00200000);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_ADDR,
+               0x00300000);
+       __asm__ __volatile__ ("sync");
+
+       /* Masks for HLP banks */
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_MASK,
+               0xFFF00000);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_MASK,
+               0xFFF00000);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_MASK,
+               0xFFF00000);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_MASK,
+               0xFFF00000);
+       __asm__ __volatile__ ("sync");
+
+       /* Set CTRL0 values for banks */
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_CTRL0,
+               0x7FFC44C2);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_CTRL0,
+               0x7FFC44C0);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_CTRL0,
+               0x7FFC44C0);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_CTRL0,
+               0x7FFC44C2);
+       __asm__ __volatile__ ("sync");
+
+       /* Set banks to latched mode, enabled, and other default settings */
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_CTRL1,
+               0x7C0F2000);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_CTRL1,
+               0x7C0F2000);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_CTRL1,
+               0x7C0F2000);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_CTRL1,
+               0x7C0F2000);
+       __asm__ __volatile__ ("sync");
+       
+       /*
+        * Set new value for PB_OCN_BAR1: switch from BOOT to LUT mode.
+        * value for PB_OCN_BAR1: (BA-0xE000_0000 + size 512MB + ENable)
+        */
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR1,
+               0xE0000011);
+       __asm__ __volatile__ ("sync");
+
+       /* Make sure that OCN_BAR2 decoder is set (to allow following
+        * immediate read from SDRAM)
+        */
+       
+       temp = in32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR1);
+       __asm__ __volatile__ ("sync");
+
+       /*
+        * SRI: At this point we have enabled the HLP banks. That means we can
+        * now read from the NVRAM and initialize the environment variables.
+        * We will over-ride the env_init called in board_init_f
+        * This is really a work-around because, the HLP bank 1
+        * where NVRAM resides is not visible during board_init_f
+        * (lib_ppc/board.c)
+        * Alternatively, we could use the I2C EEPROM at start-up to configure
+        * and enable all HLP banks and not just HLP 0 as is being done for
+        * Taiga Rev. 2.
+        */
+       
+       env_init ();
+
+#ifndef DISABLE_PBM
+       
+       /*
+        * For IBM processors we have to set Address-Only commands generated
+        * by PBM that are different from ones set after reset.
+        */
+
+       temp = get_cpu_type ();
+
+       if ((CPU_750FX == temp) || (CPU_750GX == temp))
+               out32 (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_MCMD,
+                       0x00009955);
+#endif /* DISABLE_PBM */
+
+#ifdef CONFIG_PCI
+       /*
+        * Initialize PCI/X block
+        */
+
+       /* Map PCI/X Configuration Space (16MB @ 0x0_FE000000) */
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
+               PCI_PFAB_BAR0_UPPER, 0);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_BAR0,
+               0xFB000001);
+       __asm__ __volatile__ ("sync");
+
+       /* Set Bus Number for the attached PCI/X bus (we will use 0 for NB) */
+
+       temp =  in32(CFG_TSI108_CSR_BASE +
+               TSI108_PCI_REG_OFFSET + PCI_PCIX_STAT);
+
+       temp &= ~0xFF00;        /* Clear the BUS_NUM field */
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PCIX_STAT,
+               temp);
+
+       /* Map PCI/X IO Space (64KB @ 0x0_FD000000) takes one 16MB LUT entry */
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_IO_UPPER,
+               0);
+       __asm__ __volatile__ ("sync");
+
+       /* This register is on the PCI side to interpret the address it receives
+        * and maps it as a IO address.
+        */
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_IO,
+               0xFA000001);
+       __asm__ __volatile__ ("sync");
+
+       /*
+        * Map PCI/X Memory Space
+        *
+        * Transactions directed from OCM to PCI Memory Space are directed
+        * from PB to PCI
+        * unchanged (as defined by PB_OCN_BAR1,2 and LUT settings).
+        * If address remapping is required the corresponding PCI_PFAB_MEM32
+        * and PCI_PFAB_PFMx register groups have to be configured.
+        *
+        * Map the path from the PCI/X bus into the system memory
+        *
+        * The memory mapped window assotiated with PCI P2O_BAR2 provides
+        * access to the system memory without address remapping.
+        * All system memory is opened for accesses initiated by PCI/X bus
+        * masters.
+        *
+        * Initialize LUT associated with PCI P2O_BAR2
+        *
+        * set pointer to LUT associated with PCI P2O_BAR2
+        */
+
+       reg_ptr =
+               (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + 0x500);
+
+#ifdef DISABLE_PBM
+
+       /* In case when PBM is disabled (no HW supported cache snoopng on PB)
+        * P2O_BAR2 is directly mapped into the system memory without address
+        * translation.
+        */
+
+       reg_val = 0x00000004;   /* SDRAM port + NO Addr_Translation */
+
+       for (i = 0; i < 32; i++) {
+               *reg_ptr++ = reg_val;   /* P2O_BAR2_LUTx */
+               *reg_ptr++ = 0;         /* P2O_BAR2_LUT_UPPERx */
+       }
+
+       /* value for PCI BAR2 (size = 512MB, Enabled, No Addr. Translation) */
+       reg_val = 0x00007500;
+#else
+
+       reg_val = 0x00000002;   /* Destination port = PBM */
+
+       for (i = 0; i < 32; i++) {
+               *reg_ptr++ = reg_val;   /* P2O_BAR2_LUTx */
+/* P2O_BAR2_LUT_UPPERx : Set data swapping mode for PBM (byte swapping) */
+               *reg_ptr++ = 0x40000000;
+/* offset = 16MB, address translation is enabled to allow byte swapping */
+               reg_val += 0x01000000;
+       }
+
+/* value for PCI BAR2 (size = 512MB, Enabled, Address Translation Enabled) */
+       reg_val = 0x00007100;
+#endif
+
+       __asm__ __volatile__ ("eieio");
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_PAGE_SIZES,
+               reg_val);
+       __asm__ __volatile__ ("sync");
+
+       /* Set 64-bit PCI bus address for system memory
+        * ( 0 is the best choice for easy mapping)
+        */
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR2,
+               0x00000000);
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR2_UPPER,
+               0x00000000);
+       __asm__ __volatile__ ("sync");
+
+#ifndef DISABLE_PBM
+       /*
+        *  The memory mapped window assotiated with PCI P2O_BAR3 provides
+        *  access to the system memory using SDRAM OCN port and address
+        *  translation. This is alternative way to access SDRAM from PCI
+        *  required for Tsi108 emulation testing.
+        *  All system memory is opened for accesses initiated by
+        *  PCI/X bus masters.
+        *
+        *  Initialize LUT associated with PCI P2O_BAR3
+        *
+        *  set pointer to LUT associated with PCI P2O_BAR3
+        */
+       reg_ptr =
+               (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + 0x600);
+
+       reg_val = 0x00000004;   /* Destination port = SDC */
+
+       for (i = 0; i < 32; i++) {
+               *reg_ptr++ = reg_val;   /* P2O_BAR3_LUTx */
+               
+/* P2O_BAR3_LUT_UPPERx : Set data swapping mode for PBM (byte swapping) */
+               *reg_ptr++ = 0; 
+               
+/* offset = 16MB, address translation is enabled to allow byte swapping */
+               reg_val += 0x01000000;
+       }
+
+       __asm__ __volatile__ ("eieio");
+       __asm__ __volatile__ ("sync");
+
+       /* Configure PCI P2O_BAR3 (size = 512MB, Enabled) */
+
+       reg_val =
+               in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
+                PCI_P2O_PAGE_SIZES);
+       reg_val &= ~0x00FF;
+       reg_val |= 0x0071;
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_PAGE_SIZES,
+               reg_val);
+       __asm__ __volatile__ ("sync");
+
+       /* Set 64-bit base PCI bus address for window (0x20000000) */
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR3_UPPER,
+               0x00000000);
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR3,
+               0x20000000);
+       __asm__ __volatile__ ("sync");
+
+#endif /* !DISABLE_PBM */
+
+#ifdef ENABLE_PCI_CSR_BAR      
+       /* open if required access to Tsi108 CSRs from the PCI/X bus */
+       /* enable BAR0 on the PCI/X bus */
+       reg_val = in32(CFG_TSI108_CSR_BASE +
+               TSI108_PCI_REG_OFFSET + PCI_MISC_CSR);
+       reg_val |= 0x02;
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_MISC_CSR,
+               reg_val);
+       __asm__ __volatile__ ("sync");
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR0_UPPER,
+               0x00000000);
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR0,
+               CFG_TSI108_CSR_BASE);
+       __asm__ __volatile__ ("sync");
+
+#endif
+
+       /*
+        * Finally enable PCI/X Bus Master and Memory Space access
+        */
+       
+       reg_val = in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_CSR);
+       reg_val |= 0x06;
+       out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_CSR, reg_val);
+       __asm__ __volatile__ ("sync");
+
+#endif /* CONFIG_PCI */
+
+       /*
+        * Initialize MPIC outputs (interrupt pins):
+        * Interrupt routing on the Grendel Emul. Board:
+        * PB_INT[0] -> INT (CPU0)
+        * PB_INT[1] -> INT (CPU1)
+        * PB_INT[2] -> MCP (CPU0)
+        * PB_INT[3] -> MCP (CPU1)
+        * Set interrupt controller outputs as Level_Sensitive/Active_Low
+        */
+       out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(0), 0x02);
+       out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(1), 0x02);
+       out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(2), 0x02);
+       out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(3), 0x02);
+       __asm__ __volatile__ ("sync");
+
+       /*
+        * Ensure that Machine Check exception is enabled
+        * We need it to support PCI Bus probing (configuration reads)
+        */
+       
+       reg_val = mfmsr ();
+       mtmsr(reg_val | MSR_ME);
+
+       return 0;
+}
+
+/*
+ * Needed to print out L2 cache info
+ * used in the misc_init_r function
+ */
+
+unsigned long get_l2cr (void)
+{
+       unsigned long l2controlreg;
+       asm volatile ("mfspr %0, 1017":"=r" (l2controlreg):);
+       return l2controlreg;
+}
+
+/*
+ * misc_init_r()
+ *
+ * various things to do after relocation
+ *
+ */
+
+int misc_init_r (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+#ifdef CFG_CLK_SPREAD  /* Initialize Spread-Spectrum Clock generation */
+       ulong i;
+
+       /* Ensure that Spread-Spectrum is disabled */
+       out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0, 0);
+       out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0, 0);
+
+       /* Initialize PLL1: CG_PCI_CLK , internal OCN_CLK
+        * Uses pre-calculated value for Fout = 800 MHz, Fs = 30 kHz, D = 0.5%
+        */
+
+       out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0,
+               0x002e0044);    /* D = 0.25% */
+       out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL1,
+               0x00000039);    /* BWADJ */
+
+       /* Initialize PLL0: CG_PB_CLKO  */
+       /* Detect PB clock freq. */
+       i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PWRUP_STATUS);
+       i = (i >> 16) & 0x07;   /* Get PB PLL multiplier */
+
+       out32 (CFG_TSI108_CSR_BASE +
+               TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0, pll0_config[i].ctrl0);
+       out32 (CFG_TSI108_CSR_BASE +
+               TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL1, pll0_config[i].ctrl1);
+
+       /* Wait and set SSEN for both PLL0 and 1 */
+       udelay (1000);
+       out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0,
+               0x802e0044);    /* D=0.25% */
+       out32 (CFG_TSI108_CSR_BASE +
+               TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0,
+               0x80000000 | pll0_config[i].ctrl0);
+#endif /* CFG_CLK_SPREAD */
+
+#ifdef CFG_L2
+       l2cache_enable ();
+#endif
+       printf ("BUS:   %d MHz\n", gd->bus_clk / 1000000);
+       printf ("MEM:   %d MHz\n", gd->mem_clk / 1000000);
+
+       /*
+        * All the information needed to print the cache details is avaiblable
+        * at this point i.e. above call to l2cache_enable is the very last
+        * thing done with regards to enabling diabling the cache.
+        * So this seems like a good place to print all this information
+        */
+       
+       printf ("CACHE: ");
+       switch (get_cpu_type()) {
+       case CPU_7447A:
+               printf ("L1 Instruction cache - 32KB 8-way");
+               (get_hid0 () & (1 << 15)) ? printf (" ENABLED\n") :
+                       printf (" DISABLED\n");
+               printf ("L1 Data cache - 32KB 8-way");
+               (get_hid0 () & (1 << 14)) ? printf (" ENABLED\n") :
+                       printf (" DISABLED\n");
+               printf ("Unified L2 cache - 512KB 8-way");
+               (get_l2cr () & (1 << 31)) ? printf (" ENABLED\n") :
+                       printf (" DISABLED\n");
+               printf ("\n");
+               break;
+
+       case CPU_7448:
+               printf ("L1 Instruction cache - 32KB 8-way");
+               (get_hid0 () & (1 << 15)) ? printf (" ENABLED\n") :
+                       printf (" DISABLED\n");
+               printf ("L1 Data cache - 32KB 8-way");
+               (get_hid0 () & (1 << 14)) ? printf (" ENABLED\n") :
+                       printf (" DISABLED\n");
+               printf ("Unified L2 cache - 1MB 8-way");
+               (get_l2cr () & (1 << 31)) ? printf (" ENABLED\n") :
+                       printf (" DISABLED\n");
+               break;
+       default:
+               break;
+       }
+       return 0;
+}
diff --git a/board/mpc7448hpc2/u-boot.lds b/board/mpc7448hpc2/u-boot.lds
new file mode 100644 (file)
index 0000000..8f24213
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * u-boot.lds - linker script for U-Boot on mpc7448hpc2 Board.
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+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/74xx_7xx/start.o       (.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/*    . = env_offset; */
+/*    common/environment.o(.text) */
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+  }
+  .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 = .);
+
+  . = .;
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+  . = .;
+  __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 f4e5fc504b3479f214944e0de6a07b697d5fc191..84d5da3116babd52295e21c12a4eae7a8beadc66 100644 (file)
 #include <74xx_7xx.h>
 #include <asm/cache.h>
 
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
 #ifdef CONFIG_AMIGAONEG3SE
 #include "../board/MAI/AmigaOneG3SE/via686.h"
 #include "../board/MAI/AmigaOneG3SE/memio.h"
@@ -101,6 +105,10 @@ get_cpu_type(void)
                type = CPU_7457;
                break;
 
+       case 0x8003:
+               type = CPU_7447A;
+               break;
+
        case 0x8004:
                type = CPU_7448;
                break;
@@ -156,6 +164,10 @@ int checkcpu (void)
                str = "MPC7410";
                break;
 
+       case CPU_7447A:
+               str = "MPC7447A";
+               break;
+
        case CPU_7448:
                str = "MPC7448";
                break;
@@ -264,20 +276,19 @@ do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 /*
  * For the 7400 the TB clock runs at 1/4 the cpu bus speed.
  */
-#ifdef CONFIG_AMIGAONEG3SE
+#if defined(CONFIG_AMIGAONEG3SE) || defined(CFG_CONFIG_BUS_CLK)
 unsigned long get_tbclk(void)
 {
        return (gd->bus_clk / 4);
 }
-#else  /* ! CONFIG_AMIGAONEG3SE */
+#else  /* ! CONFIG_AMIGAONEG3SE and !CFG_CONFIG_BUS_CLK*/
 
 unsigned long get_tbclk (void)
 {
        return CFG_BUS_HZ / 4;
 }
-#endif /* CONFIG_AMIGAONEG3SE */
+#endif /* CONFIG_AMIGAONEG3SE or CFG_CONFIG_BUS_CLK*/
 /* ------------------------------------------------------------------------- */
-
 #if defined(CONFIG_WATCHDOG)
 #if !defined(CONFIG_PCIPPC2) && !defined(CONFIG_BAB7xx)
 void
@@ -289,3 +300,30 @@ watchdog_reset(void)
 #endif /* CONFIG_WATCHDOG */
 
 /* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_cpu_setup (void *blob, bd_t *bd)
+{
+       u32 *p;
+       ulong clock;
+       int len;
+               
+       clock = bd->bi_busfreq;
+       
+       p = ft_get_prop (blob, "/cpus/" OF_CPU "/bus-frequency", &len);
+       if (p != NULL)
+               *p = cpu_to_be32 (clock);
+
+#if defined(CONFIG_TSI108_ETH)
+       p = ft_get_prop (blob, "/" OF_TSI "/ethernet@6200/address", &len);
+               memcpy (p, bd->bi_enetaddr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH1)
+       p = ft_get_prop (blob, "/" OF_TSI "/ethernet@6600/address", &len);
+               memcpy (p, bd->bi_enet1addr, 6);
+#endif
+}
+#endif
+/* ------------------------------------------------------------------------- */
index e02a4cc21cbc4484b92764c64601b8b2e0ed33a4..1dd1b2cd8426017b92aa47e2e08dd983f77f1ee7 100644 (file)
@@ -43,6 +43,7 @@ cpu_init_f (void)
        case CPU_7450:
        case CPU_7455:
        case CPU_7457:
+       case CPU_7447A:
        case CPU_7448:
                /* enable the timebase bit in HID0 */
                set_hid0(get_hid0() | 0x4000000);
index d1800ede05653803f57eeafb152d3a83bbfb428f..d8c40cea01ccb7f4675570515492dcd0574d85c2 100644 (file)
@@ -31,6 +31,8 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+extern unsigned long get_board_bus_clk (void);
+
 static const int hid1_multipliers_x_10[] = {
        25,     /* 0000 - 2.5x */
        75,     /* 0001 - 7.5x */
@@ -50,6 +52,42 @@ static const int hid1_multipliers_x_10[] = {
        0       /* 1111 - off */
 };
 
+/* PLL_CFG[0:4] table for cpu 7448/7447A/7455/7457 */
+static const int hid1_74xx_multipliers_x_10[] = {
+       115,    /* 00000 - 11.5x  */
+       170,    /* 00001 - 17x    */
+       75,     /* 00010 -  7.5x  */
+       150,    /* 00011 - 15x    */
+       70,     /* 00100 -  7x    */
+       180,    /* 00101 - 18x    */
+       10,     /* 00110 - bypass */
+       200,    /* 00111 - 20x    */
+       20,     /* 01000 -  2x    */
+       210,    /* 01001 - 21x    */
+       65,     /* 01010 -  6.5x  */
+       130,    /* 01011 - 13x    */
+       85,     /* 01100 -  8.5x  */
+       240,    /* 01101 - 24x    */
+       95,     /* 01110 -  9.5x  */
+       90,     /* 01111 -  9x    */
+       30,     /* 10000 -  3x    */
+       105,    /* 10001 - 10.5x  */
+       55,     /* 10010 -  5.5x  */
+       110,    /* 10011 - 11x    */
+       40,     /* 10100 -  4x    */
+       100,    /* 10101 - 10x    */
+       50,     /* 10110 -  5x    */
+       120,    /* 10111 - 12x    */
+       80,     /* 11000 -  8x    */
+       140,    /* 11001 - 14x    */
+       60,     /* 11010 -  6x    */
+       160,    /* 11011 - 16x    */
+       135,    /* 11100 - 13.5x  */
+       280,    /* 11101 - 28x    */
+       0,      /* 11110 - off    */
+       125     /* 11111 - 12.5x  */
+};
+
 static const int hid1_fx_multipliers_x_10[] = {
        00,     /* 0000 - off */
        00,     /* 0001 - off */
@@ -89,22 +127,30 @@ int get_clocks (void)
 {
        ulong clock = 0;
 
+#ifdef CFG_BUS_CLK
+       gd->bus_clk = CFG_BUS_CLK;      /* bus clock is a fixed frequency */
+#else
+       gd->bus_clk = get_board_bus_clk ();     /* bus clock is configurable */
+#endif
+
        /* calculate the clock frequency based upon the CPU type */
        switch (get_cpu_type()) {
+       case CPU_7447A:
        case CPU_7448:
        case CPU_7455:
        case CPU_7457:
                /*
-                * It is assumed that the PLL_EXT line is zero.
                 * Make sure division is done before multiplication to prevent 32-bit
                 * arithmetic overflows which will cause a negative number
                 */
-               clock = (CFG_BUS_CLK / 10) * hid1_multipliers_x_10[(get_hid1 () >> 13) & 0xF];
+               clock = (gd->bus_clk / 10) *
+                       hid1_74xx_multipliers_x_10[(get_hid1 () >> 12) & 0x1F];
                break;
 
        case CPU_750GX:
        case CPU_750FX:
-               clock = CFG_BUS_CLK * hid1_fx_multipliers_x_10[get_hid1 () >> 27] / 10;
+               clock = gd->bus_clk *
+                       hid1_fx_multipliers_x_10[get_hid1 () >> 27] / 10;
                break;
 
        case CPU_7450:
@@ -121,7 +167,8 @@ int get_clocks (void)
                 * Make sure division is done before multiplication to prevent 32-bit
                 * arithmetic overflows which will cause a negative number
                 */
-               clock = (CFG_BUS_CLK / 10) * hid1_multipliers_x_10[get_hid1 () >> 28];
+               clock = (gd->bus_clk / 10) *
+                       hid1_multipliers_x_10[get_hid1 () >> 28];
                break;
 
        case CPU_UNKNOWN:
@@ -131,7 +178,6 @@ int get_clocks (void)
        }
 
        gd->cpu_clk = clock;
-       gd->bus_clk = CFG_BUS_CLK;
 
        return (0);
 }
diff --git a/doc/README.mpc7448hpc2 b/doc/README.mpc7448hpc2
new file mode 100644 (file)
index 0000000..0e40e39
--- /dev/null
@@ -0,0 +1,185 @@
+Freescale MPC7448hpc2 (Taiga) board
+===================================
+
+Created 08/11/2006 Roy Zang
+--------------------------
+MPC7448hpc2 (Taiga) board is a high-performance PowerPC server reference
+design, which is optimized for high speed throughput between the processor and
+the memory, disk drive and Ethernet port subsystems.
+
+MPC7448hpc2(Taiga) is designed to the micro-ATX chassis, allowing it to be
+used in 1U or 2U rack-mount chassis¡¯, as well as in standard ATX/Micro-ATX
+chassis.
+
+Building U-Boot
+------------------
+The mpc7448hpc2 code base is known to compile using:
+       Binutils 2.15, Gcc 3.4.3, Glibc 2.3.3
+
+       $ make mpc7448hpc2_config
+       Configuring for mpc7448hpc2 board...
+
+       $ make
+
+Memory Map
+----------
+
+The memory map is setup for Linux to operate properly.
+
+The mapping is:
+
+       Range Start     Range End       Definition                      Size
+
+       0x0000_0000     0x7fff_ffff     DDR                             2G
+       0xe000_0000     0xe7ff_ffff     PCI Memory                      128M
+       0xfa00_0000     0xfaff_ffff     PCI IO                          16M
+       0xfb00_0000     0xfbff_ffff     PCI Config                      16M
+       0xfc00_0000     0xfc0f_ffff     NVRAM/CADMUS                    1M
+       0xfe00_0000     0xfeff_ffff     PromJet                         16M
+       0xff00_0000     0xff80_0000     FLASH (boot flash)              8M
+       0xff80_0000     0xffff_ffff     FLASH (second half flash)       8M
+
+Using Flash
+-----------
+
+The MPC7448hpc2 board has two "banks" of flash, each 8MB in size
+(2^23 = 0x00800000).
+
+Note: the "bank" here refers to half of the flash. In fact, there is only one
+bank of flash, which is divided into low and high half. Each is controlled by
+the most significant bit of the address bus. The so called "bank" is only for
+convenience.
+
+There is a switch which allows the "bank" to be selected.  The switch
+settings for updating flash are given below.
+
+The u-boot commands for copying the boot-bank into the secondary bank are
+as follows:
+
+       erase ff800000 ff880000
+       cp.b ff000000 ff800000 80000
+
+U-boot commands for downloading an image via tftp and flashing
+it into the secondary bank:
+
+       tftp 10000 <u-boot.bin.image>
+       erase ff000000 ff080000
+       cp.b 10000 ff000000 80000
+
+After copying the image into the second bank of flash, be sure to toggle
+SW3[4] on board before resetting the board in order to set the
+secondary bank as the boot-bank.
+
+Board Switches
+----------------------
+
+Most switches on the board should not be changed.  The most frequent
+user-settable switches on the board are used to configure
+the flash banks and determining the PCI frequency.
+
+SW1[1-5]: Processor core voltage
+
+       12345           Core Voltage
+       -----
+       SW1=01111       1.000V.
+       SW1=01101       1.100V.
+       SW1=01011       1.200V.
+       SW1=01001       1.300V only for MPC7447A.
+
+
+SW2[1-6]: CPU core frequency
+
+               CPU Core Frequency (MHz)
+                       Bus Frequency
+       123456          100     133     167     200     Ratio
+       
+       ------
+       SW2=101100      500     667     833     1000    5x
+       SW2=100100      550     733     917     1100    5.5x
+       SW2=110100      600     800     1000    1200    6x
+       SW2=010100      650     866     1083    1300    6.5x
+       SW2=001000      700     930     1167    1400    7x
+       SW2=000100      750     1000    1250    1500    7.5x
+       SW2=110000      800     1066    1333    1600    8x
+       SW2=011000      850     1333    1417    1700    8.5x only for MPC7447A
+       SW2=011110      900     1200    1500    1800    9x
+
+This table shows only a subset of available frequency options; see the CPU
+hardware specifications for more information.
+
+SW2[7-8]: Bus Protocol and CPU Reset Option
+
+       7               
+       -
+       SW2=0           System bus uses MPX bus protocol
+       SW2=1           System bus uses 60x bus protocol
+
+       8               
+       -
+       SW2=0           TSI108 can cause CPU reset
+       SW2=1           TSI108 can not cause CPU reset
+
+SW3[1-8] system options
+
+       123             
+       ---
+       SW3=xxx         Connected to GPIO[0:2] on TSI108
+
+       4               
+       -
+       SW3=0           CPU boots from low half of flash
+       SW3=1           CPU boots from high half of flash
+
+       5               
+       -
+       SW3=0           SATA and slot2 connected to PCI bus
+       SW3=1           Only slot1 connected to PCI bus
+
+       6               
+       -
+       SW3=0           USB connected to PCI bus
+       SW3=1           USB disconnected from PCI bus
+
+       7               
+       -
+       SW3=0           Flash is write protected
+       SW3=1           Flash is NOT write protected
+
+       8               
+       -
+       SW3=0           CPU will boot from flash
+       SW3=1           CPU will boot from PromJet
+
+SW4[1-3]: System bus frequency
+
+                       Bus Frequency (MHz)
+       ---
+       SW4=010                 183
+       SW4=011                 100
+       SW4=100                 133
+       SW4=101                 166 only for MPC7447A
+       SW4=110                 200 only for MPC7448
+       others                  reserved
+
+SW4[4-6]: DDR2 SDRAM frequency
+
+                       Bus Frequency (MHz)
+       ---
+       SW4=000         external clock
+       SW4=011         system clock    
+       SW4=100         133
+       SW4=101         166
+       SW4=110         200
+       others          reserved
+
+SW4[7-8]: PCI/PCI-X frequency control
+       7               
+       -
+       SW4=0           PCI/PCI-X bus operates normally
+       SW4=1           PCI bus forced to PCI-33 mode
+
+       8               
+       -
+       SW4=0           PCI-X mode at 133 MHz allowed
+       SW4=1           PCI-X mode limited to 100 MHz
+
index 5a369df2c418914c2e1245fafb57ddd21d10582f..6a3ea5da255e8392740ce61ca6ac4a94715000cf 100644 (file)
@@ -35,8 +35,8 @@ COBJS = 3c589.o 5701rls.o ali512x.o atmel_usart.o \
          lan91c96.o \
          natsemi.o ne2000.o netarm_eth.o netconsole.o \
          ns16550.o ns8382x.o ns87308.o ns7520_eth.o omap1510_i2c.o \
-         omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o \
-         pcnet.o plb2800_eth.o \
+         omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o tsi108_pci.o\
+         tsi108_i2c.o pcnet.o plb2800_eth.o \
          ps2ser.o ps2mult.o pc_keyb.o \
          rtl8019.o rtl8139.o rtl8169.o \
          s3c4510b_eth.o s3c4510b_uart.o \
@@ -45,7 +45,7 @@ COBJS = 3c589.o 5701rls.o ali512x.o atmel_usart.o \
          serial_pl010.o serial_pl011.o serial_xuartlite.o \
          sl811_usb.o sm501.o smc91111.o smiLynxEM.o \
          status_led.o sym53c8xx.o ahci.o \
-         ti_pci1410a.o tigon3.o tsec.o \
+         ti_pci1410a.o tigon3.o tsec.o tsi108_eth.o\
          usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \
          videomodes.o w83c553f.o \
          ks8695eth.o \
index 2699cce859af61d6d94e1446e3956c051e3561e3..a834cb4cf08def5e025e52b537f92ddc6b759f24 100644 (file)
@@ -2,7 +2,7 @@
  * (C) Copyright 2002-2004
  * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com
  *
- * Copyright (C) 2003 Arabella Software Ltd.
+ * Copyright (C) 2003, 2006 Arabella Software Ltd.
  * Yuli Barcohen <yuli@arabellasw.com>
  *
  * Copyright (C) 2004
 /* #define DEBUG       */
 
 #include <common.h>
+
+#ifdef CFG_FLASH_CFI_DRIVER
+
+#include <watchdog.h>
 #include <asm/processor.h>
 #include <asm/byteorder.h>
 #include <environment.h>
-#ifdef CFG_FLASH_CFI_DRIVER
 
 /*
  * This file implements a Common Flash Interface (CFI) driver for U-Boot.
  *
  */
 
+#if defined(__LITTLE_ENDIAN) && !defined(CFG_FLASH_CFI_SWAP)
+#define CFG_FLASH_CFI_SWAP
+#endif
+
 #ifndef CFG_FLASH_BANKS_LIST
 #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE }
 #endif
@@ -256,7 +263,7 @@ inline uchar flash_read_uchar (flash_info_t * info, uint offset)
        uchar *cp;
 
        cp = flash_make_addr (info, 0, offset);
-#if defined(__LITTLE_ENDIAN)
+#if defined(CFG_FLASH_CFI_SWAP)
        return (cp[0]);
 #else
        return (cp[info->portwidth - 1]);
@@ -283,7 +290,7 @@ ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
                debug ("addr[%x] = 0x%x\n", x, addr[x]);
        }
 #endif
-#if defined(__LITTLE_ENDIAN)
+#if defined(CFG_FLASH_CFI_SWAP)
        retval = ((addr[(info->portwidth)] << 8) | addr[0]);
 #else
        retval = ((addr[(2 * info->portwidth) - 1] << 8) |
@@ -315,7 +322,7 @@ ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
                debug ("addr[%x] = 0x%x\n", x, addr[x]);
        }
 #endif
-#if defined(__LITTLE_ENDIAN)
+#if defined(CFG_FLASH_CFI_SWAP)
        retval = (addr[0] << 16) | (addr[(info->portwidth)] << 24) |
                (addr[(2 * info->portwidth)]) | (addr[(3 * info->portwidth)] << 8);
 #else
@@ -905,12 +912,22 @@ static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf)
        int i;
        uchar *cp = (uchar *) cmdbuf;
 
-#if defined(__LITTLE_ENDIAN)
+#if defined(CFG_FLASH_CFI_SWAP)
        for (i = info->portwidth; i > 0; i--)
 #else
        for (i = 1; i <= info->portwidth; i++)
 #endif
                *cp++ = (i & (info->chipwidth - 1)) ? '\0' : cmd;
+#ifdef CFG_FLASH_CFI_2x16
+       if ((info->portwidth == FLASH_CFI_32BIT) && (info->chipwidth == FLASH_CFI_BY16))
+       {
+          uchar tmp;
+          cp = (uchar *) cmdbuf;
+          tmp = cp[1];
+          cp[1] = cp[2];
+          cp[2] = tmp;
+       }
+#endif /* CFG_FLASH_CFI_2x16 */
 }
 
 /*
diff --git a/drivers/tsi108_eth.c b/drivers/tsi108_eth.c
new file mode 100644 (file)
index 0000000..47341be
--- /dev/null
@@ -0,0 +1,1036 @@
+/***********************************************************************
+ *
+ * Copyright (c) 2005 Freescale Semiconductor, Inc.
+ *
+ * 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
+ *
+ * Description:
+ *   Ethernet interface for Tundra TSI108 bridge chip
+ *
+ ***********************************************************************/
+
+#include <config.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
+       && defined(CONFIG_TSI108_ETH)
+
+#if !defined(CONFIG_TSI108_ETH_NUM_PORTS) || (CONFIG_TSI108_ETH_NUM_PORTS > 2)
+#error "CONFIG_TSI108_ETH_NUM_PORTS must be defined as 1 or 2"
+#endif
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/cache.h>
+
+#ifdef DEBUG
+#define TSI108_ETH_DEBUG 7
+#else
+#define TSI108_ETH_DEBUG 0
+#endif
+
+#if TSI108_ETH_DEBUG > 0
+#define debug_lev(lev, fmt, args...) \
+if (lev <= TSI108_ETH_DEBUG) \
+printf ("%s %d: " fmt, __FUNCTION__, __LINE__, ##args)
+#else
+#define debug_lev(lev, fmt, args...) do{}while(0)
+#endif
+
+#define RX_PRINT_ERRORS
+#define TX_PRINT_ERRORS
+
+#define ETH_BASE       (CFG_TSI108_CSR_BASE + 0x6000)
+
+#define ETH_PORT_OFFSET        0x400
+
+#define __REG32(base, offset) (*((volatile u32 *)((char *)(base) + (offset))))
+
+#define reg_MAC_CONFIG_1(base)         __REG32(base, 0x00000000)
+#define MAC_CONFIG_1_TX_ENABLE         (0x00000001)
+#define MAC_CONFIG_1_SYNC_TX_ENABLE    (0x00000002)
+#define MAC_CONFIG_1_RX_ENABLE         (0x00000004)
+#define MAC_CONFIG_1_SYNC_RX_ENABLE    (0x00000008)
+#define MAC_CONFIG_1_TX_FLOW_CONTROL   (0x00000010)
+#define MAC_CONFIG_1_RX_FLOW_CONTROL   (0x00000020)
+#define MAC_CONFIG_1_LOOP_BACK         (0x00000100)
+#define MAC_CONFIG_1_RESET_TX_FUNCTION (0x00010000)
+#define MAC_CONFIG_1_RESET_RX_FUNCTION (0x00020000)
+#define MAC_CONFIG_1_RESET_TX_MAC      (0x00040000)
+#define MAC_CONFIG_1_RESET_RX_MAC      (0x00080000)
+#define MAC_CONFIG_1_SIM_RESET         (0x40000000)
+#define MAC_CONFIG_1_SOFT_RESET                (0x80000000)
+
+#define reg_MAC_CONFIG_2(base)         __REG32(base, 0x00000004)
+#define MAC_CONFIG_2_FULL_DUPLEX       (0x00000001)
+#define MAC_CONFIG_2_CRC_ENABLE                (0x00000002)
+#define MAC_CONFIG_2_PAD_CRC           (0x00000004)
+#define MAC_CONFIG_2_LENGTH_CHECK      (0x00000010)
+#define MAC_CONFIG_2_HUGE_FRAME                (0x00000020)
+#define MAC_CONFIG_2_INTERFACE_MODE(val)       (((val) & 0x3) << 8)
+#define MAC_CONFIG_2_PREAMBLE_LENGTH(val)      (((val) & 0xf) << 12)
+#define INTERFACE_MODE_NIBBLE          1       /* 10/100 Mb/s MII) */
+#define INTERFACE_MODE_BYTE            2       /* 1000 Mb/s GMII/TBI */
+
+#define reg_MAXIMUM_FRAME_LENGTH(base)         __REG32(base, 0x00000010)
+
+#define reg_MII_MGMT_CONFIG(base)              __REG32(base, 0x00000020)
+#define MII_MGMT_CONFIG_MGMT_CLOCK_SELECT(val) ((val) & 0x7)
+#define MII_MGMT_CONFIG_NO_PREAMBLE            (0x00000010)
+#define MII_MGMT_CONFIG_SCAN_INCREMENT         (0x00000020)
+#define MII_MGMT_CONFIG_RESET_MGMT             (0x80000000)
+
+#define reg_MII_MGMT_COMMAND(base)             __REG32(base, 0x00000024)
+#define MII_MGMT_COMMAND_READ_CYCLE            (0x00000001)
+#define MII_MGMT_COMMAND_SCAN_CYCLE            (0x00000002)
+
+#define reg_MII_MGMT_ADDRESS(base)             __REG32(base, 0x00000028)
+#define reg_MII_MGMT_CONTROL(base)             __REG32(base, 0x0000002c)
+#define reg_MII_MGMT_STATUS(base)              __REG32(base, 0x00000030)
+
+#define reg_MII_MGMT_INDICATORS(base)          __REG32(base, 0x00000034)
+#define MII_MGMT_INDICATORS_BUSY               (0x00000001)
+#define MII_MGMT_INDICATORS_SCAN               (0x00000002)
+#define MII_MGMT_INDICATORS_NOT_VALID          (0x00000004)
+
+#define reg_INTERFACE_STATUS(base)             __REG32(base, 0x0000003c)
+#define INTERFACE_STATUS_LINK_FAIL             (0x00000008)
+#define INTERFACE_STATUS_EXCESS_DEFER          (0x00000200)
+
+#define reg_STATION_ADDRESS_1(base)            __REG32(base, 0x00000040)
+#define reg_STATION_ADDRESS_2(base)            __REG32(base, 0x00000044)
+
+#define reg_PORT_CONTROL(base)                 __REG32(base, 0x00000200)
+#define PORT_CONTROL_PRI               (0x00000001)
+#define PORT_CONTROL_BPT               (0x00010000)
+#define PORT_CONTROL_SPD               (0x00040000)
+#define PORT_CONTROL_RBC               (0x00080000)
+#define PORT_CONTROL_PRB               (0x00200000)
+#define PORT_CONTROL_DIS               (0x00400000)
+#define PORT_CONTROL_TBI               (0x00800000)
+#define PORT_CONTROL_STE               (0x10000000)
+#define PORT_CONTROL_ZOR               (0x20000000)
+#define PORT_CONTROL_CLR               (0x40000000)
+#define PORT_CONTROL_SRT               (0x80000000)
+
+#define reg_TX_CONFIG(base)            __REG32(base, 0x00000220)
+#define TX_CONFIG_START_Q              (0x00000003)
+#define TX_CONFIG_EHP                  (0x00400000)
+#define TX_CONFIG_CHP                  (0x00800000)
+#define TX_CONFIG_RST                  (0x80000000)
+
+#define reg_TX_CONTROL(base)           __REG32(base, 0x00000224)
+#define TX_CONTROL_GO                  (0x00008000)
+#define TX_CONTROL_MP                  (0x01000000)
+#define TX_CONTROL_EAI                 (0x20000000)
+#define TX_CONTROL_ABT                 (0x40000000)
+#define TX_CONTROL_EII                 (0x80000000)
+
+#define reg_TX_STATUS(base)            __REG32(base, 0x00000228)
+#define TX_STATUS_QUEUE_USABLE         (0x0000000f)
+#define TX_STATUS_CURR_Q               (0x00000300)
+#define TX_STATUS_ACT                  (0x00008000)
+#define TX_STATUS_QUEUE_IDLE           (0x000f0000)
+#define TX_STATUS_EOQ_PENDING          (0x0f000000)
+
+#define reg_TX_EXTENDED_STATUS(base)           __REG32(base, 0x0000022c)
+#define TX_EXTENDED_STATUS_END_OF_QUEUE_CONDITION              (0x0000000f)
+#define TX_EXTENDED_STATUS_END_OF_FRAME_CONDITION              (0x00000f00)
+#define TX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION      (0x000f0000)
+#define TX_EXTENDED_STATUS_ERROR_FLAG                          (0x0f000000)
+
+#define reg_TX_THRESHOLDS(base)                        __REG32(base, 0x00000230)
+
+#define reg_TX_DIAGNOSTIC_ADDR(base)           __REG32(base, 0x00000270)
+#define TX_DIAGNOSTIC_ADDR_INDEX               (0x0000007f)
+#define TX_DIAGNOSTIC_ADDR_DFR                 (0x40000000)
+#define TX_DIAGNOSTIC_ADDR_AI                  (0x80000000)
+
+#define reg_TX_DIAGNOSTIC_DATA(base)           __REG32(base, 0x00000274)
+
+#define reg_TX_ERROR_STATUS(base)              __REG32(base, 0x00000278)
+#define TX_ERROR_STATUS                                (0x00000278)
+#define TX_ERROR_STATUS_QUEUE_0_ERROR_RESPONSE (0x0000000f)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_0         (0x00000010)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_0         (0x00000020)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_0         (0x00000040)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_0         (0x00000080)
+#define TX_ERROR_STATUS_QUEUE_1_ERROR_RESPONSE (0x00000f00)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_1         (0x00001000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_1         (0x00002000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_1         (0x00004000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_1         (0x00008000)
+#define TX_ERROR_STATUS_QUEUE_2_ERROR_RESPONSE (0x000f0000)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_2         (0x00100000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_2         (0x00200000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_2         (0x00400000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_2         (0x00800000)
+#define TX_ERROR_STATUS_QUEUE_3_ERROR_RESPONSE (0x0f000000)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_3         (0x10000000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_3         (0x20000000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_3         (0x40000000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_3         (0x80000000)
+
+#define reg_TX_QUEUE_0_CONFIG(base)            __REG32(base, 0x00000280)
+#define TX_QUEUE_0_CONFIG_OCN_PORT             (0x0000003f)
+#define TX_QUEUE_0_CONFIG_BSWP                 (0x00000400)
+#define TX_QUEUE_0_CONFIG_WSWP                 (0x00000800)
+#define TX_QUEUE_0_CONFIG_AM                   (0x00004000)
+#define TX_QUEUE_0_CONFIG_GVI                  (0x00008000)
+#define TX_QUEUE_0_CONFIG_EEI                  (0x00010000)
+#define TX_QUEUE_0_CONFIG_ELI                  (0x00020000)
+#define TX_QUEUE_0_CONFIG_ENI                  (0x00040000)
+#define TX_QUEUE_0_CONFIG_ESI                  (0x00080000)
+#define TX_QUEUE_0_CONFIG_EDI                  (0x00100000)
+
+#define reg_TX_QUEUE_0_BUF_CONFIG(base)                __REG32(base, 0x00000284)
+#define TX_QUEUE_0_BUF_CONFIG_OCN_PORT         (0x0000003f)
+#define TX_QUEUE_0_BUF_CONFIG_BURST            (0x00000300)
+#define TX_QUEUE_0_BUF_CONFIG_BSWP             (0x00000400)
+#define TX_QUEUE_0_BUF_CONFIG_WSWP             (0x00000800)
+
+#define OCN_PORT_HLP                   0       /* HLP Interface */
+#define OCN_PORT_PCI_X                 1       /* PCI-X Interface */
+#define OCN_PORT_PROCESSOR_MASTER      2       /* Processor Interface (master) */
+#define OCN_PORT_PROCESSOR_SLAVE       3       /* Processor Interface (slave) */
+#define OCN_PORT_MEMORY                        4       /* Memory Controller */
+#define OCN_PORT_DMA                   5       /* DMA Controller */
+#define OCN_PORT_ETHERNET              6       /* Ethernet Controller */
+#define OCN_PORT_PRINT                 7       /* Print Engine Interface */
+
+#define reg_TX_QUEUE_0_PTR_LOW(base)           __REG32(base, 0x00000288)
+
+#define reg_TX_QUEUE_0_PTR_HIGH(base)          __REG32(base, 0x0000028c)
+#define TX_QUEUE_0_PTR_HIGH_VALID              (0x80000000)
+
+#define reg_RX_CONFIG(base)                    __REG32(base, 0x00000320)
+#define RX_CONFIG_DEF_Q                                (0x00000003)
+#define RX_CONFIG_EMF                          (0x00000100)
+#define RX_CONFIG_EUF                          (0x00000200)
+#define RX_CONFIG_BFE                          (0x00000400)
+#define RX_CONFIG_MFE                          (0x00000800)
+#define RX_CONFIG_UFE                          (0x00001000)
+#define RX_CONFIG_SE                           (0x00002000)
+#define RX_CONFIG_ABF                          (0x00200000)
+#define RX_CONFIG_APE                          (0x00400000)
+#define RX_CONFIG_CHP                          (0x00800000)
+#define RX_CONFIG_RST                          (0x80000000)
+
+#define reg_RX_CONTROL(base)                   __REG32(base, 0x00000324)
+#define GE_E0_RX_CONTROL_QUEUE_ENABLES         (0x0000000f)
+#define GE_E0_RX_CONTROL_GO                    (0x00008000)
+#define GE_E0_RX_CONTROL_EAI                   (0x20000000)
+#define GE_E0_RX_CONTROL_ABT                   (0x40000000)
+#define GE_E0_RX_CONTROL_EII                   (0x80000000)
+
+#define reg_RX_EXTENDED_STATUS(base)           __REG32(base, 0x0000032c)
+#define RX_EXTENDED_STATUS                     (0x0000032c)
+#define RX_EXTENDED_STATUS_EOQ                 (0x0000000f)
+#define RX_EXTENDED_STATUS_EOQ_0               (0x00000001)
+#define RX_EXTENDED_STATUS_EOF                 (0x00000f00)
+#define RX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION      (0x000f0000)
+#define RX_EXTENDED_STATUS_ERROR_FLAG                          (0x0f000000)
+
+#define reg_RX_THRESHOLDS(base)                        __REG32(base, 0x00000330)
+
+#define reg_RX_DIAGNOSTIC_ADDR(base)           __REG32(base, 0x00000370)
+#define RX_DIAGNOSTIC_ADDR_INDEX               (0x0000007f)
+#define RX_DIAGNOSTIC_ADDR_DFR                 (0x40000000)
+#define RX_DIAGNOSTIC_ADDR_AI                  (0x80000000)
+
+#define reg_RX_DIAGNOSTIC_DATA(base)           __REG32(base, 0x00000374)
+
+#define reg_RX_QUEUE_0_CONFIG(base)            __REG32(base, 0x00000380)
+#define RX_QUEUE_0_CONFIG_OCN_PORT             (0x0000003f)
+#define RX_QUEUE_0_CONFIG_BSWP                 (0x00000400)
+#define RX_QUEUE_0_CONFIG_WSWP                 (0x00000800)
+#define RX_QUEUE_0_CONFIG_AM                   (0x00004000)
+#define RX_QUEUE_0_CONFIG_EEI                  (0x00010000)
+#define RX_QUEUE_0_CONFIG_ELI                  (0x00020000)
+#define RX_QUEUE_0_CONFIG_ENI                  (0x00040000)
+#define RX_QUEUE_0_CONFIG_ESI                  (0x00080000)
+#define RX_QUEUE_0_CONFIG_EDI                  (0x00100000)
+
+#define reg_RX_QUEUE_0_BUF_CONFIG(base)                __REG32(base, 0x00000384)
+#define RX_QUEUE_0_BUF_CONFIG_OCN_PORT         (0x0000003f)
+#define RX_QUEUE_0_BUF_CONFIG_BURST            (0x00000300)
+#define RX_QUEUE_0_BUF_CONFIG_BSWP             (0x00000400)
+#define RX_QUEUE_0_BUF_CONFIG_WSWP             (0x00000800)
+
+#define reg_RX_QUEUE_0_PTR_LOW(base)           __REG32(base, 0x00000388)
+
+#define reg_RX_QUEUE_0_PTR_HIGH(base)          __REG32(base, 0x0000038c)
+#define RX_QUEUE_0_PTR_HIGH_VALID              (0x80000000)
+
+/*
+ *  PHY register definitions
+ */
+/* the first 15 PHY registers are standard. */
+#define PHY_CTRL_REG           0       /* Control Register */
+#define PHY_STATUS_REG         1       /* Status Regiser */
+#define PHY_ID1_REG            2       /* Phy Id Reg (word 1) */
+#define PHY_ID2_REG            3       /* Phy Id Reg (word 2) */
+#define PHY_AN_ADV_REG         4       /* Autoneg Advertisement */
+#define PHY_LP_ABILITY_REG     5       /* Link Partner Ability (Base Page) */
+#define PHY_AUTONEG_EXP_REG    6       /* Autoneg Expansion Reg */
+#define PHY_NEXT_PAGE_TX_REG   7       /* Next Page TX */
+#define PHY_LP_NEXT_PAGE_REG   8       /* Link Partner Next Page */
+#define PHY_1000T_CTRL_REG     9       /* 1000Base-T Control Reg */
+#define PHY_1000T_STATUS_REG   10      /* 1000Base-T Status Reg */
+#define PHY_EXT_STATUS_REG     11      /* Extended Status Reg */
+
+/*
+ * PHY Register bit masks.
+ */
+#define PHY_CTRL_RESET         (1 << 15)
+#define PHY_CTRL_LOOPBACK      (1 << 14)
+#define PHY_CTRL_SPEED0                (1 << 13)
+#define PHY_CTRL_AN_EN         (1 << 12)
+#define PHY_CTRL_PWR_DN                (1 << 11)
+#define PHY_CTRL_ISOLATE       (1 << 10)
+#define PHY_CTRL_RESTART_AN    (1 << 9)
+#define PHY_CTRL_FULL_DUPLEX   (1 << 8)
+#define PHY_CTRL_CT_EN         (1 << 7)
+#define PHY_CTRL_SPEED1                (1 << 6)
+
+#define PHY_STAT_100BASE_T4    (1 << 15)
+#define PHY_STAT_100BASE_X_FD  (1 << 14)
+#define PHY_STAT_100BASE_X_HD  (1 << 13)
+#define PHY_STAT_10BASE_T_FD   (1 << 12)
+#define PHY_STAT_10BASE_T_HD   (1 << 11)
+#define PHY_STAT_100BASE_T2_FD (1 << 10)
+#define PHY_STAT_100BASE_T2_HD (1 << 9)
+#define PHY_STAT_EXT_STAT      (1 << 8)
+#define PHY_STAT_RESERVED      (1 << 7)
+#define PHY_STAT_MFPS          (1 << 6)        /* Management Frames Preamble Suppression */
+#define PHY_STAT_AN_COMPLETE   (1 << 5)
+#define PHY_STAT_REM_FAULT     (1 << 4)
+#define PHY_STAT_AN_CAP                (1 << 3)
+#define PHY_STAT_LINK_UP       (1 << 2)
+#define PHY_STAT_JABBER                (1 << 1)
+#define PHY_STAT_EXT_CAP       (1 << 0)
+
+#define TBI_CONTROL_2                                  0x11
+#define TBI_CONTROL_2_ENABLE_COMMA_DETECT              0x0001
+#define TBI_CONTROL_2_ENABLE_WRAP                      0x0002
+#define TBI_CONTROL_2_G_MII_MODE                       0x0010
+#define TBI_CONTROL_2_RECEIVE_CLOCK_SELECT             0x0020
+#define TBI_CONTROL_2_AUTO_NEGOTIATION_SENSE           0x0100
+#define TBI_CONTROL_2_DISABLE_TRANSMIT_RUNNING_DISPARITY       0x1000
+#define TBI_CONTROL_2_DISABLE_RECEIVE_RUNNING_DISPARITY                0x2000
+#define TBI_CONTROL_2_SHORTCUT_LINK_TIMER                      0x4000
+#define TBI_CONTROL_2_SOFT_RESET                               0x8000
+
+/* marvel specific */
+#define MV1111_EXT_CTRL1_REG   16      /* PHY Specific Control Reg */
+#define MV1111_SPEC_STAT_REG   17      /* PHY Specific Status Reg */
+#define MV1111_EXT_CTRL2_REG   20      /* Extended PHY Specific Control Reg */
+
+/*
+ * MARVELL 88E1111 PHY register bit masks
+ */
+/* PHY Specific Status Register (MV1111_EXT_CTRL1_REG) */
+
+#define SPEC_STAT_SPEED_MASK   (3 << 14)
+#define SPEC_STAT_FULL_DUP     (1 << 13)
+#define SPEC_STAT_PAGE_RCVD    (1 << 12)
+#define SPEC_STAT_RESOLVED     (1 << 11)       /* Speed and Duplex Resolved */
+#define SPEC_STAT_LINK_UP      (1 << 10)
+#define SPEC_STAT_CABLE_LEN_MASK       (7 << 7)/* Cable Length (100/1000 modes only) */
+#define SPEC_STAT_MDIX         (1 << 6)
+#define SPEC_STAT_POLARITY     (1 << 1)
+#define SPEC_STAT_JABBER       (1 << 0)
+
+#define SPEED_1000             (2 << 14)
+#define SPEED_100              (1 << 14)
+#define SPEED_10               (0 << 14)
+
+#define TBI_ADDR       0x1E    /* Ten Bit Interface address */
+
+/* negotiated link parameters */
+#define LINK_SPEED_UNKNOWN     0
+#define LINK_SPEED_10          1
+#define LINK_SPEED_100         2
+#define LINK_SPEED_1000                3
+
+#define LINK_DUPLEX_UNKNOWN    0
+#define LINK_DUPLEX_HALF       1
+#define LINK_DUPLEX_FULL       2
+
+static unsigned int phy_address[] = { 8, 9 };
+
+#define vuint32 volatile u32
+
+/* TX/RX buffer descriptors. MUST be cache line aligned in memory. (32 byte)
+ * This structure is accessed by the ethernet DMA engine which means it
+ * MUST be in LITTLE ENDIAN format */
+struct dma_descriptor {
+       vuint32 start_addr0;    /* buffer address, least significant bytes. */
+       vuint32 start_addr1;    /* buffer address, most significant bytes. */
+       vuint32 next_descr_addr0;/* next descriptor address, least significant bytes.  Must be 64-bit aligned. */
+       vuint32 next_descr_addr1;/* next descriptor address, most significant bytes. */
+       vuint32 vlan_byte_count;/* VLAN tag(top 2 bytes) and byte countt (bottom 2 bytes). */
+       vuint32 config_status;  /* Configuration/Status. */
+       vuint32 reserved1;      /* reserved to make the descriptor cache line aligned. */
+       vuint32 reserved2;      /* reserved to make the descriptor cache line aligned. */
+};
+
+/* last next descriptor address flag */
+#define DMA_DESCR_LAST         (1 << 31)
+
+/* TX DMA descriptor config status bits */
+#define DMA_DESCR_TX_EOF       (1 <<  0)       /* end of frame */
+#define DMA_DESCR_TX_SOF       (1 <<  1)       /* start of frame */
+#define DMA_DESCR_TX_PFVLAN    (1 <<  2)
+#define DMA_DESCR_TX_HUGE      (1 <<  3)
+#define DMA_DESCR_TX_PAD       (1 <<  4)
+#define DMA_DESCR_TX_CRC       (1 <<  5)
+#define DMA_DESCR_TX_DESCR_INT (1 << 14)
+#define DMA_DESCR_TX_RETRY_COUNT       0x000F0000
+#define DMA_DESCR_TX_ONE_COLLISION     (1 << 20)
+#define DMA_DESCR_TX_LATE_COLLISION    (1 << 24)
+#define DMA_DESCR_TX_UNDERRUN          (1 << 25)
+#define DMA_DESCR_TX_RETRY_LIMIT       (1 << 26)
+#define DMA_DESCR_TX_OK                        (1 << 30)
+#define DMA_DESCR_TX_OWNER             (1 << 31)
+
+/* RX DMA descriptor status bits */
+#define DMA_DESCR_RX_EOF               (1 <<  0)
+#define DMA_DESCR_RX_SOF               (1 <<  1)
+#define DMA_DESCR_RX_VTF               (1 <<  2)
+#define DMA_DESCR_RX_FRAME_IS_TYPE     (1 <<  3)
+#define DMA_DESCR_RX_SHORT_FRAME       (1 <<  4)
+#define DMA_DESCR_RX_HASH_MATCH                (1 <<  7)
+#define DMA_DESCR_RX_BAD_FRAME         (1 <<  8)
+#define DMA_DESCR_RX_OVERRUN           (1 <<  9)
+#define DMA_DESCR_RX_MAX_FRAME_LEN     (1 << 11)
+#define DMA_DESCR_RX_CRC_ERROR         (1 << 12)
+#define DMA_DESCR_RX_DESCR_INT         (1 << 13)
+#define DMA_DESCR_RX_OWNER             (1 << 15)
+
+#define RX_BUFFER_SIZE PKTSIZE
+#define NUM_RX_DESC    PKTBUFSRX
+
+static struct dma_descriptor tx_descriptor __attribute__ ((aligned(32)));
+
+static struct dma_descriptor rx_descr_array[NUM_RX_DESC]
+       __attribute__ ((aligned(32)));
+
+static struct dma_descriptor *rx_descr_current;
+
+static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis);
+static int tsi108_eth_send (struct eth_device *dev,
+                          volatile void *packet, int length);
+static int tsi108_eth_recv (struct eth_device *dev);
+static void tsi108_eth_halt (struct eth_device *dev);
+static unsigned int read_phy (unsigned int base,
+                            unsigned int phy_addr, unsigned int phy_reg);
+static void write_phy (unsigned int base,
+                     unsigned int phy_addr,
+                     unsigned int phy_reg, unsigned int phy_data);
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print phy debug infomation
+ */
+static void dump_phy_regs (unsigned int phy_addr)
+{
+       int i;
+
+       printf ("PHY %d registers\n", phy_addr);
+       for (i = 0; i <= 30; i++) {
+               printf ("%2d  0x%04x\n", i, read_phy (ETH_BASE, phy_addr, i));
+       }
+       printf ("\n");
+
+}
+#else
+#define dump_phy_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void tx_diag_regs (unsigned int base)
+{
+       int i;
+       unsigned long dummy;
+
+       printf ("TX diagnostics registers\n");
+       reg_TX_DIAGNOSTIC_ADDR(base) = 0x00 | TX_DIAGNOSTIC_ADDR_AI;
+       udelay (1000);
+       dummy = reg_TX_DIAGNOSTIC_DATA(base);
+       for (i = 0x00; i <= 0x05; i++) {
+               udelay (1000);
+               printf ("0x%02x  0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base));
+       }
+       reg_TX_DIAGNOSTIC_ADDR(base) = 0x40 | TX_DIAGNOSTIC_ADDR_AI;
+       udelay (1000);
+       dummy = reg_TX_DIAGNOSTIC_DATA(base);
+       for (i = 0x40; i <= 0x47; i++) {
+               udelay (1000);
+               printf ("0x%02x  0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base));
+       }
+       printf ("\n");
+
+}
+#else
+#define tx_diag_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void rx_diag_regs (unsigned int base)
+{
+       int i;
+       unsigned long dummy;
+
+       printf ("RX diagnostics registers\n");
+       reg_RX_DIAGNOSTIC_ADDR(base) = 0x00 | RX_DIAGNOSTIC_ADDR_AI;
+       udelay (1000);
+       dummy = reg_RX_DIAGNOSTIC_DATA(base);
+       for (i = 0x00; i <= 0x05; i++) {
+               udelay (1000);
+               printf ("0x%02x  0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base));
+       }
+       reg_RX_DIAGNOSTIC_ADDR(base) = 0x40 | RX_DIAGNOSTIC_ADDR_AI;
+       udelay (1000);
+       dummy = reg_RX_DIAGNOSTIC_DATA(base);
+       for (i = 0x08; i <= 0x0a; i++) {
+               udelay (1000);
+               printf ("0x%02x  0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base));
+       }
+       printf ("\n");
+
+}
+#else
+#define rx_diag_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void debug_mii_regs (unsigned int base)
+{
+       printf ("MII_MGMT_CONFIG     0x%08x\n", reg_MII_MGMT_CONFIG(base));
+       printf ("MII_MGMT_COMMAND    0x%08x\n", reg_MII_MGMT_COMMAND(base));
+       printf ("MII_MGMT_ADDRESS    0x%08x\n", reg_MII_MGMT_ADDRESS(base));
+       printf ("MII_MGMT_CONTROL    0x%08x\n", reg_MII_MGMT_CONTROL(base));
+       printf ("MII_MGMT_STATUS     0x%08x\n", reg_MII_MGMT_STATUS(base));
+       printf ("MII_MGMT_INDICATORS 0x%08x\n", reg_MII_MGMT_INDICATORS(base));
+       printf ("\n");
+
+}
+#else
+#define debug_mii_regs(base) do{}while(0)
+#endif
+
+/*
+ * Wait until the phy bus is non-busy
+ */
+static void phy_wait (unsigned int base, unsigned int condition)
+{
+       int timeout;
+
+       timeout = 0;
+       while (reg_MII_MGMT_INDICATORS(base) & condition) {
+               udelay (10);
+               if (++timeout > 10000) {
+                       printf ("ERROR: timeout waiting for phy bus (%d)\n",
+                              condition);
+                       break;
+               }
+       }
+}
+
+/*
+ * read phy register
+ */
+static unsigned int read_phy (unsigned int base,
+                            unsigned int phy_addr, unsigned int phy_reg)
+{
+       unsigned int value;
+
+       phy_wait (base, MII_MGMT_INDICATORS_BUSY);
+
+       reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg;
+
+       /* Ensure that the Read Cycle bit is cleared prior to next read cycle */
+       reg_MII_MGMT_COMMAND(base) = 0;
+
+       /* start the read */
+       reg_MII_MGMT_COMMAND(base) = MII_MGMT_COMMAND_READ_CYCLE;
+
+       /* wait for the read to complete */
+       phy_wait (base,
+                MII_MGMT_INDICATORS_NOT_VALID | MII_MGMT_INDICATORS_BUSY);
+
+       value = reg_MII_MGMT_STATUS(base);
+
+       reg_MII_MGMT_COMMAND(base) = 0;
+
+       return value;
+}
+
+/*
+ * write phy register
+ */
+static void write_phy (unsigned int base,
+                     unsigned int phy_addr,
+                     unsigned int phy_reg, unsigned int phy_data)
+{
+       phy_wait (base, MII_MGMT_INDICATORS_BUSY);
+
+       reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg;
+
+       /* Ensure that the Read Cycle bit is cleared prior to next cycle */
+       reg_MII_MGMT_COMMAND(base) = 0;
+
+       /* start the write */
+       reg_MII_MGMT_CONTROL(base) = phy_data;
+}
+
+/*
+ * configure the marvell 88e1111 phy
+ */
+static int marvell_88e_phy_config (struct eth_device *dev, int *speed,
+                                 int *duplex)
+{
+       unsigned long base;
+       unsigned long phy_addr;
+       unsigned int phy_status;
+       unsigned int phy_spec_status;
+       int timeout;
+       int phy_speed;
+       int phy_duplex;
+       unsigned int value;
+
+       phy_speed = LINK_SPEED_UNKNOWN;
+       phy_duplex = LINK_DUPLEX_UNKNOWN;
+
+       base = dev->iobase;
+       phy_addr = (unsigned long)dev->priv;
+
+       /* Take the PHY out of reset. */
+       write_phy (ETH_BASE, phy_addr, PHY_CTRL_REG, PHY_CTRL_RESET);
+
+       /* Wait for the reset process to complete. */
+       udelay (10);
+       timeout = 0;
+       while ((phy_status =
+               read_phy (ETH_BASE, phy_addr, PHY_CTRL_REG)) & PHY_CTRL_RESET) {
+               udelay (10);
+               if (++timeout > 10000) {
+                       printf ("ERROR: timeout waiting for phy reset\n");
+                       break;
+               }
+       }
+
+       /* TBI Configuration. */
+       write_phy (base, TBI_ADDR, TBI_CONTROL_2, TBI_CONTROL_2_G_MII_MODE |
+                 TBI_CONTROL_2_RECEIVE_CLOCK_SELECT);
+       /* Wait for the link to be established. */
+       timeout = 0;
+       do {
+               udelay (20000);
+               phy_status = read_phy (ETH_BASE, phy_addr, PHY_STATUS_REG);
+               if (++timeout > 100) {
+                       debug_lev(1, "ERROR: unable to establish link!!!\n");
+                       break;
+               }
+       } while ((phy_status & PHY_STAT_LINK_UP) == 0);
+
+       if ((phy_status & PHY_STAT_LINK_UP) == 0)
+               return 0;
+
+       value = 0;
+       phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG);
+       if (phy_spec_status & SPEC_STAT_RESOLVED) {
+               switch (phy_spec_status & SPEC_STAT_SPEED_MASK) {
+               case SPEED_1000:
+                       phy_speed = LINK_SPEED_1000;
+                       value |= PHY_CTRL_SPEED1;
+                       break;
+               case SPEED_100:
+                       phy_speed = LINK_SPEED_100;
+                       value |= PHY_CTRL_SPEED0;
+                       break;
+               case SPEED_10:
+                       phy_speed = LINK_SPEED_10;
+                       break;
+               }
+               if (phy_spec_status & SPEC_STAT_FULL_DUP) {
+                       phy_duplex = LINK_DUPLEX_FULL;
+                       value |= PHY_CTRL_FULL_DUPLEX;
+               } else
+                       phy_duplex = LINK_DUPLEX_HALF;
+       }
+       /* set TBI speed */
+       write_phy (base, TBI_ADDR, PHY_CTRL_REG, value);
+       write_phy (base, TBI_ADDR, PHY_AN_ADV_REG, 0x0060);
+
+#if TSI108_ETH_DEBUG > 0
+       printf ("%s link is up", dev->name);
+       phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG);
+       if (phy_spec_status & SPEC_STAT_RESOLVED) {
+               switch (phy_speed) {
+               case LINK_SPEED_1000:
+                       printf (", 1000 Mbps");
+                       break;
+               case LINK_SPEED_100:
+                       printf (", 100 Mbps");
+                       break;
+               case LINK_SPEED_10:
+                       printf (", 10 Mbps");
+                       break;
+               }
+               if (phy_duplex == LINK_DUPLEX_FULL)
+                       printf (", Full duplex");
+               else
+                       printf (", Half duplex");
+       }
+       printf ("\n");
+#endif
+
+       dump_phy_regs (TBI_ADDR);
+       if (speed)
+               *speed = phy_speed;
+       if (duplex)
+               *duplex = phy_duplex;
+
+       return 1;
+}
+
+/*
+ * External interface
+ *
+ * register the tsi108 ethernet controllers with the multi-ethernet system
+ */
+int tsi108_eth_initialize (bd_t * bis)
+{
+       struct eth_device *dev;
+       int index;
+
+       for (index = 0; index < CONFIG_TSI108_ETH_NUM_PORTS; index++) {
+               dev = (struct eth_device *)malloc(sizeof(struct eth_device));
+
+               sprintf (dev->name, "TSI108_eth%d", index);
+
+               dev->iobase = ETH_BASE + (index * ETH_PORT_OFFSET);
+               dev->priv = (void *)(phy_address[index]);
+               dev->init = tsi108_eth_probe;
+               dev->halt = tsi108_eth_halt;
+               dev->send = tsi108_eth_send;
+               dev->recv = tsi108_eth_recv;
+
+               eth_register(dev);
+       }
+       return index;
+}
+
+/*
+ * probe for and initialize a single ethernet interface
+ */
+static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis)
+{
+       unsigned long base;
+       unsigned long value;
+       int index;
+       struct dma_descriptor *tx_descr;
+       struct dma_descriptor *rx_descr;
+       int speed;
+       int duplex;
+
+       base = dev->iobase;
+
+       reg_PORT_CONTROL(base) = PORT_CONTROL_STE | PORT_CONTROL_BPT;
+
+       /* Bring DMA/FIFO out of reset. */
+       reg_TX_CONFIG(base) = 0x00000000;
+       reg_RX_CONFIG(base) = 0x00000000;
+
+       reg_TX_THRESHOLDS(base) = (192 << 16) | 192;
+       reg_RX_THRESHOLDS(base) = (192 << 16) | 112;
+
+       /* Bring MAC out of reset. */
+       reg_MAC_CONFIG_1(base) = 0x00000000;
+
+       /* DMA MAC configuration. */
+       reg_MAC_CONFIG_1(base) =
+           MAC_CONFIG_1_RX_ENABLE | MAC_CONFIG_1_TX_ENABLE;
+
+       reg_MII_MGMT_CONFIG(base) = MII_MGMT_CONFIG_NO_PREAMBLE;
+       reg_MAXIMUM_FRAME_LENGTH(base) = RX_BUFFER_SIZE;
+
+       /* Note: Early tsi108 manual did not have correct byte order
+        * for the station address.*/
+       reg_STATION_ADDRESS_1(base) = (dev->enetaddr[5] << 24) |
+           (dev->enetaddr[4] << 16) |
+           (dev->enetaddr[3] << 8) | (dev->enetaddr[2] << 0);
+
+       reg_STATION_ADDRESS_2(base) = (dev->enetaddr[1] << 24) |
+           (dev->enetaddr[0] << 16);
+
+       if (marvell_88e_phy_config(dev, &speed, &duplex) == 0)
+               return 0;
+
+       value =
+           MAC_CONFIG_2_PREAMBLE_LENGTH(7) | MAC_CONFIG_2_PAD_CRC |
+           MAC_CONFIG_2_CRC_ENABLE;
+       if (speed == LINK_SPEED_1000)
+               value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_BYTE);
+       else {
+               value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_NIBBLE);
+               reg_PORT_CONTROL(base) |= PORT_CONTROL_SPD;
+       }
+       if (duplex == LINK_DUPLEX_FULL) {
+               value |= MAC_CONFIG_2_FULL_DUPLEX;
+               reg_PORT_CONTROL(base) &= ~PORT_CONTROL_BPT;
+       } else
+               reg_PORT_CONTROL(base) |= PORT_CONTROL_BPT;
+       reg_MAC_CONFIG_2(base) = value;
+
+       reg_RX_CONFIG(base) = RX_CONFIG_SE;
+       reg_RX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;
+       reg_RX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;
+
+       /* initialize the RX DMA descriptors */
+       rx_descr = &rx_descr_array[0];
+       rx_descr_current = rx_descr;
+       for (index = 0; index < NUM_RX_DESC; index++) {
+               /* make sure the receive buffers are not in cache */
+               invalidate_dcache_range((unsigned long)NetRxPackets[index],
+                                       (unsigned long)NetRxPackets[index] +
+                                       RX_BUFFER_SIZE);
+               rx_descr->start_addr0 =
+                   cpu_to_le32((vuint32) NetRxPackets[index]);
+               rx_descr->start_addr1 = 0;
+               rx_descr->next_descr_addr0 =
+                   cpu_to_le32((vuint32) (rx_descr + 1));
+               rx_descr->next_descr_addr1 = 0;
+               rx_descr->vlan_byte_count = 0;
+               rx_descr->config_status = cpu_to_le32((RX_BUFFER_SIZE << 16) |
+                                                     DMA_DESCR_RX_OWNER);
+               rx_descr++;
+       }
+       rx_descr--;
+       rx_descr->next_descr_addr0 = 0;
+       rx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+       /* Push the descriptors to RAM so the ethernet DMA can see them */
+       invalidate_dcache_range((unsigned long)rx_descr_array,
+                               (unsigned long)rx_descr_array +
+                               sizeof(rx_descr_array));
+
+       /* enable RX queue */
+       reg_RX_CONTROL(base) = TX_CONTROL_GO | 0x01;
+       reg_RX_QUEUE_0_PTR_LOW(base) = (u32) rx_descr_current;
+       /* enable receive DMA */
+       reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID;
+
+       reg_TX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;
+       reg_TX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;
+
+       /* initialize the TX DMA descriptor */
+       tx_descr = &tx_descriptor;
+
+       tx_descr->start_addr0 = 0;
+       tx_descr->start_addr1 = 0;
+       tx_descr->next_descr_addr0 = 0;
+       tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+       tx_descr->vlan_byte_count = 0;
+       tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OK |
+                                             DMA_DESCR_TX_SOF |
+                                             DMA_DESCR_TX_EOF);
+       /* enable TX queue */
+       reg_TX_CONTROL(base) = TX_CONTROL_GO | 0x01;
+
+       return 1;
+}
+
+/*
+ * send a packet
+ */
+static int tsi108_eth_send (struct eth_device *dev,
+                          volatile void *packet, int length)
+{
+       unsigned long base;
+       int timeout;
+       struct dma_descriptor *tx_descr;
+       unsigned long status;
+
+       base = dev->iobase;
+       tx_descr = &tx_descriptor;
+
+       /* Wait until the last packet has been transmitted. */
+       timeout = 0;
+       do {
+               /* make sure we see the changes made by the DMA engine */
+               invalidate_dcache_range((unsigned long)tx_descr,
+                                       (unsigned long)tx_descr +
+                                       sizeof(struct dma_descriptor));
+
+               if (timeout != 0)
+                       udelay (15);
+               if (++timeout > 10000) {
+                       tx_diag_regs(base);
+                       debug_lev(1,
+                                 "ERROR: timeout waiting for last transmit packet to be sent\n");
+                       return 0;
+               }
+       } while (tx_descr->config_status & cpu_to_le32(DMA_DESCR_TX_OWNER));
+
+       status = le32_to_cpu(tx_descr->config_status);
+       if ((status & DMA_DESCR_TX_OK) == 0) {
+#ifdef TX_PRINT_ERRORS
+               printf ("TX packet error: 0x%08x\n    %s%s%s%s\n", status,
+                      status & DMA_DESCR_TX_OK ? "tx error, " : "",
+                      status & DMA_DESCR_TX_RETRY_LIMIT ?
+                      "retry limit reached, " : "",
+                      status & DMA_DESCR_TX_UNDERRUN ? "underrun, " : "",
+                      status & DMA_DESCR_TX_LATE_COLLISION ? "late collision, "
+                      : "");
+#endif
+       }
+
+       debug_lev (9, "sending packet %d\n", length);
+       tx_descr->start_addr0 = cpu_to_le32((vuint32) packet);
+       tx_descr->start_addr1 = 0;
+       tx_descr->next_descr_addr0 = 0;
+       tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+       tx_descr->vlan_byte_count = cpu_to_le32(length);
+       tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OWNER |
+                                             DMA_DESCR_TX_CRC |
+                                             DMA_DESCR_TX_PAD |
+                                             DMA_DESCR_TX_SOF |
+                                             DMA_DESCR_TX_EOF);
+
+       invalidate_dcache_range((unsigned long)tx_descr,
+                               (unsigned long)tx_descr +
+                               sizeof(struct dma_descriptor));
+
+       invalidate_dcache_range((unsigned long)packet,
+                               (unsigned long)packet + length);
+
+       reg_TX_QUEUE_0_PTR_LOW(base) = (u32) tx_descr;
+       reg_TX_QUEUE_0_PTR_HIGH(base) = TX_QUEUE_0_PTR_HIGH_VALID;
+
+       return length;
+}
+
+/*
+ * Check for received packets and send them up the protocal stack
+ */
+static int tsi108_eth_recv (struct eth_device *dev)
+{
+       struct dma_descriptor *rx_descr;
+       unsigned long base;
+       int length = 0;
+       unsigned long status;
+       volatile uchar *buffer;
+
+       base = dev->iobase;
+
+       /* make sure we see the changes made by the DMA engine */
+       invalidate_dcache_range ((unsigned long)rx_descr_array,
+                               (unsigned long)rx_descr_array +
+                               sizeof(rx_descr_array));
+
+       /* process all of the received packets */
+       rx_descr = rx_descr_current;
+       while ((rx_descr->config_status & cpu_to_le32(DMA_DESCR_RX_OWNER)) == 0) {
+               /* check for error */
+               status = le32_to_cpu(rx_descr->config_status);
+               if (status & DMA_DESCR_RX_BAD_FRAME) {
+#ifdef RX_PRINT_ERRORS
+                       printf ("RX packet error: 0x%08x\n    %s%s%s%s%s%s\n",
+                              status,
+                              status & DMA_DESCR_RX_FRAME_IS_TYPE ? "too big, "
+                              : "",
+                              status & DMA_DESCR_RX_SHORT_FRAME ? "too short, "
+                              : "",
+                              status & DMA_DESCR_RX_BAD_FRAME ? "bad frame, " :
+                              "",
+                              status & DMA_DESCR_RX_OVERRUN ? "overrun, " : "",
+                              status & DMA_DESCR_RX_MAX_FRAME_LEN ?
+                              "max length, " : "",
+                              status & DMA_DESCR_RX_CRC_ERROR ? "CRC error, " :
+                              "");
+#endif
+               } else {
+                       length =
+                           le32_to_cpu(rx_descr->vlan_byte_count) & 0xFFFF;
+
+                       /*** process packet ***/
+                       buffer =
+                           (volatile uchar
+                            *)(le32_to_cpu (rx_descr->start_addr0));
+                       NetReceive (buffer, length);
+
+                       invalidate_dcache_range ((unsigned long)buffer,
+                                               (unsigned long)buffer +
+                                               RX_BUFFER_SIZE);
+               }
+               /* Give this buffer back to the DMA engine */
+               rx_descr->vlan_byte_count = 0;
+               rx_descr->config_status = cpu_to_le32 ((RX_BUFFER_SIZE << 16) |
+                                                     DMA_DESCR_RX_OWNER);
+               /* move descriptor pointer forward */
+               rx_descr =
+                   (struct dma_descriptor
+                    *)(le32_to_cpu (rx_descr->next_descr_addr0));
+               if (rx_descr == 0)
+                       rx_descr = &rx_descr_array[0];
+       }
+       /* remember where we are for next time */
+       rx_descr_current = rx_descr;
+
+       /* If the DMA engine has reached the end of the queue
+        * start over at the begining */
+       if (reg_RX_EXTENDED_STATUS(base) & RX_EXTENDED_STATUS_EOQ_0) {
+
+               reg_RX_EXTENDED_STATUS(base) = RX_EXTENDED_STATUS_EOQ_0;
+               reg_RX_QUEUE_0_PTR_LOW(base) = (u32) & rx_descr_array[0];
+               reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID;
+       }
+
+       return length;
+}
+
+/*
+ * disable an ethernet interface
+ */
+static void tsi108_eth_halt (struct eth_device *dev)
+{
+       unsigned long base;
+
+       base = dev->iobase;
+
+       /* Put DMA/FIFO into reset state. */
+       reg_TX_CONFIG(base) = TX_CONFIG_RST;
+       reg_RX_CONFIG(base) = RX_CONFIG_RST;
+
+       /* Put MAC into reset state. */
+       reg_MAC_CONFIG_1(base) = MAC_CONFIG_1_SOFT_RESET;
+}
+
+#endif
diff --git a/drivers/tsi108_i2c.c b/drivers/tsi108_i2c.c
new file mode 100644 (file)
index 0000000..c100cb8
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * (C) Copyright 2004 Tundra Semiconductor Corp.
+ * Author: Alex Bounine
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+#include <common.h>
+
+#ifdef CONFIG_TSI108_I2C
+#include <tsi108.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_I2C)
+
+#define I2C_DELAY      100000
+#undef  DEBUG_I2C
+
+#ifdef DEBUG_I2C
+#define DPRINT(x) printf (x)
+#else
+#define DPRINT(x)
+#endif
+
+/* All functions assume that Tsi108 I2C block is the only master on the bus */
+/* I2C read helper function */
+
+static int i2c_read_byte (
+               uint i2c_chan,  /* I2C channel number: 0 - main, 1 - SDC SPD */
+               uchar chip_addr,/* I2C device address on the bus */
+               uint byte_addr, /* Byte address within I2C device */
+               uchar * buffer  /* pointer to data buffer */
+               )
+{
+       u32 temp;
+       u32 to_count = I2C_DELAY;
+       u32 op_status = TSI108_I2C_TIMEOUT_ERR;
+       u32 chan_offset = TSI108_I2C_OFFSET;
+
+       DPRINT (("I2C read_byte() %d 0x%02x 0x%02x\n",
+               i2c_chan, chip_addr, byte_addr));
+
+       if (0 != i2c_chan)
+               chan_offset = TSI108_I2C_SDRAM_OFFSET;
+
+       /* Check if I2C operation is in progress */
+       temp = *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2);
+
+       if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS |
+                         I2C_CNTRL2_START))) {
+               /* Set device address and operation (read = 0) */
+               temp = (byte_addr << 16) | ((chip_addr & 0x07) << 8) |
+                   ((chip_addr >> 3) & 0x0F);
+               *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL1) =
+                   temp;
+
+               /* Issue the read command
+                * (at this moment all other parameters are 0
+                * (size = 1 byte, lane = 0)
+                */
+
+               *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2) =
+                   (I2C_CNTRL2_START);
+
+               /* Wait until operation completed */
+               do {
+                       /* Read I2C operation status */
+                       temp =
+                           *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset +
+                                     I2C_CNTRL2);
+
+                       if (0 ==
+                           (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_START)))
+                       {
+                               if (0 ==
+                                   (temp &
+                                    (I2C_CNTRL2_I2C_CFGERR |
+                                     I2C_CNTRL2_I2C_TO_ERR))
+                                   ) {
+                                       op_status = TSI108_I2C_SUCCESS;
+
+                                       temp = *(u32 *) (CFG_TSI108_CSR_BASE +
+                                                        chan_offset +
+                                                        I2C_RD_DATA);
+
+                                       *buffer = (u8) (temp & 0xFF);
+                               } else {
+                                       /* report HW error */
+                                       op_status = TSI108_I2C_IF_ERROR;
+
+                                       DPRINT (("I2C HW error reported: 0x%02x\n", temp));
+                               }
+
+                               break;
+                       }
+               } while (to_count--);
+       } else {
+               op_status = TSI108_I2C_IF_BUSY;
+
+               DPRINT (("I2C Transaction start failed: 0x%02x\n", temp));
+       }
+
+       DPRINT (("I2C read_byte() status: 0x%02x\n", op_status));
+       return op_status;
+}
+
+/*
+ * I2C Read interface as defined in "include/i2c.h" :
+ *   chip_addr: I2C chip address, range 0..127
+ *                  (to read from SPD channel EEPROM use (0xD0 ... 0xD7)
+ *              NOTE: The bit 7 in the chip_addr serves as a channel select.
+ *              This hack is for enabling "isdram" command on Tsi108 boards
+ *              without changes to common code. Used for I2C reads only.
+ *   byte_addr: Memory or register address within the chip
+ *   alen:      Number of bytes to use for addr (typically 1, 2 for larger
+ *              memories, 0 for register type devices with only one
+ *              register)
+ *   buffer:    Pointer to destination buffer for data to be read
+ *   len:       How many bytes to read
+ *
+ *   Returns: 0 on success, not 0 on failure
+ */
+
+int i2c_read (uchar chip_addr, uint byte_addr, int alen,
+               uchar * buffer, int len)
+{
+       u32 op_status = TSI108_I2C_PARAM_ERR;
+       u32 i2c_if = 0;
+
+       /* Hack to support second (SPD) I2C controller (SPD EEPROM read only).*/
+       if (0xD0 == (chip_addr & ~0x07)) {
+               i2c_if = 1;
+               chip_addr &= 0x7F;
+       }
+       /* Check for valid I2C address */
+       if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen * 8))) {
+               while (len--) {
+                       op_status =
+                           i2c_read_byte(i2c_if, chip_addr, byte_addr++,
+                                         buffer++);
+
+                       if (TSI108_I2C_SUCCESS != op_status) {
+                               DPRINT (("I2C read_byte() failed: 0x%02x (%d left)\n", op_status, len));
+
+                               break;
+                       }
+               }
+       }
+
+       DPRINT (("I2C read() status: 0x%02x\n", op_status));
+       return op_status;
+}
+
+/* I2C write helper function */
+
+static int i2c_write_byte (uchar chip_addr,/* I2C device address on the bus */
+                         uint byte_addr, /* Byte address within I2C device */
+                         uchar * buffer  /*  pointer to data buffer */
+                         )
+{
+       u32 temp;
+       u32 to_count = I2C_DELAY;
+       u32 op_status = TSI108_I2C_TIMEOUT_ERR;
+
+       /* Check if I2C operation is in progress */
+       temp = *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + I2C_CNTRL2);
+
+       if (0 ==
+           (temp &
+            (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START)))
+       {
+               /* Place data into the I2C Tx Register */
+               *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
+                         I2C_TX_DATA) = (u32) * buffer;
+
+               /* Set device address and operation  */
+               temp =
+                   I2C_CNTRL1_I2CWRITE | (byte_addr << 16) |
+                   ((chip_addr & 0x07) << 8) | ((chip_addr >> 3) & 0x0F);
+               *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
+                         I2C_CNTRL1) = temp;
+
+               /* Issue the write command (at this moment all other parameters
+                * are 0 (size = 1 byte, lane = 0)
+                */
+               
+               *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
+                         I2C_CNTRL2) = (I2C_CNTRL2_START);
+
+               op_status = TSI108_I2C_TIMEOUT_ERR;
+
+               /* Wait until operation completed */
+               do {
+                       /* Read I2C operation status */
+                       temp =
+                           *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
+                                     I2C_CNTRL2);
+
+                       if (0 ==
+                           (temp & (I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START)))
+                       {
+                               if (0 ==
+                                   (temp &
+                                    (I2C_CNTRL2_I2C_CFGERR |
+                                     I2C_CNTRL2_I2C_TO_ERR))) {
+                                       op_status = TSI108_I2C_SUCCESS;
+                               } else {
+                                       /* report detected HW error */
+                                       op_status = TSI108_I2C_IF_ERROR;
+
+                                       DPRINT (("I2C HW error reported: 0x%02x\n", temp));
+                               }
+
+                               break;
+                       }
+
+               } while (to_count--);
+       } else {
+               op_status = TSI108_I2C_IF_BUSY;
+
+               DPRINT (("I2C Transaction start failed: 0x%02x\n", temp));
+       }
+
+       return op_status;
+}
+
+/*
+ * I2C Write interface as defined in "include/i2c.h" :
+ *   chip_addr: I2C chip address, range 0..127
+ *   byte_addr: Memory or register address within the chip
+ *   alen:      Number of bytes to use for addr (typically 1, 2 for larger
+ *              memories, 0 for register type devices with only one
+ *              register)
+ *   buffer:    Pointer to data to be written
+ *   len:       How many bytes to write
+ *
+ *   Returns: 0 on success, not 0 on failure
+ */
+
+int i2c_write (uchar chip_addr, uint byte_addr, int alen, uchar * buffer,
+             int len)
+{
+       u32 op_status = TSI108_I2C_PARAM_ERR;
+
+       /* Check for valid I2C address */
+       if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen * 8))) {
+               while (len--) {
+                       op_status =
+                           i2c_write_byte (chip_addr, byte_addr++, buffer++);
+
+                       if (TSI108_I2C_SUCCESS != op_status) {
+                               DPRINT (("I2C write_byte() failed: 0x%02x (%d left)\n", op_status, len));
+
+                               break;
+                       }
+               }
+       }
+
+       return op_status;
+}
+
+/*
+ * I2C interface function as defined in "include/i2c.h".
+ * Probe the given I2C chip address by reading single byte from offset 0.
+ * Returns 0 if a chip responded, not 0 on failure.
+ */
+
+int i2c_probe (uchar chip)
+{
+       u32 tmp;
+
+       /*
+        * Try to read the first location of the chip.
+        * The Tsi108 HW doesn't support sending just the chip address
+        * and checkong for an <ACK> back.
+        */
+       return i2c_read (chip, 0, 1, (char *)&tmp, 1);
+}
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_I2C) */
+#endif /* CONFIG_TSI108_I2C */
diff --git a/drivers/tsi108_pci.c b/drivers/tsi108_pci.c
new file mode 100644 (file)
index 0000000..9f606df
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * (C) Copyright 2004 Tundra Semiconductor Corp.
+ * Alex Bounine <alexandreb@tundra.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
+ */
+
+/*
+ * PCI initialisation for the Tsi108 EMU board.
+ */
+
+#include <config.h>
+
+#ifdef CONFIG_TSI108_PCI
+
+#include <common.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <tsi108.h>
+
+struct pci_controller local_hose;
+
+void tsi108_clear_pci_error (void)
+{
+       u32 err_stat, err_addr, pci_stat;
+
+       /*
+        * Quietly clear errors signalled as result of PCI/X configuration read
+        * requests.
+        */
+       /* Read PB Error Log Registers */
+       err_stat = *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+                                    TSI108_PB_REG_OFFSET + PB_ERRCS);
+       err_addr = *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+                                    TSI108_PB_REG_OFFSET + PB_AERR);
+       if (err_stat & PB_ERRCS_ES) {
+               /* Clear PCI/X bus errors if applicable */
+               if ((err_addr & 0xFF000000) == CFG_PCI_CFG_BASE) {
+                       /* Clear error flag */
+                       *(u32 *) (CFG_TSI108_CSR_BASE +
+                                 TSI108_PB_REG_OFFSET + PB_ERRCS) =
+                           PB_ERRCS_ES;
+
+                       /* Clear read error reported in PB_ISR */
+                       *(u32 *) (CFG_TSI108_CSR_BASE +
+                                 TSI108_PB_REG_OFFSET + PB_ISR) =
+                           PB_ISR_PBS_RD_ERR;
+
+               /* Clear errors reported by PCI CSR (Normally Master Abort) */
+                       pci_stat = *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+                                                    TSI108_PCI_REG_OFFSET +
+                                                    PCI_CSR);
+                       *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+                                         TSI108_PCI_REG_OFFSET + PCI_CSR) =
+                           pci_stat;
+
+                       *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+                                         TSI108_PCI_REG_OFFSET +
+                                         PCI_IRP_STAT) = PCI_IRP_STAT_P_CSR;
+               }
+       }
+
+       return;
+}
+
+unsigned int __get_pci_config_dword (u32 addr)
+{
+       unsigned int retval;
+
+       __asm__ __volatile__ ("       lwbrx %0,0,%1\n"
+                            "1:     eieio\n"
+                            "2:\n"
+                            ".section .fixup,\"ax\"\n"
+                            "3:     li %0,-1\n"
+                            "       b 2b\n"
+                            ".section __ex_table,\"a\"\n"
+                            "       .align 2\n"
+                            "       .long 1b,3b\n"
+                            ".text":"=r"(retval):"r"(addr));
+
+       return (retval);
+}
+
+static int tsi108_read_config_dword (struct pci_controller *hose,
+                                   pci_dev_t dev, int offset, u32 * value)
+{
+       dev &= (CFG_PCI_CFG_SIZE - 1);
+       dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc));
+       *value = __get_pci_config_dword(dev);
+       if (0xFFFFFFFF == *value)
+               tsi108_clear_pci_error ();
+       return 0;
+}
+
+static int tsi108_write_config_dword (struct pci_controller *hose,
+                                    pci_dev_t dev, int offset, u32 value)
+{
+       dev &= (CFG_PCI_CFG_SIZE - 1);
+       dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc));
+
+       out_le32 ((volatile unsigned *)dev, value);
+
+       return 0;
+}
+
+void pci_init_board (void)
+{
+       struct pci_controller *hose = (struct pci_controller *)&local_hose;
+
+       hose->first_busno = 0;
+       hose->last_busno = 0xff;
+
+       pci_set_region (hose->regions + 0,
+                      CFG_PCI_MEMORY_BUS,
+                      CFG_PCI_MEMORY_PHYS,
+                      CFG_PCI_MEMORY_SIZE, PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+       /* PCI memory space */
+       pci_set_region (hose->regions + 1,
+                      CFG_PCI_MEM_BUS,
+                      CFG_PCI_MEM_PHYS, CFG_PCI_MEM_SIZE, PCI_REGION_MEM);
+
+       /* PCI I/O space */
+       pci_set_region (hose->regions + 2,
+                      CFG_PCI_IO_BUS,
+                      CFG_PCI_IO_PHYS, CFG_PCI_IO_SIZE, PCI_REGION_IO);
+
+       hose->region_count = 3;
+
+       pci_set_ops (hose,
+                   pci_hose_read_config_byte_via_dword,
+                   pci_hose_read_config_word_via_dword,
+                   tsi108_read_config_dword,
+                   pci_hose_write_config_byte_via_dword,
+                   pci_hose_write_config_word_via_dword,
+                   tsi108_write_config_dword);
+
+       pci_register_hose (hose);
+
+       hose->last_busno = pci_hose_scan (hose);
+
+       debug ("Done PCI initialization\n");
+       return;
+}
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup (void *blob, bd_t *bd)
+{
+       u32 *p;
+       int len;
+
+       p = (u32 *)ft_get_prop (blob, "/" OF_TSI "/pci@1000/bus-range", &len);
+       if (p != NULL) {
+               p[0] = local_hose.first_busno;
+               p[1] = local_hose.last_busno;
+       }
+
+}
+#endif
+
+#endif /* CONFIG_TSI108_PCI */
index 33e396a066c8ad0387f07a48d0ef9eccf91012df..ba73bae9e5f8470f979c01490c978d2491b9a144 100644 (file)
@@ -111,7 +111,7 @@ typedef enum __cpu_t {
        CPU_750CX, CPU_750FX, CPU_750GX,
        CPU_7400,
        CPU_7410,
-       CPU_7448,
+       CPU_7447A, CPU_7448,
        CPU_7450, CPU_7455, CPU_7457,
        CPU_UNKNOWN} cpu_t;
 
index 8bc61b63a859943220e37f7df6a34bbe78eb2dcc..5f0f0b4b029cccc142b87f01b7815de2a44e26e5 100644 (file)
@@ -49,6 +49,9 @@ typedef       struct  global_data {
        unsigned long   scc_clk;
        unsigned long   brg_clk;
 #endif
+#if defined(CONFIG_MPC7448HPC2)
+       unsigned long   mem_clk;
+#endif
 #if defined(CONFIG_MPC83XX)
        /* There are other clocks in the MPC83XX */
        u32 csb_clk;
diff --git a/include/configs/mpc7448hpc2.h b/include/configs/mpc7448hpc2.h
new file mode 100644 (file)
index 0000000..6bad515
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2005 Freescale Semiconductor, Inc.
+ *
+ * (C) Copyright 2006
+ * Alex Bounine , Tundra Semiconductor Corp.
+ * Roy Zang    , <tie-fei.zang@freescale.com> Freescale Corp.
+ *
+ * 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 specific configuration options for Freescale
+ * MPC7448HPC2 (High-Performance Computing II) (Taiga) board
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#undef DEBUG
+
+/* Board Configuration Definitions */
+/* MPC7448HPC2 (High-Performance Computing II) (Taiga) board */
+
+#define CONFIG_MPC7448HPC2
+
+#define CONFIG_74xx
+#define CONFIG_750FX           /* this option to enable init of extended BATs */
+#define CONFIG_ALTIVEC         /* undef to disable */
+
+#define CFG_BOARD_NAME         "MPC7448 HPC II"
+#define CONFIG_IDENT_STRING    " Freescale MPC7448 HPC II"
+
+#define CFG_OCN_CLK            133000000       /* 133 MHz */
+#define CFG_CONFIG_BUS_CLK     133000000
+
+#define CFG_CLK_SPREAD         /* Enable Spread-Spectrum Clock generation */
+
+#undef  CONFIG_ECC             /* disable ECC support */
+
+/* Board-specific Initialization Functions to be called */
+#define CFG_BOARD_ASM_INIT
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_EARLY_INIT_R
+#define CONFIG_MISC_INIT_R
+
+#define CONFIG_HAS_ETH1
+
+#define CONFIG_ENV_OVERWRITE
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_BAUDRATE                115200  /* console baudrate = 115000 */
+
+/*#define CFG_HUSH_PARSER */
+#undef CFG_HUSH_PARSER
+
+#define CFG_PROMPT_HUSH_PS2    "> "
+
+/* Pass open firmware flat tree */
+#define CONFIG_OF_FLAT_TREE    1
+#define CONFIG_OF_BOARD_SETUP  1
+
+/* maximum size of the flat tree (8K) */
+#define OF_FLAT_TREE_MAX_SIZE  8192
+
+#define OF_CPU                 "PowerPC,7448@0"
+#define OF_TSI                 "tsi108@c0000000"
+#define OF_TBCLK               (bd->bi_busfreq / 8)
+#define OF_STDOUT_PATH         "/tsi108@c0000000/serial@7808"
+
+/*
+ * The following defines let you select what serial you want to use
+ * for your console driver.
+ *
+ * what to do:
+ * If you have hacked a serial cable onto the second DUART channel,
+ * change the CFG_DUART port from 1 to 0 below.
+ *
+ */
+
+#define CONFIG_CONS_INDEX      1
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+#define CFG_NS16550_REG_SIZE   1
+#define CFG_NS16550_CLK                CFG_OCN_CLK * 8
+
+#define CFG_NS16550_COM1       (CFG_TSI108_CSR_RST_BASE+0x7808)
+#define CFG_NS16550_COM2       (CFG_TSI108_CSR_RST_BASE+0x7C08)
+#define CFG_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_BOOTDELAY       3       /* autoboot after 3 seconds */
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#undef CONFIG_BOOTARGS
+/* #define CONFIG_PREBOOT  "echo;echo Type \"run flash_nfs\"
+ * to mount root filesystem over NFS;echo" */
+
+#if (CONFIG_BOOTDELAY >= 0)
+#define CONFIG_BOOTCOMMAND     "tftpboot 0x400000 zImage.initrd.elf;\
+ setenv bootargs $(bootargs) $(bootargs_root) nfsroot=$(serverip):$(rootpath) \
+ ip=$(ipaddr):$(serverip)$(bootargs_end);  bootm 0x400000; "
+
+#define CONFIG_BOOTARGS "console=ttyS0,115200"
+#endif
+
+#undef CONFIG_EXTRA_ENV_SETTINGS
+
+#define CONFIG_SERIAL  "No. 1"
+
+/* Networking Configuration */
+
+#define KSEG1ADDR(a)   (a)     /* Needed by the rtl8139 driver */
+
+#define CONFIG_TSI108_ETH
+#define CONFIG_TSI108_ETH_NUM_PORTS    2
+
+#define CONFIG_NET_MULTI
+
+#define CONFIG_BOOTFILE                zImage.initrd.elf
+#define CONFIG_LOADADDR                0x400000
+
+/*-------------------------------------------------------------------------- */
+
+#define CONFIG_LOADS_ECHO      0       /* echo off for serial download */
+#define CFG_LOADS_BAUD_CHANGE  /* allow baudrate changes */
+
+#undef CONFIG_WATCHDOG         /* watchdog disabled */
+
+#define CONFIG_BOOTP_MASK      (CONFIG_BOOTP_DEFAULT | \
+                               CONFIG_BOOTP_BOOTFILESIZE)
+
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL \
+               | CFG_CMD_ASKENV \
+               | CFG_CMD_CACHE \
+               | CFG_CMD_PCI \
+               | CFG_CMD_I2C \
+               | CFG_CMD_SDRAM \
+               | CFG_CMD_EEPROM \
+               | CFG_CMD_FLASH \
+               | CFG_CMD_ENV \
+               | CFG_CMD_BSP \
+               | CFG_CMD_DHCP \
+               | CFG_CMD_PING \
+               | CFG_CMD_DATE)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*set date in u-boot*/
+#define CONFIG_RTC_M48T35A
+#define CFG_NVRAM_BASE_ADDR    0xfc000000
+#define CFG_NVRAM_SIZE         0x8000
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_VERSION_VARIABLE                1
+#define CONFIG_TSI108_I2C
+
+#define CFG_I2C_EEPROM_ADDR            0x50    /* I2C EEPROM page 1 */
+#define CFG_I2C_EEPROM_ADDR_LEN                1       /* Bytes of address */
+
+#define CFG_LONGHELP           /* undef to save memory */
+#define CFG_PROMPT     "=> "   /* Monitor Command Prompt */
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE             1024    /* Console I/O Buffer Size */
+#define CONFIG_KGDB_BAUDRATE   115200  /* speed to run kgdb serial port at */
+#else
+#define CFG_CBSIZE             256     /* Console I/O Buffer Size */
+#endif
+
+#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)/* Print Buffer Size */
+#define CFG_MAXARGS    16              /* max number of command args */
+#define CFG_BARGSIZE   CFG_CBSIZE      /* Boot Argument Buffer Size */
+
+#define CFG_MEMTEST_START      0x00400000      /* memtest works on */
+#define CFG_MEMTEST_END                0x07c00000      /* 4 ... 124 MB in DRAM */
+
+#define CFG_LOAD_ADDR  0x00400000      /* default load address */
+
+#define CFG_HZ         1000            /* decr freq: 1ms ticks */
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+
+/*
+ * When locking data in cache you should point the CFG_INIT_RAM_ADDRESS
+ * To an unused memory region. The stack will remain in cache until RAM
+ * is initialized
+ */
+#undef  CFG_INIT_RAM_LOCK
+#define CFG_INIT_RAM_ADDR      0x07d00000      /* unused memory region */
+#define CFG_INIT_RAM_END       0x4000/* larger space - we have SDRAM initialized */
+
+#define CFG_GBL_DATA_SIZE      128/* size in bytes reserved for init data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+/*-----------------------------------------------------------------------
+ * 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         0x00000000      /* first 256 MB of SDRAM */
+#define CFG_SDRAM1_BASE                0x10000000      /* next 256MB of SDRAM */
+
+#define CFG_SDRAM2_BASE        0x40000000      /* beginning of non-cacheable alias for SDRAM - first 256MB */
+#define CFG_SDRAM3_BASE        0x50000000      /* next Non-Cacheable 256MB of SDRAM */
+
+#define CFG_PCI_PFM_BASE       0x80000000      /* Prefetchable (cacheable) PCI/X PFM and SDRAM OCN (128MB+128MB) */
+
+#define CFG_PCI_MEM32_BASE     0xE0000000      /* Non-Cacheable PCI/X MEM and SDRAM OCN (128MB+128MB) */
+
+#define CFG_MISC_REGION_BASE   0xf0000000      /* Base Address for (PCI/X + Flash) region */
+
+#define CFG_FLASH_BASE 0xff000000      /* Base Address of Flash device */
+#define CFG_FLASH_BASE2        0xfe000000      /* Alternate Flash Base Address */
+
+#define CONFIG_VERY_BIG_RAM    /* we will use up to 256M memory for cause we are short of BATS */
+
+#define PCI0_IO_BASE_BOOTM     0xfd000000
+
+#define CFG_RESET_ADDRESS      0x3fffff00
+#define CFG_MONITOR_LEN                (256 << 10)     /* Reserve 256 kB for Monitor */
+#define CFG_MONITOR_BASE       TEXT_BASE       /* u-boot code base */
+#define CFG_MALLOC_LEN         (256 << 10)     /* Reserve 256 kB for malloc */
+
+/* Peripheral Device section */
+
+/*
+ * Resources on the Tsi108
+ */
+
+#define CFG_TSI108_CSR_RST_BASE        0xC0000000      /* Tsi108 CSR base after reset */
+#define CFG_TSI108_CSR_BASE    CFG_TSI108_CSR_RST_BASE /* Runtime Tsi108 CSR base */
+
+#define ENABLE_PCI_CSR_BAR     /* enables access to Tsi108 CSRs from the PCI/X bus */
+
+#undef  DISABLE_PBM
+
+/*
+ * PCI stuff
+ *
+ */
+
+#define CONFIG_PCI             /* include pci support */
+#define CONFIG_TSI108_PCI      /* include tsi108 pci support */
+
+#define PCI_HOST_ADAPTER       0       /* configure as pci adapter */
+#define PCI_HOST_FORCE         1       /* configure as pci host */
+#define PCI_HOST_AUTO          2       /* detected via arbiter enable */
+
+#define CONFIG_PCI_HOST PCI_HOST_FORCE /* select pci host function */
+#define CONFIG_PCI_PNP         /* do pci plug-and-play */
+
+/* PCI MEMORY MAP section */
+
+/* PCI view of System Memory */
+#define CFG_PCI_MEMORY_BUS     0x00000000
+#define CFG_PCI_MEMORY_PHYS    0x00000000
+#define CFG_PCI_MEMORY_SIZE    0x80000000      
+
+/* PCI Memory Space */
+#define CFG_PCI_MEM_BUS                (CFG_PCI_MEM_PHYS)
+#define CFG_PCI_MEM_PHYS       (CFG_PCI_MEM32_BASE)    /* 0xE0000000 */
+#define CFG_PCI_MEM_SIZE       0x10000000      /* 256 MB space for PCI/X Mem + SDRAM OCN */
+
+/* PCI I/O Space */
+#define CFG_PCI_IO_BUS         0x00000000
+#define CFG_PCI_IO_PHYS                0xfa000000      /* Changed from fd000000 */
+
+#define CFG_PCI_IO_SIZE                0x01000000      /* 16MB */
+
+#define _IO_BASE               0x00000000      /* points to PCI I/O space      */
+
+/* PCI Config Space mapping */
+#define CFG_PCI_CFG_BASE       0xfb000000      /* Changed from FE000000 */
+#define CFG_PCI_CFG_SIZE       0x01000000      /* 16MB */
+
+#define CFG_IBAT0U     0xFE0003FF
+#define CFG_IBAT0L     0xFE000002
+
+#define CFG_IBAT1U     0x00007FFF
+#define CFG_IBAT1L     0x00000012
+
+#define CFG_IBAT2U     0x80007FFF
+#define CFG_IBAT2L     0x80000022
+
+#define CFG_IBAT3U     0x00000000
+#define CFG_IBAT3L     0x00000000
+
+#define CFG_IBAT4U     0x00000000
+#define CFG_IBAT4L     0x00000000
+
+#define CFG_IBAT5U     0x00000000
+#define CFG_IBAT5L     0x00000000
+
+#define CFG_IBAT6U     0x00000000
+#define CFG_IBAT6L     0x00000000
+
+#define CFG_IBAT7U     0x00000000
+#define CFG_IBAT7L     0x00000000
+
+#define CFG_DBAT0U     0xE0003FFF
+#define CFG_DBAT0L     0xE000002A
+
+#define CFG_DBAT1U     0x00007FFF
+#define CFG_DBAT1L     0x00000012
+
+#define CFG_DBAT2U     0x00000000
+#define CFG_DBAT2L     0x00000000
+
+#define CFG_DBAT3U     0xC0000003
+#define CFG_DBAT3L     0xC000002A
+
+#define CFG_DBAT4U     0x00000000
+#define CFG_DBAT4L     0x00000000
+
+#define CFG_DBAT5U     0x00000000
+#define CFG_DBAT5L     0x00000000
+
+#define CFG_DBAT6U     0x00000000
+#define CFG_DBAT6L     0x00000000
+
+#define CFG_DBAT7U     0x00000000
+#define CFG_DBAT7L     0x00000000
+
+/* I2C addresses for the two DIMM SPD chips */
+#define DIMM0_I2C_ADDR 0x51
+#define DIMM1_I2C_ADDR 0x52
+
+/*
+ * 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<<20) /* Initial Memory map for Linux */
+
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS    1/* Flash can be at one of two addresses */
+#define FLASH_BANK_SIZE                0x01000000      /* 16 MB Total */
+#define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE, CFG_FLASH_BASE2}
+
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+#define CFG_FLASH_CFI_SWAP
+
+#define PHYS_FLASH_SIZE                0x01000000
+#define CFG_MAX_FLASH_SECT     (128)
+
+#define CFG_ENV_IS_IN_NVRAM
+#define CFG_ENV_ADDR           0xFC000000
+
+#define CFG_ENV_OFFSET 0x00000000      /* Offset of Environment Sector */
+#define CFG_ENV_SIZE   0x00000400      /* Total Size of Environment Space */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE     32      /* For all MPC74xx CPUs */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT    5       /* log base 2 of the above value */
+#endif
+
+/*-----------------------------------------------------------------------
+ * L2CR setup -- make sure this is right for your board!
+ * look in include/mpc74xx.h for the defines used here
+ */
+#undef CFG_L2
+
+#define L2_INIT                0
+#define L2_ENABLE      (L2_INIT | L2CR_L2E)
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD  0x01    /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM  0x02    /* Software reboot */
+#define CFG_SERIAL_HANG_IN_EXCEPTION
+#endif /* __CONFIG_H */
diff --git a/include/tsi108.h b/include/tsi108.h
new file mode 100644 (file)
index 0000000..ba62e7a
--- /dev/null
@@ -0,0 +1,221 @@
+/*****************************************************************************
+ * (C) Copyright 2003;  Tundra Semiconductor Corp.
+ * (C) Copyright 2006;  Freescale Semiconductor Corp.
+ *
+ * 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
+ *****************************************************************************/
+
+/*
+ * FILENAME: tsi108.h
+ *
+ * Originator: Alex Bounine
+ *
+ * DESCRIPTION:
+ * Common definitions for the Tundra Tsi108 bridge chip
+ *
+ */
+
+#ifndef _TSI108_H_
+#define _TSI108_H_
+
+#define TSI108_HLP_REG_OFFSET  (0x0000)
+#define TSI108_PCI_REG_OFFSET  (0x1000)
+#define TSI108_CLK_REG_OFFSET  (0x2000)
+#define TSI108_PB_REG_OFFSET   (0x3000)
+#define TSI108_SD_REG_OFFSET   (0x4000)
+#define TSI108_MPIC_REG_OFFSET (0x7400)
+
+#define PB_ID                  (0x000)
+#define PB_RSR                 (0x004)
+#define PB_BUS_MS_SELECT       (0x008)
+#define PB_ISR                 (0x00C)
+#define PB_ARB_CTRL            (0x018)
+#define PB_PVT_CTRL2           (0x034)
+#define PB_SCR                 (0x400)
+#define PB_ERRCS               (0x404)
+#define PB_AERR                        (0x408)
+#define PB_REG_BAR             (0x410)
+#define PB_OCN_BAR1            (0x414)
+#define PB_OCN_BAR2            (0x418)
+#define PB_SDRAM_BAR1          (0x41C)
+#define PB_SDRAM_BAR2          (0x420)
+#define PB_MCR                 (0xC00)
+#define PB_MCMD                        (0xC04)
+
+#define HLP_B0_ADDR            (0x000)
+#define HLP_B1_ADDR            (0x010)
+#define HLP_B2_ADDR            (0x020)
+#define HLP_B3_ADDR            (0x030)
+
+#define HLP_B0_MASK            (0x004)
+#define HLP_B1_MASK            (0x014)
+#define HLP_B2_MASK            (0x024)
+#define HLP_B3_MASK            (0x034)
+
+#define HLP_B0_CTRL0           (0x008)
+#define HLP_B1_CTRL0           (0x018)
+#define HLP_B2_CTRL0           (0x028)
+#define HLP_B3_CTRL0           (0x038)
+
+#define HLP_B0_CTRL1           (0x00C)
+#define HLP_B1_CTRL1           (0x01C)
+#define HLP_B2_CTRL1           (0x02C)
+#define HLP_B3_CTRL1           (0x03C)
+
+#define PCI_CSR                        (0x004)
+#define PCI_P2O_BAR0           (0x010)
+#define PCI_P2O_BAR0_UPPER     (0x014)
+#define PCI_P2O_BAR2           (0x018)
+#define PCI_P2O_BAR2_UPPER     (0x01C)
+#define PCI_P2O_BAR3           (0x020)
+#define PCI_P2O_BAR3_UPPER     (0x024)
+
+#define PCI_MISC_CSR           (0x040)
+#define PCI_P2O_PAGE_SIZES     (0x04C)
+
+#define PCI_PCIX_STAT          (0x0F4)
+
+#define PCI_IRP_STAT           (0x184)
+
+#define PCI_PFAB_BAR0          (0x204)
+#define PCI_PFAB_BAR0_UPPER    (0x208)
+#define PCI_PFAB_IO            (0x20C)
+#define PCI_PFAB_IO_UPPER      (0x210)
+
+#define PCI_PFAB_MEM32         (0x214)
+#define PCI_PFAB_MEM32_REMAP   (0x218)
+#define PCI_PFAB_MEM32_MASK    (0x21C)
+
+#define CG_PLL0_CTRL0          (0x210)
+#define CG_PLL0_CTRL1          (0x214)
+#define CG_PLL1_CTRL0          (0x220)
+#define CG_PLL1_CTRL1          (0x224)
+#define CG_PWRUP_STATUS                (0x234)
+
+#define MPIC_CSR(n) (0x30C + (n * 0x40))
+
+#define SD_CTRL                        (0x000)
+#define SD_STATUS              (0x004)
+#define SD_TIMING              (0x008)
+#define SD_REFRESH             (0x00C)
+#define SD_INT_STATUS          (0x010)
+#define SD_INT_ENABLE          (0x014)
+#define SD_INT_SET             (0x018)
+#define SD_D0_CTRL             (0x020)
+#define SD_D1_CTRL             (0x024)
+#define SD_D0_BAR              (0x028)
+#define SD_D1_BAR              (0x02C)
+#define SD_ECC_CTRL            (0x040)
+#define SD_DLL_STATUS          (0x250)
+
+#define TS_SD_CTRL_ENABLE      (1 << 31)
+
+#define PB_ERRCS_ES            (1 << 1)
+#define PB_ISR_PBS_RD_ERR      (1 << 8)
+#define PCI_IRP_STAT_P_CSR     (1 << 23)
+
+/*
+ * I2C : Register address offset definitions
+ */
+#define I2C_CNTRL1             (0x00000000)
+#define I2C_CNTRL2             (0x00000004)
+#define I2C_RD_DATA            (0x00000008)
+#define I2C_TX_DATA            (0x0000000c)
+
+/*
+ * I2C : Register Bit Masks and Reset Values
+ * definitions for every register
+ */
+
+/* I2C_CNTRL1 : Reset Value */
+#define I2C_CNTRL1_RESET_VALUE                         (0x0000000a)
+
+/* I2C_CNTRL1 : Register Bits Masks Definitions */
+#define I2C_CNTRL1_DEVCODE                             (0x0000000f)
+#define I2C_CNTRL1_PAGE                                        (0x00000700)
+#define I2C_CNTRL1_BYTADDR                             (0x00ff0000)
+#define I2C_CNTRL1_I2CWRITE                            (0x01000000)
+
+/* I2C_CNTRL1 : Read/Write Bit Mask Definition */
+#define I2C_CNTRL1_RWMASK                              (0x01ff070f)
+
+/* I2C_CNTRL1 : Unused/Reserved bits Definition */
+#define I2C_CNTRL1_RESERVED                            (0xfe00f8f0)
+
+/* I2C_CNTRL2 : Reset Value */
+#define I2C_CNTRL2_RESET_VALUE                         (0x00000000)
+
+/* I2C_CNTRL2 : Register Bits Masks Definitions */
+#define I2C_CNTRL2_SIZE                                        (0x00000003)
+#define I2C_CNTRL2_LANE                                        (0x0000000c)
+#define I2C_CNTRL2_MULTIBYTE                           (0x00000010)
+#define I2C_CNTRL2_START                               (0x00000100)
+#define I2C_CNTRL2_WR_STATUS                           (0x00010000)
+#define I2C_CNTRL2_RD_STATUS                           (0x00020000)
+#define I2C_CNTRL2_I2C_TO_ERR                          (0x04000000)
+#define I2C_CNTRL2_I2C_CFGERR                          (0x08000000)
+#define I2C_CNTRL2_I2C_CMPLT                           (0x10000000)
+
+/* I2C_CNTRL2 : Read/Write Bit Mask Definition */
+#define I2C_CNTRL2_RWMASK                              (0x0000011f)
+
+/* I2C_CNTRL2 : Unused/Reserved bits Definition */
+#define I2C_CNTRL2_RESERVED                            (0xe3fcfee0)
+
+/* I2C_RD_DATA : Reset Value */
+#define I2C_RD_DATA_RESET_VALUE                                (0x00000000)
+
+/* I2C_RD_DATA : Register Bits Masks Definitions */
+#define I2C_RD_DATA_RBYTE0                             (0x000000ff)
+#define I2C_RD_DATA_RBYTE1                             (0x0000ff00)
+#define I2C_RD_DATA_RBYTE2                             (0x00ff0000)
+#define I2C_RD_DATA_RBYTE3                             (0xff000000)
+
+/* I2C_RD_DATA : Read/Write Bit Mask Definition */
+#define I2C_RD_DATA_RWMASK                             (0x00000000)
+
+/* I2C_RD_DATA : Unused/Reserved bits Definition */
+#define I2C_RD_DATA_RESERVED                           (0x00000000)
+
+/* I2C_TX_DATA : Reset Value */
+#define I2C_TX_DATA_RESET_VALUE                                (0x00000000)
+
+/* I2C_TX_DATA : Register Bits Masks Definitions */
+#define I2C_TX_DATA_TBYTE0                             (0x000000ff)
+#define I2C_TX_DATA_TBYTE1                             (0x0000ff00)
+#define I2C_TX_DATA_TBYTE2                             (0x00ff0000)
+#define I2C_TX_DATA_TBYTE3                             (0xff000000)
+
+/* I2C_TX_DATA : Read/Write Bit Mask Definition */
+#define I2C_TX_DATA_RWMASK                             (0xffffffff)
+
+/* I2C_TX_DATA : Unused/Reserved bits Definition */
+#define I2C_TX_DATA_RESERVED                           (0x00000000)
+
+#define TSI108_I2C_OFFSET      0x7000  /* offset for general use I2C channel */
+#define TSI108_I2C_SDRAM_OFFSET        0x4400  /* offset for SPD I2C channel */
+
+#define I2C_EEPROM_DEVCODE     0xA     /* standard I2C EEPROM device code */
+
+/* I2C status codes */
+
+#define TSI108_I2C_SUCCESS     0
+#define TSI108_I2C_PARAM_ERR   1
+#define TSI108_I2C_TIMEOUT_ERR 2
+#define TSI108_I2C_IF_BUSY     3
+#define TSI108_I2C_IF_ERROR    4
+
+#endif         /* _TSI108_H_ */
index d92f14270ef189fc80fa02f8b0ce2443478c116f..fe856ffbb527a4e5dd62d1925d39f0fe14fc8ada 100644 (file)
@@ -37,6 +37,8 @@
  * on our cache or tlb entries.
  */
 
+DECLARE_GLOBAL_DATA_PTR;
+
 struct exception_table_entry
 {
        unsigned long insn, fixup;
@@ -55,10 +57,22 @@ search_one_table(const struct exception_table_entry *first,
                long diff;
 
                mid = (last - first) / 2 + first;
-               diff = mid->insn - value;
-               if (diff == 0)
-                       return mid->fixup;
-               else if (diff < 0)
+               if (mid > CFG_MONITOR_BASE) {
+               /* exception occurs in FLASH, before u-boot relocation.
+                * No relocation offset is needed.
+                */
+                       diff = mid->insn - value;
+                       if (diff == 0)
+                               return mid->fixup;
+               } else {
+               /* exception occurs in RAM, after u-boot relocation.
+                * A relocation offset should be added.
+                */
+                       diff = (mid->insn + gd->reloc_off) - value;
+                       if (diff == 0)
+                               return (mid->fixup + gd->reloc_off);
+               }
+               if (diff < 0)
                        first = mid+1;
                else
                        last = mid-1;
@@ -75,8 +89,11 @@ search_exception_table(unsigned long addr)
 
        /* There is only the kernel to search.  */
        ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
+       /* if the serial port does not hang in exception, printf can be used */
+#if !defined(CFG_SERIAL_HANG_IN_EXCEPTION)
        if (ex_tab_message)
                printf("Bus Fault @ 0x%08lx, fixup 0x%08lx\n", addr, ret);
+#endif
        if (ret) return ret;
 
        return 0;
index cca93920594b521b634c8315462b1518d4208350..44390d237b2f1386f8c8fd40ea1682e29b938224 100644 (file)
--- a/net/eth.c
+++ b/net/eth.c
@@ -52,6 +52,7 @@ extern int rtl8139_initialize(bd_t*);
 extern int rtl8169_initialize(bd_t*);
 extern int scc_initialize(bd_t*);
 extern int skge_initialize(bd_t*);
+extern int tsi108_eth_initialize(bd_t*);
 extern int tsec_initialize(bd_t*, int, char *);
 extern int npe_initialize(bd_t *);
 extern int uec_initialize(int);
@@ -249,6 +250,9 @@ int eth_initialize(bd_t *bis)
 #ifdef CONFIG_NS8382X
        ns8382x_initialize(bis);
 #endif
+#if defined(CONFIG_TSI108_ETH)
+       tsi108_eth_initialize(bis);
+#endif
 #if defined(CONFIG_RTL8139)
        rtl8139_initialize(bis);
 #endif