summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorStefan Roese <sr@denx.de>2007-02-03 07:53:41 +0100
committerStefan Roese <sr@denx.de>2007-02-03 07:53:41 +0100
commite7511c266f6d47ec8d41bef301d9474776bfeedf (patch)
treedc2115dee023f934ec5705e96d7713ac397f9c04 /board
parent73e815b7fc11478aee180909e990009ebdb26725 (diff)
parent23744d6b5bf17592eb6a0ef4f318f6089f55993b (diff)
downloadu-boot-imx-e7511c266f6d47ec8d41bef301d9474776bfeedf.zip
u-boot-imx-e7511c266f6d47ec8d41bef301d9474776bfeedf.tar.gz
u-boot-imx-e7511c266f6d47ec8d41bef301d9474776bfeedf.tar.bz2
Merge with git+ssh://sr@pollux.denx.org/home/sr/git/u-boot/denx/.git
Diffstat (limited to 'board')
-rw-r--r--board/amcc/yellowstone/init.S112
-rw-r--r--board/amcc/yellowstone/yellowstone.c549
-rw-r--r--board/amcc/yosemite/yosemite.c8
-rw-r--r--board/esd/cpci750/cpci750.c22
-rw-r--r--board/esd/cpci750/sdram_init.c41
-rw-r--r--board/esd/mecp5200/Makefile (renamed from board/amcc/yellowstone/Makefile)6
-rw-r--r--board/esd/mecp5200/config.mk44
-rw-r--r--board/esd/mecp5200/mecp5200.c261
-rw-r--r--board/esd/mecp5200/mt46v16m16-75.h37
-rw-r--r--board/esd/mecp5200/u-boot.lds (renamed from board/amcc/yellowstone/u-boot.lds)51
-rw-r--r--board/lpc2292sodimm/Makefile58
-rw-r--r--board/lpc2292sodimm/config.mk (renamed from board/amcc/yellowstone/config.mk)30
-rw-r--r--board/lpc2292sodimm/eth.c885
-rw-r--r--board/lpc2292sodimm/flash.c476
-rw-r--r--board/lpc2292sodimm/iap_entry.S7
-rw-r--r--board/lpc2292sodimm/lowlevel_init.S87
-rw-r--r--board/lpc2292sodimm/lpc2292sodimm.c62
-rw-r--r--board/lpc2292sodimm/mmc.c154
-rw-r--r--board/lpc2292sodimm/mmc_hw.c233
-rw-r--r--board/lpc2292sodimm/mmc_hw.h29
-rw-r--r--board/lpc2292sodimm/spi.c40
-rw-r--r--board/lpc2292sodimm/spi.h82
-rw-r--r--board/lpc2292sodimm/u-boot.lds55
23 files changed, 2590 insertions, 739 deletions
diff --git a/board/amcc/yellowstone/init.S b/board/amcc/yellowstone/init.S
deleted file mode 100644
index 425ad08..0000000
--- a/board/amcc/yellowstone/init.S
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-*
-* 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 <ppc_asm.tmpl>
-#include <config.h>
-
-/* General */
-#define TLB_VALID 0x00000200
-
-/* Supported page sizes */
-
-#define SZ_1K 0x00000000
-#define SZ_4K 0x00000010
-#define SZ_16K 0x00000020
-#define SZ_64K 0x00000030
-#define SZ_256K 0x00000040
-#define SZ_1M 0x00000050
-#define SZ_8M 0x00000060
-#define SZ_16M 0x00000070
-#define SZ_256M 0x00000090
-
-/* Storage attributes */
-#define SA_W 0x00000800 /* Write-through */
-#define SA_I 0x00000400 /* Caching inhibited */
-#define SA_M 0x00000200 /* Memory coherence */
-#define SA_G 0x00000100 /* Guarded */
-#define SA_E 0x00000080 /* Endian */
-
-/* Access control */
-#define AC_X 0x00000024 /* Execute */
-#define AC_W 0x00000012 /* Write */
-#define AC_R 0x00000009 /* Read */
-
-/* Some handy macros */
-
-#define EPN(e) ((e) & 0xfffffc00)
-#define TLB0(epn,sz) ( (EPN((epn)) | (sz) | TLB_VALID ) )
-#define TLB1(rpn,erpn) ( ((rpn)&0xfffffc00) | (erpn) )
-#define TLB2(a) ( (a)&0x00000fbf )
-
-#define tlbtab_start\
- mflr r1 ;\
- bl 0f ;
-
-#define tlbtab_end\
- .long 0, 0, 0 ; \
-0: mflr r0 ; \
- mtlr r1 ; \
- blr ;
-
-#define tlbentry(epn,sz,rpn,erpn,attr)\
- .long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr)
-
-
-/**************************************************************************
- * TLB TABLE
- *
- * This table is used by the cpu boot code to setup the initial tlb
- * entries. Rather than make broad assumptions in the cpu source tree,
- * this table lets each board set things up however they like.
- *
- * Pointer to the table is returned in r1
- *
- *************************************************************************/
-
- .section .bootpg,"ax"
- .globl tlbtab
-
-tlbtab:
- tlbtab_start
-
- /*
- * BOOT_CS (FLASH) must be first. Before relocation SA_I can be off to use the
- * speed up boot process. It is patched after relocation to enable SA_I
- */
- tlbentry( CFG_BOOT_BASE_ADDR, SZ_256M, CFG_BOOT_BASE_ADDR, 0, AC_R|AC_W|AC_X|SA_G/*|SA_I*/)
-
- /* TLB-entry for init-ram in dcache (SA_I must be turned off!) */
- tlbentry( CFG_INIT_RAM_ADDR, SZ_64K, CFG_INIT_RAM_ADDR, 0, AC_R|AC_W|AC_X|SA_G )
-
- tlbentry( CFG_SDRAM_BASE, SZ_256M, CFG_SDRAM_BASE, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
- tlbentry( CFG_PCI_BASE, SZ_256M, CFG_PCI_BASE, 0, AC_R|AC_W|SA_G|SA_I )
- tlbentry( CFG_NVRAM_BASE_ADDR, SZ_256M, CFG_NVRAM_BASE_ADDR, 0, AC_R|AC_W|AC_X|SA_W|SA_I )
-
- /* PCI */
- tlbentry( CFG_PCI_MEMBASE, SZ_256M, CFG_PCI_MEMBASE, 0, AC_R|AC_W|SA_G|SA_I )
- tlbentry( CFG_PCI_MEMBASE1, SZ_256M, CFG_PCI_MEMBASE1, 0, AC_R|AC_W|SA_G|SA_I )
- tlbentry( CFG_PCI_MEMBASE2, SZ_256M, CFG_PCI_MEMBASE2, 0, AC_R|AC_W|SA_G|SA_I )
- tlbentry( CFG_PCI_MEMBASE3, SZ_256M, CFG_PCI_MEMBASE3, 0, AC_R|AC_W|SA_G|SA_I )
-
- /* USB 2.0 Device */
- tlbentry( CFG_USB_DEVICE, SZ_1K, 0x50000000, 0, AC_R|AC_W|SA_G|SA_I )
-
- tlbtab_end
diff --git a/board/amcc/yellowstone/yellowstone.c b/board/amcc/yellowstone/yellowstone.c
deleted file mode 100644
index 04f58e0..0000000
--- a/board/amcc/yellowstone/yellowstone.c
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- *
- * 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 <ppc4xx.h>
-#include <asm/processor.h>
-#include <spd_sdram.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
-
-int board_early_init_f(void)
-{
- register uint reg;
-
- /*--------------------------------------------------------------------
- * Setup the external bus controller/chip selects
- *-------------------------------------------------------------------*/
- mtdcr(ebccfga, xbcfg);
- reg = mfdcr(ebccfgd);
- mtdcr(ebccfgd, reg | 0x04000000); /* Set ATC */
-
- /*--------------------------------------------------------------------
- * Setup the GPIO pins
- *-------------------------------------------------------------------*/
- /*CPLD cs */
- /*setup Address lines for flash size 64Meg. */
- out32(GPIO0_OSRL, in32(GPIO0_OSRL) | 0x50010000);
- out32(GPIO0_TSRL, in32(GPIO0_TSRL) | 0x50010000);
- out32(GPIO0_ISR1L, in32(GPIO0_ISR1L) | 0x50000000);
-
- /*setup emac */
- out32(GPIO0_TCR, in32(GPIO0_TCR) | 0xC080);
- out32(GPIO0_TSRL, in32(GPIO0_TSRL) | 0x40);
- out32(GPIO0_ISR1L, in32(GPIO0_ISR1L) | 0x55);
- out32(GPIO0_OSRH, in32(GPIO0_OSRH) | 0x50004000);
- out32(GPIO0_ISR1H, in32(GPIO0_ISR1H) | 0x00440000);
-
- /*UART1 */
- out32(GPIO1_TCR, in32(GPIO1_TCR) | 0x02000000);
- out32(GPIO1_OSRL, in32(GPIO1_OSRL) | 0x00080000);
- out32(GPIO1_ISR2L, in32(GPIO1_ISR2L) | 0x00010000);
-
- /* external interrupts IRQ0...3 */
- out32(GPIO1_TCR, in32(GPIO1_TCR) & ~0x00f00000);
- out32(GPIO1_TSRL, in32(GPIO1_TSRL) & ~0x0000ff00);
- out32(GPIO1_ISR1L, in32(GPIO1_ISR1L) | 0x00005500);
-
-#if 0 /* test-only */
- /*setup USB 2.0 */
- out32(GPIO1_TCR, in32(GPIO1_TCR) | 0xc0000000);
- out32(GPIO1_OSRL, in32(GPIO1_OSRL) | 0x50000000);
- out32(GPIO0_TCR, in32(GPIO0_TCR) | 0xf);
- out32(GPIO0_OSRH, in32(GPIO0_OSRH) | 0xaa);
- out32(GPIO0_ISR2H, in32(GPIO0_ISR2H) | 0x00000500);
-#endif
-
- /*--------------------------------------------------------------------
- * Setup the interrupt controller polarities, triggers, etc.
- *-------------------------------------------------------------------*/
- mtdcr(uic0sr, 0xffffffff); /* clear all */
- mtdcr(uic0er, 0x00000000); /* disable all */
- mtdcr(uic0cr, 0x00000009); /* ATI & UIC1 crit are critical */
- mtdcr(uic0pr, 0xfffffe13); /* per ref-board manual */
- mtdcr(uic0tr, 0x01c00008); /* per ref-board manual */
- mtdcr(uic0vr, 0x00000001); /* int31 highest, base=0x000 */
- mtdcr(uic0sr, 0xffffffff); /* clear all */
-
- mtdcr(uic1sr, 0xffffffff); /* clear all */
- mtdcr(uic1er, 0x00000000); /* disable all */
- mtdcr(uic1cr, 0x00000000); /* all non-critical */
- mtdcr(uic1pr, 0xffffe0ff); /* per ref-board manual */
- mtdcr(uic1tr, 0x00ffc000); /* per ref-board manual */
- mtdcr(uic1vr, 0x00000001); /* int31 highest, base=0x000 */
- mtdcr(uic1sr, 0xffffffff); /* clear all */
-
- /*--------------------------------------------------------------------
- * Setup other serial configuration
- *-------------------------------------------------------------------*/
- mfsdr(sdr_pci0, reg);
- mtsdr(sdr_pci0, 0x80000000 | reg); /* PCI arbiter enabled */
- mtsdr(sdr_pfc0, 0x00003e00); /* Pin function */
- mtsdr(sdr_pfc1, 0x00048000); /* Pin function: UART0 has 4 pins */
-
- /*clear tmrclk divisor */
- *(unsigned char *)(CFG_BCSR_BASE | 0x04) = 0x00;
-
- /*enable ethernet */
- *(unsigned char *)(CFG_BCSR_BASE | 0x08) = 0xf0;
-
-#if 0 /* test-only */
- /*enable usb 1.1 fs device and remove usb 2.0 reset */
- *(unsigned char *)(CFG_BCSR_BASE | 0x09) = 0x00;
-#endif
-
- /*get rid of flash write protect */
- *(unsigned char *)(CFG_BCSR_BASE | 0x07) = 0x00;
-
- return 0;
-}
-
-int misc_init_r (void)
-{
- uint pbcr;
- int size_val = 0;
-
- /* Re-do sizing to get full correct info */
- mtdcr(ebccfga, pb0cr);
- pbcr = mfdcr(ebccfgd);
- switch (gd->bd->bi_flashsize) {
- case 1 << 20:
- size_val = 0;
- break;
- case 2 << 20:
- size_val = 1;
- break;
- case 4 << 20:
- size_val = 2;
- break;
- case 8 << 20:
- size_val = 3;
- break;
- case 16 << 20:
- size_val = 4;
- break;
- case 32 << 20:
- size_val = 5;
- break;
- case 64 << 20:
- size_val = 6;
- break;
- case 128 << 20:
- size_val = 7;
- break;
- }
- pbcr = (pbcr & 0x0001ffff) | gd->bd->bi_flashstart | (size_val << 17);
- mtdcr(ebccfga, pb0cr);
- mtdcr(ebccfgd, pbcr);
-
- /* adjust flash start and offset */
- gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
- gd->bd->bi_flashoffset = 0;
-
- /* Monitor protection ON by default */
- (void)flash_protect(FLAG_PROTECT_SET,
- -CFG_MONITOR_LEN,
- 0xffffffff,
- &flash_info[0]);
-
- return 0;
-}
-
-int checkboard(void)
-{
- char *s = getenv("serial#");
- u8 rev;
- u8 val;
-
- printf("Board: Yellowstone - AMCC PPC440GR Evaluation Board");
-
- rev = *(u8 *)(CFG_CPLD + 0);
- val = *(u8 *)(CFG_CPLD + 5) & 0x01;
- printf(", Rev. %X, PCI=%d MHz", rev, val ? 66 : 33);
-
- if (s != NULL) {
- puts(", serial# ");
- puts(s);
- }
- putc('\n');
-
- return (0);
-}
-
-/*************************************************************************
- * sdram_init -- doesn't use serial presence detect.
- *
- * Assumes: 256 MB, ECC, non-registered
- * PLB @ 133 MHz
- *
- ************************************************************************/
-#define NUM_TRIES 64
-#define NUM_READS 10
-
-void sdram_tr1_set(int ram_address, int* tr1_value)
-{
- int i;
- int j, k;
- volatile unsigned int* ram_pointer = (unsigned int*)ram_address;
- int first_good = -1, last_bad = 0x1ff;
-
- unsigned long test[NUM_TRIES] = {
- 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
- 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
- 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
- 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
- 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
- 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
- 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
- 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
- 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
- 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
- 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
- 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
- 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
- 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
- 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
-
- /* go through all possible SDRAM0_TR1[RDCT] values */
- for (i=0; i<=0x1ff; i++) {
- /* set the current value for TR1 */
- mtsdram(mem_tr1, (0x80800800 | i));
-
- /* write values */
- for (j=0; j<NUM_TRIES; j++) {
- ram_pointer[j] = test[j];
-
- /* clear any cache at ram location */
- __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
- }
-
- /* read values back */
- for (j=0; j<NUM_TRIES; j++) {
- for (k=0; k<NUM_READS; k++) {
- /* clear any cache at ram location */
- __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
-
- if (ram_pointer[j] != test[j])
- break;
- }
-
- /* read error */
- if (k != NUM_READS) {
- break;
- }
- }
-
- /* we have a SDRAM0_TR1[RDCT] that is part of the window */
- if (j == NUM_TRIES) {
- if (first_good == -1)
- first_good = i; /* found beginning of window */
- } else { /* bad read */
- /* if we have not had a good read then don't care */
- if(first_good != -1) {
- /* first failure after a good read */
- last_bad = i-1;
- break;
- }
- }
- }
-
- /* return the current value for TR1 */
- *tr1_value = (first_good + last_bad) / 2;
-}
-
-void sdram_init(void)
-{
- register uint reg;
- int tr1_bank1, tr1_bank2;
-
- /*--------------------------------------------------------------------
- * Setup some default
- *------------------------------------------------------------------*/
- mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */
- mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
- mtsdram(mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */
- mtsdram(mem_clktr, 0x40000000); /* ?? */
- mtsdram(mem_wddctr, 0x40000000); /* ?? */
-
- /*clear this first, if the DDR is enabled by a debugger
- then you can not make changes. */
- mtsdram(mem_cfg0, 0x00000000); /* Disable EEC */
-
- /*--------------------------------------------------------------------
- * Setup for board-specific specific mem
- *------------------------------------------------------------------*/
- /*
- * Following for CAS Latency = 2.5 @ 133 MHz PLB
- */
- mtsdram(mem_b0cr, 0x000a4001); /* SDBA=0x000 128MB, Mode 3, enabled */
- mtsdram(mem_b1cr, 0x080a4001); /* SDBA=0x080 128MB, Mode 3, enabled */
-
- mtsdram(mem_tr0, 0x410a4012); /* ?? */
- mtsdram(mem_rtr, 0x04080000); /* ?? */
- mtsdram(mem_cfg1, 0x00000000); /* Self-refresh exit, disable PM */
- mtsdram(mem_cfg0, 0x30000000); /* Disable EEC */
- udelay(400); /* Delay 200 usecs (min) */
-
- /*--------------------------------------------------------------------
- * Enable the controller, then wait for DCEN to complete
- *------------------------------------------------------------------*/
- mtsdram(mem_cfg0, 0x80000000); /* Enable */
-
- for (;;) {
- mfsdram(mem_mcsts, reg);
- if (reg & 0x80000000)
- break;
- }
-
- sdram_tr1_set(0x00000000, &tr1_bank1);
- sdram_tr1_set(0x08000000, &tr1_bank2);
- mtsdram(mem_tr1, (((tr1_bank1+tr1_bank2)/2) | 0x80800800) );
-}
-
-/*************************************************************************
- * long int initdram
- *
- ************************************************************************/
-long int initdram(int board)
-{
- sdram_init();
- return CFG_SDRAM_BANKS * (CFG_KBYTES_SDRAM * 1024); /* return bytes */
-}
-
-#if defined(CFG_DRAM_TEST)
-int testdram(void)
-{
- unsigned long *mem = (unsigned long *)0;
- const unsigned long kend = (1024 / sizeof(unsigned long));
- unsigned long k, n;
-
- mtmsr(0);
-
- for (k = 0; k < CFG_KBYTES_SDRAM;
- ++k, mem += (1024 / sizeof(unsigned long))) {
- if ((k & 1023) == 0) {
- printf("%3d MB\r", k / 1024);
- }
-
- memset(mem, 0xaaaaaaaa, 1024);
- for (n = 0; n < kend; ++n) {
- if (mem[n] != 0xaaaaaaaa) {
- printf("SDRAM test fails at: %08x\n",
- (uint) & mem[n]);
- return 1;
- }
- }
-
- memset(mem, 0x55555555, 1024);
- for (n = 0; n < kend; ++n) {
- if (mem[n] != 0x55555555) {
- printf("SDRAM test fails at: %08x\n",
- (uint) & mem[n]);
- return 1;
- }
- }
- }
- printf("SDRAM test passes\n");
- return 0;
-}
-#endif
-
-/*************************************************************************
- * pci_pre_init
- *
- * This routine is called just prior to registering the hose and gives
- * the board the opportunity to check things. Returning a value of zero
- * indicates that things are bad & PCI initialization should be aborted.
- *
- * Different boards may wish to customize the pci controller structure
- * (add regions, override default access routines, etc) or perform
- * certain pre-initialization actions.
- *
- ************************************************************************/
-#if defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT)
-int pci_pre_init(struct pci_controller *hose)
-{
- unsigned long addr;
-
- /*-------------------------------------------------------------------------+
- | Set priority for all PLB3 devices to 0.
- | Set PLB3 arbiter to fair mode.
- +-------------------------------------------------------------------------*/
- mfsdr(sdr_amp1, addr);
- mtsdr(sdr_amp1, (addr & 0x000000FF) | 0x0000FF00);
- addr = mfdcr(plb3_acr);
- mtdcr(plb3_acr, addr | 0x80000000);
-
- /*-------------------------------------------------------------------------+
- | Set priority for all PLB4 devices to 0.
- +-------------------------------------------------------------------------*/
- mfsdr(sdr_amp0, addr);
- mtsdr(sdr_amp0, (addr & 0x000000FF) | 0x0000FF00);
- addr = mfdcr(plb4_acr) | 0xa0000000; /* Was 0x8---- */
- mtdcr(plb4_acr, addr);
-
- /*-------------------------------------------------------------------------+
- | Set Nebula PLB4 arbiter to fair mode.
- +-------------------------------------------------------------------------*/
- /* Segment0 */
- addr = (mfdcr(plb0_acr) & ~plb0_acr_ppm_mask) | plb0_acr_ppm_fair;
- addr = (addr & ~plb0_acr_hbu_mask) | plb0_acr_hbu_enabled;
- addr = (addr & ~plb0_acr_rdp_mask) | plb0_acr_rdp_4deep;
- addr = (addr & ~plb0_acr_wrp_mask) | plb0_acr_wrp_2deep;
- mtdcr(plb0_acr, addr);
-
- /* Segment1 */
- addr = (mfdcr(plb1_acr) & ~plb1_acr_ppm_mask) | plb1_acr_ppm_fair;
- addr = (addr & ~plb1_acr_hbu_mask) | plb1_acr_hbu_enabled;
- addr = (addr & ~plb1_acr_rdp_mask) | plb1_acr_rdp_4deep;
- addr = (addr & ~plb1_acr_wrp_mask) | plb1_acr_wrp_2deep;
- mtdcr(plb1_acr, addr);
-
- return 1;
-}
-#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) */
-
-/*************************************************************************
- * pci_target_init
- *
- * The bootstrap configuration provides default settings for the pci
- * inbound map (PIM). But the bootstrap config choices are limited and
- * may not be sufficient for a given board.
- *
- ************************************************************************/
-#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT)
-void pci_target_init(struct pci_controller *hose)
-{
- /*--------------------------------------------------------------------------+
- * Set up Direct MMIO registers
- *--------------------------------------------------------------------------*/
- /*--------------------------------------------------------------------------+
- | PowerPC440 EP PCI Master configuration.
- | Map one 1Gig range of PLB/processor addresses to PCI memory space.
- | PLB address 0xA0000000-0xDFFFFFFF ==> PCI address 0xA0000000-0xDFFFFFFF
- | Use byte reversed out routines to handle endianess.
- | Make this region non-prefetchable.
- +--------------------------------------------------------------------------*/
- out32r(PCIX0_PMM0MA, 0x00000000); /* PMM0 Mask/Attribute - disabled b4 setting */
- out32r(PCIX0_PMM0LA, CFG_PCI_MEMBASE); /* PMM0 Local Address */
- out32r(PCIX0_PMM0PCILA, CFG_PCI_MEMBASE); /* PMM0 PCI Low Address */
- out32r(PCIX0_PMM0PCIHA, 0x00000000); /* PMM0 PCI High Address */
- out32r(PCIX0_PMM0MA, 0xE0000001); /* 512M + No prefetching, and enable region */
-
- out32r(PCIX0_PMM1MA, 0x00000000); /* PMM0 Mask/Attribute - disabled b4 setting */
- out32r(PCIX0_PMM1LA, CFG_PCI_MEMBASE2); /* PMM0 Local Address */
- out32r(PCIX0_PMM1PCILA, CFG_PCI_MEMBASE2); /* PMM0 PCI Low Address */
- out32r(PCIX0_PMM1PCIHA, 0x00000000); /* PMM0 PCI High Address */
- out32r(PCIX0_PMM1MA, 0xE0000001); /* 512M + No prefetching, and enable region */
-
- out32r(PCIX0_PTM1MS, 0x00000001); /* Memory Size/Attribute */
- out32r(PCIX0_PTM1LA, 0); /* Local Addr. Reg */
- out32r(PCIX0_PTM2MS, 0); /* Memory Size/Attribute */
- out32r(PCIX0_PTM2LA, 0); /* Local Addr. Reg */
-
- /*--------------------------------------------------------------------------+
- * Set up Configuration registers
- *--------------------------------------------------------------------------*/
-
- /* Program the board's subsystem id/vendor id */
- pci_write_config_word(0, PCI_SUBSYSTEM_VENDOR_ID,
- CFG_PCI_SUBSYS_VENDORID);
- pci_write_config_word(0, PCI_SUBSYSTEM_ID, CFG_PCI_SUBSYS_ID);
-
- /* Configure command register as bus master */
- pci_write_config_word(0, PCI_COMMAND, PCI_COMMAND_MASTER);
-
- /* 240nS PCI clock */
- pci_write_config_word(0, PCI_LATENCY_TIMER, 1);
-
- /* No error reporting */
- pci_write_config_word(0, PCI_ERREN, 0);
-
- pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101);
-
-}
-#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
-
-/*************************************************************************
- * pci_master_init
- *
- ************************************************************************/
-#if defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT)
-void pci_master_init(struct pci_controller *hose)
-{
- unsigned short temp_short;
-
- /*--------------------------------------------------------------------------+
- | Write the PowerPC440 EP PCI Configuration regs.
- | Enable PowerPC440 EP to be a master on the PCI bus (PMM).
- | Enable PowerPC440 EP to act as a PCI memory target (PTM).
- +--------------------------------------------------------------------------*/
- pci_read_config_word(0, PCI_COMMAND, &temp_short);
- pci_write_config_word(0, PCI_COMMAND,
- temp_short | PCI_COMMAND_MASTER |
- PCI_COMMAND_MEMORY);
-}
-#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT) */
-
-/*************************************************************************
- * is_pci_host
- *
- * This routine is called to determine if a pci scan should be
- * performed. With various hardware environments (especially cPCI and
- * PPMC) it's insufficient to depend on the state of the arbiter enable
- * bit in the strap register, or generic host/adapter assumptions.
- *
- * Rather than hard-code a bad assumption in the general 440 code, the
- * 440 pci code requires the board to decide at runtime.
- *
- * Return 0 for adapter mode, non-zero for host (monarch) mode.
- *
- *
- ************************************************************************/
-#if defined(CONFIG_PCI)
-int is_pci_host(struct pci_controller *hose)
-{
- /* Bamboo is always configured as host. */
- return (1);
-}
-#endif /* defined(CONFIG_PCI) */
-
-/*************************************************************************
- * hw_watchdog_reset
- *
- * This routine is called to reset (keep alive) the watchdog timer
- *
- ************************************************************************/
-#if defined(CONFIG_HW_WATCHDOG)
-void hw_watchdog_reset(void)
-{
-
-}
-#endif
-
-void board_reset(void)
-{
- /* give reset to BCSR */
- *(unsigned char *)(CFG_BCSR_BASE | 0x06) = 0x09;
-}
diff --git a/board/amcc/yosemite/yosemite.c b/board/amcc/yosemite/yosemite.c
index d47219c..c2e12ba 100644
--- a/board/amcc/yosemite/yosemite.c
+++ b/board/amcc/yosemite/yosemite.c
@@ -65,12 +65,14 @@ int board_early_init_f(void)
out32(GPIO1_TSRL, in32(GPIO1_TSRL) & ~0x0000ff00);
out32(GPIO1_ISR1L, in32(GPIO1_ISR1L) | 0x00005500);
+#ifdef CONFIG_440EP
/*setup USB 2.0 */
out32(GPIO1_TCR, in32(GPIO1_TCR) | 0xc0000000);
out32(GPIO1_OSRL, in32(GPIO1_OSRL) | 0x50000000);
out32(GPIO0_TCR, in32(GPIO0_TCR) | 0xf);
out32(GPIO0_OSRH, in32(GPIO0_OSRH) | 0xaa);
out32(GPIO0_ISR2H, in32(GPIO0_ISR2H) | 0x00000500);
+#endif
/*--------------------------------------------------------------------
* Setup the interrupt controller polarities, triggers, etc.
@@ -105,8 +107,10 @@ int board_early_init_f(void)
/*enable ethernet */
*(unsigned char *)(CFG_BCSR_BASE | 0x08) = 0xf0;
+#ifdef CONFIG_440EP
/*enable usb 1.1 fs device and remove usb 2.0 reset */
*(unsigned char *)(CFG_BCSR_BASE | 0x09) = 0x00;
+#endif
/*get rid of flash write protect */
*(unsigned char *)(CFG_BCSR_BASE | 0x07) = 0x00;
@@ -171,7 +175,11 @@ int checkboard(void)
u8 rev;
u8 val;
+#ifdef CONFIG_440EP
printf("Board: Yosemite - AMCC PPC440EP Evaluation Board");
+#else
+ printf("Board: Yellowstone - AMCC PPC440GR Evaluation Board");
+#endif
rev = *(u8 *)(CFG_CPLD + 0);
val = *(u8 *)(CFG_CPLD + 5) & 0x01;
diff --git a/board/esd/cpci750/cpci750.c b/board/esd/cpci750/cpci750.c
index dbed597..36bb7ce 100644
--- a/board/esd/cpci750/cpci750.c
+++ b/board/esd/cpci750/cpci750.c
@@ -29,6 +29,7 @@
*/
#include <common.h>
+#include <command.h>
#include <74xx_7xx.h>
#include "../../Marvell/include/memory.h"
#include "../../Marvell/include/pci.h"
@@ -899,3 +900,24 @@ void board_prebootm_init ()
flush_data_cache ();
dcache_disable ();
}
+
+
+int do_show_cfg(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ unsigned int reset_sample_low;
+ unsigned int reset_sample_high;
+
+ GT_REG_READ(0x3c4, &reset_sample_low);
+ GT_REG_READ(0x3d4, &reset_sample_high);
+ printf("Reset configuration 0x%08x 0x%08x\n", reset_sample_low, reset_sample_high);
+
+ return(0);
+}
+
+
+U_BOOT_CMD(
+ show_cfg, 1, 1, do_show_cfg,
+ "show_cfg- Show Marvell strapping register\n",
+ "Show Marvell strapping register (ResetSampleLow ResetSampleHigh)\n"
+ );
+
diff --git a/board/esd/cpci750/sdram_init.c b/board/esd/cpci750/sdram_init.c
index 6bdfc1d..c094755 100644
--- a/board/esd/cpci750/sdram_init.c
+++ b/board/esd/cpci750/sdram_init.c
@@ -1504,6 +1504,8 @@ int setup_sdram (AUX_MEM_DIMM_INFO * info)
/* for (i = info->slot * 2; i < ((info->slot * 2) + info->banks); i++) */
{
+ int l, l1;
+
i = info->slot;
DP (printf
("\n*** Running a MRS cycle for bank %d ***\n", i));
@@ -1511,20 +1513,39 @@ int setup_sdram (AUX_MEM_DIMM_INFO * info)
/* map the bank */
memory_map_bank (i, 0, GB / 4);
#if 1 /* test only */
- /* set SDRAM mode */ /* To_do check it */
+
+ tmp = GTREGREAD (SDRAM_MODE);
+ GT_REG_WRITE (EXTENDED_DRAM_MODE, 0x0);
+ GT_REG_WRITE (SDRAM_OPERATION, 0x4);
+ while (GTREGREAD (SDRAM_OPERATION) != 0) {
+ DP (printf
+ ("\n*** SDRAM_OPERATION 1418 after SDRAM_MODE: Module still busy ... please wait... ***\n"));
+ }
+
+ GT_REG_WRITE (SDRAM_MODE, tmp | 0x80);
GT_REG_WRITE (SDRAM_OPERATION, 0x3);
- check = GTREGREAD (SDRAM_OPERATION);
- DP (printf
- ("\n*** SDRAM_OPERATION 1418 (0 = Normal Operation) = %08lx ***\n",
- check));
+ while (GTREGREAD (SDRAM_OPERATION) != 0) {
+ DP (printf
+ ("\n*** SDRAM_OPERATION 1418 after SDRAM_MODE: Module still busy ... please wait... ***\n"));
+ }
+ l1 = 0;
+ for (l=0;l<200;l++)
+ l1 += GTREGREAD (SDRAM_OPERATION);
+ GT_REG_WRITE (SDRAM_MODE, tmp);
+ GT_REG_WRITE (SDRAM_OPERATION, 0x3);
+ while (GTREGREAD (SDRAM_OPERATION) != 0) {
+ DP (printf
+ ("\n*** SDRAM_OPERATION 1418 after SDRAM_MODE: Module still busy ... please wait... ***\n"));
+ }
/* switch back to normal operation mode */
- GT_REG_WRITE (SDRAM_OPERATION, 0);
- check = GTREGREAD (SDRAM_OPERATION);
- DP (printf
- ("\n*** SDRAM_OPERATION 1418 (0 = Normal Operation) = %08lx ***\n",
- check));
+ GT_REG_WRITE (SDRAM_OPERATION, 0x5);
+ while (GTREGREAD (SDRAM_OPERATION) != 0) {
+ DP (printf
+ ("\n*** SDRAM_OPERATION 1418 after SDRAM_MODE: Module still busy ... please wait... ***\n"));
+ }
+
#endif /* test only */
/* unmap the bank */
memory_map_bank (i, 0, 0);
diff --git a/board/amcc/yellowstone/Makefile b/board/esd/mecp5200/Makefile
index 261e5d4..45efdb0 100644
--- a/board/amcc/yellowstone/Makefile
+++ b/board/esd/mecp5200/Makefile
@@ -1,5 +1,6 @@
+
#
-# (C) Copyright 2002-2006
+# (C) Copyright 2003-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -26,13 +27,12 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
COBJS = $(BOARD).o
-SOBJS = init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
-$(LIB): $(OBJS) $(SOBJS)
+$(LIB): $(obj).depend $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
clean:
diff --git a/board/esd/mecp5200/config.mk b/board/esd/mecp5200/config.mk
new file mode 100644
index 0000000..07b5de1
--- /dev/null
+++ b/board/esd/mecp5200/config.mk
@@ -0,0 +1,44 @@
+#
+# (C) Copyright 2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# IceCube board:
+#
+# Valid values for TEXT_BASE are:
+#
+# 0xFFF00000 boot high (standard configuration)
+# 0xFF000000 boot low for 16 MiB boards
+# 0xFF800000 boot low for 8 MiB boards
+# 0x00100000 boot from RAM (for testing only)
+#
+
+sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp
+
+ifndef TEXT_BASE
+## Standard: boot high
+TEXT_BASE = 0xFFF00000
+## For testing: boot from RAM
+# TEXT_BASE = 0x00100000
+endif
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
diff --git a/board/esd/mecp5200/mecp5200.c b/board/esd/mecp5200/mecp5200.c
new file mode 100644
index 0000000..c4b91e9
--- /dev/null
+++ b/board/esd/mecp5200/mecp5200.c
@@ -0,0 +1,261 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2004
+ * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * pf5200.c - main board support/init for the esd pf5200.
+ */
+
+#include <common.h>
+#include <mpc5xxx.h>
+#include <pci.h>
+#include <command.h>
+
+#include "mt46v16m16-75.h"
+
+void init_power_switch(void);
+
+static void sdram_start(int hi_addr)
+{
+ long hi_addr_bit = hi_addr ? 0x01000000 : 0;
+
+ /* unlock mode register */
+ *(vu_long *) MPC5XXX_SDRAM_CTRL =
+ SDRAM_CONTROL | 0x80000000 | hi_addr_bit;
+ __asm__ volatile ("sync");
+
+ /* precharge all banks */
+ *(vu_long *) MPC5XXX_SDRAM_CTRL =
+ SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
+ __asm__ volatile ("sync");
+
+ /* set mode register: extended mode */
+ *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
+ __asm__ volatile ("sync");
+
+ /* set mode register: reset DLL */
+ *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
+ __asm__ volatile ("sync");
+
+ /* precharge all banks */
+ *(vu_long *) MPC5XXX_SDRAM_CTRL =
+ SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
+ __asm__ volatile ("sync");
+
+ /* auto refresh */
+ *(vu_long *) MPC5XXX_SDRAM_CTRL =
+ SDRAM_CONTROL | 0x80000004 | hi_addr_bit;
+ __asm__ volatile ("sync");
+
+ /* set mode register */
+ *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE;
+ __asm__ volatile ("sync");
+
+ /* normal operation */
+ *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
+ __asm__ volatile ("sync");
+}
+
+/*
+ * ATTENTION: Although partially referenced initdram does NOT make real use
+ * use of CFG_SDRAM_BASE. The code does not work if CFG_SDRAM_BASE
+ * is something else than 0x00000000.
+ */
+
+long int initdram(int board_type)
+{
+ ulong dramsize = 0;
+ ulong test1, test2;
+
+ /* setup SDRAM chip selects */
+ *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0x0000001e; /* 2G at 0x0 */
+ *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x80000000; /* disabled */
+ __asm__ volatile ("sync");
+
+ /* setup config registers */
+ *(vu_long *) MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
+ *(vu_long *) MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
+ __asm__ volatile ("sync");
+
+ /* set tap delay */
+ *(vu_long *) MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
+ __asm__ volatile ("sync");
+
+ /* find RAM size using SDRAM CS0 only */
+ sdram_start(0);
+ test1 = get_ram_size(CFG_SDRAM_BASE, 0x80000000);
+ sdram_start(1);
+ test2 = get_ram_size(CFG_SDRAM_BASE, 0x80000000);
+
+ if (test1 > test2) {
+ sdram_start(0);
+ dramsize = test1;
+ } else {
+ dramsize = test2;
+ }
+
+ /* memory smaller than 1MB is impossible */
+ if (dramsize < (1 << 20))
+ dramsize = 0;
+
+ /* set SDRAM CS0 size according to the amount of RAM found */
+ if (dramsize > 0) {
+ *(vu_long *) MPC5XXX_SDRAM_CS0CFG =
+ 0x13 + __builtin_ffs(dramsize >> 20) - 1;
+ /* let SDRAM CS1 start right after CS0 */
+ *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e; /* 2G */
+ } else {
+#if 0
+ *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
+ /* let SDRAM CS1 start right after CS0 */
+ *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e; /* 2G */
+#else
+ *(vu_long *) MPC5XXX_SDRAM_CS0CFG =
+ 0x13 + __builtin_ffs(0x08000000 >> 20) - 1;
+ /* let SDRAM CS1 start right after CS0 */
+ *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x08000000 + 0x0000001e; /* 2G */
+#endif
+ }
+
+#if 0
+ /* find RAM size using SDRAM CS1 only */
+ sdram_start(0);
+ get_ram_size((ulong *) (CFG_SDRAM_BASE + dramsize), 0x80000000);
+ sdram_start(1);
+ get_ram_size((ulong *) (CFG_SDRAM_BASE + dramsize), 0x80000000);
+ sdram_start(0);
+#endif
+ /* set SDRAM CS1 size according to the amount of RAM found */
+
+ *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
+
+ init_power_switch();
+ return (dramsize);
+}
+
+int checkboard(void)
+{
+ puts("Board: esd CPX CPU5200 (mecp5200)\n");
+ return 0;
+}
+
+void flash_preinit(void)
+{
+ /*
+ * Now, when we are in RAM, enable flash write
+ * access for detection process.
+ * Note that CS_BOOT cannot be cleared when
+ * executing in flash.
+ */
+ *(vu_long *) MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
+}
+
+void flash_afterinit(ulong size)
+{
+ if (size == CFG_FLASH_SIZE) {
+ /* adjust mapping */
+ *(vu_long *) MPC5XXX_BOOTCS_START =
+ *(vu_long *) MPC5XXX_CS0_START =
+ START_REG(CFG_BOOTCS_START | size);
+ *(vu_long *) MPC5XXX_BOOTCS_STOP =
+ *(vu_long *) MPC5XXX_CS0_STOP =
+ STOP_REG(CFG_BOOTCS_START | size, size);
+ }
+}
+
+#ifdef CONFIG_PCI
+static struct pci_controller hose;
+
+extern void pci_mpc5xxx_init(struct pci_controller *);
+
+void pci_init_board(void)
+{
+ pci_mpc5xxx_init(&hose);
+}
+#endif
+
+#if defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET)
+
+#define GPIO_PSC1_4 0x01000000UL
+
+void init_ide_reset(void)
+{
+ debug("init_ide_reset\n");
+
+ /* Configure PSC1_4 as GPIO output for ATA reset */
+ *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
+ *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4;
+}
+
+void ide_set_reset(int idereset)
+{
+ debug("ide_reset(%d)\n", idereset);
+
+ if (idereset)
+ *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4;
+ else
+ *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4;
+}
+#endif /* defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) */
+
+#define MPC5XXX_SIMPLEIO_GPIO_ENABLE (MPC5XXX_GPIO + 0x0004)
+#define MPC5XXX_SIMPLEIO_GPIO_DIR (MPC5XXX_GPIO + 0x000C)
+#define MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT (MPC5XXX_GPIO + 0x0010)
+#define MPC5XXX_SIMPLEIO_GPIO_DATA_INPUT (MPC5XXX_GPIO + 0x0014)
+
+#define MPC5XXX_INTERRUPT_GPIO_ENABLE (MPC5XXX_GPIO + 0x0020)
+#define MPC5XXX_INTERRUPT_GPIO_DIR (MPC5XXX_GPIO + 0x0028)
+#define MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT (MPC5XXX_GPIO + 0x002C)
+#define MPC5XXX_INTERRUPT_GPIO_STATUS (MPC5XXX_GPIO + 0x003C)
+
+#define GPIO_WU6 0x40000000UL
+#define GPIO_USB0 0x00010000UL
+#define GPIO_USB9 0x08000000UL
+#define GPIO_USB9S 0x00080000UL
+
+void init_power_switch(void)
+{
+ debug("init_power_switch\n");
+
+ /* Configure GPIO_WU6 as GPIO output for ATA reset */
+ *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_WU6;
+ *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_WU6;
+ *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_WU6;
+ __asm__ volatile ("sync");
+
+ *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT &= ~GPIO_USB0;
+ *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_ENABLE |= GPIO_USB0;
+ *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DIR |= GPIO_USB0;
+ __asm__ volatile ("sync");
+
+ *(vu_long *) MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT &= ~GPIO_USB9;
+ *(vu_long *) MPC5XXX_INTERRUPT_GPIO_ENABLE &= ~GPIO_USB9;
+ __asm__ volatile ("sync");
+
+ if ((*(vu_long *) MPC5XXX_INTERRUPT_GPIO_STATUS & GPIO_USB9S) == 0) {
+ *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT |= GPIO_USB0;
+ __asm__ volatile ("sync");
+ }
+}
diff --git a/board/esd/mecp5200/mt46v16m16-75.h b/board/esd/mecp5200/mt46v16m16-75.h
new file mode 100644
index 0000000..22d0a55
--- /dev/null
+++ b/board/esd/mecp5200/mt46v16m16-75.h
@@ -0,0 +1,37 @@
+/*
+ * (C) Copyright 2004
+ * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#define SDRAM_DDR 1 /* is DDR */
+
+#if defined(CONFIG_MPC5200)
+/* Settings for XLB = 132 MHz */
+#define SDRAM_MODE 0x018D0000
+#define SDRAM_EMODE 0x40090000
+#define SDRAM_CONTROL 0x705f0f00
+#define SDRAM_CONFIG1 0x73722930
+#define SDRAM_CONFIG2 0x47770000
+#define SDRAM_TAPDELAY 0x10000000
+
+#else
+#error CONFIG_MPC5200 not defined
+#endif
diff --git a/board/amcc/yellowstone/u-boot.lds b/board/esd/mecp5200/u-boot.lds
index a0ba44d..d999dd1 100644
--- a/board/amcc/yellowstone/u-boot.lds
+++ b/board/esd/mecp5200/u-boot.lds
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2002
+ * (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -27,16 +27,6 @@ SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/
__DYNAMIC = 0; */
SECTIONS
{
- .resetvec 0xFFFFFFFC :
- {
- *(.resetvec)
- } = 0xffff
-
- .bootpg 0xFFFFF000 :
- {
- cpu/ppc4xx/start.o (.bootpg)
- } = 0xffff
-
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
@@ -63,44 +53,21 @@ SECTIONS
.plt : { *(.plt) }
.text :
{
- /* WARNING - the following is hand-optimized to fit within */
- /* the sector layout of our flash chips! XXX FIXME XXX */
-
- cpu/ppc4xx/start.o (.text)
- board/amcc/yellowstone/init.o (.text)
- cpu/ppc4xx/kgdb.o (.text)
- cpu/ppc4xx/traps.o (.text)
- cpu/ppc4xx/interrupts.o (.text)
- cpu/ppc4xx/serial.o (.text)
- cpu/ppc4xx/cpu_init.o (.text)
- cpu/ppc4xx/speed.o (.text)
- common/dlmalloc.o (.text)
- lib_generic/crc32.o (.text)
- lib_ppc/extable.o (.text)
- lib_generic/zlib.o (.text)
-
-/* . = env_offset;*/
-/* common/environment.o(.text)*/
-
+ cpu/mpc5xxx/start.o (.text)
*(.text)
*(.fixup)
*(.got1)
- }
- _etext = .;
- PROVIDE (etext = .);
- .rodata :
- {
+ . = ALIGN(16);
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
- *(.eh_frame)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
- . = (. + 0x00FF) & 0xFFFFFF00;
+ . = (. + 0x0FFF) & 0xFFFFF000;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
@@ -111,8 +78,8 @@ SECTIONS
_FIXUP_TABLE_ = .;
*(.fixup)
}
- __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
- __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
.data :
{
@@ -126,22 +93,20 @@ SECTIONS
_edata = .;
PROVIDE (edata = .);
- . = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
- . = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
- . = ALIGN(256);
+ . = ALIGN(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
- . = ALIGN(256);
+ . = ALIGN(4096);
__init_end = .;
__bss_start = .;
diff --git a/board/lpc2292sodimm/Makefile b/board/lpc2292sodimm/Makefile
new file mode 100644
index 0000000..5a30198
--- /dev/null
+++ b/board/lpc2292sodimm/Makefile
@@ -0,0 +1,58 @@
+#
+# (C) Copyright 2002
+# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+# Marius Groeger <mgroeger@sysgo.de>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS := lpc2292sodimm.o flash.o mmc.o spi.o mmc_hw.o eth.o
+SOBJS := lowlevel_init.o iap_entry.o
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $(OBJS) $(SOBJS)
+
+# this MUST be compiled as thumb code!
+iap_entry.o:
+ arm-linux-gcc -D__ASSEMBLY__ -g -Os -fno-strict-aliasing \
+ -fno-common -ffixed-r8 -msoft-float -D__KERNEL__ \
+ -DTEXT_BASE=0x81500000 -I/home/garyj/proj/LPC/u-boot/include \
+ -fno-builtin -ffreestanding -nostdinc -isystem \
+ /opt/eldk/arm/usr/bin/../lib/gcc/arm-linux/4.0.0/include -pipe \
+ -DCONFIG_ARM -D__ARM__ -march=armv4t -mtune=arm7tdmi -mabi=apcs-gnu \
+ -c -o iap_entry.o iap_entry.S
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+-include .depend
+
+#########################################################################
diff --git a/board/amcc/yellowstone/config.mk b/board/lpc2292sodimm/config.mk
index 4ab0ea0..b28f418 100644
--- a/board/amcc/yellowstone/config.mk
+++ b/board/lpc2292sodimm/config.mk
@@ -1,5 +1,9 @@
#
-# (C) Copyright 2002
+# (C) Copyright 2000
+# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+# Marius Groeger <mgroeger@sysgo.de>
+#
+# (C) Copyright 2000
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -21,24 +25,6 @@
# MA 02111-1307 USA
#
-#
-# esd ADCIOP boards
-#
-
-#TEXT_BASE = 0x00001000
-
-ifeq ($(ramsym),1)
-TEXT_BASE = 0xFBD00000
-else
-TEXT_BASE = 0xFFF80000
-endif
-
-PLATFORM_CPPFLAGS += -DCONFIG_440=1
-
-ifeq ($(debug),1)
-PLATFORM_CPPFLAGS += -DDEBUG
-endif
-
-ifeq ($(dbcr),1)
-PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000
-endif
+#address where u-boot will be relocated
+#TEXT_BASE = 0x0
+TEXT_BASE = 0x81500000
diff --git a/board/lpc2292sodimm/eth.c b/board/lpc2292sodimm/eth.c
new file mode 100644
index 0000000..249ab04
--- /dev/null
+++ b/board/lpc2292sodimm/eth.c
@@ -0,0 +1,885 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <net.h>
+#include <asm/arch/hardware.h>
+#include "spi.h"
+
+/*
+ * Control Registers in Bank 0
+ */
+
+#define CTL_REG_ERDPTL 0x00
+#define CTL_REG_ERDPTH 0x01
+#define CTL_REG_EWRPTL 0x02
+#define CTL_REG_EWRPTH 0x03
+#define CTL_REG_ETXSTL 0x04
+#define CTL_REG_ETXSTH 0x05
+#define CTL_REG_ETXNDL 0x06
+#define CTL_REG_ETXNDH 0x07
+#define CTL_REG_ERXSTL 0x08
+#define CTL_REG_ERXSTH 0x09
+#define CTL_REG_ERXNDL 0x0A
+#define CTL_REG_ERXNDA 0x0B
+#define CTL_REG_ERXRDPTL 0x0C
+#define CTL_REG_ERXRDPTH 0x0D
+#define CTL_REG_ERXWRPTL 0x0E
+#define CTL_REG_ERXWRPTH 0x0F
+#define CTL_REG_EDMASTL 0x10
+#define CTL_REG_EDMASTH 0x11
+#define CTL_REG_EDMANDL 0x12
+#define CTL_REG_EDMANDH 0x13
+#define CTL_REG_EDMADSTL 0x14
+#define CTL_REG_EDMADSTH 0x15
+#define CTL_REG_EDMACSL 0x16
+#define CTL_REG_EDMACSH 0x17
+/* these are common in all banks */
+#define CTL_REG_EIE 0x1B
+#define CTL_REG_EIR 0x1C
+#define CTL_REG_ESTAT 0x1D
+#define CTL_REG_ECON2 0x1E
+#define CTL_REG_ECON1 0x1F
+
+/*
+ * Control Registers in Bank 1
+ */
+
+#define CTL_REG_EHT0 0x00
+#define CTL_REG_EHT1 0x01
+#define CTL_REG_EHT2 0x02
+#define CTL_REG_EHT3 0x03
+#define CTL_REG_EHT4 0x04
+#define CTL_REG_EHT5 0x05
+#define CTL_REG_EHT6 0x06
+#define CTL_REG_EHT7 0x07
+#define CTL_REG_EPMM0 0x08
+#define CTL_REG_EPMM1 0x09
+#define CTL_REG_EPMM2 0x0A
+#define CTL_REG_EPMM3 0x0B
+#define CTL_REG_EPMM4 0x0C
+#define CTL_REG_EPMM5 0x0D
+#define CTL_REG_EPMM6 0x0E
+#define CTL_REG_EPMM7 0x0F
+#define CTL_REG_EPMCSL 0x10
+#define CTL_REG_EPMCSH 0x11
+#define CTL_REG_EPMOL 0x14
+#define CTL_REG_EPMOH 0x15
+#define CTL_REG_EWOLIE 0x16
+#define CTL_REG_EWOLIR 0x17
+#define CTL_REG_ERXFCON 0x18
+#define CTL_REG_EPKTCNT 0x19
+
+/*
+ * Control Registers in Bank 2
+ */
+
+#define CTL_REG_MACON1 0x00
+#define CTL_REG_MACON2 0x01
+#define CTL_REG_MACON3 0x02
+#define CTL_REG_MACON4 0x03
+#define CTL_REG_MABBIPG 0x04
+#define CTL_REG_MAIPGL 0x06
+#define CTL_REG_MAIPGH 0x07
+#define CTL_REG_MACLCON1 0x08
+#define CTL_REG_MACLCON2 0x09
+#define CTL_REG_MAMXFLL 0x0A
+#define CTL_REG_MAMXFLH 0x0B
+#define CTL_REG_MAPHSUP 0x0D
+#define CTL_REG_MICON 0x11
+#define CTL_REG_MICMD 0x12
+#define CTL_REG_MIREGADR 0x14
+#define CTL_REG_MIWRL 0x16
+#define CTL_REG_MIWRH 0x17
+#define CTL_REG_MIRDL 0x18
+#define CTL_REG_MIRDH 0x19
+
+/*
+ * Control Registers in Bank 3
+ */
+
+#define CTL_REG_MAADR1 0x00
+#define CTL_REG_MAADR0 0x01
+#define CTL_REG_MAADR3 0x02
+#define CTL_REG_MAADR2 0x03
+#define CTL_REG_MAADR5 0x04
+#define CTL_REG_MAADR4 0x05
+#define CTL_REG_EBSTSD 0x06
+#define CTL_REG_EBSTCON 0x07
+#define CTL_REG_EBSTCSL 0x08
+#define CTL_REG_EBSTCSH 0x09
+#define CTL_REG_MISTAT 0x0A
+#define CTL_REG_EREVID 0x12
+#define CTL_REG_ECOCON 0x15
+#define CTL_REG_EFLOCON 0x17
+#define CTL_REG_EPAUSL 0x18
+#define CTL_REG_EPAUSH 0x19
+
+
+/*
+ * PHY Register
+ */
+
+#define PHY_REG_PHID1 0x02
+#define PHY_REG_PHID2 0x03
+
+
+/*
+ * Receive Filter Register (ERXFCON) bits
+ */
+
+#define ENC_RFR_UCEN 0x80
+#define ENC_RFR_ANDOR 0x40
+#define ENC_RFR_CRCEN 0x20
+#define ENC_RFR_PMEN 0x10
+#define ENC_RFR_MPEN 0x08
+#define ENC_RFR_HTEN 0x04
+#define ENC_RFR_MCEN 0x02
+#define ENC_RFR_BCEN 0x01
+
+/*
+ * ECON1 Register Bits
+ */
+
+#define ENC_ECON1_TXRST 0x80
+#define ENC_ECON1_RXRST 0x40
+#define ENC_ECON1_DMAST 0x20
+#define ENC_ECON1_CSUMEN 0x10
+#define ENC_ECON1_TXRTS 0x08
+#define ENC_ECON1_RXEN 0x04
+#define ENC_ECON1_BSEL1 0x02
+#define ENC_ECON1_BSEL0 0x01
+
+/*
+ * ECON2 Register Bits
+ */
+#define ENC_ECON2_AUTOINC 0x80
+#define ENC_ECON2_PKTDEC 0x40
+#define ENC_ECON2_PWRSV 0x20
+#define ENC_ECON2_VRPS 0x08
+
+/*
+ * EIR Register Bits
+ */
+#define ENC_EIR_PKTIF 0x40
+#define ENC_EIR_DMAIF 0x20
+#define ENC_EIR_LINKIF 0x10
+#define ENC_EIR_TXIF 0x08
+#define ENC_EIR_WOLIF 0x04
+#define ENC_EIR_TXERIF 0x02
+#define ENC_EIR_RXERIF 0x01
+
+/*
+ * ESTAT Register Bits
+ */
+
+#define ENC_ESTAT_INT 0x80
+#define ENC_ESTAT_LATECOL 0x10
+#define ENC_ESTAT_RXBUSY 0x04
+#define ENC_ESTAT_TXABRT 0x02
+#define ENC_ESTAT_CLKRDY 0x01
+
+/*
+ * EIE Register Bits
+ */
+
+#define ENC_EIE_INTIE 0x80
+#define ENC_EIE_PKTIE 0x40
+#define ENC_EIE_DMAIE 0x20
+#define ENC_EIE_LINKIE 0x10
+#define ENC_EIE_TXIE 0x08
+#define ENC_EIE_WOLIE 0x04
+#define ENC_EIE_TXERIE 0x02
+#define ENC_EIE_RXERIE 0x01
+
+/*
+ * MACON1 Register Bits
+ */
+#define ENC_MACON1_LOOPBK 0x10
+#define ENC_MACON1_TXPAUS 0x08
+#define ENC_MACON1_RXPAUS 0x04
+#define ENC_MACON1_PASSALL 0x02
+#define ENC_MACON1_MARXEN 0x01
+
+
+/*
+ * MACON2 Register Bits
+ */
+#define ENC_MACON2_MARST 0x80
+#define ENC_MACON2_RNDRST 0x40
+#define ENC_MACON2_MARXRST 0x08
+#define ENC_MACON2_RFUNRST 0x04
+#define ENC_MACON2_MATXRST 0x02
+#define ENC_MACON2_TFUNRST 0x01
+
+/*
+ * MACON3 Register Bits
+ */
+#define ENC_MACON3_PADCFG2 0x80
+#define ENC_MACON3_PADCFG1 0x40
+#define ENC_MACON3_PADCFG0 0x20
+#define ENC_MACON3_TXCRCEN 0x10
+#define ENC_MACON3_PHDRLEN 0x08
+#define ENC_MACON3_HFRMEN 0x04
+#define ENC_MACON3_FRMLNEN 0x02
+#define ENC_MACON3_FULDPX 0x01
+
+/*
+ * MICMD Register Bits
+ */
+#define ENC_MICMD_MIISCAN 0x02
+#define ENC_MICMD_MIIRD 0x01
+
+/*
+ * MISTAT Register Bits
+ */
+#define ENC_MISTAT_NVALID 0x04
+#define ENC_MISTAT_SCAN 0x02
+#define ENC_MISTAT_BUSY 0x01
+
+/*
+ * PHID1 and PHID2 values
+ */
+#define ENC_PHID1_VALUE 0x0083
+#define ENC_PHID2_VALUE 0x1400
+#define ENC_PHID2_MASK 0xFC00
+
+
+#define ENC_SPI_SLAVE_CS 0x00010000 /* pin P1.16 */
+#define ENC_RESET 0x00020000 /* pin P1.17 */
+
+#define FAILSAFE_VALUE 5000
+
+/*
+ * Controller memory layout:
+ *
+ * 0x0000 - 0x17ff 6k bytes receive buffer
+ * 0x1800 - 0x1fff 2k bytes transmit buffer
+ */
+/* Use the lower memory for receiver buffer. See errata pt. 5 */
+#define ENC_RX_BUF_START 0x0000
+#define ENC_TX_BUF_START 0x1800
+
+/* maximum frame length */
+#define ENC_MAX_FRM_LEN 1518
+
+#define enc_enable() PUT32(IO1CLR, ENC_SPI_SLAVE_CS)
+#define enc_disable() PUT32(IO1SET, ENC_SPI_SLAVE_CS)
+#define enc_cfg_spi() spi_set_cfg(0, 0, 0); spi_set_clock(8);
+
+
+static unsigned char encReadReg (unsigned char regNo);
+static void encWriteReg (unsigned char regNo, unsigned char data);
+static void encWriteRegRetry (unsigned char regNo, unsigned char data, int c);
+static void encReadBuff (unsigned short length, unsigned char *pBuff);
+static void encWriteBuff (unsigned short length, unsigned char *pBuff);
+static void encBitSet (unsigned char regNo, unsigned char data);
+static void encBitClr (unsigned char regNo, unsigned char data);
+static void encReset (void);
+static void encInit (unsigned char *pEthAddr);
+static unsigned short phyRead (unsigned char addr);
+static void encPoll (void);
+static void encRx (void);
+
+#define m_nic_read(reg) encReadReg(reg)
+#define m_nic_write(reg, data) encWriteReg(reg, data)
+#define m_nic_write_retry(reg, data, count) encWriteRegRetry(reg, data, count)
+#define m_nic_read_data(len, buf) encReadBuff((len), (buf))
+#define m_nic_write_data(len, buf) encWriteBuff((len), (buf))
+
+/* bit field set */
+#define m_nic_bfs(reg, data) encBitSet(reg, data)
+
+/* bit field clear */
+#define m_nic_bfc(reg, data) encBitClr(reg, data)
+
+static unsigned char bank = 0; /* current bank in enc28j60 */
+static unsigned char next_pointer_lsb;
+static unsigned char next_pointer_msb;
+
+static unsigned char buffer[ENC_MAX_FRM_LEN];
+static int rxResetCounter = 0;
+
+#define RX_RESET_COUNTER 1000;
+
+/*-----------------------------------------------------------------------------
+ * Returns 0 when failes otherwize 1
+ */
+int eth_init (bd_t * bis)
+{
+ /* configure GPIO */
+ (*((volatile unsigned long *) IO1DIR)) |= ENC_SPI_SLAVE_CS;
+ (*((volatile unsigned long *) IO1DIR)) |= ENC_RESET;
+
+ /* CS and RESET active low */
+ PUT32 (IO1SET, ENC_SPI_SLAVE_CS);
+ PUT32 (IO1SET, ENC_RESET);
+
+ spi_init ();
+
+ /* initialize controller */
+ encReset ();
+ encInit (bis->bi_enetaddr);
+
+ m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_RXEN); /* enable receive */
+
+ return 0;
+}
+
+int eth_send (volatile void *packet, int length)
+{
+ /* check frame length, etc. */
+ /* TODO: */
+
+ /* switch to bank 0 */
+ m_nic_bfc (CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
+
+ /* set EWRPT */
+ m_nic_write (CTL_REG_EWRPTL, (ENC_TX_BUF_START & 0xff));
+ m_nic_write (CTL_REG_EWRPTH, (ENC_TX_BUF_START >> 8));
+
+ /* set ETXST */
+ m_nic_write (CTL_REG_ETXSTL, ENC_TX_BUF_START & 0xFF);
+ m_nic_write (CTL_REG_ETXSTH, ENC_TX_BUF_START >> 8);
+
+ /* write packet */
+ m_nic_write_data (length, (unsigned char *) packet);
+
+ /* set ETXND */
+ m_nic_write (CTL_REG_ETXNDL, (length + ENC_TX_BUF_START) & 0xFF);
+ m_nic_write (CTL_REG_ETXNDH, (length + ENC_TX_BUF_START) >> 8);
+
+ /* set ECON1.TXRTS */
+ m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_TXRTS);
+
+ return 0;
+}
+
+
+/*****************************************************************************
+ * This function resets the receiver only. This function may be called from
+ * interrupt-context.
+ */
+static void encReceiverReset (void)
+{
+ unsigned char econ1;
+
+ econ1 = m_nic_read (CTL_REG_ECON1);
+ if ((econ1 & ENC_ECON1_RXRST) == 0) {
+ m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_RXRST);
+ rxResetCounter = RX_RESET_COUNTER;
+ }
+}
+
+/*****************************************************************************
+ * receiver reset timer
+ */
+static void encReceiverResetCallback (void)
+{
+ m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_RXRST);
+ m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_RXEN); /* enable receive */
+}
+
+/*-----------------------------------------------------------------------------
+ * Check for received packets. Call NetReceive for each packet. The return
+ * value is ignored by the caller.
+ */
+int eth_rx (void)
+{
+ if (rxResetCounter > 0 && --rxResetCounter == 0) {
+ encReceiverResetCallback ();
+ }
+
+ encPoll ();
+
+ return 0;
+}
+
+void eth_halt (void)
+{
+ m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_RXEN); /* disable receive */
+}
+
+/*****************************************************************************/
+
+static void encPoll (void)
+{
+ unsigned char eir_reg;
+ volatile unsigned char estat_reg;
+ unsigned char pkt_cnt;
+
+ /* clear global interrupt enable bit in enc28j60 */
+ m_nic_bfc (CTL_REG_EIE, ENC_EIE_INTIE);
+ estat_reg = m_nic_read (CTL_REG_ESTAT);
+
+ eir_reg = m_nic_read (CTL_REG_EIR);
+
+ if (eir_reg & ENC_EIR_TXIF) {
+ /* clear TXIF bit in EIR */
+ m_nic_bfc (CTL_REG_EIR, ENC_EIR_TXIF);
+ }
+
+ /* We have to use pktcnt and not pktif bit, see errata pt. 6 */
+
+ /* move to bank 1 */
+ m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL1);
+ m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL0);
+
+ /* read pktcnt */
+ pkt_cnt = m_nic_read (CTL_REG_EPKTCNT);
+
+ if (pkt_cnt > 0) {
+ if ((eir_reg & ENC_EIR_PKTIF) == 0) {
+ /*printf("encPoll: pkt cnt > 0, but pktif not set\n"); */
+ }
+ encRx ();
+ /* clear PKTIF bit in EIR, this should not need to be done but it
+ seems like we get problems if we do not */
+ m_nic_bfc (CTL_REG_EIR, ENC_EIR_PKTIF);
+ }
+
+ if (eir_reg & ENC_EIR_RXERIF) {
+ printf ("encPoll: rx error\n");
+ m_nic_bfc (CTL_REG_EIR, ENC_EIR_RXERIF);
+ }
+ if (eir_reg & ENC_EIR_TXERIF) {
+ printf ("encPoll: tx error\n");
+ m_nic_bfc (CTL_REG_EIR, ENC_EIR_TXERIF);
+ }
+
+ /* set global interrupt enable bit in enc28j60 */
+ m_nic_bfs (CTL_REG_EIE, ENC_EIE_INTIE);
+}
+
+static void encRx (void)
+{
+ unsigned short pkt_len;
+ unsigned short copy_len;
+ unsigned short status;
+ unsigned char eir_reg;
+ unsigned char pkt_cnt = 0;
+
+ /* switch to bank 0 */
+ m_nic_bfc (CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
+
+ m_nic_write (CTL_REG_ERDPTL, next_pointer_lsb);
+ m_nic_write (CTL_REG_ERDPTH, next_pointer_msb);
+
+ do {
+ m_nic_read_data (6, buffer);
+ next_pointer_lsb = buffer[0];
+ next_pointer_msb = buffer[1];
+ pkt_len = buffer[2];
+ pkt_len |= (unsigned short) buffer[3] << 8;
+ status = buffer[4];
+ status |= (unsigned short) buffer[5] << 8;
+
+ if (pkt_len <= ENC_MAX_FRM_LEN) {
+ copy_len = pkt_len;
+ } else {
+ copy_len = 0;
+ /* p_priv->stats.rx_dropped++; */
+ /* we will drop this packet */
+ }
+
+ if ((status & (1L << 7)) == 0) { /* check Received Ok bit */
+ copy_len = 0;
+ /* p_priv->stats.rx_errors++; */
+ }
+
+ if (copy_len > 0) {
+ m_nic_read_data (copy_len, buffer);
+ }
+
+ /* advance read pointer to next pointer */
+ m_nic_write (CTL_REG_ERDPTL, next_pointer_lsb);
+ m_nic_write (CTL_REG_ERDPTH, next_pointer_msb);
+
+ /* decrease packet counter */
+ m_nic_bfs (CTL_REG_ECON2, ENC_ECON2_PKTDEC);
+
+ /* move to bank 1 */
+ m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL1);
+ m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL0);
+
+ /* read pktcnt */
+ pkt_cnt = m_nic_read (CTL_REG_EPKTCNT);
+
+ /* switch to bank 0 */
+ m_nic_bfc (CTL_REG_ECON1,
+ (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
+
+ if (copy_len == 0) {
+ eir_reg = m_nic_read (CTL_REG_EIR);
+ encReceiverReset ();
+ printf ("eth_rx: copy_len=0\n");
+ continue;
+ }
+
+ NetReceive ((unsigned char *) buffer, pkt_len);
+
+ eir_reg = m_nic_read (CTL_REG_EIR);
+ } while (pkt_cnt); /* Use EPKTCNT not EIR.PKTIF flag, see errata pt. 6 */
+ m_nic_write (CTL_REG_ERXRDPTL, next_pointer_lsb);
+ m_nic_write (CTL_REG_ERXRDPTH, next_pointer_msb);
+}
+
+static void encWriteReg (unsigned char regNo, unsigned char data)
+{
+ spi_lock ();
+ enc_cfg_spi ();
+ enc_enable ();
+
+ spi_write (0x40 | regNo); /* write in regNo */
+ spi_write (data);
+
+ enc_disable ();
+ enc_enable ();
+
+ spi_write (0x1f); /* write reg 0x1f */
+
+ enc_disable ();
+ spi_unlock ();
+}
+
+static void encWriteRegRetry (unsigned char regNo, unsigned char data, int c)
+{
+ unsigned char readback;
+ int i;
+
+ spi_lock ();
+
+ for (i = 0; i < c; i++) {
+ enc_cfg_spi ();
+ enc_enable ();
+
+ spi_write (0x40 | regNo); /* write in regNo */
+ spi_write (data);
+
+ enc_disable ();
+ enc_enable ();
+
+ spi_write (0x1f); /* write reg 0x1f */
+
+ enc_disable ();
+
+ spi_unlock (); /* we must unlock spi first */
+
+ readback = encReadReg (regNo);
+
+ spi_lock ();
+
+ if (readback == data)
+ break;
+ }
+ spi_unlock ();
+
+ if (i == c) {
+ printf ("enc28j60: write reg %d failed\n", regNo);
+ }
+}
+
+static unsigned char encReadReg (unsigned char regNo)
+{
+ unsigned char rxByte;
+
+ spi_lock ();
+ enc_cfg_spi ();
+ enc_enable ();
+
+ spi_write (0x1f); /* read reg 0x1f */
+
+ bank = spi_read () & 0x3;
+
+ enc_disable ();
+ enc_enable ();
+
+ spi_write (regNo);
+ rxByte = spi_read ();
+
+ /* check if MAC or MII register */
+ if (((bank == 2) && (regNo <= 0x1a)) ||
+ ((bank == 3) && (regNo <= 0x05 || regNo == 0x0a))) {
+ /* ignore first byte and read another byte */
+ rxByte = spi_read ();
+ }
+
+ enc_disable ();
+ spi_unlock ();
+
+ return rxByte;
+}
+
+static void encReadBuff (unsigned short length, unsigned char *pBuff)
+{
+ spi_lock ();
+ enc_cfg_spi ();
+ enc_enable ();
+
+ spi_write (0x20 | 0x1a); /* read buffer memory */
+
+ while (length--) {
+ if (pBuff != NULL)
+ *pBuff++ = spi_read ();
+ else
+ spi_write (0);
+ }
+
+ enc_disable ();
+ spi_unlock ();
+}
+
+static void encWriteBuff (unsigned short length, unsigned char *pBuff)
+{
+ spi_lock ();
+ enc_cfg_spi ();
+ enc_enable ();
+
+ spi_write (0x60 | 0x1a); /* write buffer memory */
+
+ spi_write (0x00); /* control byte */
+
+ while (length--)
+ spi_write (*pBuff++);
+
+ enc_disable ();
+ spi_unlock ();
+}
+
+static void encBitSet (unsigned char regNo, unsigned char data)
+{
+ spi_lock ();
+ enc_cfg_spi ();
+ enc_enable ();
+
+ spi_write (0x80 | regNo); /* bit field set */
+ spi_write (data);
+
+ enc_disable ();
+ spi_unlock ();
+}
+
+static void encBitClr (unsigned char regNo, unsigned char data)
+{
+ spi_lock ();
+ enc_cfg_spi ();
+ enc_enable ();
+
+ spi_write (0xA0 | regNo); /* bit field clear */
+ spi_write (data);
+
+ enc_disable ();
+ spi_unlock ();
+}
+
+static void encReset (void)
+{
+ spi_lock ();
+ enc_cfg_spi ();
+ enc_enable ();
+
+ spi_write (0xff); /* soft reset */
+
+ enc_disable ();
+ spi_unlock ();
+
+ /* sleep 1 ms. See errata pt. 2 */
+ udelay (1000);
+
+#if 0
+ (*((volatile unsigned long *) IO1CLR)) &= ENC_RESET;
+ mdelay (5);
+ (*((volatile unsigned long *) IO1SET)) &= ENC_RESET;
+#endif
+}
+
+static void encInit (unsigned char *pEthAddr)
+{
+ unsigned short phid1 = 0;
+ unsigned short phid2 = 0;
+
+ /* switch to bank 0 */
+ m_nic_bfc (CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
+
+ /*
+ * Setup the buffer space. The reset values are valid for the
+ * other pointers.
+ */
+#if 0
+ /* We shall not write to ERXST, see errata pt. 5. Instead we
+ have to make sure that ENC_RX_BUS_START is 0. */
+ m_nic_write_retry (CTL_REG_ERXSTL, (ENC_RX_BUF_START & 0xFF), 1);
+ m_nic_write_retry (CTL_REG_ERXSTH, (ENC_RX_BUF_START >> 8), 1);
+#endif
+ m_nic_write_retry (CTL_REG_ERDPTL, (ENC_RX_BUF_START & 0xFF), 1);
+ m_nic_write_retry (CTL_REG_ERDPTH, (ENC_RX_BUF_START >> 8), 1);
+
+ next_pointer_lsb = (ENC_RX_BUF_START & 0xFF);
+ next_pointer_msb = (ENC_RX_BUF_START >> 8);
+
+ /*
+ * For tracking purposes, the ERXRDPT registers should be programmed with
+ * the same value. This is the read pointer.
+ */
+ m_nic_write (CTL_REG_ERXRDPTL, (ENC_RX_BUF_START & 0xFF));
+ m_nic_write_retry (CTL_REG_ERXRDPTH, (ENC_RX_BUF_START >> 8), 1);
+
+ /* Setup receive filters. */
+
+ /* move to bank 1 */
+ m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL1);
+ m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL0);
+
+ /* OR-filtering, Unicast, CRC-check and broadcast */
+ m_nic_write_retry (CTL_REG_ERXFCON,
+ (ENC_RFR_UCEN | ENC_RFR_CRCEN | ENC_RFR_BCEN), 1);
+
+ /* Wait for Oscillator Start-up Timer (OST). */
+ while ((m_nic_read (CTL_REG_ESTAT) & ENC_ESTAT_CLKRDY) == 0) {
+ static int cnt = 0;
+
+ if (cnt++ >= 1000) {
+ cnt = 0;
+ }
+ }
+
+ /* verify identification */
+ phid1 = phyRead (PHY_REG_PHID1);
+ phid2 = phyRead (PHY_REG_PHID2);
+
+ if (phid1 != ENC_PHID1_VALUE
+ || (phid2 & ENC_PHID2_MASK) != ENC_PHID2_VALUE) {
+ printf ("ERROR: failed to identify controller\n");
+ printf ("phid1 = %x, phid2 = %x\n",
+ phid1, (phid2 & ENC_PHID2_MASK));
+ printf ("should be phid1 = %x, phid2 = %x\n",
+ ENC_PHID1_VALUE, ENC_PHID2_VALUE);
+ }
+
+ /*
+ * --- MAC Initialization ---
+ */
+
+ /* Pull MAC out of Reset */
+
+ /* switch to bank 2 */
+ m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL0);
+ m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL1);
+ /* clear MAC reset bits */
+ m_nic_write_retry (CTL_REG_MACON2, 0, 1);
+
+ /* enable MAC to receive frames */
+ m_nic_write_retry (CTL_REG_MACON1, ENC_MACON1_MARXEN, 10);
+
+ /* configure pad, tx-crc and duplex */
+ /* TODO maybe enable FRMLNEN */
+ m_nic_write_retry (CTL_REG_MACON3,
+ (ENC_MACON3_PADCFG0 | ENC_MACON3_TXCRCEN), 10);
+
+ /* set maximum frame length */
+ m_nic_write_retry (CTL_REG_MAMXFLL, (ENC_MAX_FRM_LEN & 0xff), 10);
+ m_nic_write_retry (CTL_REG_MAMXFLH, (ENC_MAX_FRM_LEN >> 8), 10);
+
+ /*
+ * Set MAC back-to-back inter-packet gap. Recommended 0x12 for half duplex
+ * and 0x15 for full duplex.
+ */
+ m_nic_write_retry (CTL_REG_MABBIPG, 0x12, 10);
+
+ /* Set (low byte) Non-Back-to_Back Inter-Packet Gap. Recommended 0x12 */
+ m_nic_write_retry (CTL_REG_MAIPGL, 0x12, 10);
+
+ /*
+ * Set (high byte) Non-Back-to_Back Inter-Packet Gap. Recommended
+ * 0x0c for half-duplex. Nothing for full-duplex
+ */
+ m_nic_write_retry (CTL_REG_MAIPGH, 0x0C, 10);
+
+ /* set MAC address */
+
+ /* switch to bank 3 */
+ m_nic_bfs (CTL_REG_ECON1, (ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1));
+
+ m_nic_write_retry (CTL_REG_MAADR0, pEthAddr[5], 1);
+ m_nic_write_retry (CTL_REG_MAADR1, pEthAddr[4], 1);
+ m_nic_write_retry (CTL_REG_MAADR2, pEthAddr[3], 1);
+ m_nic_write_retry (CTL_REG_MAADR3, pEthAddr[2], 1);
+ m_nic_write_retry (CTL_REG_MAADR4, pEthAddr[1], 1);
+ m_nic_write_retry (CTL_REG_MAADR5, pEthAddr[0], 1);
+
+ /*
+ * Receive settings
+ */
+
+ /* auto-increment RX-pointer when reading a received packet */
+ m_nic_bfs (CTL_REG_ECON2, ENC_ECON2_AUTOINC);
+
+ /* enable interrupts */
+ m_nic_bfs (CTL_REG_EIE, ENC_EIE_PKTIE);
+ m_nic_bfs (CTL_REG_EIE, ENC_EIE_TXIE);
+ m_nic_bfs (CTL_REG_EIE, ENC_EIE_RXERIE);
+ m_nic_bfs (CTL_REG_EIE, ENC_EIE_TXERIE);
+ m_nic_bfs (CTL_REG_EIE, ENC_EIE_INTIE);
+}
+
+/*****************************************************************************
+ *
+ * Description:
+ * Read PHY registers.
+ *
+ * NOTE! This function will change to Bank 2.
+ *
+ * Params:
+ * [in] addr address of the register to read
+ *
+ * Returns:
+ * The value in the register
+ */
+static unsigned short phyRead (unsigned char addr)
+{
+ unsigned short ret = 0;
+
+ /* move to bank 2 */
+ m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL0);
+ m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL1);
+
+ /* write address to MIREGADR */
+ m_nic_write (CTL_REG_MIREGADR, addr);
+
+ /* set MICMD.MIIRD */
+ m_nic_write (CTL_REG_MICMD, ENC_MICMD_MIIRD);
+
+ /* poll MISTAT.BUSY bit until operation is complete */
+ while ((m_nic_read (CTL_REG_MISTAT) & ENC_MISTAT_BUSY) != 0) {
+ static int cnt = 0;
+
+ if (cnt++ >= 1000) {
+ /* GJ - this seems extremely dangerous! */
+ /* printf("#"); */
+ cnt = 0;
+ }
+ }
+
+ /* clear MICMD.MIIRD */
+ m_nic_write (CTL_REG_MICMD, 0);
+
+ ret = (m_nic_read (CTL_REG_MIRDH) << 8);
+ ret |= (m_nic_read (CTL_REG_MIRDL) & 0xFF);
+
+ return ret;
+}
diff --git a/board/lpc2292sodimm/flash.c b/board/lpc2292sodimm/flash.c
new file mode 100644
index 0000000..55aaabf
--- /dev/null
+++ b/board/lpc2292sodimm/flash.c
@@ -0,0 +1,476 @@
+/*
+ * (C) Copyright 2006 Embedded Artists AB <www.embeddedartists.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+
+/* IAP commands use 32 bytes at the top of CPU internal sram, we
+ use 512 bytes below that */
+#define COPY_BUFFER_LOCATION 0x40003de0
+
+#define IAP_LOCATION 0x7ffffff1
+#define IAP_CMD_PREPARE 50
+#define IAP_CMD_COPY 51
+#define IAP_CMD_ERASE 52
+#define IAP_CMD_CHECK 53
+#define IAP_CMD_ID 54
+#define IAP_CMD_VERSION 55
+#define IAP_CMD_COMPARE 56
+
+#define IAP_RET_CMD_SUCCESS 0
+
+#define SST_BASEADDR 0x80000000
+#define SST_ADDR1 ((volatile ushort*)(SST_BASEADDR + (0x5555 << 1)))
+#define SST_ADDR2 ((volatile ushort*)(SST_BASEADDR + (0x2AAA << 1)))
+
+
+static unsigned long command[5];
+static unsigned long result[2];
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+extern void iap_entry(unsigned long * command, unsigned long * result);
+
+/*-----------------------------------------------------------------------
+ *
+ */
+int get_flash_sector(flash_info_t * info, ulong flash_addr)
+{
+ int i;
+
+ for(i=1; i < (info->sector_count); i++) {
+ if (flash_addr < (info->start[i]))
+ break;
+ }
+
+ return (i-1);
+}
+
+/*-----------------------------------------------------------------------
+ * This function assumes that flash_addr is aligned on 512 bytes boundary
+ * in flash. This function also assumes that prepare have been called
+ * for the sector in question.
+ */
+int copy_buffer_to_flash(flash_info_t * info, ulong flash_addr)
+{
+ int first_sector;
+ int last_sector;
+
+ first_sector = get_flash_sector(info, flash_addr);
+ last_sector = get_flash_sector(info, flash_addr + 512 - 1);
+
+ /* prepare sectors for write */
+ command[0] = IAP_CMD_PREPARE;
+ command[1] = first_sector;
+ command[2] = last_sector;
+ iap_entry(command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf("IAP prepare failed\n");
+ return ERR_PROG_ERROR;
+ }
+
+ command[0] = IAP_CMD_COPY;
+ command[1] = flash_addr;
+ command[2] = COPY_BUFFER_LOCATION;
+ command[3] = 512;
+ command[4] = CFG_SYS_CLK_FREQ >> 10;
+ iap_entry(command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf("IAP copy failed\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------
+ *
+ */
+void write_word_sst(ulong addr, ushort data)
+{
+ ushort tmp;
+
+ *SST_ADDR1 = 0x00AA;
+ *SST_ADDR2 = 0x0055;
+ *SST_ADDR1 = 0x00A0;
+ *((volatile ushort*)addr) = data;
+ /* do data polling */
+ do {
+ tmp = *((volatile ushort*)addr);
+ } while (tmp != data);
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+ulong flash_init (void)
+{
+ int j, k;
+ ulong size = 0;
+ ulong flashbase = 0;
+
+ flash_info[0].flash_id = (PHILIPS_LPC2292 & FLASH_VENDMASK);
+ flash_info[0].size = 0x003E000; /* 256 - 8 KB */
+ flash_info[0].sector_count = 17;
+ memset (flash_info[0].protect, 0, 17);
+ flashbase = 0x00000000;
+ for (j = 0, k = 0; j < 8; j++, k++) {
+ flash_info[0].start[k] = flashbase;
+ flashbase += 0x00002000;
+ }
+ for (j = 0; j < 2; j++, k++) {
+ flash_info[0].start[k] = flashbase;
+ flashbase += 0x00010000;
+ }
+ for (j = 0; j < 7; j++, k++) {
+ flash_info[0].start[k] = flashbase;
+ flashbase += 0x00002000;
+ }
+ size += flash_info[0].size;
+
+ flash_info[1].flash_id = (SST_MANUFACT & FLASH_VENDMASK);
+ flash_info[1].size = 0x00200000; /* 2 MB */
+ flash_info[1].sector_count = 512;
+ memset (flash_info[1].protect, 0, 512);
+ flashbase = SST_BASEADDR;
+ for (j=0; j<512; j++) {
+ flash_info[1].start[j] = flashbase;
+ flashbase += 0x1000; /* 4 KB sectors */
+ }
+ size += flash_info[1].size;
+
+ /* Protect monitor and environment sectors */
+ flash_protect (FLAG_PROTECT_SET,
+ 0x0,
+ 0x0 + monitor_flash_len - 1,
+ &flash_info[0]);
+
+ flash_protect (FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+ &flash_info[0]);
+
+ return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+ int i;
+ int erased = 0;
+ unsigned long j;
+ unsigned long count;
+ unsigned char *p;
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case (SST_MANUFACT & FLASH_VENDMASK):
+ printf("SST: ");
+ break;
+ case (PHILIPS_LPC2292 & FLASH_VENDMASK):
+ printf("Philips: ");
+ break;
+ default:
+ printf ("Unknown Vendor ");
+ break;
+ }
+
+ printf (" Size: %ld KB in %d Sectors\n",
+ info->size >> 10, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i = 0; i < info->sector_count; i++) {
+ if ((i % 5) == 0) {
+ printf ("\n ");
+ }
+ if (i < (info->sector_count - 1)) {
+ count = info->start[i+1] - info->start[i];
+ }
+ else {
+ count = info->start[0] + info->size - info->start[i];
+ }
+ p = (unsigned char*)(info->start[i]);
+ erased = 1;
+ for (j = 0; j < count; j++) {
+ if (*p != 0xFF) {
+ erased = 0;
+ break;
+ }
+ p++;
+ }
+ printf (" %08lX%s%s", info->start[i], info->protect[i] ? " RO" : " ",
+ erased ? " E" : " ");
+ }
+ printf ("\n");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase_philips (flash_info_t * info, int s_first, int s_last)
+{
+ int flag;
+ int prot;
+ int sect;
+
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+ if (prot)
+ return ERR_PROTECTED;
+
+
+ flag = disable_interrupts();
+
+ printf ("Erasing %d sectors starting at sector %2d.\n"
+ "This make take some time ... ",
+ s_last - s_first + 1, s_first);
+
+ command[0] = IAP_CMD_PREPARE;
+ command[1] = s_first;
+ command[2] = s_last;
+ iap_entry(command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf("IAP prepare failed\n");
+ return ERR_PROTECTED;
+ }
+
+ command[0] = IAP_CMD_ERASE;
+ command[1] = s_first;
+ command[2] = s_last;
+ command[3] = CFG_SYS_CLK_FREQ >> 10;
+ iap_entry(command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf("IAP erase failed\n");
+ return ERR_PROTECTED;
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ERR_OK;
+}
+
+int flash_erase_sst (flash_info_t * info, int s_first, int s_last)
+{
+ int i;
+
+ for (i = s_first; i <= s_last; i++) {
+ *SST_ADDR1 = 0x00AA;
+ *SST_ADDR2 = 0x0055;
+ *SST_ADDR1 = 0x0080;
+ *SST_ADDR1 = 0x00AA;
+ *SST_ADDR2 = 0x0055;
+ *((volatile ushort*)(info->start[i])) = 0x0030;
+ /* wait for erase to finish */
+ udelay(25000);
+ }
+
+ return ERR_OK;
+}
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case (SST_MANUFACT & FLASH_VENDMASK):
+ return flash_erase_sst(info, s_first, s_last);
+ case (PHILIPS_LPC2292 & FLASH_VENDMASK):
+ return flash_erase_philips(info, s_first, s_last);
+ default:
+ return ERR_PROTECTED;
+ }
+ return ERR_PROTECTED;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ *
+ * cnt is in bytes
+ */
+
+int write_buff_sst (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+ ushort tmp;
+ ulong i;
+ uchar* src_org;
+ uchar* dst_org;
+ ulong cnt_org = cnt;
+ int ret = ERR_OK;
+
+ src_org = src;
+ dst_org = (uchar*)addr;
+
+ if (addr & 1) { /* if odd address */
+ tmp = *((uchar*)(addr - 1)); /* little endian */
+ tmp |= (*src << 8);
+ write_word_sst(addr - 1, tmp);
+ addr += 1;
+ cnt -= 1;
+ src++;
+ }
+ while (cnt > 1) {
+ tmp = ((*(src+1)) << 8) + (*src); /* little endian */
+ write_word_sst(addr, tmp);
+ addr += 2;
+ src += 2;
+ cnt -= 2;
+ }
+ if (cnt > 0) {
+ tmp = (*((uchar*)(addr + 1))) << 8;
+ tmp |= *src;
+ write_word_sst(addr, tmp);
+ }
+
+ for (i = 0; i < cnt_org; i++) {
+ if (*dst_org != *src_org) {
+ printf("Write failed. Byte %lX differs\n", i);
+ ret = ERR_PROG_ERROR;
+ break;
+ }
+ dst_org++;
+ src_org++;
+ }
+
+ return ret;
+}
+
+int write_buff_philips (flash_info_t * info,
+ uchar * src,
+ ulong addr,
+ ulong cnt)
+{
+ int first_copy_size;
+ int last_copy_size;
+ int first_block;
+ int last_block;
+ int nbr_mid_blocks;
+ uchar memmap_value;
+ ulong i;
+ uchar* src_org;
+ uchar* dst_org;
+ int ret = ERR_OK;
+
+ src_org = src;
+ dst_org = (uchar*)addr;
+
+ first_block = addr / 512;
+ last_block = (addr + cnt) / 512;
+ nbr_mid_blocks = last_block - first_block - 1;
+
+ first_copy_size = 512 - (addr % 512);
+ last_copy_size = (addr + cnt) % 512;
+
+#if 0
+ printf("\ncopy first block: (1) %lX -> %lX 0x200 bytes, "
+ "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX 0x200 bytes\n",
+ (ulong)(first_block * 512),
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)src,
+ (ulong)(COPY_BUFFER_LOCATION + 512 - first_copy_size),
+ first_copy_size,
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)(first_block * 512));
+#endif
+
+ /* copy first block */
+ memcpy((void*)COPY_BUFFER_LOCATION,
+ (void*)(first_block * 512), 512);
+ memcpy((void*)(COPY_BUFFER_LOCATION + 512 - first_copy_size),
+ src, first_copy_size);
+ copy_buffer_to_flash(info, first_block * 512);
+ src += first_copy_size;
+ addr += first_copy_size;
+
+ /* copy middle blocks */
+ for (i = 0; i < nbr_mid_blocks; i++) {
+#if 0
+ printf("copy middle block: %lX -> %lX 512 bytes, "
+ "%lX -> %lX 512 bytes\n",
+ (ulong)src,
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)addr);
+#endif
+ memcpy((void*)COPY_BUFFER_LOCATION, src, 512);
+ copy_buffer_to_flash(info, addr);
+ src += 512;
+ addr += 512;
+ }
+
+
+ if (last_copy_size > 0) {
+#if 0
+ printf("copy last block: (1) %lX -> %lX 0x200 bytes, "
+ "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX x200 bytes\n",
+ (ulong)(last_block * 512),
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)src,
+ (ulong)(COPY_BUFFER_LOCATION),
+ last_copy_size,
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)addr);
+#endif
+ /* copy last block */
+ memcpy((void*)COPY_BUFFER_LOCATION,
+ (void*)(last_block * 512), 512);
+ memcpy((void*)COPY_BUFFER_LOCATION,
+ src, last_copy_size);
+ copy_buffer_to_flash(info, addr);
+ }
+
+ /* verify write */
+ memmap_value = GET8(MEMMAP);
+
+ disable_interrupts();
+
+ PUT8(MEMMAP, 01); /* we must make sure that initial 64
+ bytes are taken from flash when we
+ do the compare */
+
+ for (i = 0; i < cnt; i++) {
+ if (*dst_org != *src_org){
+ printf("Write failed. Byte %lX differs\n", i);
+ ret = ERR_PROG_ERROR;
+ break;
+ }
+ dst_org++;
+ src_org++;
+ }
+
+ PUT8(MEMMAP, memmap_value);
+ enable_interrupts();
+
+ return ret;
+}
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case (SST_MANUFACT & FLASH_VENDMASK):
+ return write_buff_sst(info, src, addr, cnt);
+ case (PHILIPS_LPC2292 & FLASH_VENDMASK):
+ return write_buff_philips(info, src, addr, cnt);
+ default:
+ return ERR_PROG_ERROR;
+ }
+ return ERR_PROG_ERROR;
+}
diff --git a/board/lpc2292sodimm/iap_entry.S b/board/lpc2292sodimm/iap_entry.S
new file mode 100644
index 0000000..c31d519
--- /dev/null
+++ b/board/lpc2292sodimm/iap_entry.S
@@ -0,0 +1,7 @@
+IAP_ADDRESS: .word 0x7FFFFFF1
+
+.globl iap_entry
+iap_entry:
+ ldr r2, IAP_ADDRESS
+ bx r2
+ mov pc, lr
diff --git a/board/lpc2292sodimm/lowlevel_init.S b/board/lpc2292sodimm/lowlevel_init.S
new file mode 100644
index 0000000..a0e9747
--- /dev/null
+++ b/board/lpc2292sodimm/lowlevel_init.S
@@ -0,0 +1,87 @@
+/*
+ * (C) Copyright 2006 Embedded Artists AB <www.embeddedartists.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <version.h>
+#include <asm/arch/hardware.h>
+
+/* some parameters for the board */
+/* setting up the memory */
+#define SRAM_START 0x40000000
+#define SRAM_SIZE 0x00004000
+#define BCFG0_VALUE 0x1000ffef
+#define BCFG1_VALUE 0x10001C61
+
+_TEXT_BASE:
+ .word TEXT_BASE
+MEMMAP_ADR:
+ .word MEMMAP
+BCFG0_ADR:
+ .word BCFG0
+_BCFG0_VALUE:
+ .word BCFG0_VALUE
+BCFG1_ADR:
+ .word BCFG1
+_BCFG1_VALUE:
+ .word BCFG1_VALUE
+PINSEL2_ADR:
+ .word PINSEL2
+PINSEL2_MASK:
+ .word 0x00000000
+PINSEL2_VALUE:
+ .word 0x0F800914
+
+.extern _start
+
+.globl lowlevel_init
+lowlevel_init:
+ /* set up memory control register for bank 0 */
+ ldr r0, _BCFG0_VALUE
+ ldr r1, BCFG0_ADR
+ str r0, [r1]
+
+ /* set up memory control register for bank 1 */
+ ldr r0, _BCFG1_VALUE
+ ldr r1, BCFG1_ADR
+ str r0, [r1]
+
+ /* set up PINSEL2 for bus-pins */
+ ldr r0, PINSEL2_ADR
+ ldr r1, [r0]
+ ldr r2, PINSEL2_MASK
+ ldr r3, PINSEL2_VALUE
+ and r1, r1, r2
+ orr r1, r1, r3
+ str r1, [r0]
+
+ /* move vectors to beginning of SRAM */
+ mov r2, #SRAM_START
+ mov r0, #0 /*_start*/
+ ldmneia r0!, {r3-r10}
+ stmneia r2!, {r3-r10}
+ ldmneia r0, {r3-r9}
+ stmneia r2, {r3-r9}
+
+ /* Set-up MEMMAP register, so vectors are taken from SRAM */
+ ldr r0, MEMMAP_ADR
+ mov r1, #0x02 /* vectors re-mapped to static RAM */
+ str r1, [r0]
+
+ /* everything is fine now */
+ mov pc, lr
diff --git a/board/lpc2292sodimm/lpc2292sodimm.c b/board/lpc2292sodimm/lpc2292sodimm.c
new file mode 100644
index 0000000..de04c66
--- /dev/null
+++ b/board/lpc2292sodimm/lpc2292sodimm.c
@@ -0,0 +1,62 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2005 Rowel Atienza <rowel@diwalabs.com>
+ * Armadillo board HT1070
+ *
+ * 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 <clps7111.h>
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Miscelaneous platform dependent initialisations
+ */
+
+int board_init (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /* Activate LED flasher */
+ IO_LEDFLSH = 0x40;
+
+ /* arch number MACH_TYPE_ARMADILLO - not official*/
+ gd->bd->bi_arch_number = 83;
+
+ /* location of boot parameters */
+ gd->bd->bi_boot_params = 0xc0000100;
+
+ return 0;
+}
+
+int dram_init (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+ return (0);
+}
diff --git a/board/lpc2292sodimm/mmc.c b/board/lpc2292sodimm/mmc.c
new file mode 100644
index 0000000..1c0922f
--- /dev/null
+++ b/board/lpc2292sodimm/mmc.c
@@ -0,0 +1,154 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <mmc.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+#include <part.h>
+#include <fat.h>
+#include "mmc_hw.h"
+#include "spi.h"
+
+#ifdef CONFIG_MMC
+
+#undef MMC_DEBUG
+
+static block_dev_desc_t mmc_dev;
+
+/* these are filled out by a call to mmc_hw_get_parameters */
+static int hw_size; /* in kbytes */
+static int hw_nr_sects;
+static int hw_sect_size; /* in bytes */
+
+block_dev_desc_t * mmc_get_dev(int dev)
+{
+ return (block_dev_desc_t *)(&mmc_dev);
+}
+
+unsigned long mmc_block_read(int dev,
+ unsigned long start,
+ lbaint_t blkcnt,
+ unsigned long *buffer)
+{
+ unsigned long rc = 0;
+ unsigned char *p = (unsigned char *)buffer;
+ unsigned long i;
+ unsigned long addr = start;
+
+#ifdef MMC_DEBUG
+ printf("mmc_block_read: start=%lu, blkcnt=%lu\n", start,
+ (unsigned long)blkcnt);
+#endif
+
+ for(i = 0; i < (unsigned long)blkcnt; i++) {
+#ifdef MMC_DEBUG
+ printf("mmc_read_sector: addr=%lu, buffer=%p\n", addr, p);
+#endif
+ (void)mmc_read_sector(addr, p);
+ rc++;
+ addr++;
+ p += hw_sect_size;
+ }
+
+ return rc;
+}
+
+/*-----------------------------------------------------------------------------
+ * Read hardware paramterers (sector size, size, number of sectors)
+ */
+static int mmc_hw_get_parameters(void)
+{
+ unsigned char csddata[16];
+ unsigned int sizemult;
+ unsigned int size;
+
+ mmc_read_csd(csddata);
+ hw_sect_size = 1<<(csddata[5] & 0x0f);
+ size = ((csddata[6]&0x03)<<10)+(csddata[7]<<2)+(csddata[8]&0xc0);
+ sizemult = ((csddata[10] & 0x80)>>7)+((csddata[9] & 0x03)<<1);
+ hw_nr_sects = (size+1)*(1<<(sizemult+2));
+ hw_size = hw_nr_sects*hw_sect_size/1024;
+
+#ifdef MMC_DEBUG
+ printf("mmc_hw_get_parameters: hw_sect_size=%d, hw_nr_sects=%d, "
+ "hw_size=%d\n", hw_sect_size, hw_nr_sects, hw_size);
+#endif
+
+ return 0;
+}
+
+int mmc_init(int verbose)
+{
+ int ret = -ENODEV;
+
+ if (verbose)
+ printf("mmc_init\n");
+
+ spi_init();
+ mmc_hw_init();
+
+ mmc_hw_get_parameters();
+
+ mmc_dev.if_type = IF_TYPE_MMC;
+ mmc_dev.part_type = PART_TYPE_DOS;
+ mmc_dev.dev = 0;
+ mmc_dev.lun = 0;
+ mmc_dev.type = 0;
+ mmc_dev.blksz = hw_sect_size;
+ mmc_dev.lba = hw_nr_sects;
+ sprintf((char*)mmc_dev.vendor, "Unknown vendor");
+ sprintf((char*)mmc_dev.product, "Unknown product");
+ sprintf((char*)mmc_dev.revision, "N/A");
+ mmc_dev.removable = 0; /* should be true??? */
+ mmc_dev.block_read = mmc_block_read;
+
+ fat_register_device(&mmc_dev, 1);
+
+ ret = 0;
+
+ return ret;
+}
+
+int mmc_write(uchar * src, ulong dst, int size)
+{
+#ifdef MMC_DEBUG
+ printf("mmc_write: src=%p, dst=%lu, size=%u\n", src, dst, size);
+#endif
+ /* Since mmc2info always returns 0 this function will never be called */
+ return 0;
+}
+
+int mmc_read(ulong src, uchar * dst, int size)
+{
+#ifdef MMC_DEBUG
+ printf("mmc_read: src=%lu, dst=%p, size=%u\n", src, dst, size);
+#endif
+ /* Since mmc2info always returns 0 this function will never be called */
+ return 0;
+}
+
+int mmc2info(ulong addr)
+{
+ /* This function is used by cmd_cp to determine if source or destination
+ address resides on MMC-card or not. We do not support copy to and from
+ MMC-card so we always return 0. */
+ return 0;
+}
+
+#endif /* CONFIG_MMC */
diff --git a/board/lpc2292sodimm/mmc_hw.c b/board/lpc2292sodimm/mmc_hw.c
new file mode 100644
index 0000000..31f2a79
--- /dev/null
+++ b/board/lpc2292sodimm/mmc_hw.c
@@ -0,0 +1,233 @@
+/*
+ This code was original written by Ulrich Radig and modified by
+ Embedded Artists AB (www.embeddedartists.com).
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <config.h>
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include "spi.h"
+
+#define MMC_Enable() PUT32(IO1CLR, 1l << 22)
+#define MMC_Disable() PUT32(IO1SET, 1l << 22)
+#define mmc_spi_cfg() spi_set_clock(8); spi_set_cfg(0, 1, 0);
+
+static unsigned char Write_Command_MMC (unsigned char *CMD);
+static void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer,
+ unsigned short int Bytes);
+
+/* initialize the hardware */
+int mmc_hw_init(void)
+{
+ unsigned long a;
+ unsigned short int Timeout = 0;
+ unsigned char b;
+ unsigned char CMD[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95};
+
+ /* set-up GPIO and SPI */
+ (*((volatile unsigned long *)PINSEL2)) &= ~(1l << 3); /* clear bit 3 */
+ (*((volatile unsigned long *)IO1DIR)) |= (1l << 22); /* set bit 22 (output) */
+
+ MMC_Disable();
+
+ spi_lock();
+ spi_set_clock(248);
+ spi_set_cfg(0, 1, 0);
+ MMC_Enable();
+
+ /* waste some time */
+ for(a=0; a < 20000; a++)
+ asm("nop");
+
+ /* Put the MMC/SD-card into SPI-mode */
+ for (b = 0; b < 10; b++) /* Sends min 74+ clocks to the MMC/SD-card */
+ spi_write(0xff);
+
+ /* Sends command CMD0 to MMC/SD-card */
+ while (Write_Command_MMC(CMD) != 1) {
+ if (Timeout++ > 200) {
+ MMC_Disable();
+ spi_unlock();
+ return(1); /* Abort with command 1 (return 1) */
+ }
+ }
+ /* Sends Command CMD1 an MMC/SD-card */
+ Timeout = 0;
+ CMD[0] = 0x41;/* Command 1 */
+ CMD[5] = 0xFF;
+
+ while (Write_Command_MMC(CMD) != 0) {
+ if (Timeout++ > 200) {
+ MMC_Disable();
+ spi_unlock();
+ return (2); /* Abort with command 2 (return 2) */
+ }
+ }
+
+ MMC_Disable();
+ spi_unlock();
+
+ return 0;
+}
+
+/* ############################################################################
+ Sends a command to the MMC/SD-card
+ ######################################################################### */
+static unsigned char Write_Command_MMC (unsigned char *CMD)
+{
+ unsigned char a, tmp = 0xff;
+ unsigned short int Timeout = 0;
+
+ MMC_Disable();
+ spi_write(0xFF);
+ MMC_Enable();
+
+ for (a = 0; a < 0x06; a++)
+ spi_write(*CMD++);
+
+ while (tmp == 0xff) {
+ tmp = spi_read();
+ if (Timeout++ > 5000)
+ break;
+ }
+
+ return (tmp);
+}
+
+/* ############################################################################
+ Routine to read the CID register from the MMC/SD-card (16 bytes)
+ ######################################################################### */
+void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer, unsigned short
+ int Bytes)
+{
+ unsigned short int a;
+
+ spi_lock();
+ mmc_spi_cfg();
+ MMC_Enable();
+
+ if (Write_Command_MMC(CMD) != 0) {
+ MMC_Disable();
+ spi_unlock();
+ return;
+ }
+
+ while (spi_read() != 0xfe) {};
+ for (a = 0; a < Bytes; a++)
+ *Buffer++ = spi_read();
+
+ /* Read the CRC-byte */
+ spi_read(); /* CRC - byte is discarded */
+ spi_read(); /* CRC - byte is discarded */
+ /* set MMC_Chip_Select to high (MMC/SD-card Inaktiv) */
+ MMC_Disable();
+ spi_unlock();
+
+ return;
+}
+
+/* ############################################################################
+ Routine to read a block (512 bytes) from the MMC/SD-card
+ ######################################################################### */
+unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer)
+{
+ /* Command 16 to read aBlocks from the MMC/SD - caed */
+ unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
+
+ /* The addres on the MMC/SD-card is in bytes,
+ addr is transformed from blocks to bytes and the result is
+ placed into the command */
+
+ addr = addr << 9; /* addr = addr * 512 */
+
+ CMD[1] = ((addr & 0xFF000000) >> 24);
+ CMD[2] = ((addr & 0x00FF0000) >> 16);
+ CMD[3] = ((addr & 0x0000FF00) >> 8 );
+
+ MMC_Read_Block(CMD, Buffer, 512);
+
+ return (0);
+}
+
+/* ############################################################################
+ Routine to write a block (512 byte) to the MMC/SD-card
+ ######################################################################### */
+unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer)
+{
+ unsigned char tmp, a;
+ unsigned short int b;
+ /* Command 24 to write a block to the MMC/SD - card */
+ unsigned char CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};
+
+ /* The addres on the MMC/SD-card is in bytes,
+ addr is transformed from blocks to bytes and the result is
+ placed into the command */
+
+ addr = addr << 9; /* addr = addr * 512 */
+
+ CMD[1] = ((addr & 0xFF000000) >> 24);
+ CMD[2] = ((addr & 0x00FF0000) >> 16);
+ CMD[3] = ((addr & 0x0000FF00) >> 8 );
+
+ spi_lock();
+ mmc_spi_cfg();
+ MMC_Enable();
+
+ /* Send command CMD24 to the MMC/SD-card (Write 1 Block/512 Bytes) */
+ tmp = Write_Command_MMC(CMD);
+ if (tmp != 0) {
+ MMC_Disable();
+ spi_unlock();
+ return(tmp);
+ }
+
+ /* Do a short delay and send a clock-pulse to the MMC/SD-card */
+ for (a = 0; a < 100; a++)
+ spi_read();
+
+ /* Send a start byte to the MMC/SD-card */
+ spi_write(0xFE);
+
+ /* Write the block (512 bytes) to the MMC/SD-card */
+ for (b = 0; b < 512; b++)
+ spi_write(*Buffer++);
+
+ /* write the CRC-Byte */
+ spi_write(0xFF); /* write a dummy CRC */
+ spi_write(0xFF); /* CRC code is not used */
+
+ /* Wait for MMC/SD-card busy */
+ while (spi_read() != 0xff) {};
+
+ /* set MMC_Chip_Select to high (MMC/SD-card inactive) */
+ MMC_Disable();
+ spi_unlock();
+ return (0);
+}
+
+/* #########################################################################
+ Routine to read the CSD register from the MMC/SD-card (16 bytes)
+ ######################################################################### */
+unsigned char mmc_read_csd (unsigned char *Buffer)
+{
+ /* Command to read the CSD register */
+ unsigned char CMD[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0xFF};
+
+ MMC_Read_Block(CMD, Buffer, 16);
+
+ return (0);
+}
diff --git a/board/lpc2292sodimm/mmc_hw.h b/board/lpc2292sodimm/mmc_hw.h
new file mode 100644
index 0000000..3687dbf
--- /dev/null
+++ b/board/lpc2292sodimm/mmc_hw.h
@@ -0,0 +1,29 @@
+/*
+ This module implements a linux character device driver for the 24c256 chip.
+ Copyright (C) 2006 Embedded Artists AB (www.embeddedartists.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _MMC_HW_
+#define _MMC_HW_
+
+unsigned char mmc_read_csd(unsigned char *Buffer);
+unsigned char mmc_read_sector (unsigned long addr,
+ unsigned char *Buffer);
+unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer);
+int mmc_hw_init(void);
+
+#endif /* _MMC_HW_ */
diff --git a/board/lpc2292sodimm/spi.c b/board/lpc2292sodimm/spi.c
new file mode 100644
index 0000000..4ba1468
--- /dev/null
+++ b/board/lpc2292sodimm/spi.c
@@ -0,0 +1,40 @@
+/*
+ This module implements an interface to the SPI on the lpc22xx.
+ Copyright (C) 2006 Embedded Artists AB (www.embeddedartists.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <config.h>
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+#include "spi.h"
+
+unsigned long spi_flags;
+unsigned char spi_idle = 0x00;
+
+int spi_init(void)
+{
+ unsigned long pinsel0_value;
+
+ /* activate spi pins */
+ pinsel0_value = GET32(PINSEL0);
+ pinsel0_value &= ~(0xFFl << 8);
+ pinsel0_value |= (0x55l << 8);
+ PUT32(PINSEL0, pinsel0_value);
+
+ return 0;
+}
diff --git a/board/lpc2292sodimm/spi.h b/board/lpc2292sodimm/spi.h
new file mode 100644
index 0000000..6ae66e8
--- /dev/null
+++ b/board/lpc2292sodimm/spi.h
@@ -0,0 +1,82 @@
+/*
+ This file defines the interface to the lpc22xx SPI module.
+ Copyright (C) 2006 Embedded Artists AB (www.embeddedartists.com)
+
+ This file may be included in software not adhering to the GPL.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef SPI_H
+#define SPI_H
+
+#include <config.h>
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+
+#define SPIF 0x80
+
+#define spi_lock() disable_interrupts();
+#define spi_unlock() enable_interrupts();
+
+extern unsigned long spi_flags;
+extern unsigned char spi_idle;
+
+int spi_init(void);
+
+static inline unsigned char spi_read(void)
+{
+ unsigned char b;
+
+ PUT8(S0SPDR, spi_idle);
+ while (!(GET8(S0SPSR) & SPIF));
+ b = GET8(S0SPDR);
+
+ return b;
+}
+
+static inline void spi_write(unsigned char b)
+{
+ PUT8(S0SPDR, b);
+ while (!(GET8(S0SPSR) & SPIF));
+ GET8(S0SPDR); /* this will clear the SPIF bit */
+}
+
+static inline void spi_set_clock(unsigned char clk_value)
+{
+ PUT8(S0SPCCR, clk_value);
+}
+
+static inline void spi_set_cfg(unsigned char phase,
+ unsigned char polarity,
+ unsigned char lsbf)
+{
+ unsigned char v = 0x20; /* master bit set */
+
+ if (phase)
+ v |= 0x08; /* set phase bit */
+ if (polarity) {
+ v |= 0x10; /* set polarity bit */
+ spi_idle = 0xFF;
+ } else {
+ spi_idle = 0x00;
+ }
+ if (lsbf)
+ v |= 0x40; /* set lsbf bit */
+
+ PUT8(S0SPCR, v);
+}
+#endif /* SPI_H */
diff --git a/board/lpc2292sodimm/u-boot.lds b/board/lpc2292sodimm/u-boot.lds
new file mode 100644
index 0000000..64d946c
--- /dev/null
+++ b/board/lpc2292sodimm/u-boot.lds
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm720t/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss) }
+ _end = .;
+}