]> git.sur5r.net Git - u-boot/commitdiff
Initial revision
authorwdenk <wdenk>
Sun, 3 Nov 2002 01:41:26 +0000 (01:41 +0000)
committerwdenk <wdenk>
Sun, 3 Nov 2002 01:41:26 +0000 (01:41 +0000)
board/bmw/early_init.S [new file with mode: 0644]
board/gw8260/flash.c [new file with mode: 0644]
board/gw8260/gw8260.c [new file with mode: 0644]
board/mvs1/flash.c [new file with mode: 0644]

diff --git a/board/bmw/early_init.S b/board/bmw/early_init.S
new file mode 100644 (file)
index 0000000..ec20a67
--- /dev/null
@@ -0,0 +1,1172 @@
+#include <ppc_asm.tmpl>
+#include <mpc824x.h>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#define USE_V2_INIT 1 /* Jimmy Blair's initialization. */
+
+
+/*
+ * Initialize the MMU using BAT entries and hardwired TLB
+ * This obviates the need for any code in cpu_init_f which
+ * configures the BAT registers.
+*/
+#define MEMORY_MGMT_MSR_BITS (MSR_DR | MSR_IR) /* Data and Inst Relocate */
+       .global iommu_setup
+       /* Initialize IO/MMU mappings via BAT method Ch. 7,
+        * PPC Programming Reference
+         */
+iommu_setup:
+
+/* initialize the BAT registers (SPRs 528 - 543 */
+#define        mtibat0u(x)     mtspr   528,(x)                 /* SPR 528 (IBAT0U) */
+#define mtibat0l(x)    mtspr   529,(x)                 /* SPR 529 (IBAT0L) */
+#define mtibat1u(x)    mtspr   530,(x)                 /* SPR 530 (IBAT1U) */
+#define mtibat1l(x)    mtspr   531,(x)                 /* SPR 531 (IBAT1L) */
+#define mtibat2u(x)    mtspr   532,(x)                 /* SPR 532 (IBAT2U) */
+#define mtibat2l(x)    mtspr   533,(x)                 /* SPR 533 (IBAT2L) */
+#define mtibat3u(x)    mtspr   534,(x)                 /* SPR 534 (IBAT3U) */
+#define mtibat3l(x)    mtspr   535,(x)                 /* SPR 535 (IBAT3L) */
+#define mtdbat0u(x)    mtspr   536,(x)                 /* SPR 536 (DBAT0U) */
+#define mtdbat0l(x)    mtspr   537,(x)                 /* SPR 537 (DBAT0L) */
+#define mtdbat1u(x)    mtspr   538,(x)                 /* SPR 538 (DBAT1U) */
+#define mtdbat1l(x)    mtspr   539,(x)                 /* SPR 539 (DBAT1L) */
+#define mtdbat2u(x)    mtspr   540,(x)                 /* SPR 540 (DBAT2U) */
+#define mtdbat2l(x)    mtspr   541,(x)                 /* SPR 541 (DBAT2L) */
+#define mtdbat3u(x)    mtspr   542,(x)                 /* SPR 542 (DBAT3U) */
+#define mtdbat3l(x)    mtspr   543,(x)                 /* SPR 543 (DBAT3L) */
+
+
+/* PowerPC processors do not necessarily initialize the BAT
+   registers on power-up or reset.  So they are in an unknown
+   state.  Before programming the BATs for the first time, all
+   BAT registers MUST have their Vs and Vp bits cleared in the
+   upper BAT half in order to avoid possibly having 2 BATs
+   valid and mapping the same memory region.
+
+   The reason for this is that, even with address translation
+   disabled, multiple BAT hits for an address are treated as
+   programming errors and can cause unpredictable results.
+
+   It is up to the software to make sure it never has 2 IBAT
+   mappings or 2 DBAT mappings that are valid for the same
+   addresses.  It is not necessary to perform this code
+   sequence every time the BATs are programmed, only when
+   there is a possibility that there may be overlapping BAT
+   entries.
+
+   When programming the BATs in non-reset scenarios, even if
+   you are sure that your new mapping will not temporarily
+   create overlapping regions, it is still a wise idea to
+   invalidate a BAT entry by setting its upper BAT register to
+   all 0's before programming it.  This will avoid having a
+   BAT marked valid that is in an unknown or transient state
+*/
+
+        addis   r5,0,0x0000
+       mtibat0u(r5)
+       mtibat0l(r5)
+       mtibat1u(r5)
+       mtibat1l(r5)
+       mtibat2u(r5)
+       mtibat2l(r5)
+       mtibat3u(r5)
+       mtibat3l(r5)
+       mtdbat0u(r5)
+       mtdbat0l(r5)
+       mtdbat1u(r5)
+       mtdbat1l(r5)
+       mtdbat2u(r5)
+       mtdbat2l(r5)
+       mtdbat3u(r5)
+       mtdbat3l(r5)
+        isync
+
+/*
+ *  Set up I/D BAT0
+ */
+        lis     r4, CFG_DBAT0L@h
+        ori     r4, r4, CFG_DBAT0L@l
+        lis     r3, CFG_DBAT0U@h
+        ori     r3, r3, CFG_DBAT0U@l
+
+        mtdbat0l(r4)
+        isync
+        mtdbat0u(r3)
+        isync
+        sync
+
+        lis     r4, CFG_IBAT0L@h
+        ori     r4, r4, CFG_IBAT0L@l
+        lis     r3, CFG_IBAT0U@h
+        ori     r3, r3, CFG_IBAT0U@l
+
+        isync
+        mtibat0l(r4)
+        isync
+       mtibat0u(r3)
+        isync
+
+/*
+ *  Set up I/D BAT1
+ */
+        lis     r4, CFG_IBAT1L@h
+        ori     r4, r4, CFG_IBAT1L@l
+        lis     r3, CFG_IBAT1U@h
+        ori     r3, r3, CFG_IBAT1U@l
+
+        isync
+        mtibat1l(r4)
+        isync
+        mtibat1u(r3)
+        isync
+        mtdbat1l(r4)
+        isync
+        mtdbat1u(r3)
+        isync
+        sync
+
+/*
+ *  Set up I/D BAT2
+ */
+        lis     r4, CFG_IBAT2L@h
+        ori     r4, r4, CFG_IBAT2L@l
+        lis     r3, CFG_IBAT2U@h
+        ori     r3, r3, CFG_IBAT2U@l
+
+        isync
+        mtibat2l(r4)
+        isync
+        mtibat2u(r3)
+        isync
+        mtdbat2l(r4)
+        isync
+        mtdbat2u(r3)
+        isync
+        sync
+
+/*
+ *  Setup I/D BAT3
+ */
+        lis     r4, CFG_IBAT3L@h
+        ori     r4, r4, CFG_IBAT3L@l
+        lis     r3, CFG_IBAT3U@h
+        ori     r3, r3, CFG_IBAT3U@l
+
+        isync
+        mtibat3l(r4)
+        isync
+        mtibat3u(r3)
+        isync
+        mtdbat3l(r4)
+        isync
+        mtdbat3u(r3)
+        isync
+        sync
+
+
+/*
+ *  Invalidate all 64 TLB's
+ */
+        lis     r3, 0
+        mtctr   r3
+        lis     r5, 4
+
+tlblp:
+        tlbie   r3
+        sync
+        addi    r3, r3, 0x1000
+        cmplw   r3, r5
+        blt     tlblp
+
+        sync
+
+/*
+ *  Enable Data Translation
+ */
+       lis     r4, MEMORY_MGMT_MSR_BITS@h
+       ori     r4, r4, MEMORY_MGMT_MSR_BITS@l
+       mfmsr   r3
+       or      r3, r4, r3
+       mtmsr   r3
+       isync
+       sync
+
+        blr
+
+
+#ifdef USE_V2_INIT
+/* #define USER_I_CACHE_ENABLE 1*/ /* Fast rom boots */
+/* Macro for hiadjust and lo */
+#define HIADJ(arg)     arg@ha
+#define HI(arg)                arg@h
+#define LO(arg)                arg@l
+
+#undef LOADPTR
+#define        LOADPTR(reg,const32) \
+         addis reg,r0,HIADJ(const32); addi reg,reg,LO(const32)
+
+.globl  early_init_f
+
+early_init_f:
+/* MPC8245/BMW CPCI System Init
+ * Jimmy Blair, Broadcom Corp, 2002.
+ */
+        mflr    r11
+       /* Zero-out registers */
+
+       addis   r0,r0,0
+       mtspr   SPRG0,r0
+       mtspr   SPRG1,r0
+       mtspr   SPRG2,r0
+       mtspr   SPRG3,r0
+
+       /* Set MPU/MSR to a known state. Turn on FP */
+
+       LOADPTR (r3, MSR_FP)
+       sync
+       mtmsr   r3
+       isync
+
+       /* Init the floating point control/status register */
+
+       mtfsfi  7,0x0
+       mtfsfi  6,0x0
+       mtfsfi  5,0x0
+       mtfsfi  4,0x0
+       mtfsfi  3,0x0
+       mtfsfi  2,0x0
+       mtfsfi  1,0x0
+       mtfsfi  0,0x0
+       isync
+
+       /* Set MPU/MSR to a known state. Turn off FP */
+
+#if 1  /* Turn off floating point (remove to keep FP on) */
+        andi.  r3, r3, 0
+       sync
+       mtmsr   r3
+       isync
+#endif
+
+       /* Init the Segment registers */
+
+       andi.   r3, r3, 0
+       isync
+       mtsr    0,r3
+       isync
+       mtsr    1,r3
+       isync
+       mtsr    2,r3
+       isync
+       mtsr    3,r3
+       isync
+       mtsr    4,r3
+       isync
+       mtsr    5,r3
+       isync
+       mtsr    6,r3
+       isync
+       mtsr    7,r3
+       isync
+       mtsr    8,r3
+       isync
+       mtsr    9,r3
+       isync
+       mtsr    10,r3
+       isync
+       mtsr    11,r3
+       isync
+       mtsr    12,r3
+       isync
+       mtsr    13,r3
+       isync
+       mtsr    14,r3
+       isync
+       mtsr    15,r3
+       isync
+
+       /* Turn off data and instruction cache control bits */
+
+       mfspr   r3, HID0
+       isync
+       rlwinm  r4, r3, 0, 18, 15       /* r4 has ICE and DCE bits cleared */
+       sync
+       isync
+       mtspr   HID0, r4                /* HID0 = r4 */
+       isync
+
+       /* Get cpu type */
+
+       mfspr   r28, PVR
+       rlwinm  r28, r28, 16, 16, 31
+
+       /* invalidate the MPU's data/instruction caches */
+
+       lis     r3, 0x0
+       cmpli   0, 0, r28, CPU_TYPE_603
+       beq     cpuIs603
+       cmpli   0, 0, r28, CPU_TYPE_603E
+       beq     cpuIs603
+       cmpli   0, 0, r28, CPU_TYPE_603P
+       beq     cpuIs603
+       cmpli   0, 0, r28, CPU_TYPE_604R
+       bne     cpuNot604R
+
+cpuIs604R:
+       lis     r3, 0x0
+       mtspr   HID0, r3                /* disable the caches */
+       isync
+       ori     r4, r4, 0x0002          /* disable BTAC by setting bit 30 */
+
+cpuNot604R:
+       ori     r3, r3, (HID0_ICFI |HID0_DCI)
+
+cpuIs603:
+       ori     r3, r3, (HID0_ICE | HID0_DCE)
+       or      r4, r4, r3              /* set bits */
+       sync
+       isync
+       mtspr   HID0, r4                /* HID0 = r4 */
+       andc    r4, r4, r3              /* clear bits */
+       isync
+       cmpli   0, 0, r28, CPU_TYPE_604
+       beq     cpuIs604
+       cmpli   0, 0, r28, CPU_TYPE_604E
+       beq     cpuIs604
+       cmpli   0, 0, r28, CPU_TYPE_604R
+       beq     cpuIs604
+       mtspr   HID0, r4
+       isync
+
+#ifdef USER_I_CACHE_ENABLE
+       b       instCacheOn603
+#else
+       b       cacheEnableDone
+#endif
+
+cpuIs604:
+       LOADPTR (r5, 0x1000)            /* loop count, 0x1000 */
+       mtspr   CTR, r5
+loopDelay:
+       nop
+       bdnz    loopDelay
+       isync
+       mtspr   HID0, r4
+       isync
+
+       /* turn the Instruction cache ON for faster FLASH ROM boots */
+
+#ifdef USER_I_CACHE_ENABLE
+
+       ori     r4, r4, (HID0_ICE | HID0_ICFI)
+       isync                           /* Synchronize for ICE enable */
+       b       writeReg4
+instCacheOn603:
+       ori     r4, r4, (HID0_ICE | HID0_ICFI)
+       rlwinm  r3, r4, 0, 21, 19       /* clear the ICFI bit */
+
+       /*
+         * The setting of the instruction cache enable (ICE) bit must be
+         * preceded by an isync instruction to prevent the cache from being
+         * enabled or disabled while an instruction access is in progress.
+         */
+       isync
+writeReg4:
+       mtspr   HID0, r4                /* Enable Instr Cache & Inval cache */
+       cmpli   0, 0, r28, CPU_TYPE_604
+       beq     cacheEnableDone
+       cmpli   0, 0, r28, CPU_TYPE_604E
+       beq     cacheEnableDone
+
+       mtspr   HID0, r3                /* using 2 consec instructions */
+                                       /* PPC603 recommendation */
+#endif
+cacheEnableDone:
+
+       /* Detect map A or B */
+
+       addis   r5,r0, HI(CHRP_REG_ADDR)
+       addis   r6,r0, HI(CHRP_REG_DATA)
+       LOADPTR (r7, KAHLUA_ID)         /* Kahlua PCI controller ID */
+       LOADPTR (r8, BMC_BASE)
+
+       stwbrx  r8,0,(r5)
+       lwbrx   r3,0,(r6)               /* Store read value to r3 */
+       cmp     0,0,r3,r7
+       beq     cr0, X4_KAHLUA_START
+
+        /* It's not an 8240, is it an 8245? */
+
+       LOADPTR (r7, KAHLUA2_ID)        /* Kahlua PCI controller ID */
+       cmp     0,0,r3,r7
+       beq     cr0, X4_KAHLUA_START
+
+        /* Save the PCI controller type in r7 */
+       mr      r7, r3
+
+       LOADPTR (r5, PREP_REG_ADDR)
+       LOADPTR (r6, PREP_REG_DATA)
+
+X4_KAHLUA_START:
+       /* MPC8245 changes begin here */
+       LOADPTR (r3, MPC107_PCI_CMD)    /* PCI command reg */
+       stwbrx  r3,0,r5
+       li      r4, 6                   /* Command register value */
+       sthbrx  r4, 0, r6
+
+       LOADPTR (r3, MPC107_PCI_STAT)   /* PCI status reg */
+       stwbrx  r3,0,r5
+       li      r4, -1                  /* Write-to-clear all bits */
+       li      r3, 2                   /* PCI_STATUS is at +2 offset */
+       sthbrx  r4, r3, r6
+
+       /*-------PROC_INT1_ADR */
+
+       LOADPTR (r3, PROC_INT1_ADR)     /* Processor I/F Config 1 reg. */
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0xff141b98)
+       stwbrx  r4,0,r6
+
+       /*-------PROC_INT2_ADR */
+
+       LOADPTR (r3, PROC_INT2_ADR)     /* Processor I/F Config 2 reg. */
+       stwbrx  r3,0,r5
+        lis    r4, 0x2000              /* Flush PCI config writes */
+       stwbrx  r4,0,r6
+
+       LOADPTR (r9, KAHLUA2_ID)
+        cmpl   0, 0, r7, r9
+        bne     L1not8245
+
+        /* MIOCR1 -- turn on bit for DLL delay */
+
+       LOADPTR (r3, MIOCR1_ADR_X)
+       stwbrx  r3,0,r5
+        li      r4, 0x04
+       stb     r4, MIOCR1_SHIFT(r6)
+
+        /* For the MPC8245, set register 77 to %00100000 (see Errata #15) */
+        /* SDRAM_CLK_DEL (0x77)*/
+
+       LOADPTR (r3, MIOCR2_ADR_X)
+       stwbrx  r3,0,r5
+        li      r4, 0x10
+       stb     r4, MIOCR2_SHIFT(r6)
+
+        /* PMCR2 -- set PCI hold delay to <10>b for 33 MHz */
+
+       LOADPTR (r3, PMCR2_ADR_X)
+       stwbrx  r3,0,r5
+        li      r4, 0x20
+       stb     r4, PMCR2_SHIFT(r6)
+
+       /* Initialize EUMBBAR early since 8245 has internal UART in EUMB */
+
+       LOADPTR (r3, EUMBBAR)
+       stwbrx  r3,0,r5
+       LOADPTR (r4, CFG_EUMB_ADDR)
+       stwbrx  r4,0,r6
+
+L1not8245:
+
+        /* Toggle the DLL reset bit in AMBOR */
+
+       LOADPTR (r3, AMBOR)
+       stwbrx  r3,0,r5
+       lbz     r4, 0(r6)
+
+        andi.   r4, r4, 0xdf
+       stb     r4, 0(r6)               /* Clear DLL_RESET */
+        sync
+
+        ori     r4, r4, 0x20           /* Set DLL_RESET */
+       stb     r4, 0(r6)
+        sync
+
+        andi.   r4, r4, 0xdf
+       stb     r4, 0(r6)               /* Clear DLL_RESET */
+
+
+       /* Enable RCS2, use supplied timings */
+       LOADPTR (r3, ERCR1)
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0x80408000)
+       stwbrx  r4,0,r6
+
+       /* Disable RCS3 parameters */
+       LOADPTR (r3, ERCR2)
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0x00000000)
+       stwbrx  r4,0,r6
+
+       /* RCS3 at 0x70000000, 64KBytes */
+       LOADPTR (r3, ERCR2)
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0x00000004)
+       stwbrx  r4,0,r6
+
+       /*-------MCCR1 */
+
+#ifdef INCLUDE_ECC
+#define MC_ECC                         1
+#else /* INCLUDE_ECC */
+#define MC_ECC                         0
+#endif /* INCLUDE_ECC */
+
+#define MC1_ROMNAL                     8               /* 0-15 */
+#define MC1_ROMFAL                     11              /* 0-31 */
+#define MC1_DBUS_SIZE                  0               /* 0-3, read only */
+#define MC1_BURST                      0               /* 0-1 */
+#define MC1_MEMGO                      0               /* 0-1 */
+#define MC1_SREN                       1               /* 0-1 */
+#define MC1_RAM_TYPE                   0               /* 0-1 */
+#define MC1_PCKEN                      MC_ECC          /* 0-1 */
+#define MC1_BANKBITS                   0x5555          /* 2 bits/bank 7-0 */
+
+       LOADPTR (r3, MEM_CONT1_ADR)     /* Set MCCR1 (F0) */
+       stwbrx  r3,0,r5
+       LOADPTR(r4, \
+               MC1_ROMNAL << 28 | MC1_ROMFAL << 23 | \
+               MC1_DBUS_SIZE << 21 | MC1_BURST << 20 | \
+               MC1_MEMGO << 19 | MC1_SREN << 18 | \
+               MC1_RAM_TYPE << 17 | MC1_PCKEN << 16 )
+       li      r3, MC1_BANKBITS
+        cmpl   0, 0, r7, r9            /* Check for Kahlua2 */
+        bne     BankBitsAdd
+        cmpli   0, 0, r3, 0x5555
+        beq     K2BankBitsHack         /* On 8245, 5555 ==> 0 */
+BankBitsAdd:
+       ori     r4, r3, 0
+K2BankBitsHack:
+       stwbrx  r4, 0, r6
+
+       /*------- MCCR2 */
+
+#define MC2_TS_WAIT_TIMER              0               /* 0-7 */
+#define MC2_ASRISE                     8               /* 0-15 */
+#define MC2_ASFALL                     4               /* 0-15 */
+#define MC2_INLINE_PAR_NOT_ECC         0               /* 0-1 */
+#define MC2_WRITE_PARITY_CHK_EN                MC_ECC          /* 0-1 */
+#define MC2_INLRD_PARECC_CHK_EN                MC_ECC          /* 0-1 */
+#define MC2_ECC_EN                     0               /* 0-1 */
+#define MC2_EDO                                0               /* 0-1 */
+/*
+*  N.B. This refresh interval looks good up to 85 MHz with Hynix SDRAM.
+*  May need to be decreased for 100 MHz
+*/
+#define MC2_REFINT                     0x3a5           /* 0-0x3fff */
+#define MC2_RSV_PG                     0               /* 0-1 */
+#define MC2_RMW_PAR                    MC_ECC          /* 0-1 */
+
+       LOADPTR (r3, MEM_CONT2_ADR)     /* Set MCCR2 (F4) */
+       stwbrx  r3,0,r5
+       LOADPTR(r4, \
+               MC2_TS_WAIT_TIMER << 29 | MC2_ASRISE << 25 | \
+               MC2_ASFALL << 21 | MC2_INLINE_PAR_NOT_ECC << 20 | \
+               MC2_WRITE_PARITY_CHK_EN << 19 | \
+               MC2_INLRD_PARECC_CHK_EN << 18 | \
+               MC2_ECC_EN << 17 | MC2_EDO << 16 | \
+               MC2_REFINT << 2 | MC2_RSV_PG << 1 | MC2_RMW_PAR)
+        cmpl   0, 0, r7, r9            /* Check for Kahlua2 */
+        bne     notK2
+        /* clear Kahlua2 reserved bits */
+       LOADPTR (r3, 0xfffcffff)
+       and     r4, r4, r3
+notK2:
+       stwbrx  r4,0,r6
+
+       /*------- MCCR3 */
+
+#define MC_BSTOPRE                     0x079           /* 0-0x7ff */
+
+#define MC3_BSTOPRE_U                  (MC_BSTOPRE >> 4 & 0xf)
+#define MC3_REFREC                     8               /* 0-15 */
+#define MC3_RDLAT                      (4+MC_ECC)      /* 0-15 */
+#define MC3_CPX                                0               /* 0-1 */
+#define MC3_RAS6P                      0               /* 0-15 */
+#define MC3_CAS5                       0               /* 0-7 */
+#define MC3_CP4                                0               /* 0-7 */
+#define MC3_CAS3                       0               /* 0-7 */
+#define MC3_RCD2                       0               /* 0-7 */
+#define MC3_RP1                                0               /* 0-7 */
+
+       LOADPTR (r3, MEM_CONT3_ADR)     /* Set MCCR3 (F8) */
+       stwbrx  r3,0,r5
+       LOADPTR(r4, \
+               MC3_BSTOPRE_U << 28 | MC3_REFREC << 24 | \
+               MC3_RDLAT << 20 | MC3_CPX << 19 | \
+               MC3_RAS6P << 15 | MC3_CAS5 << 12 | MC3_CP4 << 9 | \
+               MC3_CAS3 << 6 | MC3_RCD2 << 3 | MC3_RP1)
+        cmpl   0, 0, r7, r9              /* Check for Kahlua2 */
+        bne     notK2b
+        /* clear Kahlua2 reserved bits */
+       LOADPTR (r3, 0xff000000)
+       and     r4, r4, r3
+notK2b:
+       stwbrx  r4,0,r6
+
+       /*------- MCCR4 */
+
+#define MC4_PRETOACT                   3               /* 0-15 */
+#define MC4_ACTOPRE                    5               /* 0-15 */
+#define MC4_WMODE                      0               /* 0-1 */
+#define MC4_INLINE                     MC_ECC          /* 0-1 */
+#define MC4_REGISTERED                 (1-MC_ECC)      /* 0-1 */
+#define MC4_BSTOPRE_UU                 (MC_BSTOPRE >> 8 & 3)
+#define MC4_REGDIMM                    0               /* 0-1 */
+#define MC4_SDMODE_CAS                 2               /* 0-7 */
+#define MC4_DBUS_RCS1                  1               /* 0-1, 8-bit */
+#define MC4_SDMODE_WRAP                        0               /* 0-1 */
+#define MC4_SDMODE_BURST               2               /* 0-7 */
+#define MC4_ACTORW                     3               /* 0-15 */
+#define MC4_BSTOPRE_L                  (MC_BSTOPRE & 0xf)
+
+       LOADPTR (r3, MEM_CONT4_ADR)     /* Set MCCR4 (FC) */
+       stwbrx  r3,0,r5
+       LOADPTR(r4, \
+               MC4_PRETOACT << 28 | MC4_ACTOPRE << 24 | \
+               MC4_WMODE << 23 | MC4_INLINE << 22 | \
+               MC4_REGISTERED << 20 | MC4_BSTOPRE_UU << 18 | \
+               MC4_DBUS_RCS1 << 17 | \
+               MC4_REGDIMM << 15 | MC4_SDMODE_CAS << 12 | \
+               MC4_SDMODE_WRAP << 11 | MC4_SDMODE_BURST << 8 | \
+               MC4_ACTORW << 4 | MC4_BSTOPRE_L)
+        cmpl   0, 0, r7, r9                /* Check for Kahlua 2 */
+        bne     notK2c
+        /* Turn on Kahlua2 extended ROM space */
+       LOADPTR (r3, 0x00200000)
+       or      r4, r4, r3
+notK2c:
+       stwbrx  r4,0,r6
+
+#ifdef INCLUDE_ECC
+       /*------- MEM_ERREN1 */
+
+       LOADPTR (r3, MEM_ERREN1_ADR)    /* Set MEM_ERREN1 (c0) */
+       stwbrx  r3,0,r5
+       lwbrx   r4,0,r6
+       ori     r4,r4,4                 /* Set MEM_PERR_EN */
+       stwbrx  r4,0,r6
+#endif /* INCLUDE_ECC */
+
+       /*------- MSAR/MEAR */
+
+       LOADPTR (r3, MEM_START1_ADR)    /* Set MSAR1 (80) */
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0xc0804000)
+       stwbrx  r4,0,r6
+
+       LOADPTR (r3, MEM_START2_ADR)    /* Set MSAR2 (84) */
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0xc0804000)
+       stwbrx  r4,0,r6
+
+       LOADPTR (r3, XMEM_START1_ADR)   /* Set MESAR1 (88) */
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0x00000000)
+       stwbrx  r4,0,r6
+
+       LOADPTR (r3, XMEM_START2_ADR)   /* Set MESAR2 (8c) */
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0x01010101)
+       stwbrx  r4,0,r6
+
+       LOADPTR (r3, MEM_END1_ADR)      /* Set MEAR1 (90) */
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0xffbf7f3f)
+       stwbrx  r4,0,r6
+
+       LOADPTR (r3, MEM_END2_ADR)      /* Set MEAR2 (94) */
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0xffbf7f3f)
+       stwbrx  r4,0,r6
+
+       LOADPTR (r3, XMEM_END1_ADR)     /* MEEAR1 (98) */
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0x00000000)
+       stwbrx  r4,0,r6
+
+       LOADPTR (r3, XMEM_END2_ADR)     /* MEEAR2 (9c) */
+       stwbrx  r3,0,r5
+       LOADPTR (r4, 0x01010101)
+       stwbrx  r4,0,r6
+
+       /*-------ODCR */
+
+       LOADPTR (r3, ODCR_ADR_X)        /* Set ODCR */
+       stwbrx  r3,0,r5
+
+       li      r4, 0x7f
+       stb     r4, ODCR_SHIFT(r6)      /* ODCR is at +3 offset */
+
+       /*-------MBEN */
+
+       LOADPTR (r3, MEM_EN_ADR)        /* Set MBEN (a0) */
+       stwbrx  r3,0,r5
+       li      r4, 0x01                /* Enable bank 0 */
+       stb     r4, 0(r6)               /* MBEN is at +0 offset */
+
+#if 0   /* Jimmy:  I think page made is broken */
+       /*-------PGMAX */
+
+       LOADPTR (r3, MPM_ADR_X)
+       stwbrx  r3,0,r5
+       li      r4, 0x32
+       stb     r4, MPM_SHIFT(r6)               /* PAGE_MODE is at +3 offset */
+#endif
+
+       /* Wait before initializing other registers */
+
+       lis     r4,0x0001
+       mtctr   r4
+
+KahluaX4wait200us:
+       bdnz    KahluaX4wait200us
+
+       /* Set MEMGO bit */
+
+       LOADPTR (r3, MEM_CONT1_ADR)     /* MCCR1 (F0) |= PGMAX */
+       stwbrx  r3,0,r5
+       lwbrx   r4,0,r6                 /* old MCCR1 */
+       oris    r4,r4,0x0008            /* MEMGO=1 */
+       stwbrx  r4, 0, r6
+
+       /* Wait again */
+
+       addis   r4,r0,0x0002
+       ori     r4,r4,0xffff
+
+       mtctr   r4
+
+KahluaX4wait8ref:
+       bdnz    KahluaX4wait8ref
+
+       sync
+       eieio
+        mtlr    r11
+       blr
+
+#else /* USE_V2_INIT */
+
+
+
+/* U-Boot works, but memory will not run reliably for all address ranges.
+ * Early U-Boot Working init, but 2.4.19 kernel will crash since memory is not
+ * initialized correctly. Could work if debugged.
+ */
+/* PCI Support routines */
+
+    .globl __pci_config_read_32
+__pci_config_read_32:
+    lis     r4, 0xfec0
+    stwbrx   r3, r0, r4
+    sync
+    lis     r4, 0xfee0
+    lwbrx   r3, 0, r4
+    blr
+    .globl __pci_config_read_16
+__pci_config_read_16:
+    lis     r4, 0xfec0
+    andi.    r5, r3, 2
+    stwbrx  r3, r0, r4
+    sync
+    oris     r4, r5, 0xfee0
+    lhbrx    r3, r0, r4
+    blr
+    .globl __pci_config_read_8
+__pci_config_read_8:
+    lis     r4, 0xfec0
+    andi.    r5, r3, 3
+    stwbrx  r3, r0, r4
+    sync
+    oris     r4, r5, 0xfee0
+    lbz      r3, 0(4)
+    blr
+    .globl __pci_config_write_32
+__pci_config_write_32:
+    lis     r5, 0xfec0
+    stwbrx   r3, r0, r5
+    sync
+    lis      r5, 0xfee0
+    stwbrx   r4, r0, r5
+    sync
+    blr
+    .globl __pci_config_write_16
+__pci_config_write_16:
+    lis     r5, 0xfec0
+    andi.    r6, r3, 2
+    stwbrx  r3, r0, 5
+    sync
+    oris     r5, r6, 0xfee0
+    sthbrx    r4, r0, r5
+    sync
+    blr
+    .globl __pci_config_write_8
+__pci_config_write_8:
+    lis      r5, 0xfec0
+    andi.    r6, r3, 3
+    stwbrx   r3, r0, r5
+    sync
+    oris      r5, r6, 0xfee0
+    stb       r4, 0(r5)
+    sync
+    blr
+    .globl  in_8
+in_8:
+    oris    r3, r3, 0xfe00
+    lbz     r3,0(r3)
+    blr
+    .globl  in_16
+in_16:
+    oris    r3, r3, 0xfe00
+    lhbrx   r3, 0, r3
+    blr
+    .globl in_16_ne
+in_16_ne:
+    oris    r3, r3, 0xfe00
+    lhzx    r3, 0, r3
+    blr
+    .globl  in_32
+in_32:
+    oris    r3, r3, 0xfe00
+    lwbrx   r3, 0, r3
+    blr
+    .globl  out_8
+out_8:
+    oris    r3, r3, 0xfe00
+    stb     r4, 0(r3)
+    eieio
+    blr
+    .globl  out_16
+out_16:
+    oris    r3, r3, 0xfe00
+    sthbrx  r4, 0, r3
+    eieio
+    blr
+    .globl  out_16_ne
+out_16_ne:
+    oris    r3, r3, 0xfe00
+    sth     r4, 0(r3)
+    eieio
+    blr
+    .globl  out_32
+out_32:
+    oris    r3, r3, 0xfe00
+    stwbrx  r4, 0, r3
+    eieio
+    blr
+    .globl  read_8
+read_8:
+    lbz     r3,0(r3)
+    blr
+    .globl  read_16
+read_16:
+    lhbrx   r3, 0, r3
+    blr
+    .globl  read_32
+read_32:
+    lwbrx   r3, 0, r3
+    blr
+    .globl  read_32_ne
+read_32_ne:
+    lwz     r3, 0(r3)
+    blr
+    .globl  write_8
+write_8:
+    stb     r4, 0(r3)
+    eieio
+    blr
+    .globl  write_16
+write_16:
+    sthbrx  r4, 0, r3
+    eieio
+    blr
+    .globl  write_32
+write_32:
+    stwbrx  r4, 0, r3
+    eieio
+    blr
+    .globl  write_32_ne
+write_32_ne:
+    stw     r4, 0(r3)
+    eieio
+    blr
+
+
+.globl  early_init_f
+
+early_init_f:
+        mflr    r11
+        lis     r10, 0x8000
+
+        /* PCI Latency Timer */
+        li      r4, 0x0d
+        ori     r3, r10, PLTR@l
+        bl      __pci_config_write_8
+
+        /* Cache Line Size */
+        li      r4, 0x08
+        ori     r3, r10, PCLSR@l
+        bl      __pci_config_write_8
+
+        /* PCI Cmd */
+        li      r4, 6
+        ori     r3, r10, PCICR@l
+        bl      __pci_config_write_16
+
+#if 1
+        /* PCI Stat */
+        ori     r3, r10, PCISR@l
+        bl      __pci_config_read_16
+        ori     r4, r4, 0xffff
+        ori     r3, r10, PCISR@l
+        bl      __pci_config_write_16
+#endif
+
+        /* PICR1 */
+        lis     r4, 0xff14
+        ori     r4, r4, 0x1b98
+        ori     r3, r10, PICR1@l
+        bl      __pci_config_write_32
+
+
+        /* PICR2 */
+        lis     r4, 0x0404
+        ori     r4, r4, 0x0004
+        ori     r3, r10, PICR2@l
+        bl      __pci_config_write_32
+
+       /* MIOCR1 */
+        li      r4, 0x04
+        ori     r3, r10, MIOCR1@l
+        bl      __pci_config_write_8
+
+       /* For the MPC8245, set register 77 to %00100000 (see Errata #15) */
+       /* SDRAM_CLK_DEL (0x77)*/
+        li      r4, 0x10
+        ori     r3, r10, MIOCR2@l
+        bl      __pci_config_write_8
+
+        /* EUMBBAR */
+        lis     r4, 0xfc00
+        ori     r3, r10, EUMBBAR@l
+        bl      __pci_config_write_32
+
+       /* AMBOR */
+
+       /* Even if Address Map B is not being used (though it should),
+        * the memory DLL needs to be cleared/set/cleared before using memory.
+       */
+
+        ori     r3, r10, AMBOR@l
+        bl      __pci_config_read_8    /* get Current bits */
+
+        andi.   r4, r4, 0xffdf
+        ori     r3, r10, AMBOR@l
+        bl      __pci_config_write_16  /* Clear DLL_RESET */
+
+        ori    r4, r4, 0x0020
+        ori     r3, r10, AMBOR@l
+        bl      __pci_config_write_16  /* Set DLL_RESET */
+
+        andi.   r4, r4, 0xffdf
+        ori     r3, r10, AMBOR@l
+        bl      __pci_config_write_16  /* Clear DLL_RESET */
+
+        /* ERCR1 */
+        lis     r4, 0x8040             /* Enable RCS2, use supplied timings */
+        ori     r4, r4, 0x8000
+        ori     r3, r10, ERCR1@l
+        bl      __pci_config_write_32
+
+        /* ERCR2 */
+        lis     r4, 0x0000             /* Disable RCS3 parms */
+        ori     r4, r4, 0x0000
+        ori     r3, r10, ERCR2@l
+        bl      __pci_config_write_32
+
+        /* ERCR3 */
+        lis     r4, 0x0000             /* RCS3 at 0x70000000, 64K bytes */
+        ori     r4, r4, 0x0004
+        ori     r3, r10, ERCR2@l
+        bl      __pci_config_write_32
+
+       /* Preserve memgo bit */
+        /* MCCR1 */
+
+/*     lis     r4, 0x75a8              /  Safe Local ROM = 11+3 clocks */
+       lis     r4, 0x75a0              /* Safe Local ROM = 11+3 clocks */
+/*      lis     r4, 0x73a0              /  Fast Local ROM = 7+3 clocks */
+/*      oris    r4, r4, 0x0010          /  Burst ROM/Flash enable */
+/*      oris    r4, r4, 0x0004          /  Self-refresh enable */
+
+/*      ori     r4,r4,0xFFFF            /  16Mbit  2bank SDRAM */
+/*      ori     r4,r4,0xAAAA            /  256Mbit 4bank SDRAM (8245 only) */
+/*      ori     r4,r4,0x5555            /  64Mbit  2bank SDRAM */
+        ori     r4,r4,0x0000            /* 64Mbit  4bank SDRAM */
+
+        ori     r3, r10, MCCR1@l
+        bl      __pci_config_write_32
+
+        /* MCCR2 */
+
+        lis     r4,0x0000
+/*      oris    r4,r4,0x4000            /  TS_WAIT_TIMER = 3 clocks */
+        oris    r4,r4,0x1000            /* ASRISE = 8 clocks */
+        oris    r4,r4,0x0080            /* ASFALL = 8 clocks */
+/*      oris    r4,r4,0x0010            /  SDRAM Parity (else ECC) */
+/*      oris    r4,r4,0x0008            /  Write parity check */
+/*      oris    r4,r4,0x0004            /  SDRAM inline reads */
+
+
+/* Select a refresh rate; it needs to match the bus speed; if too */
+/* slow, data may be lost; if too fast, performance is lost.  We */
+/* use the fastest value so we run at all speeds. */
+/* Refresh = (15600ns/busclk) - (213 (see UM)). */
+
+/*      ori     r4,r4,0x1d2c            /  133 MHz mem bus        = 1867 */
+/*      ori     r4,r4,0x150c            /  100 MHz mem bus        = 1347 */
+/*      ori     r4,r4,0x10fc            /   83 MHz mem bus        = 1087 */
+/*      ori     r4,r4,0x0cc4            /   66 MHz mem bus        =  817 */
+        ori     r4,r4,0x04cc            /*  33 MHz mem bus (SAFE) =  307 */
+/*      ori     r4,r4,0x0002            /  Reserve a page */
+/*      ori     r4,r4,0x0001            /  RWM parity */
+
+        ori     r3, r10, MCCR2@l
+        bl      __pci_config_write_32
+
+
+        /* MCCR3 */
+        lis     r4,0x0000               /* BSTOPRE_M = 7 (see A/N) */
+        oris    r4,r4,0x0500            /* REFREC    = 8 clocks */
+        ori     r3, r10, MCCR3@l
+        bl      __pci_config_write_32
+
+        /* MCCR4 */                     /* Turn on registered buffer mode */
+        lis     r4, 0x2000              /* PRETOACT = 3 clocks */
+        oris    r4,r4,0x0400            /* ACTOPRE  = 5 clocks */
+/*      oris    r4,r4,0x0080            /  Enable 8-beat burst (32-bit bus) */
+/*      oris    r4,r4,0x0040            /  Enable Inline ECC/Parity */
+        oris    r4,r4,0x0020            /* EXTROM enabled */
+        oris    r4,r4,0x0010            /* Registered buffers */
+/*      oris    r4,r4,0x0000            /  BSTOPRE_U = 0 (see A/N) */
+        oris    r4,r4,0x0002            /* DBUS_SIZ[2] (8 bit on RCS1) */
+
+/*      ori     r4,r4,0x8000            /  Registered DIMMs */
+        ori     r4,r4,0x2000            /*CAS Latency (CL=3) (see RDLAT) */
+/*      ori     r4,r4,0x2000            /  CAS Latency (CL=2) (see RDLAT) */
+/*      ori     r4,r4,0x0300            /  Sequential wrap/8-beat burst */
+        ori     r4,r4,0x0200            /* Sequential wrap/4-beat burst */
+        ori     r4,r4,0x0030            /* ACTORW  = 3 clocks */
+        ori     r4,r4,0x0009            /* BSTOPRE_L = 9 (see A/N) */
+
+        ori     r3, r10, MCCR4@l
+        bl      __pci_config_write_32
+
+       /* MSAR1 */
+        lis     r4, 0xc0804000@h
+        ori     r4, r4, 0xc0804000@l
+        ori     r3, r10, MSAR1@l
+        bl      __pci_config_write_32
+
+       /* MSAR2 */
+        lis     r4, 0xc0804000@h
+        ori     r4, r4, 0xc0804000@l
+        ori     r3, r10, MSAR2@l
+        bl      __pci_config_write_32
+
+       /* MESAR1 */
+        lis     r4, 0x00000000@h
+        ori     r4, r4, 0x00000000@l
+        ori     r3, r10, EMSAR1@l
+        bl      __pci_config_write_32
+
+       /* MESAR2 */
+        lis     r4, 0x01010101@h
+        ori     r4, r4, 0x01010101@l
+        ori     r3, r10, EMSAR2@l
+        bl      __pci_config_write_32
+
+       /* MEAR1 */
+        lis     r4, 0xffbf7f3f@h
+        ori     r4, r4, 0xffbf7f3f@l
+        ori     r3, r10, MEAR1@l
+        bl      __pci_config_write_32
+
+       /* MEAR2 */
+        lis     r4, 0xffbf7f3f@h
+        ori     r4, r4, 0xffbf7f3f@l
+        ori     r3, r10, MEAR2@l
+        bl      __pci_config_write_32
+
+       /* MEEAR1 */
+        lis     r4, 0x00000000@h
+        ori     r4, r4, 0x00000000@l
+        ori     r3, r10, EMEAR1@l
+        bl      __pci_config_write_32
+
+       /* MEEAR2 */
+        lis     r4, 0x01010101@h
+        ori     r4, r4, 0x01010101@l
+        ori     r3, r10, EMEAR2@l
+        bl      __pci_config_write_32
+
+       /* ODCR */
+        li      r4, 0x7f
+        ori     r3, r10, ODCR@l
+        bl      __pci_config_write_8
+
+       /* MBER */
+        li      r4, 0x01
+        ori     r3, r10, MBER@l
+        bl      __pci_config_write_8
+
+        /* Page CTR aka PGMAX */
+        li      r4, 0x32
+        ori     r3, r10, 0x70
+        bl      __pci_config_write_8
+
+#if 0
+       /* CLK Drive */
+        ori     r4, r10, 0xfc01 /* Top bit will be ignored */
+        ori     r3, r10, 0x74
+        bl      __pci_config_write_16
+#endif
+
+       /* delay */
+        lis     r7, 1
+        mtctr   r7
+label1:        bdnz    label1
+
+        /* Set memgo bit */
+        /* MCCR1 */
+        ori     r3, r10, MCCR1@l
+        bl      __pci_config_read_32
+        lis    r7, 0x0008
+        or     r4, r3, r7
+        ori     r3, r10, MCCR1@l
+        bl      __pci_config_write_32
+
+       /* delay again */
+        lis     r7, 1
+        mtctr   r7
+label2:        bdnz    label2
+#if 0
+/* DEBUG: Infinite loop, write then read */
+loop:
+        lis     r7, 0xffff
+        mtctr   r7
+        li     r3, 0x5004
+        lis    r4, 0xa0a0
+        ori    r4, r4, 0x5050
+       bl write_32_ne
+        li     r3, 0x5004
+       bl read_32_ne
+       bdnz    loop
+#endif
+        mtlr    r11
+        blr
+#endif
+
diff --git a/board/gw8260/flash.c b/board/gw8260/flash.c
new file mode 100644 (file)
index 0000000..532dd19
--- /dev/null
@@ -0,0 +1,523 @@
+/*
+ * (C) Copyright 2000
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ *
+ * (C) Copyright 2000, 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001
+ * Advent Networks, Inc. <http://www.adventnetworks.com>
+ * Oliver Brown <oliverb@alumni.utexas.net>
+ *
+ *--------------------------------------------------------------------
+ * 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:
+ *   This file contains the flash routines for the GW8260 board.
+ *
+ *
+ *
+ * MODULE DEPENDENCY:
+ *   None
+ *
+ *
+ * RESTRICTIONS/LIMITATIONS:
+ *
+ *   Only supports the following flash devices:
+ *     AMD 29F080B
+ *     AMD 29F016D
+ *
+ * Copyright (c) 2001, Advent Networks, Inc.
+ *
+ */
+/*********************************************************************/
+
+#include <common.h>
+#include <mpc8260.h>
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+
+/*********************************************************************/
+/*                   functions                                      */
+/*********************************************************************/
+
+/*********************************************************************/
+/* NAME: flash_init() -         initializes flash banks                     */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   This function initializes the flash bank(s).                   */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   The size in bytes of the flash                                 */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*                                                                  */
+/*                                                                  */
+/*********************************************************************/
+unsigned long flash_init (void)
+{
+    unsigned long size;
+    int i;
+
+    /* Init: no FLASHes known */
+    for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+       flash_info[i].flash_id = FLASH_UNKNOWN;
+    }
+
+    /* for now, only support the 4 MB Flash SIMM */
+    size = flash_get_size((vu_long *)CFG_FLASH0_BASE, &flash_info[0]);
+
+    /*
+     * protect monitor and environment sectors
+     */
+
+#if CFG_MONITOR_BASE >= CFG_FLASH0_BASE
+    flash_protect(FLAG_PROTECT_SET,
+                 CFG_MONITOR_BASE,
+                 CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+                 &flash_info[0]);
+#endif
+
+#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
+# ifndef  CFG_ENV_SIZE
+#  define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
+# endif
+    flash_protect(FLAG_PROTECT_SET,
+                 CFG_ENV_ADDR,
+                 CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+                 &flash_info[0]);
+#endif
+
+    return (CFG_FLASH0_SIZE * 1024 * 1024);  /*size*/
+}
+
+/*********************************************************************/
+/* NAME: flash_print_info() - prints flash imformation              */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   This function prints the flash information.                    */
+/*                                                                  */
+/* INPUTS:                                                          */
+/*   flash_info_t *info - flash information structure               */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   Displays flash information to console                          */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   None                                                           */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*                                                                  */
+/*                                                                  */
+/*********************************************************************/
+void flash_print_info  (flash_info_t *info)
+{
+    int i;
+
+    if (info->flash_id == FLASH_UNKNOWN) {
+       printf ("missing or unknown FLASH type\n");
+       return;
+    }
+
+    switch ((info->flash_id >> 16) & 0xff) {
+    case 0x1:
+       printf ("AMD ");
+       break;
+    default:
+       printf ("Unknown Vendor ");
+       break;
+    }
+
+    switch (info->flash_id & FLASH_TYPEMASK) {
+    case AMD_ID_F040B:
+       printf ("AM29F040B (4 Mbit)\n");
+       break;
+    case AMD_ID_F080B:
+       printf ("AM29F080B (8 Mbit)\n");
+       break;
+    case AMD_ID_F016D:
+       printf ("AM29F016D (16 Mbit)\n");
+       break;
+    default:
+       printf ("Unknown Chip Type\n");
+       break;
+    }
+
+    printf ("  Size: %ld MB in %d Sectors\n",
+           info->size >> 20, info->sector_count);
+
+    printf ("  Sector Start Addresses:");
+    for (i=0; i<info->sector_count; ++i) {
+       if ((i % 5) == 0)
+           printf ("\n   ");
+       printf (" %08lX%s",
+               info->start[i],
+               info->protect[i] ? " (RO)" : "     "
+           );
+    }
+    printf ("\n");
+    return;
+}
+
+/*********************************************************************/
+/*   The following code cannot be run from FLASH!                   */
+/*********************************************************************/
+
+/*********************************************************************/
+/* NAME: flash_get_size() - detects the flash size                  */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   1) Reads vendor ID and devices ID from the flash devices.      */
+/*   2) Initializes flash info struct.                              */
+/*   3) Return the flash size                                       */
+/*                                                                  */
+/* INPUTS:                                                          */
+/*   vu_long *addr     - pointer to start of flash                  */
+/*   flash_info_t *info - flash information structure               */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   None                                                           */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   Size of the flash in bytes, or 0 if device id is unknown.      */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*   Only supports the following devices:                           */
+/*     AM29F080D                                                    */
+/*     AM29F016D                                                    */
+/*                                                                  */
+/*********************************************************************/
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+    short i;
+    vu_long vendor, devid;
+    ulong base = (ulong)addr;
+
+    /*printf("addr   = %08lx\n", (unsigned long)addr); */
+
+    /* Reset and Write auto select command: read Manufacturer ID */
+    addr[0x0000] = 0xf0f0f0f0;
+    addr[0x0555] = 0xAAAAAAAA;
+    addr[0x02AA] = 0x55555555;
+    addr[0x0555] = 0x90909090;
+    udelay (1000);
+
+    vendor = addr[0];
+    /*printf("vendor = %08lx\n", vendor); */
+    if (vendor != 0x01010101) {
+       info->size = 0;
+       goto out;
+    }
+
+    devid = addr[1];
+    /*printf("devid  = %08lx\n", devid); */
+
+    if ((devid & 0xff) == AMD_ID_F080B) {
+       info->flash_id     = (vendor & 0xff) << 16 | AMD_ID_F080B;
+       /* we have 16 sectors with 64KB each x 4 */
+       info->sector_count = 16;
+       info->size         = 4 * info->sector_count * 64*1024;
+    } else if ((devid & 0xff) == AMD_ID_F016D){
+       info->flash_id     = (vendor & 0xff) << 16 | AMD_ID_F016D;
+       /* we have 32 sectors with 64KB each x 4 */
+       info->sector_count = 32;
+       info->size         = 4 * info->sector_count * 64*1024;
+    } else {
+       info->size = 0;
+       goto out;
+    }
+    /*printf("sector count = %08x\n", info->sector_count); */
+    /* check for protected sectors */
+    for (i = 0; i < info->sector_count; i++) {
+       /* sector base address */
+       info->start[i] = base + i * (info->size / info->sector_count);
+       /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+       /* D0 = 1 if protected */
+       addr = (volatile unsigned long *)(info->start[i]);
+       info->protect[i] = addr[2] & 1;
+    }
+
+    /* reset command */
+    addr = (vu_long *)info->start[0];
+
+  out:
+    addr[0] = 0xf0f0f0f0;
+
+    /*printf("size = %08x\n", info->size); */
+    return info->size;
+}
+
+/*********************************************************************/
+/* NAME: flash_erase() - erases flash by sector                             */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   This function erases flash sectors starting for s_first to             */
+/*   s_last.                                                        */
+/*                                                                  */
+/* INPUTS:                                                          */
+/*   flash_info_t *info - flash information structure               */
+/*   int s_first - first sector to erase                            */
+/*   int s_last         - last sector to erase                              */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   None                                                           */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   Returns 0 for success, 1 for failure.                          */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*                                                                  */
+/*********************************************************************/
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+    vu_long *addr = (vu_long*)(info->start[0]);
+    int flag, prot, sect, l_sect;
+    ulong start, now, last;
+
+    if ((s_first < 0) || (s_first > s_last)) {
+       if (info->flash_id == FLASH_UNKNOWN) {
+           printf ("- missing\n");
+       } else {
+           printf ("- no sectors to erase\n");
+       }
+       return 1;
+    }
+
+    prot = 0;
+    for (sect = s_first; sect <= s_last; sect++) {
+       if (info->protect[sect]) {
+           prot++;
+       }
+    }
+
+    if (prot) {
+       printf ("- Warning: %d protected sectors will not be erased!\n",
+               prot);
+    } else {
+       printf ("\n");
+    }
+
+    l_sect = -1;
+
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+
+    addr[0x0555] = 0xAAAAAAAA;
+    addr[0x02AA] = 0x55555555;
+    addr[0x0555] = 0x80808080;
+    addr[0x0555] = 0xAAAAAAAA;
+    addr[0x02AA] = 0x55555555;
+    udelay (100);
+
+    /* Start erase on unprotected sectors */
+    for (sect = s_first; sect <= s_last; sect++) {
+       if (info->protect[sect] == 0) { /* not protected */
+           addr = (vu_long*)(info->start[sect]);
+           addr[0] = 0x30303030;
+           l_sect = sect;
+       }
+    }
+
+    /* re-enable interrupts if necessary */
+    if (flag)
+       enable_interrupts();
+
+    /* wait at least 80us - let's wait 1 ms */
+    udelay (1000);
+
+    /*
+     * We wait for the last triggered sector
+     */
+    if (l_sect < 0)
+       goto DONE;
+
+    start = get_timer (0);
+    last  = start;
+    addr = (vu_long*)(info->start[l_sect]);
+    while ((addr[0] & 0x80808080) != 0x80808080) {
+       if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+           printf ("Timeout\n");
+           return 1;
+       }
+       /* show that we're waiting */
+       if ((now - last) > 1000) {  /* every second */
+           serial_putc ('.');
+           last = now;
+       }
+    }
+
+  DONE:
+    /* reset to read mode */
+    addr = (volatile unsigned long *)info->start[0];
+    addr[0] = 0xF0F0F0F0;   /* reset bank */
+
+    printf (" done\n");
+    return 0;
+}
+
+/*********************************************************************/
+/* NAME: write_buff() - writes a buffer to flash                    */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   This function copies a buffer, *src, to flash.                 */
+/*                                                                  */
+/* INPUTS:                                                          */
+/*  flash_info_t *info - flash information structure                */
+/*  uchar *src - pointer to buffer to write to flash                */
+/*  ulong addr - address to start write at                          */
+/*  ulong cnt - number of bytes to write to flash                   */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   None                                                           */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   0 - OK                                                         */
+/*   1 - write timeout                                              */
+/*   2 - Flash not erased                                           */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*                                                                  */
+/*********************************************************************/
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    ulong cp, wp, data;
+    int i, l, rc;
+
+    wp = (addr & ~3);  /* get lower word aligned address */
+
+    /*
+     * handle unaligned start bytes
+     */
+    if ((l = addr - wp) != 0) {
+       data = 0;
+       for (i = 0, cp = wp; i < l; ++i, ++cp) {
+           data = (data << 8) | (*(uchar *)cp);
+       }
+       for (; (i < 4) && (cnt > 0); ++i) {
+           data = (data << 8) | *src++;
+           --cnt;
+           ++cp;
+       }
+       for (; (cnt == 0) && (i < 4); ++i, ++cp) {
+           data = (data << 8) | (*(uchar *)cp);
+       }
+
+       if ((rc = write_word(info, wp, data)) != 0) {
+           return (rc);
+       }
+       wp += 4;
+    }
+
+    /*
+     * handle word aligned part
+     */
+    while (cnt >= 4) {
+       data = 0;
+       for (i = 0; i < 4; ++i) {
+           data = (data << 8) | *src++;
+       }
+       if ((rc = write_word(info, wp, data)) != 0) {
+           return (rc);
+       }
+       wp  += 4;
+       cnt -= 4;
+    }
+
+    if (cnt == 0) {
+       return (0);
+    }
+
+    /*
+     * handle unaligned tail bytes
+     */
+    data = 0;
+    for (i = 0, cp = wp; (i < 4) && (cnt > 0); ++i, ++cp) {
+       data = (data << 8) | *src++;
+       --cnt;
+    }
+    for (; (i < 4); ++i, ++cp) {
+       data = (data << 8) | (*(uchar *)cp);
+    }
+
+    return (write_word(info, wp, data));
+}
+
+/*********************************************************************/
+/* NAME: write_word() - writes a word to flash                      */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   This writes a single word to flash.                            */
+/*                                                                  */
+/* INPUTS:                                                          */
+/*  flash_info_t *info - flash information structure                */
+/*  ulong dest - address to write                                   */
+/*  ulong data - data to write                                      */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   None                                                           */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   0 - OK                                                         */
+/*   1 - write timeout                                              */
+/*   2 - Flash not erased                                           */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*                                                                  */
+/*********************************************************************/
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+    vu_long *addr = (vu_long*)(info->start[0]);
+    ulong start;
+    int flag;
+
+    /* Check if Flash is (sufficiently) erased */
+    if ((*((vu_long *)dest) & data) != data) {
+       return (2);
+    }
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+
+    addr[0x0555] = 0xAAAAAAAA;
+    addr[0x02AA] = 0x55555555;
+    addr[0x0555] = 0xA0A0A0A0;
+
+    *((vu_long *)dest) = data;
+
+    /* re-enable interrupts if necessary */
+    if (flag)
+       enable_interrupts();
+
+    /* data polling for D7 */
+    start = get_timer (0);
+    while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) {
+       if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+           return (1);
+       }
+    }
+    return (0);
+}
+/*********************************************************************/
+/*                        End of flash.c                            */
+/*********************************************************************/
diff --git a/board/gw8260/gw8260.c b/board/gw8260/gw8260.c
new file mode 100644 (file)
index 0000000..7ca1989
--- /dev/null
@@ -0,0 +1,659 @@
+/*
+ * (C) Copyright 2000
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2001
+ * Advent Networks, Inc. <http://www.adventnetworks.com>
+ * Jay Monkman <jtm@smoothsmoothie.com>
+ *
+ * (C) Copyright 2001
+ * Advent Networks, Inc. <http://www.adventnetworks.com>
+ * Oliver Brown <oliverb@alumni.utexas.net>
+ *
+ * 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:
+ *   This file contains the board routines for the GW8260 board.
+ *
+ * MODULE DEPENDENCY:
+ *   None
+ *
+ * RESTRICTIONS/LIMITATIONS:
+ *   None
+ *
+ * Copyright (c) 2001, Advent Networks, Inc.
+ */
+/*********************************************************************/
+
+#include <common.h>
+#include <ioports.h>
+#include <mpc8260.h>
+
+/*
+ * I/O Port configuration table
+ *
+ */
+const iop_conf_t iop_conf_tab[4][32] = {
+
+    /* Port A configuration */
+    {  /*             conf ppar psor pdir podr pdat */
+       /* PA31 */ {   1,   0,   0,   1,   0,   0   }, /* TP14          */
+       /* PA30 */ {   1,   1,   1,   1,   0,   0   }, /* US_RTS        */
+       /* PA29 */ {   1,   0,   0,   1,   0,   1   }, /* LSSI_DATA     */
+       /* PA28 */ {   1,   0,   0,   1,   0,   1   }, /* LSSI_CLK      */
+       /* PA27 */ {   1,   0,   0,   1,   0,   0   }, /* TP12          */
+       /* PA26 */ {   1,   0,   0,   0,   0,   0   }, /* IO_STATUS     */
+       /* PA25 */ {   1,   0,   0,   0,   0,   0   }, /* IO_CLOCK      */
+       /* PA24 */ {   1,   0,   0,   0,   0,   0   }, /* IO_CONFIG     */
+       /* PA23 */ {   1,   0,   0,   0,   0,   0   }, /* IO_DONE       */
+       /* PA22 */ {   1,   0,   0,   0,   0,   0   }, /* IO_DATA       */
+       /* PA21 */ {   1,   1,   0,   1,   0,   0   }, /* US_TXD3       */
+       /* PA20 */ {   1,   1,   0,   1,   0,   0   }, /* US_TXD2       */
+       /* PA19 */ {   1,   1,   0,   1,   0,   0   }, /* US_TXD1       */
+       /* PA18 */ {   1,   1,   0,   1,   0,   0   }, /* US_TXD0       */
+       /* PA17 */ {   1,   1,   0,   0,   0,   0   }, /* DS_RXD0       */
+       /* PA16 */ {   1,   1,   0,   0,   0,   0   }, /* DS_RXD1       */
+       /* PA15 */ {   1,   1,   0,   0,   0,   0   }, /* DS_RXD2       */
+       /* PA14 */ {   1,   1,   0,   0,   0,   0   }, /* DS_RXD3       */
+       /* PA13 */ {   1,   0,   0,   1,   0,   0   }, /* SPARE7        */
+       /* PA12 */ {   1,   0,   0,   1,   0,   0   }, /* SPARE6        */
+       /* PA11 */ {   1,   0,   0,   1,   0,   0   }, /* SPARE5        */
+       /* PA10 */ {   1,   0,   0,   1,   0,   0   }, /* SPARE4        */
+       /* PA9  */ {   1,   0,   0,   1,   0,   0   }, /* SPARE3        */
+       /* PA8  */ {   1,   0,   0,   1,   0,   0   }, /* SPARE2        */
+       /* PA7  */ {   1,   0,   0,   0,   0,   0   }, /* LSSI_IN       */
+       /* PA6  */ {   1,   0,   0,   1,   0,   0   }, /* SPARE0        */
+       /* PA5  */ {   1,   0,   0,   1,   0,   0   }, /* DEMOD_RESET_  */
+       /* PA4  */ {   1,   0,   0,   1,   0,   0   }, /* MOD_RESET_    */
+       /* PA3  */ {   1,   0,   0,   1,   0,   0   }, /* IO_RESET      */
+       /* PA2  */ {   1,   0,   0,   1,   0,   0   }, /* TX_ENABLE     */
+       /* PA1  */ {   1,   0,   0,   0,   0,   0   }, /* RX_LOCK       */
+       /* PA0  */ {   1,   0,   0,   1,   0,   1   }  /* MPC_RESET_    */
+    },
+
+    /* Port B configuration */
+    {  /*             conf ppar psor pdir podr pdat */
+       /* PB31 */ {   1,   1,   0,   1,   0,   0   }, /* FETH0_TX_ER */
+       /* PB30 */ {   1,   1,   0,   0,   0,   0   }, /* FETH0_RX_DV */
+       /* PB29 */ {   1,   1,   1,   1,   0,   0   }, /* FETH0_TX_EN */
+       /* PB28 */ {   1,   1,   0,   0,   0,   0   }, /* FETH0_RX_ER */
+       /* PB27 */ {   1,   1,   0,   0,   0,   0   }, /* FETH0_COL   */
+       /* PB26 */ {   1,   1,   0,   0,   0,   0   }, /* FETH0_CRS   */
+       /* PB25 */ {   1,   1,   0,   1,   0,   0   }, /* FETH0_TXD3  */
+       /* PB24 */ {   1,   1,   0,   1,   0,   0   }, /* FETH0_TXD2  */
+       /* PB23 */ {   1,   1,   0,   1,   0,   0   }, /* FETH0_TXD1  */
+       /* PB22 */ {   1,   1,   0,   1,   0,   0   }, /* FETH0_TXD0  */
+       /* PB21 */ {   1,   1,   0,   0,   0,   0   }, /* FETH0_RXD0  */
+       /* PB20 */ {   1,   1,   0,   0,   0,   0   }, /* FETH0_RXD1  */
+       /* PB19 */ {   1,   1,   0,   0,   0,   0   }, /* FETH0_RXD2  */
+       /* PB18 */ {   1,   1,   0,   0,   0,   0   }, /* FETH0_RXD3  */
+       /* PB17 */ {   1,   1,   0,   0,   0,   0   }, /* FETH1_RX_DV */
+       /* PB16 */ {   1,   1,   0,   0,   0,   0   }, /* FETH1_RX_ER */
+       /* PB15 */ {   1,   1,   0,   1,   0,   0   }, /* FETH1_TX_ER */
+       /* PB14 */ {   1,   1,   0,   1,   0,   0   }, /* FETH1_TX_EN */
+       /* PB13 */ {   1,   1,   0,   0,   0,   0   }, /* FETH1_COL   */
+       /* PB12 */ {   1,   1,   0,   0,   0,   0   }, /* FETH1_CRS   */
+       /* PB11 */ {   1,   1,   0,   0,   0,   0   }, /* FETH1_RXD3  */
+       /* PB10 */ {   1,   1,   0,   0,   0,   0   }, /* FETH1_RXD2  */
+       /* PB9  */ {   1,   1,   0,   0,   0,   0   }, /* FETH1_RXD1  */
+       /* PB8  */ {   1,   1,   0,   0,   0,   0   }, /* FETH1_RXD0  */
+       /* PB7  */ {   1,   1,   0,   1,   0,   0   }, /* FETH1_TXD0  */
+       /* PB6  */ {   1,   1,   0,   1,   0,   0   }, /* FETH1_TXD1  */
+       /* PB5  */ {   1,   1,   0,   1,   0,   0   }, /* FETH1_TXD2  */
+       /* PB4  */ {   1,   1,   0,   1,   0,   0   }, /* FETH1_TXD3  */
+       /* PB3  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
+       /* PB2  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
+       /* PB1  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
+       /* PB0  */ {   0,   0,   0,   0,   0,   0   }  /* pin doesn't exist */
+    },
+
+    /* Port C */
+    {  /*             conf ppar psor pdir podr pdat */
+       /* PC31 */ {   1,   0,   0,   1,   0,   1   }, /* FAST_RESET_   */
+       /* PC30 */ {   1,   0,   0,   1,   0,   1   }, /* FAST_PAUSE_   */
+       /* PC29 */ {   1,   0,   0,   1,   0,   0   }, /* FAST_SLEW1    */
+       /* PC28 */ {   1,   0,   0,   1,   0,   0   }, /* FAST_SLEW0    */
+       /* PC27 */ {   1,   0,   0,   1,   0,   0   }, /* TP13          */
+       /* PC26 */ {   1,   0,   0,   0,   0,   0   }, /* RXDECDFLG     */
+       /* PC25 */ {   1,   0,   0,   0,   0,   0   }, /* RXACQFAIL     */
+       /* PC24 */ {   1,   0,   0,   0,   0,   0   }, /* RXACQFLG      */
+       /* PC23 */ {   1,   0,   0,   1,   0,   0   }, /* WD_TCL        */
+       /* PC22 */ {   1,   0,   0,   1,   0,   0   }, /* WD_EN         */
+       /* PC21 */ {   1,   0,   0,   1,   0,   0   }, /* US_TXCLK      */
+       /* PC20 */ {   1,   0,   0,   0,   0,   0   }, /* DS_RXCLK      */
+       /* PC19 */ {   1,   1,   0,   0,   0,   0   }, /* FETH0_RX_CLK  */
+       /* PC18 */ {   1,   1,   0,   0,   0,   0   }, /* FETH0_TX_CLK  */
+       /* PC17 */ {   1,   1,   0,   0,   0,   0   }, /* FETH1_RX_CLK  */
+       /* PC16 */ {   1,   1,   0,   0,   0,   0   }, /* FETH1_TX_CLK  */
+       /* PC15 */ {   1,   0,   0,   1,   0,   0   }, /* TX_SHUTDOWN_  */
+       /* PC14 */ {   1,   0,   0,   0,   0,   0   }, /* RS_232_DTR_   */
+       /* PC13 */ {   1,   0,   0,   0,   0,   0   }, /* TXERR         */
+       /* PC12 */ {   1,   0,   0,   1,   0,   1   }, /* FETH1_MDDIS   */
+       /* PC11 */ {   1,   0,   0,   1,   0,   1   }, /* FETH0_MDDIS   */
+       /* PC10 */ {   1,   0,   0,   1,   0,   0   }, /* MDC           */
+       /* PC9  */ {   1,   0,   0,   1,   1,   1   }, /* MDIO          */
+       /* PC8  */ {   1,   0,   0,   1,   1,   1   }, /* SER_NUM       */
+       /* PC7  */ {   1,   1,   0,   0,   0,   0   }, /* US_CTS        */
+       /* PC6  */ {   1,   1,   0,   0,   0,   0   }, /* DS_CD_        */
+       /* PC5  */ {   1,   0,   0,   1,   0,   0   }, /* FETH1_PWRDWN  */
+       /* PC4  */ {   1,   0,   0,   1,   0,   0   }, /* FETH0_PWRDWN  */
+       /* PC3  */ {   1,   0,   0,   1,   0,   0   }, /* MPULED3       */
+       /* PC2  */ {   1,   0,   0,   1,   0,   0   }, /* MPULED2       */
+       /* PC1  */ {   1,   0,   0,   1,   0,   0   }, /* MPULED1       */
+       /* PC0  */ {   1,   0,   0,   1,   0,   1   }, /* MPULED0       */
+    },
+
+    /* Port D */
+    {  /*             conf ppar psor pdir podr pdat */
+       /* PD31 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD30 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD29 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD28 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD27 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD26 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD25 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD24 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD23 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD22 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD21 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD20 */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD19 */ {   1,   1,   1,   0,   0,   0   }, /*  not used     */
+       /* PD18 */ {   1,   1,   1,   0,   0,   0   }, /*  not used     */
+       /* PD17 */ {   1,   1,   1,   0,   0,   0   }, /*  not used     */
+       /* PD16 */ {   1,   1,   1,   0,   0,   0   }, /*  not used     */
+       /* PD15 */ {   1,   1,   1,   0,   1,   1   }, /*  SDRAM_SDA    */
+       /* PD14 */ {   1,   1,   1,   0,   1,   1   }, /*  SDRAM_SCL    */
+       /* PD13 */ {   1,   0,   0,   1,   0,   0   }, /*  MPULED7      */
+       /* PD12 */ {   1,   0,   0,   1,   0,   0   }, /*  MPULED6      */
+       /* PD11 */ {   1,   0,   0,   1,   0,   0   }, /*  MPULED5      */
+       /* PD10 */ {   1,   0,   0,   1,   0,   0   }, /*  MPULED4      */
+       /* PD9  */ {   1,   1,   0,   1,   0,   0   }, /*  RS232_TXD    */
+       /* PD8  */ {   1,   1,   0,   0,   0,   0   }, /*  RD232_RXD    */
+       /* PD7  */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD6  */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD5  */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD4  */ {   1,   0,   0,   0,   0,   0   }, /*  not used     */
+       /* PD3  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
+       /* PD2  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
+       /* PD1  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
+       /* PD0  */ {   0,   0,   0,   0,   0,   0   }  /* pin doesn't exist */
+    }
+};
+
+/*********************************************************************/
+/* NAME: checkboard() -         Displays the board type and serial number   */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   Displays the board type and serial number                      */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   Always returns 1                                               */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*                                                                  */
+/*                                                                  */
+/*********************************************************************/
+int checkboard(void)
+{
+    char *str;
+    puts ("Board: Advent Networks gw8260\n");
+
+    str = getenv("serial#");
+    if (str != NULL) {
+       printf("SN:    %s\n", str);
+    }
+    return 0;
+}
+
+
+#if defined (CFG_DRAM_TEST)
+/*********************************************************************/
+/* NAME:  move64() -  moves a double word (64-bit)                  */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   this function performs a double word move from the data at             */
+/*   the source pointer to the location at the destination pointer.  */
+/*                                                                  */
+/* INPUTS:                                                          */
+/*   unsigned long long *src  - pointer to data to move                     */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   unsigned long long *dest - pointer to locate to move data      */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   None                                                           */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*   May cloober fr0.                                               */
+/*                                                                  */
+/*********************************************************************/
+static void move64(unsigned long long *src, unsigned long long *dest)
+{
+       asm ("lfd  0, 0(3)\n\t" /* fpr0   =  *scr       */
+        "stfd 0, 0(4)"         /* *dest  =  fpr0       */
+        : : : "fr0" );         /* Clobbers fr0         */
+    return;
+}
+
+
+#if defined (CFG_DRAM_TEST_DATA)
+
+unsigned long long pattern[]= {
+    0xaaaaaaaaaaaaaaaa,
+    0xcccccccccccccccc,
+    0xf0f0f0f0f0f0f0f0,
+    0xff00ff00ff00ff00,
+    0xffff0000ffff0000,
+    0xffffffff00000000,
+    0x00000000ffffffff,
+    0x0000ffff0000ffff,
+    0x00ff00ff00ff00ff,
+    0x0f0f0f0f0f0f0f0f,
+    0x3333333333333333,
+    0x5555555555555555};
+
+/*********************************************************************/
+/* NAME:  mem_test_data() -  test data lines for shorts and opens    */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   Tests data lines for shorts and opens by forcing adjacent data  */
+/*   to opposite states. Because the data lines could be routed in   */
+/*   an arbitrary manner the must ensure test patterns ensure that   */
+/*   every case is tested. By using the following series of binary   */
+/*   patterns every combination of adjacent bits is test regardless  */
+/*   of routing.                                                    */
+/*                                                                  */
+/*     ...101010101010101010101010                                  */
+/*     ...110011001100110011001100                                  */
+/*     ...111100001111000011110000                                  */
+/*     ...111111110000000011111111                                  */
+/*                                                                  */
+/*   Carrying this out, gives us six hex patterns as follows:       */
+/*                                                                  */
+/*     0xaaaaaaaaaaaaaaaa                                           */
+/*     0xcccccccccccccccc                                           */
+/*     0xf0f0f0f0f0f0f0f0                                           */
+/*     0xff00ff00ff00ff00                                           */
+/*     0xffff0000ffff0000                                           */
+/*     0xffffffff00000000                                           */
+/*                                                                  */
+/*   The number test patterns will always be given by:              */
+/*                                                                  */
+/*   log(base 2)(number data bits) = log2 (64) = 6                  */
+/*                                                                  */
+/*   To test for short and opens to other signals on our boards. we  */
+/*   simply                                                         */
+/*   test with the 1's complemnt of the paterns as well.            */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   Displays failing test pattern                                  */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   0 -  Passed test                                               */
+/*   1 -  Failed test                                               */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*  Assumes only one one SDRAM bank                                 */
+/*                                                                  */
+/*********************************************************************/
+int mem_test_data(void)
+{
+    unsigned long long * pmem =
+       (unsigned long long *)CFG_SDRAM_BASE ;
+    unsigned long long temp64;
+    int num_patterns = sizeof(pattern)/ sizeof(pattern[0]);
+    int i;
+    unsigned int hi, lo;
+
+    for ( i = 0; i < num_patterns; i++) {
+       move64(&(pattern[i]), pmem);
+       move64(pmem, &temp64);
+
+       /* hi = (temp64>>32) & 0xffffffff;          */
+       /* lo = temp64 & 0xffffffff;                */
+       /* printf("\ntemp64 = 0x%08x%08x", hi, lo); */
+
+       hi = (pattern[i]>>32) & 0xffffffff;
+       lo = pattern[i] & 0xffffffff;
+       /* printf("\npattern[%d] = 0x%08x%08x", i, hi, lo);  */
+
+       if (temp64 != pattern[i]){
+           printf ("\n   Data Test Failed, pattern 0x%08x%08x", hi, lo);
+           return 1;
+       }
+    }
+
+    return 0;
+}
+#endif /* CFG_DRAM_TEST_DATA */
+
+#if defined (CFG_DRAM_TEST_ADDRESS)
+/*********************************************************************/
+/* NAME:  mem_test_address() - test address lines                   */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   This function performs a test to verify that each word im      */
+/*   memory is uniquly addressable. The test sequence is as follows: */
+/*                                                                  */
+/*   1) write the address of each word to each word.                */
+/*   2) verify that each location equals its address                */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   Displays failing test pattern and address                      */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   0 -  Passed test                                               */
+/*   1 -  Failed test                                               */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*                                                                  */
+/*                                                                  */
+/*********************************************************************/
+int mem_test_address(void)
+{
+    volatile unsigned int * pmem = (volatile unsigned int *)CFG_SDRAM_BASE ;
+    const unsigned int size = (CFG_SDRAM_SIZE * 1024 * 1024)/4;
+    unsigned int i;
+
+    /* write address to each location */
+    for ( i = 0; i < size; i++) {
+       pmem[i] = i;
+    }
+
+    /* verify each loaction */
+    for ( i = 0; i < size; i++) {
+       if (pmem[i] != i) {
+           printf("\n   Address Test Failed at 0x%x", i);
+           return 1;
+       }
+    }
+    return 0;
+}
+#endif /* CFG_DRAM_TEST_ADDRESS */
+
+#if defined (CFG_DRAM_TEST_WALK)
+/*********************************************************************/
+/* NAME:   mem_march() -  memory march                              */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   Marches up through memory. At each location verifies rmask if   */
+/*   read = 1. At each location write wmask if write = 1. Displays  */
+/*   failing address and pattern.                                   */
+/*                                                                  */
+/* INPUTS:                                                          */
+/*   volatile unsigned long long * base - start address of test             */
+/*   unsigned int size - number of dwords(64-bit) to test           */
+/*   unsigned long long rmask - read verify mask                    */
+/*   unsigned long long wmask - wrtie verify mask                   */
+/*   short read - verifies rmask if read = 1                        */
+/*   short write  - writes wmask if write = 1                       */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   Displays failing test pattern and address                      */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   0 -  Passed test                                               */
+/*   1 -  Failed test                                               */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*                                                                  */
+/*                                                                  */
+/*********************************************************************/
+int mem_march(volatile unsigned long long * base,
+             unsigned int size,
+             unsigned long long rmask,
+             unsigned long long wmask,
+             short read,
+             short write)
+{
+    unsigned int i;
+    unsigned long long temp;
+    unsigned int hitemp, lotemp, himask, lomask;
+
+    for (i = 0 ; i < size ; i++) {
+       if (read != 0) {
+           /* temp = base[i]; */
+           move64 ((unsigned long long *)&(base[i]), &temp);
+           if (rmask != temp) {
+               hitemp = (temp>>32) & 0xffffffff;
+               lotemp = temp & 0xffffffff;
+               himask = (rmask>>32) & 0xffffffff;
+               lomask = rmask & 0xffffffff;
+
+               printf("\n Walking one's test failed: address = 0x%08x,"
+                      "\n\texpected 0x%08x%08x, found 0x%08x%08x",
+                      i<<3, himask, lomask, hitemp, lotemp);
+               return 1;
+           }
+       }
+       if ( write != 0 ) {
+          /*  base[i] = wmask; */
+           move64 (&wmask, (unsigned long long *)&(base[i]));
+       }
+    }
+    return 0;
+}
+#endif /* CFG_DRAM_TEST_WALK */
+
+/*********************************************************************/
+/* NAME:   mem_test_walk() -  a simple walking ones test            */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   Performs a walking ones through entire physical memory. The     */
+/*   test uses as series of memory marches, mem_march(), to verify   */
+/*   and write the test patterns to memory. The test sequence is as  */
+/*   follows:                                                       */
+/*     1) march writing 0000...0001                                 */
+/*     2) march verifying 0000...0001  , writing  0000...0010       */
+/*     3) repeat step 2 shifting masks left 1 bit each time unitl    */
+/*        the write mask equals 1000...0000                         */
+/*     4) march verifying 1000...0000                               */
+/*   The test fails if any of the memory marches return a failure.   */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   Displays which pass on the memory test is executing            */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   0 -  Passed test                                               */
+/*   1 -  Failed test                                               */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*                                                                  */
+/*                                                                  */
+/*********************************************************************/
+int mem_test_walk(void)
+{
+    unsigned long long mask;
+    volatile unsigned long long * pmem =
+       (volatile unsigned long long *)CFG_SDRAM_BASE ;
+    const unsigned long size = (CFG_SDRAM_SIZE * 1024 * 1024)/8;
+
+    unsigned int i;
+    mask = 0x01;
+
+    printf("Initial Pass");
+    mem_march(pmem,size,0x0,0x1,0,1);
+
+    printf("\b\b\b\b\b\b\b\b\b\b\b\b");
+    printf("           ");
+    printf("\b\b\b\b\b\b\b\b\b\b\b\b");
+
+    for (i = 0 ; i < 63 ; i++) {
+       printf("Pass %2d", i+2);
+       if ( mem_march(pmem,size, mask,mask << 1, 1, 1) != 0 ){
+           /*printf("mask: 0x%x, pass: %d, ", mask, i);*/
+           return 1;
+       }
+       mask = mask<<1;
+       printf("\b\b\b\b\b\b\b");
+    }
+
+    printf("Last Pass");
+    if (mem_march(pmem, size, 0, mask, 0, 1) != 0) {
+       /* printf("mask: 0x%x", mask); */
+       return 1;
+    }
+    printf("\b\b\b\b\b\b\b\b\b");
+    printf("        ");
+    printf("\b\b\b\b\b\b\b\b\b");
+
+    return 0;
+}
+
+/*********************************************************************/
+/* NAME:    testdram() -  calls any enabled memory tests            */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   Runs memory tests if the environment test variables are set to  */
+/*   'y'.                                                           */
+/*                                                                  */
+/* INPUTS:                                                          */
+/*   testdramdata    - If set to 'y', data test is run.                     */
+/*   testdramaddress - If set to 'y', address test is run.          */
+/*   testdramwalk    - If set to 'y', walking ones test is run      */
+/*                                                                  */
+/* OUTPUTS:                                                         */
+/*   None                                                           */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   0 -  Passed test                                               */
+/*   1 -  Failed test                                               */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*                                                                  */
+/*                                                                  */
+/*********************************************************************/
+int testdram(void)
+{
+    char *s;
+    int rundata, runaddress, runwalk;
+
+    s = getenv ("testdramdata");
+    rundata = (s && (*s == 'y')) ? 1 : 0;
+    s = getenv ("testdramaddress");
+    runaddress = (s && (*s == 'y')) ? 1 : 0;
+    s = getenv ("testdramwalk");
+    runwalk = (s && (*s == 'y')) ? 1 : 0;
+
+    if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
+       printf("Testing RAM ... ");
+    }
+#ifdef CFG_DRAM_TEST_DATA
+    if (rundata == 1) {
+       if (mem_test_data() == 1){
+           return 1;
+       }
+    }
+#endif
+#ifdef CFG_DRAM_TEST_ADDRESS
+    if (runaddress == 1) {
+       if (mem_test_address() == 1){
+           return 1;
+       }
+    }
+#endif
+#ifdef CFG_DRAM_TEST_WALK
+    if (runwalk == 1) {
+       if (mem_test_walk() == 1){
+           return 1;
+       }
+    }
+#endif
+    if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
+       printf("passed");
+    }
+    return 0;
+
+}
+#endif /* CFG_DRAM_TEST */
+
+/*********************************************************************/
+/* NAME: initdram() -  initializes SDRAM controller                 */
+/*                                                                  */
+/* DESCRIPTION:                                                             */
+/*   Initializes the MPC8260's SDRAM controller.                    */
+/*                                                                  */
+/* INPUTS:                                                          */
+/*   CFG_IMMR      -  MPC8260 Internal memory map                   */
+/*   CFG_SDRAM_BASE -  Physical start address of SDRAM              */
+/*   CFG_PSDMR -       SDRAM mode register                          */
+/*   CFG_MPTPR -       Memory refresh timer prescaler register      */
+/*   CFG_SDRAM0_SIZE - SDRAM size                                   */
+/*                                                                  */
+/* RETURNS:                                                         */
+/*   SDRAM size in bytes                                            */
+/*                                                                  */
+/* RESTRICTIONS/LIMITATIONS:                                        */
+/*                                                                  */
+/*                                                                  */
+/*********************************************************************/
+long int initdram(int board_type)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+    volatile memctl8260_t *memctl = &immap->im_memctl;
+    volatile uchar c = 0, *ramaddr = (uchar *)(CFG_SDRAM_BASE + 0x8);
+    ulong psdmr = CFG_PSDMR;
+    int i;
+
+    /*
+     * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
+     *
+     * "At system reset, initialization software must set up the
+     * programmable parameters in the memory controller banks registers
+     * (ORx, BRx, P/LSDMR). After all memory parameters are configured,
+     * system software should execute the following initialization sequence
+     * for each SDRAM device.
+     *
+     * 1. Issue a PRECHARGE-ALL-BANKS command
+     * 2. Issue eight CBR REFRESH commands
+     * 3. Issue a MODE-SET command to initialize the mode register
+     *
+     * The initial commands are executed by setting P/LSDMR[OP] and
+     * accessing the SDRAM with a single-byte transaction."
+     *
+     * The appropriate BRx/ORx registers have already been set when we
+     * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
+     */
+
+    memctl->memc_psrt = CFG_PSRT;
+    memctl->memc_mptpr = CFG_MPTPR;
+
+    memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
+    *ramaddr = c;
+
+    memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
+    for (i = 0; i < 8; i++){
+       *ramaddr = c;
+    }
+    memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
+    *ramaddr = c;
+
+    memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
+    *ramaddr = c;
+
+    /* return total ram size */
+    return (CFG_SDRAM0_SIZE * 1024 * 1024);
+}
+
+/*********************************************************************/
+/*                        End of gw8260.c                           */
+/*********************************************************************/
diff --git a/board/mvs1/flash.c b/board/mvs1/flash.c
new file mode 100644 (file)
index 0000000..75d9048
--- /dev/null
@@ -0,0 +1,719 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Changes for MATRIX Vision MVsensor (C) Copyright 2001
+ * MATRIX Vision GmbH / hg, info@matrix-vision.de
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+#undef MVDEBUG
+#ifdef MVDEBUG
+#define mvdebug debug
+#else
+#define mvdebug(p) do {} while (0)
+#endif
+
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
+
+
+#ifdef CONFIG_MVS_16BIT_FLASH
+       #define FLASH_DATA_MASK 0xffff
+       #define FLASH_SHIFT 0
+#else
+       #define FLASH_DATA_MASK 0xffffffff
+       #define FLASH_SHIFT 1
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *address, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+       volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+       volatile memctl8xx_t *memctl = &immap->im_memctl;
+       unsigned long size_b0, size_b1;
+       int i;
+
+       /* Init: no FLASHes known */
+       for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+       }
+
+       /* Static FLASH Bank configuration here - FIXME XXX */
+
+       size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+       if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+               printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+                       size_b0, size_b0<<20);
+       }
+
+#if defined (FLASH_BASE1_PRELIM)
+       size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
+
+       if (size_b1 > size_b0) {
+               printf ("## ERROR: "
+                       "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
+                       size_b1, size_b1<<20,
+                       size_b0, size_b0<<20
+               );
+               flash_info[0].flash_id  = FLASH_UNKNOWN;
+               flash_info[1].flash_id  = FLASH_UNKNOWN;
+               flash_info[0].sector_count      = -1;
+               flash_info[1].sector_count      = -1;
+               flash_info[0].size              = 0;
+               flash_info[1].size              = 0;
+               return (0);
+       }
+#else
+       size_b1 = 0;
+#endif
+
+       /* Remap FLASH according to real size */
+       memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000);
+#ifdef CONFIG_MVS_16BIT_FLASH
+       memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_PS_16 | BR_MS_GPCM | BR_V;
+#else
+       memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_PS_32 | BR_MS_GPCM | BR_V;
+#endif
+
+       /* Re-do sizing to get full correct info */
+       size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
+
+       flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
+
+       /* monitor protection ON by default */
+       flash_protect(FLAG_PROTECT_SET,
+                     CFG_FLASH_BASE,
+                     CFG_FLASH_BASE+CFG_MONITOR_LEN-1,
+                     &flash_info[0]);
+
+       if (size_b1) {
+               memctl->memc_or1 = CFG_OR_TIMING_FLASH | (-size_b1 & 0xFFFF8000);
+#ifdef CONFIG_MVS_16BIT_FLASH
+               memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
+                                   BR_PS_16 | BR_MS_GPCM | BR_V;
+#else
+               memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
+                                   BR_PS_32 | BR_MS_GPCM | BR_V;
+#endif
+               /* Re-do sizing to get full correct info */
+               size_b1 = flash_get_size((vu_long *)(CFG_FLASH_BASE + size_b0),
+                                         &flash_info[1]);
+
+               flash_get_offsets (CFG_FLASH_BASE + size_b0, &flash_info[1]);
+
+               /* monitor protection ON by default */
+               flash_protect(FLAG_PROTECT_SET,
+                             CFG_FLASH_BASE,
+                             CFG_FLASH_BASE+CFG_MONITOR_LEN-1,
+                             &flash_info[1]);
+       } else {
+               memctl->memc_br1 = 0;           /* invalidate bank */
+
+               flash_info[1].flash_id = FLASH_UNKNOWN;
+               flash_info[1].sector_count = -1;
+       }
+
+       flash_info[0].size = size_b0;
+       flash_info[1].size = size_b1;
+
+       return (size_b0 + size_b1);
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+       int i;
+
+       /* set up sector start address table */
+       if (info->flash_id & FLASH_BTYPE)
+       {       /* bottom boot sector types - these are the useful ones! */
+               /* set sector offsets for bottom boot block type */
+               if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B)
+               {       /* AMDLV320B has 8 x 8k bottom boot sectors */
+                       for (i = 0; i < 8; i++)                                                                                         /* +8k          */
+                               info->start[i] = base + (i * (0x00002000 << FLASH_SHIFT));
+                       for (; i < info->sector_count; i++)                                                                     /* +64k         */
+                               info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT)) - (0x00070000 << FLASH_SHIFT);
+               }
+               else
+               {       /* other types have 4 bottom boot sectors (16,8,8,32) */
+                       i = 0;
+                       info->start[i++] = base +  0x00000000;                                                          /* -            */
+                       info->start[i++] = base + (0x00004000 << FLASH_SHIFT);                          /* +16k         */
+                       info->start[i++] = base + (0x00006000 << FLASH_SHIFT);                          /* +8k          */
+                       info->start[i++] = base + (0x00008000 << FLASH_SHIFT);                          /* +8k          */
+                       info->start[i++] = base + (0x00010000 << FLASH_SHIFT);                          /* +32k         */
+                       for (; i < info->sector_count; i++)                                                                     /* +64k         */
+                               info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT)) - (0x00030000 << FLASH_SHIFT);
+               }
+       }
+       else
+       {       /* top boot sector types - not so useful */
+               /* set sector offsets for top boot block type */
+               if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T)
+               {       /* AMDLV320T has 8 x 8k top boot sectors */
+                       for (i = 0; i < info->sector_count - 8; i++)                                            /* +64k         */
+                               info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT));
+                       for (; i < info->sector_count; i++)                                                                     /* +8k          */
+                               info->start[i] = base + (i * (0x00002000 << FLASH_SHIFT));
+               }
+               else
+               {       /* other types have 4 top boot sectors (32,8,8,16) */
+                       for (i = 0; i < info->sector_count - 4; i++)                                            /* +64k         */
+                               info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT));
+
+                       info->start[i++] = base + info->size - (0x00010000 << FLASH_SHIFT);     /* -32k         */
+                       info->start[i++] = base + info->size - (0x00008000 << FLASH_SHIFT);     /* -8k          */
+                       info->start[i++] = base + info->size - (0x00006000 << FLASH_SHIFT);     /* -8k          */
+                       info->start[i]   = base + info->size - (0x00004000 << FLASH_SHIFT);     /* -16k         */
+               }
+       }
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+       int i;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:     printf ("AMD ");                break;
+       case FLASH_MAN_FUJ:     printf ("FUJITSU ");    break;
+       case FLASH_MAN_STM:     printf ("ST ");                 break;
+       default:                printf ("Unknown Vendor ");     break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_STMW320DB:   printf ("M29W320B (32 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_STMW320DT:   printf ("M29W320T (32 Mbit, top boot sector)\n");
+                               break;
+       default:                printf ("Unknown Chip Type\n");
+                               break;
+       }
+
+       printf ("  Size: %ld MB in %d Sectors\n",
+               info->size >> 20, info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+       for (i=0; i<info->sector_count; ++i) {
+               if ((i % 5) == 0)
+                       printf ("\n   ");
+               printf (" %08lX%s",
+                       info->start[i],
+                       info->protect[i] ? " (RO)" : "     "
+               );
+       }
+       printf ("\n");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+#define        AMD_ID_LV160T_MVS       (AMD_ID_LV160T & FLASH_DATA_MASK)
+#define AMD_ID_LV160B_MVS      (AMD_ID_LV160B & FLASH_DATA_MASK)
+#define AMD_ID_LV320T_MVS      (AMD_ID_LV320T & FLASH_DATA_MASK)
+#define AMD_ID_LV320B_MVS      (AMD_ID_LV320B & FLASH_DATA_MASK)
+#define STM_ID_W320DT_MVS      (STM_ID_29W320DT & FLASH_DATA_MASK)
+#define STM_ID_W320DB_MVS      (STM_ID_29W320DB & FLASH_DATA_MASK)
+#define AMD_MANUFACT_MVS       (AMD_MANUFACT  & FLASH_DATA_MASK)
+#define FUJ_MANUFACT_MVS       (FUJ_MANUFACT  & FLASH_DATA_MASK)
+#define STM_MANUFACT_MVS       (STM_MANUFACT  & FLASH_DATA_MASK)
+
+#define AUTOSELECT_ADDR1       0x0555
+#define AUTOSELECT_ADDR2       0x02AA
+#define AUTOSELECT_ADDR3       AUTOSELECT_ADDR1
+
+#define AUTOSELECT_DATA1       (0x00AA00AA & FLASH_DATA_MASK)
+#define AUTOSELECT_DATA2       (0x00550055 & FLASH_DATA_MASK)
+#define AUTOSELECT_DATA3       (0x00900090 & FLASH_DATA_MASK)
+
+#define RESET_BANK_DATA                (0x00F000F0 & FLASH_DATA_MASK)
+
+static ulong flash_get_size (vu_long *address, flash_info_t *info)
+{
+       short i;
+#ifdef CONFIG_MVS_16BIT_FLASH
+       ushort value;
+       vu_short *addr = (vu_short *)address;
+#else
+       ulong value;
+       vu_long *addr = (vu_long *)address;
+#endif
+       ulong base = (ulong)address;
+
+       /* Write auto select command: read Manufacturer ID */
+       addr[AUTOSELECT_ADDR1] = AUTOSELECT_DATA1;
+       addr[AUTOSELECT_ADDR2] = AUTOSELECT_DATA2;
+       addr[AUTOSELECT_ADDR3] = AUTOSELECT_DATA3;
+
+       value = addr[0];                        /* manufacturer ID      */
+       switch (value) {
+       case AMD_MANUFACT_MVS:
+               info->flash_id = FLASH_MAN_AMD;
+               break;
+       case FUJ_MANUFACT_MVS:
+               info->flash_id = FLASH_MAN_FUJ;
+               break;
+       case STM_MANUFACT_MVS:
+               info->flash_id = FLASH_MAN_STM;
+               break;
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               return (0);                     /* no or unknown flash  */
+       }
+
+       value = addr[1];                        /* device ID            */
+       switch (value) {
+       case AMD_ID_LV160T_MVS:
+               info->flash_id += FLASH_AM160T;
+               info->sector_count = 37;
+               info->size = (0x00200000 << FLASH_SHIFT);
+               break;                          /* => 2 or 4 MB         */
+
+       case AMD_ID_LV160B_MVS:
+               info->flash_id += FLASH_AM160B;
+               info->sector_count = 37;
+               info->size = (0x00200000 << FLASH_SHIFT);
+               break;                          /* => 2 or 4 MB         */
+
+       case AMD_ID_LV320T_MVS:
+               info->flash_id += FLASH_AM320T;
+               info->sector_count = 71;
+               info->size = (0x00400000 << FLASH_SHIFT);
+               break;                          /* => 4 or 8 MB         */
+
+       case AMD_ID_LV320B_MVS:
+               info->flash_id += FLASH_AM320B;
+               info->sector_count = 71;
+               info->size = (0x00400000 << FLASH_SHIFT);
+               break;                          /* => 4 or 8MB          */
+
+       case STM_ID_W320DT_MVS:
+               info->flash_id += FLASH_STMW320DT;
+               info->sector_count = 67;
+               info->size = (0x00400000 << FLASH_SHIFT);
+               break;                          /* => 4 or 8 MB         */
+
+       case STM_ID_W320DB_MVS:
+               info->flash_id += FLASH_STMW320DB;
+               info->sector_count = 67;
+               info->size = (0x00400000 << FLASH_SHIFT);
+               break;                          /* => 4 or 8MB          */
+
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               return (0);                     /* => no or unknown flash */
+
+       }
+
+       /* set up sector start address table */
+       flash_get_offsets (base, info);
+
+       /* check for protected sectors */
+       for (i = 0; i < info->sector_count; i++) {
+               /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+               /* D0 = 1 if protected */
+#ifdef CONFIG_MVS_16BIT_FLASH
+               addr = (vu_short *)(info->start[i]);
+#else
+               addr = (vu_long *)(info->start[i]);
+#endif
+               info->protect[i] = addr[2] & 1;
+       }
+
+       /*
+        * Prevent writes to uninitialized FLASH.
+        */
+       if (info->flash_id != FLASH_UNKNOWN) {
+#ifdef CONFIG_MVS_16BIT_FLASH
+               addr = (vu_short *)info->start[0];
+#else
+               addr = (vu_long *)info->start[0];
+#endif
+               *addr = RESET_BANK_DATA;        /* reset bank */
+       }
+
+       return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+#define ERASE_ADDR1 0x0555
+#define ERASE_ADDR2 0x02AA
+#define ERASE_ADDR3 ERASE_ADDR1
+#define ERASE_ADDR4 ERASE_ADDR1
+#define ERASE_ADDR5 ERASE_ADDR2
+
+#define ERASE_DATA1 (0x00AA00AA & FLASH_DATA_MASK)
+#define ERASE_DATA2 (0x00550055 & FLASH_DATA_MASK)
+#define ERASE_DATA3 (0x00800080 & FLASH_DATA_MASK)
+#define ERASE_DATA4 ERASE_DATA1
+#define ERASE_DATA5 ERASE_DATA2
+
+#define ERASE_SECTOR_DATA (0x00300030 & FLASH_DATA_MASK)
+#define ERASE_CHIP_DATA (0x00100010 & FLASH_DATA_MASK)
+#define ERASE_CONFIRM_DATA (0x00800080 & FLASH_DATA_MASK)
+
+int    flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+#ifdef CONFIG_MVS_16BIT_FLASH
+       vu_short *addr = (vu_short *)(info->start[0]);
+#else
+       vu_long *addr = (vu_long *)(info->start[0]);
+#endif
+       int flag, prot, sect, l_sect;
+       ulong start, now, last;
+
+       if ((s_first < 0) || (s_first > s_last)) {
+               if (info->flash_id == FLASH_UNKNOWN) {
+                       printf ("- missing\n");
+               } else {
+                       printf ("- no sectors to erase\n");
+               }
+               return 1;
+       }
+
+       if ((info->flash_id == FLASH_UNKNOWN) ||
+           (info->flash_id > FLASH_AMD_COMP)) {
+               printf ("Can't erase unknown flash type %08lx - aborted\n",
+                       info->flash_id);
+               return 1;
+       }
+
+       prot = 0;
+       for (sect=s_first; sect<=s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n",
+                       prot);
+       } else {
+               printf ("\n");
+       }
+
+       l_sect = -1;
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+       addr[ERASE_ADDR1] = ERASE_DATA1;
+       addr[ERASE_ADDR2] = ERASE_DATA2;
+       addr[ERASE_ADDR3] = ERASE_DATA3;
+       addr[ERASE_ADDR4] = ERASE_DATA4;
+       addr[ERASE_ADDR5] = ERASE_DATA5;
+
+       /* Start erase on unprotected sectors */
+       for (sect = s_first; sect<=s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+#ifdef CONFIG_MVS_16BIT_FLASH
+                       addr = (vu_short *)(info->start[sect]);
+#else
+                       addr = (vu_long *)(info->start[sect]);
+#endif
+                       addr[0] = ERASE_SECTOR_DATA;
+                       l_sect = sect;
+               }
+       }
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* wait at least 80us - let's wait 1 ms */
+       udelay (1000);
+
+       /*
+        * We wait for the last triggered sector
+        */
+       if (l_sect < 0)
+               goto DONE;
+
+       start = get_timer (0);
+       last  = start;
+#ifdef CONFIG_MVS_16BIT_FLASH
+       addr = (vu_short *)(info->start[l_sect]);
+#else
+       addr = (vu_long *)(info->start[l_sect]);
+#endif
+       while ((addr[0] & ERASE_CONFIRM_DATA) != ERASE_CONFIRM_DATA) {
+               if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                       printf ("Timeout\n");
+                       return 1;
+               }
+               /* show that we're waiting */
+               if ((now - last) > 1000) {      /* every second */
+                       putc ('.');
+                       last = now;
+               }
+       }
+
+DONE:
+       /* reset to read mode */
+#ifdef CONFIG_MVS_16BIT_FLASH
+       addr = (vu_short *)info->start[0];
+#else
+       addr = (vu_long *)info->start[0];
+#endif
+       addr[0] = RESET_BANK_DATA;      /* reset bank */
+
+       printf (" done\n");
+       return 0;
+}
+
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+#define BUFF_INC 4
+       ulong cp, wp, data;
+       int i, l, rc;
+
+       mvdebug (("+write_buff %p ==> 0x%08lx, count = 0x%08lx\n", src, addr, cnt));
+
+       wp = (addr & ~3);       /* get lower word aligned address */
+       /*
+        * handle unaligned start bytes
+        */
+       if ((l = addr - wp) != 0) {
+               mvdebug ((" handle unaligned start bytes (cnt = 0x%08%lx)\n", cnt));
+               data = 0;
+               for (i=0, cp=wp; i<l; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+               for (; i<BUFF_INC && cnt>0; ++i) {
+                       data = (data << 8) | *src++;
+                       --cnt;
+                       ++cp;
+               }
+               for (; cnt==0 && i<BUFF_INC; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp += BUFF_INC;
+       }
+
+       /*
+        * handle (half)word aligned part
+        */
+       mvdebug ((" handle word aligned part (cnt = 0x%08%lx)\n", cnt));
+       while (cnt >= BUFF_INC) {
+               data = 0;
+               for (i=0; i<BUFF_INC; ++i) {
+                       data = (data << 8) | *src++;
+               }
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp  += BUFF_INC;
+               cnt -= BUFF_INC;
+       }
+
+       if (cnt == 0) {
+               return (0);
+       }
+
+       /*
+        * handle unaligned tail bytes
+        */
+       mvdebug ((" handle unaligned tail bytes (cnt = 0x%08%lx)\n", cnt));
+       data = 0;
+       for (i=0, cp=wp; i<BUFF_INC && cnt>0; ++i, ++cp) {
+               data = (data << 8) | *src++;
+               --cnt;
+       }
+       for (; i<BUFF_INC; ++i, ++cp) {
+               data = (data << 8) | (*(uchar *)cp);
+       }
+
+       return (write_word(info, wp, data));
+}
+
+#define WRITE_ADDR1 0x0555
+#define WRITE_ADDR2 0x02AA
+#define WRITE_ADDR3 WRITE_ADDR1
+
+#define WRITE_DATA1 (0x00AA00AA & FLASH_DATA_MASK)
+#define WRITE_DATA2 (0x00550055 & FLASH_DATA_MASK)
+#define WRITE_DATA3 (0x00A000A0 & FLASH_DATA_MASK)
+
+#define WRITE_CONFIRM_DATA ERASE_CONFIRM_DATA
+
+#ifndef CONFIG_MVS_16BIT_FLASH
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+       vu_long *addr = (vu_long *)(info->start[0]);
+       ulong start;
+       int flag;
+
+       mvdebug (("+write_word (to 0x%08lx)\n", dest));
+       /* Check if Flash is (sufficiently) erased */
+       if ((*((vu_long *)dest) & data) != data) {
+               return (2);
+       }
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+       addr[WRITE_ADDR1] = WRITE_DATA1;
+       addr[WRITE_ADDR2] = WRITE_DATA2;
+       addr[WRITE_ADDR3] = WRITE_DATA3;
+
+       *((vu_long *)dest) = data;
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* data polling for D7 */
+       start = get_timer (0);
+       addr = (vu_long *)dest;
+       while ((*addr & WRITE_CONFIRM_DATA) != (data & WRITE_CONFIRM_DATA)) {
+               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                       return (1);
+               }
+       }
+
+       mvdebug (("-write_word\n"));
+       return (0);
+}
+#else /* CONFIG_MVS_16BIT_FLASH */
+/*-----------------------------------------------------------------------
+ * Write a halfword to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_halfword (flash_info_t *info, ulong dest, ushort data)
+{
+       vu_short *addr = (vu_short *)(info->start[0]);
+       ulong start;
+       int flag;
+
+       mvdebug (("+write_halfword (to 0x%08lx)\n", dest));
+       /* Check if Flash is (sufficiently) erased */
+       if ((*((vu_short *)dest) & data) != data) {
+               return (2);
+       }
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+       addr[WRITE_ADDR1] = WRITE_DATA1;
+       addr[WRITE_ADDR2] = WRITE_DATA2;
+       addr[WRITE_ADDR3] = WRITE_DATA3;
+
+       *((vu_short *)dest) = data;
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* data polling for D7 */
+       start = get_timer (0);
+       addr = (vu_short *)dest;
+       while ((*addr & WRITE_CONFIRM_DATA) != (data & WRITE_CONFIRM_DATA)) {
+               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                       return (1);
+               }
+       }
+       mvdebug (("-write_halfword\n"));
+       return (0);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+       int result = 0;
+
+       if (write_halfword (info, dest, (data & ~FLASH_DATA_MASK) >> 16) == 0)
+       {
+               dest += 2;
+               data = data & FLASH_DATA_MASK;
+               result = write_halfword (info, dest, data);
+       }
+       return result;
+}
+#endif
+/*-----------------------------------------------------------------------
+ */